File _service:download_files:931a40a..823918e.patch of Package exiv2

From 04e4923bbdbd420b76f86960f5f32e3f07151495 Mon Sep 17 00:00:00 2001
From: antermin <103918092+antermin@users.noreply.github.com>
Date: Thu, 8 Jun 2023 20:16:05 +0900
Subject: [PATCH 1/3] Add getUint64_t

---
 src/helper_functions.cpp | 9 +++++++++
 src/helper_functions.hpp | 5 +++++
 2 files changed, 14 insertions(+)

diff --git a/src/helper_functions.cpp b/src/helper_functions.cpp
index 6894ab3911..804b64140a 100644
--- a/src/helper_functions.cpp
+++ b/src/helper_functions.cpp
@@ -62,4 +62,13 @@ std::string getAspectRatio(uint64_t width, uint64_t height) {
   return std::to_string(ratioWidth) + ":" + std::to_string(ratioHeight);
 }
 
+uint64_t getUint64_t(Exiv2::DataBuf& buf) {
+    uint64_t temp = 0;
+
+    for(size_t i = 0; i < buf.size(); ++i){
+        temp = temp + static_cast<uint64_t>((buf.read_uint8(i))*(pow(static_cast<float>(256), static_cast<float>(i))));
+    }
+    return temp;
+}
+
 }  // namespace Exiv2
diff --git a/src/helper_functions.hpp b/src/helper_functions.hpp
index a7c820e917..a56e80fab0 100644
--- a/src/helper_functions.hpp
+++ b/src/helper_functions.hpp
@@ -47,5 +47,10 @@ static constexpr size_t GUID = 0x10;
  */
 [[nodiscard]] std::string getAspectRatio(uint64_t width, uint64_t height);
 
+/*!
+  @brief Converts buffer data into 64-bit Integer, information stored in littleEndian format
+ */
+[[nodiscard]] uint64_t getUint64_t(Exiv2::DataBuf& buf);
+
 }  // namespace Exiv2
 #endif  // HELPER_FUNCTIONS_HPP

From 27a99a3f8bd009048e31ce8061d8b0b84da6ba46 Mon Sep 17 00:00:00 2001
From: antermin <103918092+antermin@users.noreply.github.com>
Date: Thu, 8 Jun 2023 20:16:36 +0900
Subject: [PATCH 2/3] Experimental JXL/codestream support

---
 include/exiv2/image_types.hpp |   1 +
 include/exiv2/jxlimage.hpp    |  85 ++++++++++++++++++++++++++++
 src/CMakeLists.txt            |   3 +
 src/image.cpp                 |   2 +
 src/jxlimage.cpp              | 103 ++++++++++++++++++++++++++++++++++
 src/jxlimage_int.cpp          |  67 ++++++++++++++++++++++
 src/jxlimage_int.hpp          |  25 +++++++++
 7 files changed, 286 insertions(+)
 create mode 100644 include/exiv2/jxlimage.hpp
 create mode 100644 src/jxlimage.cpp
 create mode 100644 src/jxlimage_int.cpp
 create mode 100644 src/jxlimage_int.hpp

diff --git a/include/exiv2/image_types.hpp b/include/exiv2/image_types.hpp
index 93502c2b48..ebf556f8bf 100644
--- a/include/exiv2/image_types.hpp
+++ b/include/exiv2/image_types.hpp
@@ -20,6 +20,7 @@ enum class ImageType {
   gif,  ///< GIF
   jp2,  ///< JPEG-2000
   jpeg,
+  jxl,  ///< JPEG XL (JXL)
   mrw,
   nef,
   orf,
diff --git a/include/exiv2/jxlimage.hpp b/include/exiv2/jxlimage.hpp
new file mode 100644
index 0000000000..1db2966eb4
--- /dev/null
+++ b/include/exiv2/jxlimage.hpp
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*!
+  @author  antermin
+  @date    18-Mar-2023, antermin: created
+ */
+#ifndef JXLIMAGE_HPP_
+#define JXLIMAGE_HPP_
+
+// *****************************************************************************
+#include "exiv2lib_export.h"
+
+// included header files
+#include "image.hpp"
+
+// *****************************************************************************
+// namespace extensions
+namespace Exiv2 {
+// *****************************************************************************
+// class definitions
+
+/*!
+  @brief Class to access JPEG XL bare codestream. This is just a stub - we only
+      read width and height.
+*/
+class EXIV2API JxlImage : public Image {
+ public:
+  //! @name Creators
+  //@{
+  /*!
+    @brief Constructor to open a JPEG XL bare codestream. Since the
+        constructor can not return a result, callers should check the
+        good() method after object construction to determine success
+        or failure.
+    @param io An auto-pointer that owns a BasicIo instance used for
+        reading and writing image metadata. \b Important: The constructor
+        takes ownership of the passed in BasicIo instance through the
+        auto-pointer. Callers should not continue to use the BasicIo
+        instance after it is passed to this method.  Use the Image::io()
+        method to get a temporary reference.
+   */
+  explicit JxlImage(BasicIo::UniquePtr io);
+  //@}
+
+  //! @name Manipulators
+  //@{
+  void readMetadata() override;
+
+  /// @throws Error(ErrorCode::kerWritingImageFormatUnsupported).
+  void writeMetadata() override;
+
+  /// @throws Error(ErrorCode::kerInvalidSettingForImage)
+  void setExifData(const ExifData& exifData) override;
+
+  /// @throws Error(ErrorCode::kerInvalidSettingForImage)
+  void setIptcData(const IptcData& iptcData) override;
+
+  /// @throws Error(ErrorCode::kerInvalidSettingForImage)
+  void setComment(const std::string&) override;
+  //@}
+
+  //! @name Accessors
+  //@{
+  [[nodiscard]] std::string mimeType() const override;
+  //@}
+};  // class JxlImage
+
+// *****************************************************************************
+// template, inline and free functions
+
+// These could be static private functions on Image subclasses but then
+// ImageFactory needs to be made a friend.
+/*!
+  @brief Create a new JxlImage instance and return an auto-pointer to it.
+         Caller owns the returned object and the auto-pointer ensures that
+         it will be deleted.
+ */
+EXIV2API Image::UniquePtr newJxlInstance(BasicIo::UniquePtr io, bool create);
+
+//! Check if the file iIo is a JPEG XL bare codestream.
+EXIV2API bool isJxlType(BasicIo& iIo, bool advance);
+
+}  // namespace Exiv2
+
+#endif  // #ifndef JXLIMAGE_HPP_
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 41a672e89e..1dccdd7c1a 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -18,6 +18,7 @@ add_library( exiv2lib_int OBJECT
     helper_functions.cpp    helper_functions.hpp
     image_int.cpp           image_int.hpp
     jp2image_int.cpp        jp2image_int.hpp
+    jxlimage_int.cpp        jxlimage_int.hpp
     makernote_int.cpp       makernote_int.hpp
     minoltamn_int.cpp       minoltamn_int.hpp
     nikonmn_int.cpp         nikonmn_int.hpp
@@ -60,6 +61,7 @@ set(PUBLIC_HEADERS
     ../include/exiv2/iptc.hpp
     ../include/exiv2/jp2image.hpp
     ../include/exiv2/jpgimage.hpp
+    ../include/exiv2/jxlimage.hpp
     ../include/exiv2/metadatum.hpp
     ../include/exiv2/mrwimage.hpp
     ../include/exiv2/orfimage.hpp
@@ -103,6 +105,7 @@ add_library( exiv2lib
     iptc.cpp
     jp2image.cpp
     jpgimage.cpp
+    jxlimage.cpp
     metadatum.cpp
     mrwimage.cpp
     orfimage.cpp
diff --git a/src/image.cpp b/src/image.cpp
index 05d8345f9d..9b1d2a053d 100644
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -26,6 +26,7 @@
 #include "bmpimage.hpp"
 #include "gifimage.hpp"
 #include "jp2image.hpp"
+#include "jxlimage.hpp"
 #include "nikonmn_int.hpp"
 #include "orfimage.hpp"
 #include "pgfimage.hpp"
@@ -103,6 +104,7 @@ constexpr Registry registry[] = {
     {ImageType::tga, newTgaInstance, isTgaType, amNone, amNone, amNone, amNone},
     {ImageType::bmp, newBmpInstance, isBmpType, amNone, amNone, amNone, amNone},
     {ImageType::jp2, newJp2Instance, isJp2Type, amReadWrite, amReadWrite, amReadWrite, amNone},
+    {ImageType::jxl, newJxlInstance, isJxlType, amNone, amNone, amNone, amNone},
 // needs to be before bmff because some ftyp files are handled as qt and
 // the rest should fall through to bmff
 #ifdef EXV_ENABLE_VIDEO
diff --git a/src/jxlimage.cpp b/src/jxlimage.cpp
new file mode 100644
index 0000000000..484a64cb61
--- /dev/null
+++ b/src/jxlimage.cpp
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+  File:      jxlimage.cpp
+  Author(s): antermin
+  History:   18-Mar-2023, antermin: created
+ */
+
+// included header files
+#include "jxlimage.hpp"
+#include "jxlimage_int.hpp"
+
+#include "config.h"
+
+#include "basicio.hpp"
+#include "error.hpp"
+#include "futils.hpp"
+#include "helper_functions.hpp"
+#include "image.hpp"
+
+// + standard includes
+#include <cstring>
+#include <iostream>
+#include <string>
+
+// *****************************************************************************
+// class member definitions
+namespace Exiv2 {
+JxlImage::JxlImage(BasicIo::UniquePtr io) : Image(ImageType::jxl, mdNone, std::move(io)) {
+}
+
+std::string JxlImage::mimeType() const {
+  return "image/jxl";
+}
+
+void JxlImage::setExifData(const ExifData& /*exifData*/) {
+  throw(Error(ErrorCode::kerInvalidSettingForImage, "Exif metadata", "JXL"));
+}
+
+void JxlImage::setIptcData(const IptcData& /*iptcData*/) {
+  throw(Error(ErrorCode::kerInvalidSettingForImage, "IPTC metadata", "JXL"));
+}
+
+void JxlImage::setComment(const std::string&) {
+  throw(Error(ErrorCode::kerInvalidSettingForImage, "Image comment", "JXL"));
+}
+
+void JxlImage::readMetadata() {
+#ifdef EXIV2_DEBUG_MESSAGES
+  std::cerr << "Exiv2::JxlImage::readMetadata: Reading JXL bare codestream " << io_->path() << "\n";
+#endif
+  if (io_->open() != 0) {
+    throw Error(ErrorCode::kerDataSourceOpenFailed, io_->path(), strError());
+  }
+  IoCloser closer(*io_);
+
+  // Ensure that this is the correct image type
+  if (!isJxlType(*io_, false)) {
+    if (io_->error() || io_->eof())
+      throw Error(ErrorCode::kerFailedToReadImageData);
+    throw Error(ErrorCode::kerNotAnImage, "JXL");
+  }
+  clearMetadata();
+
+  DataBuf data(11); // Takes up to 11 bytes to parse width and height
+  if (io_->read(data.data(), data.size())) {
+    Internal::JxlStream jxlstream;
+    jxlstream.databits = getUint64_t(data);
+    Internal::parseJxlDimensions(&jxlstream, false); // false: !nosig
+    pixelHeight_ = jxlstream.height;
+    pixelWidth_ = jxlstream.width;
+  }
+}
+
+void JxlImage::writeMetadata() {
+  /// \todo implement me!
+  throw(Error(ErrorCode::kerWritingImageFormatUnsupported, "JXL"));
+}
+
+// *************************************************************************
+// free functions
+Image::UniquePtr newJxlInstance(BasicIo::UniquePtr io, bool /*create*/) {
+  auto image = std::make_unique<JxlImage>(std::move(io));
+  if (!image->good()) {
+    return nullptr;
+  }
+  return image;
+}
+
+bool isJxlType(BasicIo& iIo, bool advance) {
+  const int32_t len = 2;
+  const unsigned char JxlImageId[2] = { 0xFF, 0x0A };
+  byte buf[len];
+  iIo.read(buf, len);
+  if (iIo.error() || iIo.eof()) {
+    return false;
+  }
+  bool matched = (memcmp(buf, JxlImageId, len) == 0);
+  if (!advance || !matched) {
+    iIo.seek(-len, BasicIo::cur);
+  }
+  return matched;
+}
+}  // namespace Exiv2
diff --git a/src/jxlimage_int.cpp b/src/jxlimage_int.cpp
new file mode 100644
index 0000000000..260d2b0277
--- /dev/null
+++ b/src/jxlimage_int.cpp
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "jxlimage_int.hpp"
+
+#include "error.hpp"
+#include "types.hpp"
+
+#include <cassert>
+
+namespace Exiv2::Internal {
+
+uint64_t JxlStream::getBits(int length) {
+  uint64_t bitmask = (1 << length) -1;
+  uint64_t value = (databits >> position) & bitmask;
+  position += length; //advance position after getting bits
+  return value;
+}
+
+uint64_t JxlStream::readU32(int c0, int u0, int c1, int u1, int c2, int u2, int c3, int u3) {
+  int dist = getBits(2);
+  int c[] = {c0, c1, c2, c3};
+  int u[] = {u0, u1, u2, u3};
+  return c[dist] + getBits(u[dist]);
+}
+
+void parseJxlDimensions(JxlStream *stream, bool nosig) {
+  // if stream has signature, we need to skip it
+  nosig ? stream->position = 0 : stream->position = 16;
+
+  int div8 = stream->getBits(1);
+  if (div8) {
+      stream->height = (1 + stream->getBits(5)) << 3; // multiply 8
+  } else {
+      stream->height = stream->readU32(1, 9, 1, 13, 1, 18, 1, 30);
+  }
+  int ratio = stream->getBits(3);
+  if ((div8) && (!ratio)) {
+      stream->width = (1 + stream->getBits(5)) << 3; // multiply 8
+  } else if (!ratio) {
+      stream->width = stream->readU32(1, 9, 1, 13, 1, 18, 1, 30);
+  } else {
+    switch (ratio) {
+      case 1:
+        stream->width = stream->height;
+        break;
+      case 2:
+        stream->width = (stream->height * 12) / 10;
+        break;
+      case 3:
+        stream->width = (stream->height * 4) / 3;
+        break;
+      case 4:
+        stream->width = (stream->height * 3) / 2;
+        break;
+      case 5:
+        stream->width = (stream->height * 16) / 9;
+        break;
+      case 6:
+        stream->width = (stream->height * 5) / 4;
+        break;
+      case 7:
+        stream->width = (stream->height * 2);
+        break;
+    }
+  }
+}
+}  // namespace Exiv2::Internal
diff --git a/src/jxlimage_int.hpp b/src/jxlimage_int.hpp
new file mode 100644
index 0000000000..8c7f55413b
--- /dev/null
+++ b/src/jxlimage_int.hpp
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifndef JXLIMAGE_INT_HPP
+#define JXLIMAGE_INT_HPP
+
+#include <stdint.h>
+#include <vector>
+
+namespace Exiv2::Internal {
+
+class JxlStream {
+ public:
+  uint64_t databits;
+  int position;
+  uint64_t width;
+  uint64_t height;
+  uint64_t getBits(int);
+  uint64_t readU32(int, int, int, int, int, int, int, int);
+}; // class JxlStream
+
+void parseJxlDimensions(JxlStream *stream, bool nosig);
+
+}  // namespace Exiv2::Internal
+
+#endif  // JXLIMAGE_INT_HPP

From 823918e9e6ca9cc29b5917607fb56a3346ba6f7b Mon Sep 17 00:00:00 2001
From: antermin <103918092+antermin@users.noreply.github.com>
Date: Thu, 8 Jun 2023 20:18:40 +0900
Subject: [PATCH 3/3] Experimental jxlp and jxlc support

---
 include/exiv2/bmffimage.hpp |  1 +
 src/bmffimage.cpp           | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/include/exiv2/bmffimage.hpp b/include/exiv2/bmffimage.hpp
index b634953925..4a407152c0 100644
--- a/include/exiv2/bmffimage.hpp
+++ b/include/exiv2/bmffimage.hpp
@@ -148,6 +148,7 @@ class EXIV2API BmffImage : public Image {
   static bool superBox(uint32_t box);
   static bool fullBox(uint32_t box);
   static std::string uuidName(const Exiv2::DataBuf& uuid);
+  bool hasJxlHeader(const Exiv2::DataBuf& jxlpdata);
 
   /*!
     @brief Wrapper around brotli to uncompress JXL brob content.
diff --git a/src/bmffimage.cpp b/src/bmffimage.cpp
index 3698d57e09..677b584e79 100644
--- a/src/bmffimage.cpp
+++ b/src/bmffimage.cpp
@@ -11,10 +11,12 @@
 #include "image.hpp"
 #include "image_int.hpp"
 #include "safe_op.hpp"
+#include "jxlimage_int.hpp"
 #include "tiffimage.hpp"
 #include "tiffimage_int.hpp"
 #include "types.hpp"
 #include "utils.hpp"
+#include "helper_functions.hpp"
 
 #ifdef EXV_HAVE_BROTLI
 #include <brotli/decode.h>  // for JXL brob
@@ -40,6 +42,8 @@ enum {
   TAG_mif1 = 0x6d696631U,  ///< "mif1" HEIF */
   TAG_crx = 0x63727820U,   ///< "crx " Canon CR3 */
   TAG_jxl = 0x6a786c20U,   ///< "jxl " JPEG XL file type */
+  TAG_jxlc = 0x6a786c63U,  ///< "jxlc" JPEG XL codestream */
+  TAG_jxlp = 0x6a786c70U,  ///< "jxlp" JPEG XL partial codestream */
   TAG_moov = 0x6d6f6f76U,  ///< "moov" Movie */
   TAG_meta = 0x6d657461U,  ///< "meta" Metadata */
   TAG_mdat = 0x6d646174U,  ///< "mdat" Media data */
@@ -163,6 +167,11 @@ std::string BmffImage::uuidName(const Exiv2::DataBuf& uuid) {
   return "";
 }
 
+bool BmffImage::hasJxlHeader(const Exiv2::DataBuf& jxlpdata) {
+  const char* JxlHeader = "\x00\x00\x00\x00\xFF\x0A";
+  return (jxlpdata.cmpBytes(0, JxlHeader, 6) == 0 ? true : false);
+}
+
 #ifdef EXV_HAVE_BROTLI
 
 // Wrapper class for BrotliDecoderState that automatically calls
@@ -570,6 +579,31 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
           break;
       }
       break;
+    case TAG_jxlp: {
+      DataBuf sig(6); // 4 bytes padding + 2 bytes sig
+      io_->read(sig.data(), sig.size());
+      if (hasJxlHeader(sig)) {
+#ifdef EXIV2_DEBUG_MESSAGES
+        std::cerr << "Exiv2::BmffImage::boxHandler: JXL Header found in this jxlp box" << "\n";
+#endif
+        DataBuf streamdata(9); // Max 11 bytes - 2 bytes sig
+        io_->read(streamdata.data(), streamdata.size());
+        Internal::JxlStream jxlstream;
+        jxlstream.databits = getUint64_t(streamdata);
+        Internal::parseJxlDimensions(&jxlstream, true); // true: nosig
+        pixelHeight_ = jxlstream.height;
+        pixelWidth_ = jxlstream.width;
+      }
+    } break;
+    case TAG_jxlc: {
+      DataBuf streamdata(11);
+      io_->read(streamdata.data(), streamdata.size());
+      Internal::JxlStream jxlstream;
+      jxlstream.databits = getUint64_t(streamdata);
+      Internal::parseJxlDimensions(&jxlstream, false); // false: !nosig
+      pixelHeight_ = jxlstream.height;
+      pixelWidth_ = jxlstream.width;
+    } break;
 
     default:
       break; /* do nothing */
openSUSE Build Service is sponsored by