Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:user5664536:linux
exiv2
_service:download_files:c351c7c..f4dfcf2.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:download_files:c351c7c..f4dfcf2.patch of Package exiv2
From 94a5af7ce942a8cfd375f274de7ebb6d1971d790 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/4] 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 7b1f2c1b1716ef926dca2271acc63ee77e82d832 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/4] 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 f1b27b861b..27b04dd4e7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,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 @@ -54,6 +55,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 @@ -97,6 +99,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 7a11b2d0a31cace7be0b2e4490d54e84287e79df 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/4] 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 38532dcc7a..f937dbb26e 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 @@ -575,6 +584,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 */ From f4dfcf2e3ade702cc85137cbe1ccda71edc438f2 Mon Sep 17 00:00:00 2001 From: antermin <103918092+antermin@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:14:53 +0900 Subject: [PATCH 4/4] Prioritize actual image dimensions --- src/bmffimage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bmffimage.cpp b/src/bmffimage.cpp index f937dbb26e..c595cfb151 100644 --- a/src/bmffimage.cpp +++ b/src/bmffimage.cpp @@ -144,14 +144,14 @@ uint32_t BmffImage::pixelWidth() const { auto imageWidth = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension")); if (imageWidth == exifData_.end() || imageWidth->count() == 0) return pixelWidth_; - return imageWidth->toUint32(); + return (pixelWidth_ > 0 ? pixelWidth_ : imageWidth->toUint32()); } uint32_t BmffImage::pixelHeight() const { auto imageHeight = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelYDimension")); if (imageHeight == exifData_.end() || imageHeight->count() == 0) return pixelHeight_; - return imageHeight->toUint32(); + return (pixelHeight_ > 0 ? pixelHeight_ : imageHeight->toUint32()); } std::string BmffImage::uuidName(const Exiv2::DataBuf& uuid) {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor