diff options
Diffstat (limited to 'third_party/jpeg-xl')
201 files changed, 2044 insertions, 1226 deletions
diff --git a/third_party/jpeg-xl/AUTHORS b/third_party/jpeg-xl/AUTHORS index ed6d72db66..3f3675858d 100644 --- a/third_party/jpeg-xl/AUTHORS +++ b/third_party/jpeg-xl/AUTHORS @@ -39,6 +39,7 @@ Alistair Barrow Andrius Lukas Narbutas <andrius4669@gmail.com> Aous Naman <aous@unsw.edu.au> Artem Selishchev +Aryan Pingle <realaryanpingle@gmail.com> Biswapriyo Nath <nathbappai@gmail.com> CanadianBaconBoi <beamconnor@gmail.com> Damiano Albani <damiano.albani@gmail.com> @@ -53,6 +54,7 @@ Dong Xu <xdong181@gmail.com> estrogently <41487185+estrogently@users.noreply.github.com> Even Rouault <even.rouault@spatialys.com> Fred Brennan <copypaste@kittens.ph> +Gerhard Huber <support@pl32.com> gi-man Gilles Devillers (GilDev) <gildev@gmail.com> Heiko Becker <heirecka@exherbo.org> diff --git a/third_party/jpeg-xl/CMakeLists.txt b/third_party/jpeg-xl/CMakeLists.txt index 9b74537f1c..ea8ccc43ba 100644 --- a/third_party/jpeg-xl/CMakeLists.txt +++ b/third_party/jpeg-xl/CMakeLists.txt @@ -160,7 +160,7 @@ set(JPEGXL_ENABLE_AVX512_SPR false CACHE BOOL "Build with AVX-512FP16 support (faster on CPUs that support it, but larger binary size).") set(JPEGXL_ENABLE_AVX512_ZEN4 false CACHE BOOL "Build with Zen4-optimized AVX512 support (faster on CPUs that support it, but larger binary size).") -set(JPEGXL_ENABLE_WASM_TRHEADS true CACHE BOOL +set(JPEGXL_ENABLE_WASM_THREADS true CACHE BOOL "Builds WASM modules with threads support") # Force system dependencies. @@ -211,10 +211,12 @@ if(JPEGXL_STATIC) # Clang developers say that in case to use "static" we have to build stdlib # ourselves; for real use case we don't care about stdlib, as it is "granted", # so just linking all other libraries is fine. - if (NOT MSVC AND NOT APPLE) + if (NOT MSVC) + string(APPEND CMAKE_EXE_LINKER_FLAGS " -static") + endif() + if ((NOT WIN32 AND NOT APPLE) OR CYGWIN OR MINGW) set(CMAKE_FIND_LIBRARY_SUFFIXES .a) - set(CMAKE_EXE_LINKER_FLAGS - "${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++") + string(APPEND CMAKE_EXE_LINKER_FLAGS " -static-libgcc -static-libstdc++") endif() endif() # JPEGXL_STATIC @@ -265,7 +267,7 @@ if(JPEGXL_STATIC) endif() endif() # JPEGXL_STATIC -if (EMSCRIPTEN AND JPEGXL_ENABLE_WASM_TRHEADS) +if (EMSCRIPTEN AND JPEGXL_ENABLE_WASM_THREADS) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") diff --git a/third_party/jpeg-xl/examples/decode_progressive.cc b/third_party/jpeg-xl/examples/decode_progressive.cc index 2cdc175e8a..7a3a9aa33b 100644 --- a/third_party/jpeg-xl/examples/decode_progressive.cc +++ b/third_party/jpeg-xl/examples/decode_progressive.cc @@ -10,16 +10,16 @@ #define __STDC_FORMAT_MACROS #endif -#include <inttypes.h> #include <jxl/decode.h> #include <jxl/decode_cxx.h> #include <jxl/resizable_parallel_runner.h> #include <jxl/resizable_parallel_runner_cxx.h> #include <limits.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> +#include <cinttypes> // PRIu64 +#include <cstdint> +#include <cstdio> +#include <cstring> #include <vector> bool WritePAM(const char* filename, const uint8_t* buffer, size_t w, size_t h) { diff --git a/third_party/jpeg-xl/lib/extras/dec/apng.cc b/third_party/jpeg-xl/lib/extras/dec/apng.cc index c607a71d08..824a6f47ee 100644 --- a/third_party/jpeg-xl/lib/extras/dec/apng.cc +++ b/third_party/jpeg-xl/lib/extras/dec/apng.cc @@ -38,8 +38,10 @@ #include <jxl/codestream_header.h> #include <jxl/encode.h> -#include <string.h> +#include <array> +#include <cstdint> +#include <cstring> #include <string> #include <utility> #include <vector> @@ -49,8 +51,7 @@ #include "lib/jxl/base/common.h" #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/printf_macros.h" -#include "lib/jxl/base/scope_guard.h" -#include "lib/jxl/sanitizers.h" +#include "lib/jxl/base/span.h" #if JPEGXL_ENABLE_APNG #include "png.h" /* original (unpatched) libpng is ok */ #endif @@ -58,39 +59,49 @@ namespace jxl { namespace extras { -#if JPEGXL_ENABLE_APNG +#if !JPEGXL_ENABLE_APNG + +bool CanDecodeAPNG() { return false; } +Status DecodeImageAPNG(const Span<const uint8_t> bytes, + const ColorHints& color_hints, PackedPixelFile* ppf, + const SizeConstraints* constraints) { + return false; +} + +#else // JPEGXL_ENABLE_APNG + namespace { -constexpr unsigned char kExifSignature[6] = {0x45, 0x78, 0x69, - 0x66, 0x00, 0x00}; +constexpr uint8_t kExifSignature[6] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; /* hIST chunk tail is not proccesed properly; skip this chunk completely; see https://github.com/glennrp/libpng/pull/413 */ -const png_byte kIgnoredPngChunks[] = { - 104, 73, 83, 84, '\0' /* hIST */ -}; +const uint8_t kIgnoredPngChunks[] = {'h', 'I', 'S', 'T', '\0'}; // Returns floating-point value from the PNG encoding (times 10^5). double F64FromU32(const uint32_t x) { return static_cast<int32_t>(x) * 1E-5; } -Status DecodeSRGB(const unsigned char* payload, const size_t payload_size, - JxlColorEncoding* color_encoding) { - if (payload_size != 1) return JXL_FAILURE("Wrong sRGB size"); +/** Extract information from 'sRGB' chunk. */ +Status DecodeSrgbChunk(const Bytes payload, JxlColorEncoding* color_encoding) { + if (payload.size() != 1) return JXL_FAILURE("Wrong sRGB size"); + uint8_t ri = payload[0]; // (PNG uses the same values as ICC.) - if (payload[0] >= 4) return JXL_FAILURE("Invalid Rendering Intent"); + if (ri >= 4) return JXL_FAILURE("Invalid Rendering Intent"); color_encoding->white_point = JXL_WHITE_POINT_D65; color_encoding->primaries = JXL_PRIMARIES_SRGB; color_encoding->transfer_function = JXL_TRANSFER_FUNCTION_SRGB; - color_encoding->rendering_intent = - static_cast<JxlRenderingIntent>(payload[0]); + color_encoding->rendering_intent = static_cast<JxlRenderingIntent>(ri); return true; } -// If the cICP profile is not fully supported, return false and leave -// color_encoding unmodified. -Status DecodeCICP(const unsigned char* payload, const size_t payload_size, - JxlColorEncoding* color_encoding) { - if (payload_size != 4) return JXL_FAILURE("Wrong cICP size"); +/** + * Extract information from 'cICP' chunk. + * + * If the cICP profile is not fully supported, return `false` and leave + * `color_encoding` unmodified. + */ +Status DecodeCicpChunk(const Bytes payload, JxlColorEncoding* color_encoding) { + if (payload.size() != 4) return JXL_FAILURE("Wrong cICP size"); JxlColorEncoding color_enc = *color_encoding; // From https://www.itu.int/rec/T-REC-H.273-202107-I/en @@ -217,257 +228,279 @@ Status DecodeCICP(const unsigned char* payload, const size_t payload_size, return true; } -Status DecodeGAMA(const unsigned char* payload, const size_t payload_size, - JxlColorEncoding* color_encoding) { - if (payload_size != 4) return JXL_FAILURE("Wrong gAMA size"); +/** Extract information from 'gAMA' chunk. */ +Status DecodeGamaChunk(Bytes payload, JxlColorEncoding* color_encoding) { + if (payload.size() != 4) return JXL_FAILURE("Wrong gAMA size"); color_encoding->transfer_function = JXL_TRANSFER_FUNCTION_GAMMA; - color_encoding->gamma = F64FromU32(LoadBE32(payload)); + color_encoding->gamma = F64FromU32(LoadBE32(payload.data())); return true; } -Status DecodeCHRM(const unsigned char* payload, const size_t payload_size, - JxlColorEncoding* color_encoding) { - if (payload_size != 32) return JXL_FAILURE("Wrong cHRM size"); - +/** Extract information from 'cHTM' chunk. */ +Status DecodeChrmChunk(Bytes payload, JxlColorEncoding* color_encoding) { + if (payload.size() != 32) return JXL_FAILURE("Wrong cHRM size"); + const uint8_t* data = payload.data(); color_encoding->white_point = JXL_WHITE_POINT_CUSTOM; - color_encoding->white_point_xy[0] = F64FromU32(LoadBE32(payload + 0)); - color_encoding->white_point_xy[1] = F64FromU32(LoadBE32(payload + 4)); + color_encoding->white_point_xy[0] = F64FromU32(LoadBE32(data + 0)); + color_encoding->white_point_xy[1] = F64FromU32(LoadBE32(data + 4)); color_encoding->primaries = JXL_PRIMARIES_CUSTOM; - color_encoding->primaries_red_xy[0] = F64FromU32(LoadBE32(payload + 8)); - color_encoding->primaries_red_xy[1] = F64FromU32(LoadBE32(payload + 12)); - color_encoding->primaries_green_xy[0] = F64FromU32(LoadBE32(payload + 16)); - color_encoding->primaries_green_xy[1] = F64FromU32(LoadBE32(payload + 20)); - color_encoding->primaries_blue_xy[0] = F64FromU32(LoadBE32(payload + 24)); - color_encoding->primaries_blue_xy[1] = F64FromU32(LoadBE32(payload + 28)); + color_encoding->primaries_red_xy[0] = F64FromU32(LoadBE32(data + 8)); + color_encoding->primaries_red_xy[1] = F64FromU32(LoadBE32(data + 12)); + color_encoding->primaries_green_xy[0] = F64FromU32(LoadBE32(data + 16)); + color_encoding->primaries_green_xy[1] = F64FromU32(LoadBE32(data + 20)); + color_encoding->primaries_blue_xy[0] = F64FromU32(LoadBE32(data + 24)); + color_encoding->primaries_blue_xy[1] = F64FromU32(LoadBE32(data + 28)); return true; } -// Retrieves XMP and EXIF/IPTC from itext and text. -class BlobsReaderPNG { - public: - static Status Decode(const png_text_struct& info, PackedMetadata* metadata) { - // We trust these are properly null-terminated by libpng. - const char* key = info.key; - const char* value = info.text; - if (strstr(key, "XML:com.adobe.xmp")) { - metadata->xmp.resize(strlen(value)); // safe, see above - memcpy(metadata->xmp.data(), value, metadata->xmp.size()); - } - - std::string type; - std::vector<uint8_t> bytes; - - // Handle text chunks annotated with key "Raw profile type ####", with - // #### a type, which may contain metadata. - const char* kKey = "Raw profile type "; - if (strncmp(key, kKey, strlen(kKey)) != 0) return false; +/** Returns false if invalid. */ +JXL_INLINE Status DecodeHexNibble(const char c, uint32_t* JXL_RESTRICT nibble) { + if ('a' <= c && c <= 'f') { + *nibble = 10 + c - 'a'; + } else if ('0' <= c && c <= '9') { + *nibble = c - '0'; + } else { + *nibble = 0; + return JXL_FAILURE("Invalid metadata nibble"); + } + JXL_ASSERT(*nibble < 16); + return true; +} - if (!MaybeDecodeBase16(key, value, &type, &bytes)) { - JXL_WARNING("Couldn't parse 'Raw format type' text chunk"); - return false; - } - if (type == "exif") { - // Remove "Exif\0\0" prefix if present - if (bytes.size() >= sizeof kExifSignature && - memcmp(bytes.data(), kExifSignature, sizeof kExifSignature) == 0) { - bytes.erase(bytes.begin(), bytes.begin() + sizeof kExifSignature); - } - if (!metadata->exif.empty()) { - JXL_WARNING("overwriting EXIF (%" PRIuS " bytes) with base16 (%" PRIuS - " bytes)", - metadata->exif.size(), bytes.size()); - } - metadata->exif = std::move(bytes); - } else if (type == "iptc") { - // TODO(jon): Deal with IPTC in some way - } else if (type == "8bim") { - // TODO(jon): Deal with 8bim in some way - } else if (type == "xmp") { - if (!metadata->xmp.empty()) { - JXL_WARNING("overwriting XMP (%" PRIuS " bytes) with base16 (%" PRIuS - " bytes)", - metadata->xmp.size(), bytes.size()); +/** Returns false if invalid. */ +JXL_INLINE Status DecodeDecimal(const char** pos, const char* end, + uint32_t* JXL_RESTRICT value) { + size_t len = 0; + *value = 0; + while (*pos < end) { + char next = **pos; + if (next >= '0' && next <= '9') { + *value = (*value * 10) + static_cast<uint32_t>(next - '0'); + len++; + if (len > 8) { + break; } - metadata->xmp = std::move(bytes); } else { - JXL_WARNING("Unknown type in 'Raw format type' text chunk: %s: %" PRIuS - " bytes", - type.c_str(), bytes.size()); + // Do not consume terminator (non-decimal digit). + break; } - return true; + (*pos)++; + } + if (len == 0 || len > 8) { + return JXL_FAILURE("Failed to parse decimal"); } + return true; +} - private: - // Returns false if invalid. - static JXL_INLINE Status DecodeNibble(const char c, - uint32_t* JXL_RESTRICT nibble) { - if ('a' <= c && c <= 'f') { - *nibble = 10 + c - 'a'; - } else if ('0' <= c && c <= '9') { - *nibble = c - '0'; - } else { - *nibble = 0; - return JXL_FAILURE("Invalid metadata nibble"); +/** + * Parses a PNG text chunk with key of the form "Raw profile type ####", with + * #### a type. + * + * Returns whether it could successfully parse the content. + * We trust key and encoded are null-terminated because they come from + * libpng. + */ +Status MaybeDecodeBase16(const char* key, const char* encoded, + std::string* type, std::vector<uint8_t>* bytes) { + const char* encoded_end = encoded + strlen(encoded); + + const char* kKey = "Raw profile type "; + if (strncmp(key, kKey, strlen(kKey)) != 0) return false; + *type = key + strlen(kKey); + const size_t kMaxTypeLen = 20; + if (type->length() > kMaxTypeLen) return false; // Type too long + + // Header: freeform string and number of bytes + // Expected format is: + // \n + // profile name/description\n + // 40\n (the number of bytes after hex-decoding) + // 01234566789abcdef....\n (72 bytes per line max). + // 012345667\n (last line) + const char* pos = encoded; + + if (*(pos++) != '\n') return false; + while (pos < encoded_end && *pos != '\n') { + pos++; + } + if (pos == encoded_end) return false; + // We parsed so far a \n, some number of non \n characters and are now + // pointing at a \n. + if (*(pos++) != '\n') return false; + // Skip leading spaces + while (pos < encoded_end && *pos == ' ') { + pos++; + } + uint32_t bytes_to_decode = 0; + JXL_RETURN_IF_ERROR(DecodeDecimal(&pos, encoded_end, &bytes_to_decode)); + + // We need 2*bytes for the hex values plus 1 byte every 36 values, + // plus terminal \n for length. + size_t tail = static_cast<size_t>(encoded_end - pos); + bool ok = ((tail / 2) >= bytes_to_decode); + if (ok) tail -= 2 * static_cast<size_t>(bytes_to_decode); + ok = ok && (tail == 1 + DivCeil(bytes_to_decode, 36)); + if (!ok) { + return JXL_FAILURE("Not enough bytes to parse %d bytes in hex", + bytes_to_decode); + } + JXL_ASSERT(bytes->empty()); + bytes->reserve(bytes_to_decode); + + // Encoding: base16 with newline after 72 chars. + // pos points to the \n before the first line of hex values. + for (size_t i = 0; i < bytes_to_decode; ++i) { + if (i % 36 == 0) { + if (pos + 1 >= encoded_end) return false; // Truncated base16 1 + if (*pos != '\n') return false; // Expected newline + ++pos; } - JXL_ASSERT(*nibble < 16); - return true; + + if (pos + 2 >= encoded_end) return false; // Truncated base16 2; + uint32_t nibble0; + uint32_t nibble1; + JXL_RETURN_IF_ERROR(DecodeHexNibble(pos[0], &nibble0)); + JXL_RETURN_IF_ERROR(DecodeHexNibble(pos[1], &nibble1)); + bytes->push_back(static_cast<uint8_t>((nibble0 << 4) + nibble1)); + pos += 2; } + if (pos + 1 != encoded_end) return false; // Too many encoded bytes + if (pos[0] != '\n') return false; // Incorrect metadata terminator + return true; +} - // Returns false if invalid. - static JXL_INLINE Status DecodeDecimal(const char** pos, const char* end, - uint32_t* JXL_RESTRICT value) { - size_t len = 0; - *value = 0; - while (*pos < end) { - char next = **pos; - if (next >= '0' && next <= '9') { - *value = (*value * 10) + static_cast<uint32_t>(next - '0'); - len++; - if (len > 8) { - break; - } - } else { - // Do not consume terminator (non-decimal digit). - break; - } - (*pos)++; - } - if (len == 0 || len > 8) { - return JXL_FAILURE("Failed to parse decimal"); - } - return true; +/** Retrieves XMP and EXIF/IPTC from itext and text. */ +Status DecodeBlob(const png_text_struct& info, PackedMetadata* metadata) { + // We trust these are properly null-terminated by libpng. + const char* key = info.key; + const char* value = info.text; + if (strstr(key, "XML:com.adobe.xmp")) { + metadata->xmp.resize(strlen(value)); // safe, see above + memcpy(metadata->xmp.data(), value, metadata->xmp.size()); } - // Parses a PNG text chunk with key of the form "Raw profile type ####", with - // #### a type. - // Returns whether it could successfully parse the content. - // We trust key and encoded are null-terminated because they come from - // libpng. - static Status MaybeDecodeBase16(const char* key, const char* encoded, - std::string* type, - std::vector<uint8_t>* bytes) { - const char* encoded_end = encoded + strlen(encoded); - - const char* kKey = "Raw profile type "; - if (strncmp(key, kKey, strlen(kKey)) != 0) return false; - *type = key + strlen(kKey); - const size_t kMaxTypeLen = 20; - if (type->length() > kMaxTypeLen) return false; // Type too long - - // Header: freeform string and number of bytes - // Expected format is: - // \n - // profile name/description\n - // 40\n (the number of bytes after hex-decoding) - // 01234566789abcdef....\n (72 bytes per line max). - // 012345667\n (last line) - const char* pos = encoded; - - if (*(pos++) != '\n') return false; - while (pos < encoded_end && *pos != '\n') { - pos++; - } - if (pos == encoded_end) return false; - // We parsed so far a \n, some number of non \n characters and are now - // pointing at a \n. - if (*(pos++) != '\n') return false; - // Skip leading spaces - while (pos < encoded_end && *pos == ' ') { - pos++; + std::string type; + std::vector<uint8_t> bytes; + + // Handle text chunks annotated with key "Raw profile type ####", with + // #### a type, which may contain metadata. + const char* kKey = "Raw profile type "; + if (strncmp(key, kKey, strlen(kKey)) != 0) return false; + + if (!MaybeDecodeBase16(key, value, &type, &bytes)) { + JXL_WARNING("Couldn't parse 'Raw format type' text chunk"); + return false; + } + if (type == "exif") { + // Remove "Exif\0\0" prefix if present + if (bytes.size() >= sizeof kExifSignature && + memcmp(bytes.data(), kExifSignature, sizeof kExifSignature) == 0) { + bytes.erase(bytes.begin(), bytes.begin() + sizeof kExifSignature); } - uint32_t bytes_to_decode = 0; - JXL_RETURN_IF_ERROR(DecodeDecimal(&pos, encoded_end, &bytes_to_decode)); - - // We need 2*bytes for the hex values plus 1 byte every 36 values, - // plus terminal \n for length. - size_t tail = static_cast<size_t>(encoded_end - pos); - bool ok = ((tail / 2) >= bytes_to_decode); - if (ok) tail -= 2 * static_cast<size_t>(bytes_to_decode); - ok = ok && (tail == 1 + DivCeil(bytes_to_decode, 36)); - if (!ok) { - return JXL_FAILURE("Not enough bytes to parse %d bytes in hex", - bytes_to_decode); + if (!metadata->exif.empty()) { + JXL_WARNING("overwriting EXIF (%" PRIuS " bytes) with base16 (%" PRIuS + " bytes)", + metadata->exif.size(), bytes.size()); } - JXL_ASSERT(bytes->empty()); - bytes->reserve(bytes_to_decode); - - // Encoding: base16 with newline after 72 chars. - // pos points to the \n before the first line of hex values. - for (size_t i = 0; i < bytes_to_decode; ++i) { - if (i % 36 == 0) { - if (pos + 1 >= encoded_end) return false; // Truncated base16 1 - if (*pos != '\n') return false; // Expected newline - ++pos; - } - - if (pos + 2 >= encoded_end) return false; // Truncated base16 2; - uint32_t nibble0; - uint32_t nibble1; - JXL_RETURN_IF_ERROR(DecodeNibble(pos[0], &nibble0)); - JXL_RETURN_IF_ERROR(DecodeNibble(pos[1], &nibble1)); - bytes->push_back(static_cast<uint8_t>((nibble0 << 4) + nibble1)); - pos += 2; + metadata->exif = std::move(bytes); + } else if (type == "iptc") { + // TODO(jon): Deal with IPTC in some way + } else if (type == "8bim") { + // TODO(jon): Deal with 8bim in some way + } else if (type == "xmp") { + if (!metadata->xmp.empty()) { + JXL_WARNING("overwriting XMP (%" PRIuS " bytes) with base16 (%" PRIuS + " bytes)", + metadata->xmp.size(), bytes.size()); } - if (pos + 1 != encoded_end) return false; // Too many encoded bytes - if (pos[0] != '\n') return false; // Incorrect metadata terminator - return true; + metadata->xmp = std::move(bytes); + } else { + JXL_WARNING("Unknown type in 'Raw format type' text chunk: %s: %" PRIuS + " bytes", + type.c_str(), bytes.size()); } -}; + return true; +} constexpr bool isAbc(char c) { return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); } -constexpr uint32_t kId_IHDR = 0x52444849; -constexpr uint32_t kId_acTL = 0x4C546361; -constexpr uint32_t kId_fcTL = 0x4C546366; -constexpr uint32_t kId_IDAT = 0x54414449; -constexpr uint32_t kId_fdAT = 0x54416466; -constexpr uint32_t kId_IEND = 0x444E4549; -constexpr uint32_t kId_cICP = 0x50434963; -constexpr uint32_t kId_iCCP = 0x50434369; -constexpr uint32_t kId_sRGB = 0x42475273; -constexpr uint32_t kId_gAMA = 0x414D4167; -constexpr uint32_t kId_cHRM = 0x4D524863; -constexpr uint32_t kId_eXIf = 0x66495865; - -struct APNGFrame { - APNGFrame() : pixels(nullptr, free) {} - std::unique_ptr<void, decltype(free)*> pixels; +/** Wrap 4-char tag name into ID. */ +constexpr uint32_t MakeTag(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { + return a | (b << 8) | (c << 16) | (d << 24); +} + +/** Reusable image data container. */ +struct Pixels { + // Use array instead of vector to avoid memory initialization. + std::unique_ptr<uint8_t[]> pixels; size_t pixels_size = 0; std::vector<uint8_t*> rows; - unsigned int w, h, delay_num, delay_den; - Status Resize(size_t new_size) { + + Status Resize(size_t row_bytes, size_t num_rows) { + size_t new_size = row_bytes * num_rows; // it is assumed size is sane if (new_size > pixels_size) { - pixels.reset(malloc(new_size)); + pixels.reset(new uint8_t[new_size]); if (!pixels) { // TODO(szabadka): use specialized OOM error code return JXL_FAILURE("Failed to allocate memory for image buffer"); } pixels_size = new_size; } + rows.resize(num_rows); + for (size_t y = 0; y < num_rows; y++) { + rows[y] = pixels.get() + y * row_bytes; + } return true; } }; +/** + * Helper that chunks in-memory input. + */ struct Reader { - const uint8_t* next; - const uint8_t* last; - bool Read(void* data, size_t len) { - size_t cap = last - next; + explicit Reader(Span<const uint8_t> data) : data_(data) {} + + const Span<const uint8_t> data_; + size_t offset_ = 0; + + Bytes Peek(size_t len) const { + size_t cap = data_.size() - offset_; size_t to_copy = std::min(cap, len); - memcpy(data, next, to_copy); - next += to_copy; - return (len == to_copy); + return {data_.data() + offset_, to_copy}; } - bool Eof() const { return next == last; } -}; -const uint32_t cMaxPNGSize = 1000000UL; -const size_t kMaxPNGChunkSize = 1lu << 30; // 1 GB + Bytes Read(size_t len) { + Bytes result = Peek(len); + offset_ += result.size(); + return result; + } -void info_fn(png_structp png_ptr, png_infop info_ptr) { + /* Returns empty Span on errror. */ + Bytes ReadChunk() { + Bytes len = Peek(4); + if (len.size() != 4) { + return Bytes(); + } + const auto size = png_get_uint_32(len.data()); + // NB: specification allows 2^31 - 1 + constexpr size_t kMaxPNGChunkSize = 1u << 30; // 1 GB + // Check first, to avoid overflow. + if (size > kMaxPNGChunkSize) { + JXL_WARNING("APNG chunk size is too big"); + return Bytes(); + } + size_t full_size = size + 12; // size does not include itself, tag and CRC. + Bytes result = Read(full_size); + return (result.size() == full_size) ? result : Bytes(); + } + + bool Eof() const { return offset_ == data_.size(); } +}; + +void ProgressiveRead_OnInfo(png_structp png_ptr, png_infop info_ptr) { png_set_expand(png_ptr); png_set_palette_to_rgb(png_ptr); png_set_tRNS_to_alpha(png_ptr); @@ -475,432 +508,437 @@ void info_fn(png_structp png_ptr, png_infop info_ptr) { png_read_update_info(png_ptr, info_ptr); } -void row_fn(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, - int pass) { - APNGFrame* frame = - reinterpret_cast<APNGFrame*>(png_get_progressive_ptr(png_ptr)); +void ProgressiveRead_OnRow(png_structp png_ptr, png_bytep new_row, + png_uint_32 row_num, int pass) { + Pixels* frame = reinterpret_cast<Pixels*>(png_get_progressive_ptr(png_ptr)); JXL_CHECK(frame); JXL_CHECK(row_num < frame->rows.size()); JXL_CHECK(frame->rows[row_num] < frame->rows[0] + frame->pixels_size); png_progressive_combine_row(png_ptr, frame->rows[row_num], new_row); } -inline unsigned int read_chunk(Reader* r, std::vector<uint8_t>* pChunk) { - unsigned char len[4]; - if (r->Read(&len, 4)) { - const auto size = png_get_uint_32(len); - // Check first, to avoid overflow. - if (size > kMaxPNGChunkSize) { - JXL_WARNING("APNG chunk size is too big"); - return 0; - } - pChunk->resize(size + 12); - memcpy(pChunk->data(), len, 4); - if (r->Read(pChunk->data() + 4, pChunk->size() - 4)) { - return LoadLE32(pChunk->data() + 4); - } +// Holds intermediate state during parsing APNG file. +struct Context { + ~Context() { + // Make sure png memory is released in any case. + ResetPngDecoder(); } - return 0; -} - -int processing_start(png_structp& png_ptr, png_infop& info_ptr, void* frame_ptr, - bool hasInfo, std::vector<uint8_t>& chunkIHDR, - std::vector<std::vector<uint8_t>>& chunksInfo) { - unsigned char header[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - // Cleanup prior decoder, if any. - png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); - // Just in case. Not all versions on libpng wipe-out the pointers. - png_ptr = nullptr; - info_ptr = nullptr; + bool CreatePngDecoder() { + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, + nullptr); + info_ptr = png_create_info_struct(png_ptr); + return (png_ptr != nullptr && info_ptr != nullptr); + } - png_ptr = - png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - info_ptr = png_create_info_struct(png_ptr); - if (!png_ptr || !info_ptr) return 1; + /** + * Initialize PNG decoder. + * + * TODO(eustas): add details + */ + bool InitPngDecoder(bool hasInfo, std::vector<Bytes>& chunksInfo) { + ResetPngDecoder(); + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, + nullptr); + info_ptr = png_create_info_struct(png_ptr); + if (png_ptr == nullptr || info_ptr == nullptr) { + return false; + } - if (setjmp(png_jmpbuf(png_ptr))) { - return 1; - } + if (setjmp(png_jmpbuf(png_ptr))) { + return false; + } - png_set_keep_unknown_chunks(png_ptr, 1, kIgnoredPngChunks, - static_cast<int>(sizeof(kIgnoredPngChunks) / 5)); + png_set_keep_unknown_chunks( + png_ptr, 1, kIgnoredPngChunks, + static_cast<int>(sizeof(kIgnoredPngChunks) / 5)); - png_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); - png_set_progressive_read_fn(png_ptr, frame_ptr, info_fn, row_fn, nullptr); + png_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); + png_set_progressive_read_fn(png_ptr, static_cast<void*>(&frameRaw), + ProgressiveRead_OnInfo, ProgressiveRead_OnRow, + nullptr); - png_process_data(png_ptr, info_ptr, header, 8); - png_process_data(png_ptr, info_ptr, chunkIHDR.data(), chunkIHDR.size()); + std::array<uint8_t, 8> header = {137, 80, 78, 71, 13, 10, 26, 10}; + png_process_data(png_ptr, info_ptr, header.data(), header.size()); + png_process_data(png_ptr, info_ptr, ihdr.data(), ihdr.size()); - if (hasInfo) { - for (auto& chunk : chunksInfo) { - png_process_data(png_ptr, info_ptr, chunk.data(), chunk.size()); + if (hasInfo) { + for (auto& chunk : chunksInfo) { + png_process_data(png_ptr, info_ptr, const_cast<uint8_t*>(chunk.data()), + chunk.size()); + } } + return true; } - return 0; -} -int processing_data(png_structp png_ptr, png_infop info_ptr, unsigned char* p, - unsigned int size) { - if (!png_ptr || !info_ptr) return 1; + /** + * Pass chunk to PNG decoder. + */ + bool FeedChunks(const Bytes& chunk1, const Bytes& chunk2 = Bytes()) { + // TODO(eustas): turn to DCHECK + if (!png_ptr || !info_ptr) return false; + + if (setjmp(png_jmpbuf(png_ptr))) { + return false; + } - if (setjmp(png_jmpbuf(png_ptr))) { - return 1; + for (const auto& chunk : {chunk1, chunk2}) { + if (!chunk.empty()) { + png_process_data(png_ptr, info_ptr, const_cast<uint8_t*>(chunk.data()), + chunk.size()); + } + } + return true; } - png_process_data(png_ptr, info_ptr, p, size); - return 0; -} + bool FinalizeStream(PackedMetadata* metadata) { + // TODO(eustas): turn to DCHECK + if (!png_ptr || !info_ptr) return false; -int processing_finish(png_structp png_ptr, png_infop info_ptr, - PackedMetadata* metadata) { - unsigned char footer[12] = {0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130}; + if (setjmp(png_jmpbuf(png_ptr))) { + return false; + } - if (!png_ptr || !info_ptr) return 1; + const std::array<uint8_t, 12> kFooter = {0, 0, 0, 0, 73, 69, + 78, 68, 174, 66, 96, 130}; + png_process_data(png_ptr, info_ptr, const_cast<uint8_t*>(kFooter.data()), + kFooter.size()); + // before destroying: check if we encountered any metadata chunks + png_textp text_ptr; + int num_text; + png_get_text(png_ptr, info_ptr, &text_ptr, &num_text); + for (int i = 0; i < num_text; i++) { + Status result = DecodeBlob(text_ptr[i], metadata); + // Ignore unknown / malformed blob. + (void)result; + } - if (setjmp(png_jmpbuf(png_ptr))) { - return 1; + return true; } - png_process_data(png_ptr, info_ptr, footer, 12); - // before destroying: check if we encountered any metadata chunks - png_textp text_ptr; - int num_text; - png_get_text(png_ptr, info_ptr, &text_ptr, &num_text); - for (int i = 0; i < num_text; i++) { - (void)BlobsReaderPNG::Decode(text_ptr[i], metadata); + void ResetPngDecoder() { + png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); + // Just in case. Not all versions on libpng wipe-out the pointers. + png_ptr = nullptr; + info_ptr = nullptr; } - return 0; -} + std::vector<uint8_t> ihdr; // (modified) copy of file IHDR chunk + png_structp png_ptr = nullptr; + png_infop info_ptr = nullptr; + Pixels frameRaw = {}; +}; + +constexpr uint32_t kMaxPNGSize = 1000000UL; + +struct FrameInfo { + PackedImage data; + uint32_t duration; + size_t x0, xsize; + size_t y0, ysize; + uint32_t dispose_op; + uint32_t blend_op; +}; } // namespace -#endif -bool CanDecodeAPNG() { -#if JPEGXL_ENABLE_APNG - return true; -#else - return false; -#endif -} +bool CanDecodeAPNG() { return true; } Status DecodeImageAPNG(const Span<const uint8_t> bytes, const ColorHints& color_hints, PackedPixelFile* ppf, const SizeConstraints* constraints) { -#if JPEGXL_ENABLE_APNG - Reader r; - unsigned char sig[8]; - png_structp png_ptr = nullptr; - png_infop info_ptr = nullptr; - std::vector<uint8_t> chunk; - std::vector<uint8_t> chunkIHDR; - std::vector<std::vector<uint8_t>> chunksInfo; - bool isAnimated = false; - bool hasInfo = false; - bool seenFctl = false; - APNGFrame frameRaw = {}; - uint32_t num_channels; - JxlPixelFormat format = {}; - unsigned int bytes_per_pixel = 0; - - struct FrameInfo { - PackedImage data; - uint32_t duration; - size_t x0, xsize; - size_t y0, ysize; - uint32_t dispose_op; - uint32_t blend_op; - }; - - std::vector<FrameInfo> frames; + // Initialize output (default settings in case e.g. only gAMA is given). + ppf->frames.clear(); + ppf->info.exponent_bits_per_sample = 0; + ppf->info.alpha_exponent_bits = 0; + ppf->info.orientation = JXL_ORIENT_IDENTITY; + ppf->color_encoding.color_space = JXL_COLOR_SPACE_RGB; + ppf->color_encoding.white_point = JXL_WHITE_POINT_D65; + ppf->color_encoding.primaries = JXL_PRIMARIES_SRGB; + ppf->color_encoding.transfer_function = JXL_TRANSFER_FUNCTION_SRGB; + ppf->color_encoding.rendering_intent = JXL_RENDERING_INTENT_RELATIVE; - // Make sure png memory is released in any case. - auto scope_guard = MakeScopeGuard([&]() { - png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); - // Just in case. Not all versions on libpng wipe-out the pointers. - png_ptr = nullptr; - info_ptr = nullptr; - }); + Reader input(bytes); - r = {bytes.data(), bytes.data() + bytes.size()}; // Not a PNG => not an error unsigned char png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - if (!r.Read(sig, 8) || memcmp(sig, png_signature, 8) != 0) { + Bytes sig = input.Read(8); + if (sig.size() != 8 || memcmp(sig.data(), png_signature, 8) != 0) { return false; } - unsigned int id = read_chunk(&r, &chunkIHDR); - ppf->info.exponent_bits_per_sample = 0; - ppf->info.alpha_exponent_bits = 0; - ppf->info.orientation = JXL_ORIENT_IDENTITY; + Bytes chunk_ihdr = input.ReadChunk(); + if (chunk_ihdr.empty()) { + return false; + } + uint32_t id = LoadLE32(chunk_ihdr.data() + 4); + if (id != MakeTag('I', 'H', 'D', 'R') || chunk_ihdr.size() != 25) { + return false; + } + const uint32_t w = png_get_uint_32(chunk_ihdr.data() + 8); + const uint32_t h = png_get_uint_32(chunk_ihdr.data() + 12); + if (w > kMaxPNGSize || h > kMaxPNGSize) { + return false; + } - ppf->frames.clear(); + Context ctx; + ctx.ihdr = chunk_ihdr.Copy(); + + std::vector<Bytes> chunksInfo; + if (!ctx.InitPngDecoder(false, chunksInfo)) { + return false; + } + bool isAnimated = false; + bool hasInfo = false; + uint32_t num_channels; + JxlPixelFormat format = {}; + unsigned int bytes_per_pixel = 0; + std::vector<FrameInfo> frames; bool have_color = false; bool have_cicp = false; bool have_iccp = false; bool have_srgb = false; - bool errorstate = true; - if (id == kId_IHDR && chunkIHDR.size() == 25) { - uint32_t x0 = 0; - uint32_t y0 = 0; - uint32_t delay_num = 1; - uint32_t delay_den = 10; - uint32_t dop = 0; - uint32_t bop = 0; - - uint32_t w = png_get_uint_32(chunkIHDR.data() + 8); - uint32_t h = png_get_uint_32(chunkIHDR.data() + 12); - uint32_t w0 = w; - uint32_t h0 = h; - if (w > cMaxPNGSize || h > cMaxPNGSize) { + uint32_t x0 = 0; + uint32_t y0 = 0; + uint32_t delay_num = 1; + uint32_t delay_den = 10; + uint32_t dop = 0; + uint32_t bop = 0; + uint32_t w0 = w; + uint32_t h0 = h; + + while (!input.Eof()) { + Bytes chunk = input.ReadChunk(); + if (chunk.empty()) { return false; } - - // default settings in case e.g. only gAMA is given - ppf->color_encoding.color_space = JXL_COLOR_SPACE_RGB; - ppf->color_encoding.white_point = JXL_WHITE_POINT_D65; - ppf->color_encoding.primaries = JXL_PRIMARIES_SRGB; - ppf->color_encoding.transfer_function = JXL_TRANSFER_FUNCTION_SRGB; - ppf->color_encoding.rendering_intent = JXL_RENDERING_INTENT_RELATIVE; - - if (!processing_start(png_ptr, info_ptr, static_cast<void*>(&frameRaw), - hasInfo, chunkIHDR, chunksInfo)) { - while (!r.Eof()) { - id = read_chunk(&r, &chunk); - if (!id) break; - seenFctl |= (id == kId_fcTL); - - if (id == kId_acTL && !hasInfo && !isAnimated) { - isAnimated = true; - ppf->info.have_animation = JXL_TRUE; - ppf->info.animation.tps_numerator = 1000; - ppf->info.animation.tps_denominator = 1; - } else if (id == kId_IEND || - (id == kId_fcTL && (!hasInfo || isAnimated))) { - if (hasInfo) { - if (!processing_finish(png_ptr, info_ptr, &ppf->metadata)) { - // Allocates the frame buffer. - uint32_t duration = delay_num * 1000 / delay_den; - JXL_ASSIGN_OR_RETURN(PackedImage image, - PackedImage::Create(w0, h0, format)); - frames.push_back(FrameInfo{std::move(image), duration, x0, w0, y0, - h0, dop, bop}); - auto& frame = frames.back().data; - for (size_t y = 0; y < h0; ++y) { - memcpy(static_cast<uint8_t*>(frame.pixels()) + frame.stride * y, - frameRaw.rows[y], bytes_per_pixel * w0); - } - } else { - break; - } + id = LoadLE32(chunk.data() + 4); + + if (id == MakeTag('a', 'c', 'T', 'L') && !hasInfo && !isAnimated) { + isAnimated = true; + ppf->info.have_animation = JXL_TRUE; + ppf->info.animation.tps_numerator = 1000; + ppf->info.animation.tps_denominator = 1; + } else if (id == MakeTag('I', 'E', 'N', 'D') || + (id == MakeTag('f', 'c', 'T', 'L') && + (!hasInfo || isAnimated))) { + if (hasInfo) { + if (ctx.FinalizeStream(&ppf->metadata)) { + // Allocates the frame buffer. + uint32_t duration = delay_num * 1000 / delay_den; + JXL_ASSIGN_OR_RETURN(PackedImage image, + PackedImage::Create(w0, h0, format)); + frames.push_back( + FrameInfo{std::move(image), duration, x0, w0, y0, h0, dop, bop}); + auto& frame = frames.back().data; + for (size_t y = 0; y < h0; ++y) { + // TODO(eustas): ensure multiplication is safe + memcpy(static_cast<uint8_t*>(frame.pixels()) + frame.stride * y, + ctx.frameRaw.rows[y], bytes_per_pixel * w0); } + } else { + return false; + } + } - if (id == kId_IEND) { - errorstate = false; - break; - } - if (chunk.size() < 34) { - return JXL_FAILURE("Received a chunk that is too small (%" PRIuS - "B)", - chunk.size()); - } - // At this point the old frame is done. Let's start a new one. - w0 = png_get_uint_32(chunk.data() + 12); - h0 = png_get_uint_32(chunk.data() + 16); - x0 = png_get_uint_32(chunk.data() + 20); - y0 = png_get_uint_32(chunk.data() + 24); - delay_num = png_get_uint_16(chunk.data() + 28); - delay_den = png_get_uint_16(chunk.data() + 30); - dop = chunk[32]; - bop = chunk[33]; - - if (!delay_den) delay_den = 100; - - if (w0 > cMaxPNGSize || h0 > cMaxPNGSize || x0 > cMaxPNGSize || - y0 > cMaxPNGSize || x0 + w0 > w || y0 + h0 > h || dop > 2 || - bop > 1) { - break; - } + if (id == MakeTag('I', 'E', 'N', 'D')) { + break; + } + if (chunk.size() < 34) { + return JXL_FAILURE("Received a chunk that is too small (%" PRIuS "B)", + chunk.size()); + } + // At this point the old frame is done. Let's start a new one. + w0 = png_get_uint_32(chunk.data() + 12); + h0 = png_get_uint_32(chunk.data() + 16); + x0 = png_get_uint_32(chunk.data() + 20); + y0 = png_get_uint_32(chunk.data() + 24); + delay_num = png_get_uint_16(chunk.data() + 28); + delay_den = png_get_uint_16(chunk.data() + 30); + dop = chunk[32]; + bop = chunk[33]; + + if (!delay_den) delay_den = 100; + + if (w0 > kMaxPNGSize || h0 > kMaxPNGSize || x0 > kMaxPNGSize || + y0 > kMaxPNGSize || x0 + w0 > w || y0 + h0 > h || dop > 2 || + bop > 1) { + return false; + } - if (hasInfo) { - memcpy(chunkIHDR.data() + 8, chunk.data() + 12, 8); - if (processing_start(png_ptr, info_ptr, - static_cast<void*>(&frameRaw), hasInfo, - chunkIHDR, chunksInfo)) { - break; - } - } - } else if (id == kId_IDAT) { - // First IDAT chunk means we now have all header info - if (seenFctl) { - // `fcTL` chunk must appear after all `IDAT` chunks - return JXL_FAILURE("IDAT chunk after fcTL chunk"); - } - hasInfo = true; - JXL_CHECK(w == png_get_image_width(png_ptr, info_ptr)); - JXL_CHECK(h == png_get_image_height(png_ptr, info_ptr)); - int colortype = png_get_color_type(png_ptr, info_ptr); - int png_bit_depth = png_get_bit_depth(png_ptr, info_ptr); - ppf->info.bits_per_sample = png_bit_depth; - png_color_8p sigbits = nullptr; - png_get_sBIT(png_ptr, info_ptr, &sigbits); - if (colortype & 1) { - // palette will actually be 8-bit regardless of the index bitdepth - ppf->info.bits_per_sample = 8; - } - if (colortype & 2) { - ppf->info.num_color_channels = 3; - ppf->color_encoding.color_space = JXL_COLOR_SPACE_RGB; - if (sigbits && sigbits->red == sigbits->green && - sigbits->green == sigbits->blue) { - ppf->info.bits_per_sample = sigbits->red; - } else if (sigbits) { - int maxbps = std::max(sigbits->red, - std::max(sigbits->green, sigbits->blue)); - JXL_WARNING( - "sBIT chunk: bit depths for R, G, and B are not the same (%i " - "%i %i), while in JPEG XL they have to be the same. Setting " - "RGB bit depth to %i.", - sigbits->red, sigbits->green, sigbits->blue, maxbps); - ppf->info.bits_per_sample = maxbps; - } - } else { - ppf->info.num_color_channels = 1; - ppf->color_encoding.color_space = JXL_COLOR_SPACE_GRAY; - if (sigbits) ppf->info.bits_per_sample = sigbits->gray; - } - if (colortype & 4 || - png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - ppf->info.alpha_bits = ppf->info.bits_per_sample; - if (sigbits && sigbits->alpha != ppf->info.bits_per_sample) { - JXL_WARNING( - "sBIT chunk: bit depths for RGBA are inconsistent " - "(%i %i %i %i). Setting A bitdepth to %i.", - sigbits->red, sigbits->green, sigbits->blue, sigbits->alpha, - ppf->info.bits_per_sample); - } - } else { - ppf->info.alpha_bits = 0; - } - ppf->color_encoding.color_space = - (ppf->info.num_color_channels == 1 ? JXL_COLOR_SPACE_GRAY - : JXL_COLOR_SPACE_RGB); - ppf->info.xsize = w; - ppf->info.ysize = h; - JXL_RETURN_IF_ERROR(VerifyDimensions(constraints, w, h)); - num_channels = - ppf->info.num_color_channels + (ppf->info.alpha_bits ? 1 : 0); - format = { - /*num_channels=*/num_channels, - /*data_type=*/ppf->info.bits_per_sample > 8 ? JXL_TYPE_UINT16 - : JXL_TYPE_UINT8, - /*endianness=*/JXL_BIG_ENDIAN, - /*align=*/0, - }; - if (png_bit_depth > 8 && format.data_type == JXL_TYPE_UINT8) { - png_set_strip_16(png_ptr); - } - bytes_per_pixel = - num_channels * (format.data_type == JXL_TYPE_UINT16 ? 2 : 1); - size_t rowbytes = w * bytes_per_pixel; - if (h > std::numeric_limits<size_t>::max() / rowbytes) { - return JXL_FAILURE("Image too big."); - } - size_t imagesize = h * rowbytes; - JXL_RETURN_IF_ERROR(frameRaw.Resize(imagesize)); - frameRaw.rows.resize(h); - for (size_t j = 0; j < h; j++) { - frameRaw.rows[j] = - reinterpret_cast<uint8_t*>(frameRaw.pixels.get()) + - j * rowbytes; - } + if (hasInfo) { + // Copy dimensions. + memcpy(ctx.ihdr.data() + 8, chunk.data() + 12, 8); + if (!ctx.InitPngDecoder(hasInfo, chunksInfo)) { + return false; + } + } + } else if (id == MakeTag('I', 'D', 'A', 'T')) { + // First IDAT chunk means we now have all header info + hasInfo = true; + JXL_CHECK(w == png_get_image_width(ctx.png_ptr, ctx.info_ptr)); + JXL_CHECK(h == png_get_image_height(ctx.png_ptr, ctx.info_ptr)); + int colortype = png_get_color_type(ctx.png_ptr, ctx.info_ptr); + int png_bit_depth = png_get_bit_depth(ctx.png_ptr, ctx.info_ptr); + ppf->info.bits_per_sample = png_bit_depth; + png_color_8p sigbits = nullptr; + png_get_sBIT(ctx.png_ptr, ctx.info_ptr, &sigbits); + if (colortype & 1) { + // palette will actually be 8-bit regardless of the index bitdepth + ppf->info.bits_per_sample = 8; + } + if (colortype & 2) { + ppf->info.num_color_channels = 3; + ppf->color_encoding.color_space = JXL_COLOR_SPACE_RGB; + if (sigbits && sigbits->red == sigbits->green && + sigbits->green == sigbits->blue) { + ppf->info.bits_per_sample = sigbits->red; + } else if (sigbits) { + int maxbps = + std::max(sigbits->red, std::max(sigbits->green, sigbits->blue)); + JXL_WARNING( + "sBIT chunk: bit depths for R, G, and B are not the same (%i " + "%i %i), while in JPEG XL they have to be the same. Setting " + "RGB bit depth to %i.", + sigbits->red, sigbits->green, sigbits->blue, maxbps); + ppf->info.bits_per_sample = maxbps; + } + } else { + ppf->info.num_color_channels = 1; + ppf->color_encoding.color_space = JXL_COLOR_SPACE_GRAY; + if (sigbits) ppf->info.bits_per_sample = sigbits->gray; + } + if (colortype & 4 || + png_get_valid(ctx.png_ptr, ctx.info_ptr, PNG_INFO_tRNS)) { + ppf->info.alpha_bits = ppf->info.bits_per_sample; + if (sigbits && sigbits->alpha != ppf->info.bits_per_sample) { + JXL_WARNING( + "sBIT chunk: bit depths for RGBA are inconsistent " + "(%i %i %i %i). Setting A bitdepth to %i.", + sigbits->red, sigbits->green, sigbits->blue, sigbits->alpha, + ppf->info.bits_per_sample); + } + } else { + ppf->info.alpha_bits = 0; + } + ppf->color_encoding.color_space = + (ppf->info.num_color_channels == 1 ? JXL_COLOR_SPACE_GRAY + : JXL_COLOR_SPACE_RGB); + ppf->info.xsize = w; + ppf->info.ysize = h; + JXL_RETURN_IF_ERROR(VerifyDimensions(constraints, w, h)); + num_channels = + ppf->info.num_color_channels + (ppf->info.alpha_bits ? 1 : 0); + format = { + /*num_channels=*/num_channels, + /*data_type=*/ppf->info.bits_per_sample > 8 ? JXL_TYPE_UINT16 + : JXL_TYPE_UINT8, + /*endianness=*/JXL_BIG_ENDIAN, + /*align=*/0, + }; + if (png_bit_depth > 8 && format.data_type == JXL_TYPE_UINT8) { + png_set_strip_16(ctx.png_ptr); + } + bytes_per_pixel = + num_channels * (format.data_type == JXL_TYPE_UINT16 ? 2 : 1); + // TODO(eustas): ensure multiplication is safe + size_t rowbytes = w * bytes_per_pixel; + if (h > std::numeric_limits<size_t>::max() / rowbytes) { + return JXL_FAILURE("Image too big."); + } + JXL_RETURN_IF_ERROR(ctx.frameRaw.Resize(rowbytes, h)); - if (processing_data(png_ptr, info_ptr, chunk.data(), chunk.size())) { - break; - } - } else if (id == kId_fdAT && isAnimated) { - if (!hasInfo) { - return JXL_FAILURE("fDAT chunk before iDAT"); - } - png_save_uint_32(chunk.data() + 4, chunk.size() - 16); - memcpy(chunk.data() + 8, "IDAT", 4); - if (processing_data(png_ptr, info_ptr, chunk.data() + 4, - chunk.size() - 4)) { - break; - } - } else if (id == kId_cICP) { - // Color profile chunks: cICP has the highest priority, followed by - // iCCP and sRGB (which shouldn't co-exist, but if they do, we use - // iCCP), followed finally by gAMA and cHRM. - if (DecodeCICP(chunk.data() + 8, chunk.size() - 12, - &ppf->color_encoding)) { - have_cicp = true; - have_color = true; - ppf->icc.clear(); - ppf->primary_color_representation = - PackedPixelFile::kColorEncodingIsPrimary; - } - } else if (!have_cicp && id == kId_iCCP) { - if (processing_data(png_ptr, info_ptr, chunk.data(), chunk.size())) { - JXL_WARNING("Corrupt iCCP chunk"); - break; - } + if (!ctx.FeedChunks(chunk)) { + return false; + } + } else if (id == MakeTag('f', 'd', 'A', 'T') && isAnimated) { + if (!hasInfo) { + return JXL_FAILURE("fdAT chunk before IDAT"); + } + /* The 'fdAT' chunk has... the same structure as an 'IDAT' chunk, + * except preceded by a sequence number. */ + size_t payload_size = chunk.size() - 12; + if (payload_size < 4) { + return JXL_FAILURE("Corrupted fdAT chunk"); + } + // Turn 'fdAT' to 'IDAT' by cutting sequence number and replacing tag. + std::array<uint8_t, 8> preamble; + png_save_uint_32(preamble.data(), payload_size - 4); + memcpy(preamble.data() + 4, "IDAT", 4); + if (!ctx.FeedChunks(Bytes(preamble), + Bytes(chunk.data() + 12, chunk.size() - 12))) { + return false; + } + } else if (id == MakeTag('c', 'I', 'C', 'P')) { + // Color profile chunks: cICP has the highest priority, followed by + // iCCP and sRGB (which shouldn't co-exist, but if they do, we use + // iCCP), followed finally by gAMA and cHRM. + if (DecodeCicpChunk(Bytes(chunk.data() + 8, chunk.size() - 12), + &ppf->color_encoding)) { + have_cicp = true; + have_color = true; + ppf->icc.clear(); + ppf->primary_color_representation = + PackedPixelFile::kColorEncodingIsPrimary; + } + } else if (!have_cicp && id == MakeTag('i', 'C', 'C', 'P')) { + if (!ctx.FeedChunks(chunk)) { + JXL_WARNING("Corrupt iCCP chunk"); + return false; + } - // TODO(jon): catch special case of PQ and synthesize color encoding - // in that case - int compression_type; - png_bytep profile; - png_charp name; - png_uint_32 proflen = 0; - auto ok = png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, - &profile, &proflen); - if (ok && proflen) { - ppf->icc.assign(profile, profile + proflen); - ppf->primary_color_representation = PackedPixelFile::kIccIsPrimary; - have_color = true; - have_iccp = true; - } else { - // TODO(eustas): JXL_WARNING? - } - } else if (!have_cicp && !have_iccp && id == kId_sRGB) { - JXL_RETURN_IF_ERROR(DecodeSRGB(chunk.data() + 8, chunk.size() - 12, - &ppf->color_encoding)); - have_srgb = true; - have_color = true; - } else if (!have_cicp && !have_srgb && !have_iccp && id == kId_gAMA) { - JXL_RETURN_IF_ERROR(DecodeGAMA(chunk.data() + 8, chunk.size() - 12, - &ppf->color_encoding)); - have_color = true; - } else if (!have_cicp && !have_srgb && !have_iccp && id == kId_cHRM) { - JXL_RETURN_IF_ERROR(DecodeCHRM(chunk.data() + 8, chunk.size() - 12, - &ppf->color_encoding)); - have_color = true; - } else if (id == kId_eXIf) { - ppf->metadata.exif.resize(chunk.size() - 12); - memcpy(ppf->metadata.exif.data(), chunk.data() + 8, - chunk.size() - 12); - } else if (!isAbc(chunk[4]) || !isAbc(chunk[5]) || !isAbc(chunk[6]) || - !isAbc(chunk[7])) { - break; - } else { - if (processing_data(png_ptr, info_ptr, chunk.data(), chunk.size())) { - break; - } - if (!hasInfo) { - chunksInfo.push_back(chunk); - continue; - } - } + // TODO(jon): catch special case of PQ and synthesize color encoding + // in that case + int compression_type; + png_bytep profile; + png_charp name; + png_uint_32 proflen = 0; + auto ok = png_get_iCCP(ctx.png_ptr, ctx.info_ptr, &name, + &compression_type, &profile, &proflen); + if (ok && proflen) { + ppf->icc.assign(profile, profile + proflen); + ppf->primary_color_representation = PackedPixelFile::kIccIsPrimary; + have_color = true; + have_iccp = true; + } else { + // TODO(eustas): JXL_WARNING? + } + } else if (!have_cicp && !have_iccp && id == MakeTag('s', 'R', 'G', 'B')) { + JXL_RETURN_IF_ERROR(DecodeSrgbChunk( + Bytes(chunk.data() + 8, chunk.size() - 12), &ppf->color_encoding)); + have_srgb = true; + have_color = true; + } else if (!have_cicp && !have_srgb && !have_iccp && + id == MakeTag('g', 'A', 'M', 'A')) { + JXL_RETURN_IF_ERROR(DecodeGamaChunk( + Bytes(chunk.data() + 8, chunk.size() - 12), &ppf->color_encoding)); + have_color = true; + } else if (!have_cicp && !have_srgb && !have_iccp && + id == MakeTag('c', 'H', 'R', 'M')) { + JXL_RETURN_IF_ERROR(DecodeChrmChunk( + Bytes(chunk.data() + 8, chunk.size() - 12), &ppf->color_encoding)); + have_color = true; + } else if (id == MakeTag('e', 'X', 'I', 'f')) { + ppf->metadata.exif.resize(chunk.size() - 12); + memcpy(ppf->metadata.exif.data(), chunk.data() + 8, chunk.size() - 12); + } else if (!isAbc(chunk[4]) || !isAbc(chunk[5]) || !isAbc(chunk[6]) || + !isAbc(chunk[7])) { + return false; + } else { + if (!ctx.FeedChunks(chunk)) { + return false; + } + if (!hasInfo) { + chunksInfo.push_back(chunk); + continue; } } - - JXL_RETURN_IF_ERROR(ApplyColorHints( - color_hints, have_color, ppf->info.num_color_channels == 1, ppf)); } - if (errorstate) return false; + JXL_RETURN_IF_ERROR(ApplyColorHints(color_hints, have_color, + ppf->info.num_color_channels == 1, ppf)); bool has_nontrivial_background = false; bool previous_frame_should_be_cleared = false; @@ -1014,14 +1052,14 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes, previous_frame_should_be_cleared = has_nontrivial_background && frame.dispose_op == DISPOSE_OP_BACKGROUND; } + if (ppf->frames.empty()) return JXL_FAILURE("No frames decoded"); ppf->frames.back().frame_info.is_last = JXL_TRUE; return true; -#else - return false; -#endif } +#endif // JPEGXL_ENABLE_APNG + } // namespace extras } // namespace jxl diff --git a/third_party/jpeg-xl/lib/extras/dec/apng.h b/third_party/jpeg-xl/lib/extras/dec/apng.h index d91364b1e6..7ebc2ee7c8 100644 --- a/third_party/jpeg-xl/lib/extras/dec/apng.h +++ b/third_party/jpeg-xl/lib/extras/dec/apng.h @@ -8,11 +8,10 @@ // Decodes APNG images in memory. -#include <stdint.h> +#include <cstdint> #include "lib/extras/dec/color_hints.h" #include "lib/extras/packed_image.h" -#include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/span.h" #include "lib/jxl/base/status.h" diff --git a/third_party/jpeg-xl/lib/extras/dec/color_description.cc b/third_party/jpeg-xl/lib/extras/dec/color_description.cc index bf229632d0..87fff6e54a 100644 --- a/third_party/jpeg-xl/lib/extras/dec/color_description.cc +++ b/third_party/jpeg-xl/lib/extras/dec/color_description.cc @@ -203,12 +203,38 @@ Status ParseTransferFunction(Tokenizer* tokenizer, JxlColorEncoding* c) { Status ParseDescription(const std::string& description, JxlColorEncoding* c) { *c = {}; - Tokenizer tokenizer(&description, '_'); - JXL_RETURN_IF_ERROR(ParseColorSpace(&tokenizer, c)); - JXL_RETURN_IF_ERROR(ParseWhitePoint(&tokenizer, c)); - JXL_RETURN_IF_ERROR(ParsePrimaries(&tokenizer, c)); - JXL_RETURN_IF_ERROR(ParseRenderingIntent(&tokenizer, c)); - JXL_RETURN_IF_ERROR(ParseTransferFunction(&tokenizer, c)); + if (description == "sRGB") { + c->color_space = JXL_COLOR_SPACE_RGB; + c->white_point = JXL_WHITE_POINT_D65; + c->primaries = JXL_PRIMARIES_SRGB; + c->transfer_function = JXL_TRANSFER_FUNCTION_SRGB; + c->rendering_intent = JXL_RENDERING_INTENT_PERCEPTUAL; + } else if (description == "DisplayP3") { + c->color_space = JXL_COLOR_SPACE_RGB; + c->white_point = JXL_WHITE_POINT_D65; + c->primaries = JXL_PRIMARIES_P3; + c->transfer_function = JXL_TRANSFER_FUNCTION_SRGB; + c->rendering_intent = JXL_RENDERING_INTENT_PERCEPTUAL; + } else if (description == "Rec2100PQ") { + c->color_space = JXL_COLOR_SPACE_RGB; + c->white_point = JXL_WHITE_POINT_D65; + c->primaries = JXL_PRIMARIES_2100; + c->transfer_function = JXL_TRANSFER_FUNCTION_PQ; + c->rendering_intent = JXL_RENDERING_INTENT_RELATIVE; + } else if (description == "Rec2100HLG") { + c->color_space = JXL_COLOR_SPACE_RGB; + c->white_point = JXL_WHITE_POINT_D65; + c->primaries = JXL_PRIMARIES_2100; + c->transfer_function = JXL_TRANSFER_FUNCTION_HLG; + c->rendering_intent = JXL_RENDERING_INTENT_RELATIVE; + } else { + Tokenizer tokenizer(&description, '_'); + JXL_RETURN_IF_ERROR(ParseColorSpace(&tokenizer, c)); + JXL_RETURN_IF_ERROR(ParseWhitePoint(&tokenizer, c)); + JXL_RETURN_IF_ERROR(ParsePrimaries(&tokenizer, c)); + JXL_RETURN_IF_ERROR(ParseRenderingIntent(&tokenizer, c)); + JXL_RETURN_IF_ERROR(ParseTransferFunction(&tokenizer, c)); + } return true; } diff --git a/third_party/jpeg-xl/lib/extras/dec/decode.cc b/third_party/jpeg-xl/lib/extras/dec/decode.cc index 3546cb65c0..2581d53f63 100644 --- a/third_party/jpeg-xl/lib/extras/dec/decode.cc +++ b/third_party/jpeg-xl/lib/extras/dec/decode.cc @@ -91,6 +91,15 @@ bool CanDecode(Codec codec) { } } +std::string ListOfDecodeCodecs() { + std::string list_of_codecs("JXL, PPM, PNM, PFM, PAM, PGX"); + if (CanDecode(Codec::kPNG)) list_of_codecs.append(", PNG, APNG"); + if (CanDecode(Codec::kGIF)) list_of_codecs.append(", GIF"); + if (CanDecode(Codec::kJPG)) list_of_codecs.append(", JPEG"); + if (CanDecode(Codec::kEXR)) list_of_codecs.append(", EXR"); + return list_of_codecs; +} + Status DecodeBytes(const Span<const uint8_t> bytes, const ColorHints& color_hints, extras::PackedPixelFile* ppf, const SizeConstraints* constraints, Codec* orig_codec) { diff --git a/third_party/jpeg-xl/lib/extras/dec/decode.h b/third_party/jpeg-xl/lib/extras/dec/decode.h index 1a90f4c6a3..26dc1409df 100644 --- a/third_party/jpeg-xl/lib/extras/dec/decode.h +++ b/third_party/jpeg-xl/lib/extras/dec/decode.h @@ -38,6 +38,8 @@ enum class Codec : uint32_t { bool CanDecode(Codec codec); +std::string ListOfDecodeCodecs(); + // If and only if extension is ".pfm", *bits_per_sample is updated to 32 so // that Encode() would encode to PFM instead of PPM. Codec CodecFromPath(const std::string& path, diff --git a/third_party/jpeg-xl/lib/extras/dec/gif.cc b/third_party/jpeg-xl/lib/extras/dec/gif.cc index 3f89d460b8..243d8b5103 100644 --- a/third_party/jpeg-xl/lib/extras/dec/gif.cc +++ b/third_party/jpeg-xl/lib/extras/dec/gif.cc @@ -17,6 +17,7 @@ #include "lib/extras/size_constraints.h" #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/sanitizers.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/extras/dec/jpg.cc b/third_party/jpeg-xl/lib/extras/dec/jpg.cc index 4a3e0d3b21..a65b46b4c8 100644 --- a/third_party/jpeg-xl/lib/extras/dec/jpg.cc +++ b/third_party/jpeg-xl/lib/extras/dec/jpg.cc @@ -6,8 +6,7 @@ #include "lib/extras/dec/jpg.h" #if JPEGXL_ENABLE_JPEG -#include <jpeglib.h> -#include <setjmp.h> +#include "lib/jxl/base/include_jpeglib.h" // NOLINT #endif #include <stdint.h> diff --git a/third_party/jpeg-xl/lib/extras/dec/jxl.cc b/third_party/jpeg-xl/lib/extras/dec/jxl.cc index 5b7fa03f02..e2534fa745 100644 --- a/third_party/jpeg-xl/lib/extras/dec/jxl.cc +++ b/third_party/jpeg-xl/lib/extras/dec/jxl.cc @@ -10,7 +10,7 @@ #include <jxl/decode_cxx.h> #include <jxl/types.h> -#include <cinttypes> +#include <cinttypes> // PRIu32 #include "lib/extras/common.h" #include "lib/extras/dec/color_description.h" @@ -211,7 +211,7 @@ bool DecodeImageJXL(const uint8_t* bytes, size_t bytes_size, return false; } uint32_t progression_index = 0; - bool codestream_done = accepted_formats.empty(); + bool codestream_done = jpeg_bytes == nullptr && accepted_formats.empty(); BoxProcessor boxes(dec); for (;;) { JxlDecoderStatus status = JxlDecoderProcessInput(dec); diff --git a/third_party/jpeg-xl/lib/extras/dec/pnm.cc b/third_party/jpeg-xl/lib/extras/dec/pnm.cc index e64d7e95f9..b3f9cd1206 100644 --- a/third_party/jpeg-xl/lib/extras/dec/pnm.cc +++ b/third_party/jpeg-xl/lib/extras/dec/pnm.cc @@ -5,17 +5,17 @@ #include "lib/extras/dec/pnm.h" -#include <stdlib.h> -#include <string.h> +#include <jxl/encode.h> #include <cmath> +#include <cstddef> #include <cstdint> -#include <mutex> +#include <cstdlib> +#include <cstring> -#include "jxl/encode.h" #include "lib/extras/size_constraints.h" #include "lib/jxl/base/bits.h" -#include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/span.h" #include "lib/jxl/base/status.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/extras/enc/encode.cc b/third_party/jpeg-xl/lib/extras/enc/encode.cc index c5e22d8c7e..71be78e36c 100644 --- a/third_party/jpeg-xl/lib/extras/enc/encode.cc +++ b/third_party/jpeg-xl/lib/extras/enc/encode.cc @@ -134,5 +134,13 @@ std::unique_ptr<Encoder> Encoder::FromExtension(std::string extension) { return nullptr; } +std::string ListOfEncodeCodecs() { + std::string list_of_codecs("PPM, PNM, PFM, PAM, PGX"); + if (GetAPNGEncoder()) list_of_codecs.append(", PNG, APNG"); + if (GetJPEGEncoder()) list_of_codecs.append(", JPEG"); + if (GetEXREncoder()) list_of_codecs.append(", EXR"); + return list_of_codecs; +} + } // namespace extras } // namespace jxl diff --git a/third_party/jpeg-xl/lib/extras/enc/encode.h b/third_party/jpeg-xl/lib/extras/enc/encode.h index 2502d9976b..a71f3b220f 100644 --- a/third_party/jpeg-xl/lib/extras/enc/encode.h +++ b/third_party/jpeg-xl/lib/extras/enc/encode.h @@ -82,6 +82,8 @@ class Encoder { std::unordered_map<std::string, std::string> options_; }; +std::string ListOfEncodeCodecs(); + } // namespace extras } // namespace jxl diff --git a/third_party/jpeg-xl/lib/extras/enc/jpegli.cc b/third_party/jpeg-xl/lib/extras/enc/jpegli.cc index cb473a1290..9735cd8cb9 100644 --- a/third_party/jpeg-xl/lib/extras/enc/jpegli.cc +++ b/third_party/jpeg-xl/lib/extras/enc/jpegli.cc @@ -454,6 +454,10 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings, cinfo.comp_info[i].h_samp_factor = 1; cinfo.comp_info[i].v_samp_factor = 1; } + } else if (!jpeg_settings.xyb) { + // Default is no chroma subsampling. + cinfo.comp_info[0].h_samp_factor = 1; + cinfo.comp_info[0].v_samp_factor = 1; } jpegli_enable_adaptive_quantization( &cinfo, TO_JXL_BOOL(jpeg_settings.use_adaptive_quantization)); diff --git a/third_party/jpeg-xl/lib/extras/enc/jpg.cc b/third_party/jpeg-xl/lib/extras/enc/jpg.cc index 0095ac9294..a2ef4a9fc4 100644 --- a/third_party/jpeg-xl/lib/extras/enc/jpg.cc +++ b/third_party/jpeg-xl/lib/extras/enc/jpg.cc @@ -6,18 +6,15 @@ #include "lib/extras/enc/jpg.h" #if JPEGXL_ENABLE_JPEG -#include <jpeglib.h> -#include <setjmp.h> +#include "lib/jxl/base/include_jpeglib.h" // NOLINT #endif -#include <stdint.h> #include <algorithm> #include <array> #include <cmath> +#include <cstdint> #include <fstream> -#include <iterator> #include <memory> -#include <numeric> #include <sstream> #include <utility> #include <vector> diff --git a/third_party/jpeg-xl/lib/extras/jpegli_test.cc b/third_party/jpeg-xl/lib/extras/jpegli_test.cc index 3049049a64..96b546755c 100644 --- a/third_party/jpeg-xl/lib/extras/jpegli_test.cc +++ b/third_party/jpeg-xl/lib/extras/jpegli_test.cc @@ -255,7 +255,7 @@ TEST(JpegliTest, JpegliHDRRoundtripTest) { std::string testimage = "jxl/hdr_room.png"; PackedPixelFile ppf_in; ASSERT_TRUE(ReadTestImage(testimage, &ppf_in)); - EXPECT_EQ("RGB_D65_202_Rel_HLG", Description(ppf_in.color_encoding)); + EXPECT_EQ("Rec2100HLG", Description(ppf_in.color_encoding)); EXPECT_EQ(16, ppf_in.info.bits_per_sample); std::vector<uint8_t> compressed; diff --git a/third_party/jpeg-xl/lib/extras/metrics.cc b/third_party/jpeg-xl/lib/extras/metrics.cc index 4259d3c375..f70ab0a61d 100644 --- a/third_party/jpeg-xl/lib/extras/metrics.cc +++ b/third_party/jpeg-xl/lib/extras/metrics.cc @@ -16,6 +16,7 @@ #include <hwy/highway.h> #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/color_encoding_internal.h" HWY_BEFORE_NAMESPACE(); diff --git a/third_party/jpeg-xl/lib/extras/packed_image_convert.cc b/third_party/jpeg-xl/lib/extras/packed_image_convert.cc index 2ad001bf09..7e4b592fc4 100644 --- a/third_party/jpeg-xl/lib/extras/packed_image_convert.cc +++ b/third_party/jpeg-xl/lib/extras/packed_image_convert.cc @@ -11,6 +11,7 @@ #include <cstdint> +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/color_encoding_internal.h" #include "lib/jxl/dec_external_image.h" diff --git a/third_party/jpeg-xl/lib/include/jxl/color_encoding.h b/third_party/jpeg-xl/lib/include/jxl/color_encoding.h index e6325dcb30..f5de188223 100644 --- a/third_party/jpeg-xl/lib/include/jxl/color_encoding.h +++ b/third_party/jpeg-xl/lib/include/jxl/color_encoding.h @@ -14,8 +14,6 @@ #ifndef JXL_COLOR_ENCODING_H_ #define JXL_COLOR_ENCODING_H_ -#include <stdint.h> - #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif diff --git a/third_party/jpeg-xl/lib/jpegli/color_transform.cc b/third_party/jpeg-xl/lib/jpegli/color_transform.cc index 60a0dc83bb..ec906bedce 100644 --- a/third_party/jpeg-xl/lib/jpegli/color_transform.cc +++ b/third_party/jpeg-xl/lib/jpegli/color_transform.cc @@ -26,11 +26,16 @@ using hwy::HWY_NAMESPACE::Mul; using hwy::HWY_NAMESPACE::MulAdd; using hwy::HWY_NAMESPACE::Sub; -void YCbCrToRGB(float* row[kMaxComponents], size_t xsize) { +template <int kRed, int kGreen, int kBlue, int kAlpha> +void YCbCrToExtRGB(float* row[kMaxComponents], size_t xsize) { const HWY_CAPPED(float, 8) df; - float* JXL_RESTRICT row0 = row[0]; - float* JXL_RESTRICT row1 = row[1]; - float* JXL_RESTRICT row2 = row[2]; + const float* row_y = row[0]; + const float* row_cb = row[1]; + const float* row_cr = row[2]; + float* row_r = row[kRed]; + float* row_g = row[kGreen]; + float* row_b = row[kBlue]; + float* row_a = row[kAlpha]; // Full-range BT.601 as defined by JFIF Clause 7: // https://www.itu.int/rec/T-REC-T.871-201105-I/en @@ -38,20 +43,48 @@ void YCbCrToRGB(float* row[kMaxComponents], size_t xsize) { const auto cgcb = Set(df, -0.114f * 1.772f / 0.587f); const auto cgcr = Set(df, -0.299f * 1.402f / 0.587f); const auto cbcb = Set(df, 1.772f); + const auto alpha_opaque = Set(df, 127.0f / 255.0f); for (size_t x = 0; x < xsize; x += Lanes(df)) { - const auto y_vec = Load(df, row0 + x); - const auto cb_vec = Load(df, row1 + x); - const auto cr_vec = Load(df, row2 + x); + const auto y_vec = Load(df, row_y + x); + const auto cb_vec = Load(df, row_cb + x); + const auto cr_vec = Load(df, row_cr + x); const auto r_vec = MulAdd(crcr, cr_vec, y_vec); const auto g_vec = MulAdd(cgcr, cr_vec, MulAdd(cgcb, cb_vec, y_vec)); const auto b_vec = MulAdd(cbcb, cb_vec, y_vec); - Store(r_vec, df, row0 + x); - Store(g_vec, df, row1 + x); - Store(b_vec, df, row2 + x); + Store(r_vec, df, row_r + x); + Store(g_vec, df, row_g + x); + Store(b_vec, df, row_b + x); + if (kAlpha >= 0) { + Store(alpha_opaque, df, row_a + x); + } } } +void YCbCrToRGB(float* row[kMaxComponents], size_t xsize) { + YCbCrToExtRGB<0, 1, 2, -1>(row, xsize); +} + +void YCbCrToBGR(float* row[kMaxComponents], size_t xsize) { + YCbCrToExtRGB<2, 1, 0, -1>(row, xsize); +} + +void YCbCrToRGBA(float* row[kMaxComponents], size_t xsize) { + YCbCrToExtRGB<0, 1, 2, 3>(row, xsize); +} + +void YCbCrToBGRA(float* row[kMaxComponents], size_t xsize) { + YCbCrToExtRGB<2, 1, 0, 3>(row, xsize); +} + +void YCbCrToARGB(float* row[kMaxComponents], size_t xsize) { + YCbCrToExtRGB<1, 2, 3, 0>(row, xsize); +} + +void YCbCrToABGR(float* row[kMaxComponents], size_t xsize) { + YCbCrToExtRGB<3, 2, 1, 0>(row, xsize); +} + void YCCKToCMYK(float* row[kMaxComponents], size_t xsize) { const HWY_CAPPED(float, 8) df; float* JXL_RESTRICT row0 = row[0]; @@ -66,11 +99,15 @@ void YCCKToCMYK(float* row[kMaxComponents], size_t xsize) { } } -void RGBToYCbCr(float* row[kMaxComponents], size_t xsize) { +template <int kRed, int kGreen, int kBlue> +void ExtRGBToYCbCr(float* row[kMaxComponents], size_t xsize) { const HWY_CAPPED(float, 8) df; - float* JXL_RESTRICT row0 = row[0]; - float* JXL_RESTRICT row1 = row[1]; - float* JXL_RESTRICT row2 = row[2]; + const float* row_r = row[kRed]; + const float* row_g = row[kGreen]; + const float* row_b = row[kBlue]; + float* row_y = row[0]; + float* row_cb = row[1]; + float* row_cr = row[2]; // Full-range BT.601 as defined by JFIF Clause 7: // https://www.itu.int/rec/T-REC-T.871-201105-I/en const auto c128 = Set(df, 128.0f); @@ -85,9 +122,9 @@ void RGBToYCbCr(float* row[kMaxComponents], size_t xsize) { const auto kNormB = Div(Set(df, 1.0f), (Add(kR, Add(kG, kAmpB)))); for (size_t x = 0; x < xsize; x += Lanes(df)) { - const auto r = Load(df, row0 + x); - const auto g = Load(df, row1 + x); - const auto b = Load(df, row2 + x); + const auto r = Load(df, row_r + x); + const auto g = Load(df, row_g + x); + const auto b = Load(df, row_b + x); const auto r_base = Mul(r, kR); const auto r_diff = Mul(r, kDiffR); const auto g_base = Mul(g, kG); @@ -96,12 +133,28 @@ void RGBToYCbCr(float* row[kMaxComponents], size_t xsize) { const auto y_base = Add(r_base, Add(g_base, b_base)); const auto cb_vec = MulAdd(Sub(b_diff, y_base), kNormB, c128); const auto cr_vec = MulAdd(Sub(r_diff, y_base), kNormR, c128); - Store(y_base, df, row0 + x); - Store(cb_vec, df, row1 + x); - Store(cr_vec, df, row2 + x); + Store(y_base, df, row_y + x); + Store(cb_vec, df, row_cb + x); + Store(cr_vec, df, row_cr + x); } } +void RGBToYCbCr(float* row[kMaxComponents], size_t xsize) { + ExtRGBToYCbCr<0, 1, 2>(row, xsize); +} + +void BGRToYCbCr(float* row[kMaxComponents], size_t xsize) { + ExtRGBToYCbCr<2, 1, 0>(row, xsize); +} + +void ARGBToYCbCr(float* row[kMaxComponents], size_t xsize) { + ExtRGBToYCbCr<1, 2, 3>(row, xsize); +} + +void ABGRToYCbCr(float* row[kMaxComponents], size_t xsize) { + ExtRGBToYCbCr<3, 2, 1>(row, xsize); +} + void CMYKToYCCK(float* row[kMaxComponents], size_t xsize) { const HWY_CAPPED(float, 8) df; float* JXL_RESTRICT row0 = row[0]; @@ -127,7 +180,15 @@ namespace jpegli { HWY_EXPORT(CMYKToYCCK); HWY_EXPORT(YCCKToCMYK); HWY_EXPORT(YCbCrToRGB); +HWY_EXPORT(YCbCrToBGR); +HWY_EXPORT(YCbCrToRGBA); +HWY_EXPORT(YCbCrToBGRA); +HWY_EXPORT(YCbCrToARGB); +HWY_EXPORT(YCbCrToABGR); HWY_EXPORT(RGBToYCbCr); +HWY_EXPORT(BGRToYCbCr); +HWY_EXPORT(ARGBToYCbCr); +HWY_EXPORT(ABGRToYCbCr); bool CheckColorSpaceComponents(int num_components, J_COLOR_SPACE colorspace) { switch (colorspace) { @@ -164,16 +225,73 @@ bool CheckColorSpaceComponents(int num_components, J_COLOR_SPACE colorspace) { void NullTransform(float* row[kMaxComponents], size_t len) {} +void FillAlpha(float* row, size_t len) { + static const float kAlpha = 127.0f / 255.0f; + for (size_t i = 0; i < len; ++i) { + row[i] = kAlpha; + } +} + +// Works for BGR as well. void GrayscaleToRGB(float* row[kMaxComponents], size_t len) { memcpy(row[1], row[0], len * sizeof(row[1][0])); memcpy(row[2], row[0], len * sizeof(row[2][0])); } +// Works for BGRA as well. +void GrayscaleToRGBA(float* row[kMaxComponents], size_t len) { + memcpy(row[1], row[0], len * sizeof(row[1][0])); + memcpy(row[2], row[0], len * sizeof(row[2][0])); + FillAlpha(row[3], len); +} + +// Works for ABGR as well. +void GrayscaleToARGB(float* row[kMaxComponents], size_t len) { + memcpy(row[1], row[0], len * sizeof(row[1][0])); + memcpy(row[2], row[0], len * sizeof(row[2][0])); + memcpy(row[3], row[0], len * sizeof(row[1][0])); + FillAlpha(row[0], len); +} + void GrayscaleToYCbCr(float* row[kMaxComponents], size_t len) { memset(row[1], 0, len * sizeof(row[1][0])); memset(row[2], 0, len * sizeof(row[2][0])); } +void RGBToBGR(float* row[kMaxComponents], size_t len) { + for (size_t i = 0; i < len; ++i) { + std::swap(row[0][i], row[2][i]); + } +} + +void RGBToRGBA(float* row[kMaxComponents], size_t len) { + FillAlpha(row[3], len); +} + +void RGBToBGRA(float* row[kMaxComponents], size_t len) { + static const float kAlpha = 127.0f / 255.0f; + for (size_t i = 0; i < len; ++i) { + std::swap(row[0][i], row[2][i]); + row[3][i] = kAlpha; + } +} + +void RGBToARGB(float* row[kMaxComponents], size_t len) { + memcpy(row[3], row[2], len * sizeof(row[1][0])); + memcpy(row[2], row[1], len * sizeof(row[2][0])); + memcpy(row[1], row[0], len * sizeof(row[1][0])); + FillAlpha(row[0], len); +} + +void RGBToABGR(float* row[kMaxComponents], size_t len) { + static const float kAlpha = 127.0f / 255.0f; + for (size_t i = 0; i < len; ++i) { + std::swap(row[1][i], row[2][i]); + row[3][i] = row[0][i]; + row[0][i] = kAlpha; + } +} + void ChooseColorTransform(j_compress_ptr cinfo) { jpeg_comp_master* m = cinfo->master; if (!CheckColorSpaceComponents(cinfo->input_components, @@ -226,6 +344,43 @@ void ChooseColorTransform(j_compress_ptr cinfo) { } } + if (cinfo->jpeg_color_space == JCS_GRAYSCALE || + cinfo->jpeg_color_space == JCS_YCbCr) { + switch (cinfo->in_color_space) { +#ifdef JCS_EXTENSIONS + case JCS_EXT_RGB: + case JCS_EXT_RGBX: + m->color_transform = HWY_DYNAMIC_DISPATCH(RGBToYCbCr); + break; + case JCS_EXT_BGR: + case JCS_EXT_BGRX: + m->color_transform = HWY_DYNAMIC_DISPATCH(BGRToYCbCr); + break; + case JCS_EXT_XRGB: + m->color_transform = HWY_DYNAMIC_DISPATCH(ARGBToYCbCr); + break; + case JCS_EXT_XBGR: + m->color_transform = HWY_DYNAMIC_DISPATCH(ABGRToYCbCr); + break; +#endif +#ifdef JCS_ALPHA_EXTENSIONS + case JCS_EXT_RGBA: + m->color_transform = HWY_DYNAMIC_DISPATCH(RGBToYCbCr); + break; + case JCS_EXT_BGRA: + m->color_transform = HWY_DYNAMIC_DISPATCH(BGRToYCbCr); + break; + case JCS_EXT_ARGB: + m->color_transform = HWY_DYNAMIC_DISPATCH(ARGBToYCbCr); + break; + case JCS_EXT_ABGR: + m->color_transform = HWY_DYNAMIC_DISPATCH(ABGRToYCbCr); + break; +#endif + default:; // Nothing to do. + } + } + if (m->color_transform == nullptr) { // TODO(szabadka) Support more color transforms. JPEGLI_ERROR("Unsupported color transform %d -> %d", cinfo->in_color_space, @@ -257,18 +412,123 @@ void ChooseColorTransform(j_decompress_ptr cinfo) { m->color_transform = nullptr; if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { - if (cinfo->out_color_space == JCS_RGB) { - m->color_transform = GrayscaleToRGB; + switch (cinfo->out_color_space) { + case JCS_RGB: + m->color_transform = GrayscaleToRGB; + break; +#ifdef JCS_EXTENSIONS + case JCS_EXT_RGB: + case JCS_EXT_BGR: + m->color_transform = GrayscaleToRGB; + break; + case JCS_EXT_RGBX: + case JCS_EXT_BGRX: + m->color_transform = GrayscaleToRGBA; + break; + case JCS_EXT_XRGB: + case JCS_EXT_XBGR: + m->color_transform = GrayscaleToARGB; + break; +#endif +#ifdef JCS_ALPHA_EXTENSIONS + case JCS_EXT_RGBA: + case JCS_EXT_BGRA: + m->color_transform = GrayscaleToRGBA; + break; + case JCS_EXT_ARGB: + case JCS_EXT_ABGR: + m->color_transform = GrayscaleToARGB; + break; +#endif + default: + m->color_transform = nullptr; } } else if (cinfo->jpeg_color_space == JCS_RGB) { - if (cinfo->out_color_space == JCS_GRAYSCALE) { - m->color_transform = HWY_DYNAMIC_DISPATCH(RGBToYCbCr); + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + m->color_transform = HWY_DYNAMIC_DISPATCH(RGBToYCbCr); + break; +#ifdef JCS_EXTENSIONS + case JCS_EXT_RGB: + m->color_transform = NullTransform; + break; + case JCS_EXT_BGR: + m->color_transform = RGBToBGR; + break; + case JCS_EXT_RGBX: + m->color_transform = RGBToRGBA; + break; + case JCS_EXT_BGRX: + m->color_transform = RGBToBGRA; + break; + case JCS_EXT_XRGB: + m->color_transform = RGBToARGB; + break; + case JCS_EXT_XBGR: + m->color_transform = RGBToABGR; + break; +#endif +#ifdef JCS_ALPHA_EXTENSIONS + case JCS_EXT_RGBA: + m->color_transform = RGBToRGBA; + break; + case JCS_EXT_BGRA: + m->color_transform = RGBToBGRA; + break; + case JCS_EXT_ARGB: + m->color_transform = RGBToARGB; + break; + case JCS_EXT_ABGR: + m->color_transform = RGBToABGR; + break; +#endif + default: + m->color_transform = nullptr; } } else if (cinfo->jpeg_color_space == JCS_YCbCr) { - if (cinfo->out_color_space == JCS_RGB) { - m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToRGB); - } else if (cinfo->out_color_space == JCS_GRAYSCALE) { - m->color_transform = NullTransform; + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + m->color_transform = NullTransform; + break; + case JCS_RGB: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToRGB); + break; +#ifdef JCS_EXTENSIONS + case JCS_EXT_RGB: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToRGB); + break; + case JCS_EXT_BGR: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToBGR); + break; + case JCS_EXT_RGBX: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToRGBA); + break; + case JCS_EXT_BGRX: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToBGRA); + break; + case JCS_EXT_XRGB: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToARGB); + break; + case JCS_EXT_XBGR: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToABGR); + break; +#endif +#ifdef JCS_ALPHA_EXTENSIONS + case JCS_EXT_RGBA: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToRGBA); + break; + case JCS_EXT_BGRA: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToBGRA); + break; + case JCS_EXT_ARGB: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToARGB); + break; + case JCS_EXT_ABGR: + m->color_transform = HWY_DYNAMIC_DISPATCH(YCbCrToABGR); + break; +#endif + default: + m->color_transform = nullptr; } } else if (cinfo->jpeg_color_space == JCS_YCCK) { if (cinfo->out_color_space == JCS_CMYK) { diff --git a/third_party/jpeg-xl/lib/jpegli/common.h b/third_party/jpeg-xl/lib/jpegli/common.h index 42487f2b89..514483afef 100644 --- a/third_party/jpeg-xl/lib/jpegli/common.h +++ b/third_party/jpeg-xl/lib/jpegli/common.h @@ -20,12 +20,7 @@ #ifndef LIB_JPEGLI_COMMON_H_ #define LIB_JPEGLI_COMMON_H_ -/* clang-format off */ -#include <stdio.h> -#include <jpeglib.h> -/* clang-format on */ - -#include "lib/jpegli/types.h" +#include "lib/jxl/base/include_jpeglib.h" // NOLINT #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/third_party/jpeg-xl/lib/jpegli/decode.cc b/third_party/jpeg-xl/lib/jpegli/decode.cc index 9fdf68dd18..d967b787d3 100644 --- a/third_party/jpeg-xl/lib/jpegli/decode.cc +++ b/third_party/jpeg-xl/lib/jpegli/decode.cc @@ -54,6 +54,7 @@ void InitializeImage(j_decompress_ptr cinfo) { m->found_soi_ = false; m->found_dri_ = false; m->found_sof_ = false; + m->found_sos_ = false; m->found_eoi_ = false; m->icc_index_ = 0; m->icc_total_ = 0; @@ -243,10 +244,14 @@ void PrepareForScan(j_decompress_ptr cinfo) { // Copy quantization tables into comp_info. for (int i = 0; i < cinfo->comps_in_scan; ++i) { jpeg_component_info* comp = cinfo->cur_comp_info[i]; + int quant_tbl_idx = comp->quant_tbl_no; + JQUANT_TBL* quant_table = cinfo->quant_tbl_ptrs[quant_tbl_idx]; + if (!quant_table) { + JPEGLI_ERROR("Quantization table with index %d not found", quant_tbl_idx); + } if (comp->quant_table == nullptr) { comp->quant_table = Allocate<JQUANT_TBL>(cinfo, 1, JPOOL_IMAGE); - memcpy(comp->quant_table, cinfo->quant_tbl_ptrs[comp->quant_tbl_no], - sizeof(JQUANT_TBL)); + memcpy(comp->quant_table, quant_table, sizeof(JQUANT_TBL)); } } if (cinfo->comps_in_scan == 1) { @@ -723,16 +728,36 @@ void jpegli_calc_output_dimensions(j_decompress_ptr cinfo) { } } } - if (cinfo->out_color_space == JCS_GRAYSCALE) { - cinfo->out_color_components = 1; - } else if (cinfo->out_color_space == JCS_RGB || - cinfo->out_color_space == JCS_YCbCr) { - cinfo->out_color_components = 3; - } else if (cinfo->out_color_space == JCS_CMYK || - cinfo->out_color_space == JCS_YCCK) { - cinfo->out_color_components = 4; - } else { - cinfo->out_color_components = cinfo->num_components; + switch (cinfo->out_color_space) { + case JCS_GRAYSCALE: + cinfo->out_color_components = 1; + break; + case JCS_RGB: + case JCS_YCbCr: +#ifdef JCS_EXTENSIONS + case JCS_EXT_RGB: + case JCS_EXT_BGR: +#endif + cinfo->out_color_components = 3; + break; + case JCS_CMYK: + case JCS_YCCK: +#ifdef JCS_EXTENSIONS + case JCS_EXT_RGBX: + case JCS_EXT_BGRX: + case JCS_EXT_XBGR: + case JCS_EXT_XRGB: +#endif +#ifdef JCS_ALPHA_EXTENSIONS + case JCS_EXT_RGBA: + case JCS_EXT_BGRA: + case JCS_EXT_ABGR: + case JCS_EXT_ARGB: +#endif + cinfo->out_color_components = 4; + break; + default: + cinfo->out_color_components = cinfo->num_components; } cinfo->output_components = cinfo->quantize_colors ? 1 : cinfo->out_color_components; diff --git a/third_party/jpeg-xl/lib/jpegli/decode.h b/third_party/jpeg-xl/lib/jpegli/decode.h index f5b099eda3..668d630586 100644 --- a/third_party/jpeg-xl/lib/jpegli/decode.h +++ b/third_party/jpeg-xl/lib/jpegli/decode.h @@ -21,6 +21,7 @@ #define LIB_JPEGLI_DECODE_H_ #include "lib/jpegli/common.h" +#include "lib/jpegli/types.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/third_party/jpeg-xl/lib/jpegli/decode_api_test.cc b/third_party/jpeg-xl/lib/jpegli/decode_api_test.cc index 3ecd479951..c429f0f810 100644 --- a/third_party/jpeg-xl/lib/jpegli/decode_api_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/decode_api_test.cc @@ -3,17 +3,27 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +#include <jxl/types.h> + +#include <algorithm> #include <cstdint> #include <cstdio> +#include <cstdlib> +#include <cstring> +#include <ostream> +#include <sstream> +#include <string> +#include <utility> #include <vector> #include "lib/jpegli/decode.h" #include "lib/jpegli/encode.h" +#include "lib/jpegli/libjpeg_test_util.h" +#include "lib/jpegli/test_params.h" #include "lib/jpegli/test_utils.h" #include "lib/jpegli/testing.h" -#include "lib/jxl/base/byte_order.h" +#include "lib/jpegli/types.h" #include "lib/jxl/base/status.h" -#include "lib/jxl/sanitizers.h" namespace jpegli { namespace { @@ -894,7 +904,9 @@ std::vector<TestConfig> GenerateTests(bool buffered) { all_tests.push_back(config); } // Tests for color transforms. - for (J_COLOR_SPACE out_color_space : {JCS_RGB, JCS_GRAYSCALE}) { + for (J_COLOR_SPACE out_color_space : + {JCS_RGB, JCS_GRAYSCALE, JCS_EXT_RGB, JCS_EXT_BGR, JCS_EXT_RGBA, + JCS_EXT_BGRA, JCS_EXT_ARGB, JCS_EXT_ABGR}) { TestConfig config; config.input.xsize = config.input.ysize = 256; config.input.color_space = JCS_GRAYSCALE; @@ -903,7 +915,9 @@ std::vector<TestConfig> GenerateTests(bool buffered) { all_tests.push_back(config); } for (J_COLOR_SPACE jpeg_color_space : {JCS_RGB, JCS_YCbCr}) { - for (J_COLOR_SPACE out_color_space : {JCS_RGB, JCS_YCbCr, JCS_GRAYSCALE}) { + for (J_COLOR_SPACE out_color_space : + {JCS_RGB, JCS_YCbCr, JCS_GRAYSCALE, JCS_EXT_RGB, JCS_EXT_BGR, + JCS_EXT_RGBA, JCS_EXT_BGRA, JCS_EXT_ARGB, JCS_EXT_ABGR}) { if (jpeg_color_space == JCS_RGB && out_color_space == JCS_YCbCr) continue; TestConfig config; config.input.xsize = config.input.ysize = 256; @@ -1108,6 +1122,8 @@ std::vector<TestConfig> GenerateTests(bool buffered) { TestConfig config; config.input.xsize = xsize; config.input.ysize = ysize; + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; all_tests.push_back(config); } } diff --git a/third_party/jpeg-xl/lib/jpegli/decode_internal.h b/third_party/jpeg-xl/lib/jpegli/decode_internal.h index 37dfcc4526..8455fae392 100644 --- a/third_party/jpeg-xl/lib/jpegli/decode_internal.h +++ b/third_party/jpeg-xl/lib/jpegli/decode_internal.h @@ -6,14 +6,15 @@ #ifndef LIB_JPEGLI_DECODE_INTERNAL_H_ #define LIB_JPEGLI_DECODE_INTERNAL_H_ -#include <stdint.h> #include <sys/types.h> +#include <cstdint> #include <vector> #include "lib/jpegli/common.h" #include "lib/jpegli/common_internal.h" #include "lib/jpegli/huffman.h" +#include "lib/jpegli/types.h" namespace jpegli { @@ -58,6 +59,7 @@ struct jpeg_decomp_master { bool found_soi_; bool found_dri_; bool found_sof_; + bool found_sos_; bool found_eoi_; // Whether this jpeg has multiple scans (progressive or non-interleaved diff --git a/third_party/jpeg-xl/lib/jpegli/decode_marker.cc b/third_party/jpeg-xl/lib/jpegli/decode_marker.cc index a9ed4df329..2621ed0867 100644 --- a/third_party/jpeg-xl/lib/jpegli/decode_marker.cc +++ b/third_party/jpeg-xl/lib/jpegli/decode_marker.cc @@ -103,9 +103,6 @@ void ProcessSOF(j_decompress_ptr cinfo, const uint8_t* data, size_t len) { int quant_tbl_idx = ReadUint8(data, &pos); JPEG_VERIFY_INPUT(quant_tbl_idx, 0, NUM_QUANT_TBLS - 1); comp->quant_tbl_no = quant_tbl_idx; - if (cinfo->quant_tbl_ptrs[quant_tbl_idx] == nullptr) { - JPEGLI_ERROR("Quantization table with index %u not found", quant_tbl_idx); - } comp->quant_table = nullptr; // will be allocated after SOS marker } JPEG_VERIFY_MARKER_END(); @@ -168,6 +165,7 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) { if (!m->found_sof_) { JPEGLI_ERROR("Unexpected SOS marker."); } + m->found_sos_ = true; size_t pos = 2; JPEG_VERIFY_LEN(1); cinfo->comps_in_scan = ReadUint8(data, &pos); @@ -337,7 +335,7 @@ void ProcessDHT(j_decompress_ptr cinfo, const uint8_t* data, size_t len) { void ProcessDQT(j_decompress_ptr cinfo, const uint8_t* data, size_t len) { jpeg_decomp_master* m = cinfo->master; - if (m->found_sof_) { + if (m->found_sos_) { JPEGLI_ERROR("Updating quant tables between scans is not supported."); } size_t pos = 2; diff --git a/third_party/jpeg-xl/lib/jpegli/encode.cc b/third_party/jpeg-xl/lib/jpegli/encode.cc index 5326f2cb0f..6cfd54ad30 100644 --- a/third_party/jpeg-xl/lib/jpegli/encode.cc +++ b/third_party/jpeg-xl/lib/jpegli/encode.cc @@ -283,15 +283,15 @@ void ProcessCompressionParams(j_compress_ptr cinfo) { JPEGLI_ERROR("Invalid sampling factor %d x %d", comp->h_samp_factor, comp->v_samp_factor); } + if (cinfo->num_components == 1) { + // Force samp factors to 1x1 for single-component images. + comp->h_samp_factor = comp->v_samp_factor = 1; + } cinfo->max_h_samp_factor = std::max(comp->h_samp_factor, cinfo->max_h_samp_factor); cinfo->max_v_samp_factor = std::max(comp->v_samp_factor, cinfo->max_v_samp_factor); } - if (cinfo->num_components == 1 && - (cinfo->max_h_samp_factor != 1 || cinfo->max_v_samp_factor != 1)) { - JPEGLI_ERROR("Sampling is not supported for simgle component image."); - } size_t iMCU_width = DCTSIZE * cinfo->max_h_samp_factor; size_t iMCU_height = DCTSIZE * cinfo->max_v_samp_factor; size_t total_iMCU_cols = DivCeil(cinfo->image_width, iMCU_width); @@ -713,18 +713,31 @@ void jpegli_set_defaults(j_compress_ptr cinfo) { void jpegli_default_colorspace(j_compress_ptr cinfo) { CheckState(cinfo, jpegli::kEncStart); + if (cinfo->in_color_space == JCS_RGB && cinfo->master->xyb_mode) { + jpegli_set_colorspace(cinfo, JCS_RGB); + return; + } switch (cinfo->in_color_space) { case JCS_GRAYSCALE: jpegli_set_colorspace(cinfo, JCS_GRAYSCALE); break; - case JCS_RGB: { - if (cinfo->master->xyb_mode) { - jpegli_set_colorspace(cinfo, JCS_RGB); - } else { - jpegli_set_colorspace(cinfo, JCS_YCbCr); - } + case JCS_RGB: +#ifdef JCS_EXTENSIONS + case JCS_EXT_RGB: + case JCS_EXT_BGR: + case JCS_EXT_RGBX: + case JCS_EXT_BGRX: + case JCS_EXT_XRGB: + case JCS_EXT_XBGR: +#endif +#if JCS_ALPHA_EXTENSIONS + case JCS_EXT_RGBA: + case JCS_EXT_BGRA: + case JCS_EXT_ARGB: + case JCS_EXT_ABGR: +#endif + jpegli_set_colorspace(cinfo, JCS_YCbCr); break; - } case JCS_YCbCr: jpegli_set_colorspace(cinfo, JCS_YCbCr); break; @@ -806,6 +819,11 @@ void jpegli_set_colorspace(j_compress_ptr cinfo, J_COLOR_SPACE colorspace) { cinfo->comp_info[2].quant_tbl_no = 1; cinfo->comp_info[1].dc_tbl_no = cinfo->comp_info[1].ac_tbl_no = 1; cinfo->comp_info[2].dc_tbl_no = cinfo->comp_info[2].ac_tbl_no = 1; + // Use chroma subsampling by default + cinfo->comp_info[0].h_samp_factor = cinfo->comp_info[0].v_samp_factor = 2; + if (colorspace == JCS_YCCK) { + cinfo->comp_info[3].h_samp_factor = cinfo->comp_info[3].v_samp_factor = 2; + } } } diff --git a/third_party/jpeg-xl/lib/jpegli/encode.h b/third_party/jpeg-xl/lib/jpegli/encode.h index ed34838450..33de674471 100644 --- a/third_party/jpeg-xl/lib/jpegli/encode.h +++ b/third_party/jpeg-xl/lib/jpegli/encode.h @@ -21,6 +21,7 @@ #define LIB_JPEGLI_ENCODE_H_ #include "lib/jpegli/common.h" +#include "lib/jpegli/types.h" #if defined(__cplusplus) || defined(c_plusplus) extern "C" { diff --git a/third_party/jpeg-xl/lib/jpegli/encode_api_test.cc b/third_party/jpeg-xl/lib/jpegli/encode_api_test.cc index 2978b3f35d..81b1b25bef 100644 --- a/third_party/jpeg-xl/lib/jpegli/encode_api_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/encode_api_test.cc @@ -4,14 +4,23 @@ // license that can be found in the LICENSE file. #include <algorithm> -#include <cmath> +#include <cstddef> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include <ostream> +#include <sstream> +#include <string> #include <vector> #include "lib/jpegli/encode.h" -#include "lib/jpegli/error.h" +#include "lib/jpegli/libjpeg_test_util.h" +#include "lib/jpegli/test_params.h" #include "lib/jpegli/test_utils.h" #include "lib/jpegli/testing.h" -#include "lib/jxl/sanitizers.h" +#include "lib/jpegli/types.h" +#include "lib/jxl/base/status.h" namespace jpegli { namespace { @@ -372,6 +381,8 @@ std::vector<TestConfig> GenerateTests() { { TestConfig config; config.jparams.quality = 100; + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; config.max_bpp = 6.6; config.max_dist = 0.6; all_tests.push_back(config); @@ -510,17 +521,23 @@ std::vector<TestConfig> GenerateTests() { config.jparams.libjpeg_mode = true; config.max_bpp = 2.1; config.max_dist = 1.7; + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; all_tests.push_back(config); } - for (J_COLOR_SPACE in_color_space : {JCS_RGB, JCS_YCbCr, JCS_GRAYSCALE}) { + for (J_COLOR_SPACE in_color_space : + {JCS_RGB, JCS_YCbCr, JCS_GRAYSCALE, JCS_EXT_RGB, JCS_EXT_BGR, + JCS_EXT_RGBA, JCS_EXT_BGRA, JCS_EXT_ARGB, JCS_EXT_ABGR}) { for (J_COLOR_SPACE jpeg_color_space : {JCS_RGB, JCS_YCbCr, JCS_GRAYSCALE}) { - if (jpeg_color_space == JCS_RGB && in_color_space == JCS_YCbCr) continue; + if (jpeg_color_space == JCS_RGB && in_color_space >= JCS_YCbCr) continue; TestConfig config; config.input.xsize = config.input.ysize = 256; config.input.color_space = in_color_space; config.jparams.set_jpeg_colorspace = true; config.jparams.jpeg_color_space = jpeg_color_space; + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; config.max_bpp = jpeg_color_space == JCS_RGB ? 4.5 : 1.85; config.max_dist = jpeg_color_space == JCS_RGB ? 1.4 : 2.05; all_tests.push_back(config); @@ -536,6 +553,8 @@ std::vector<TestConfig> GenerateTests() { config.jparams.set_jpeg_colorspace = true; config.jparams.jpeg_color_space = jpeg_color_space; } + config.jparams.h_sampling = {1, 1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1, 1}; config.max_bpp = jpeg_color_space == JCS_CMYK ? 4.0 : 3.6; config.max_dist = jpeg_color_space == JCS_CMYK ? 1.2 : 1.5; all_tests.push_back(config); @@ -546,6 +565,8 @@ std::vector<TestConfig> GenerateTests() { config.input.color_space = JCS_YCbCr; config.max_bpp = 1.6; config.max_dist = 1.35; + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; all_tests.push_back(config); } for (bool xyb : {false, true}) { @@ -596,6 +617,8 @@ std::vector<TestConfig> GenerateTests() { table.add_raw = add_raw; table.Generate(); config.jparams.optimize_coding = 1; + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; config.jparams.quant_tables.push_back(table); config.jparams.quant_indexes = {0, 0, 0}; float q = (type == 0 ? 16 : type) * scale * 0.01f; @@ -614,6 +637,8 @@ std::vector<TestConfig> GenerateTests() { config.input.ysize = 256; config.jparams.quant_indexes = {(qidx >> 2) & 1, (qidx >> 1) & 1, (qidx >> 0) & 1}; + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; config.max_bpp = 2.25; config.max_dist = 2.8; all_tests.push_back(config); @@ -626,6 +651,8 @@ std::vector<TestConfig> GenerateTests() { config.input.ysize = 256; config.jparams.quant_indexes = {(qidx >> 2) & 1, (qidx >> 1) & 1, (qidx >> 0) & 1}; + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; CustomQuantTable table; table.slot_idx = slot_idx; table.Generate(); @@ -643,6 +670,10 @@ std::vector<TestConfig> GenerateTests() { config.jparams.xyb_mode = xyb; config.jparams.quant_indexes = {(qidx >> 2) & 1, (qidx >> 1) & 1, (qidx >> 0) & 1}; + if (!xyb) { + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; + } { CustomQuantTable table; table.slot_idx = 0; @@ -667,6 +698,10 @@ std::vector<TestConfig> GenerateTests() { config.input.ysize = 256; config.jparams.xyb_mode = xyb; config.jparams.quant_indexes = {0, 1, 2}; + if (!xyb) { + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; + } { CustomQuantTable table; table.slot_idx = 0; @@ -738,6 +773,8 @@ std::vector<TestConfig> GenerateTests() { } config.jparams.progressive_mode = 0; config.jparams.optimize_coding = 0; + config.jparams.h_sampling = {1, 1, 1}; + config.jparams.v_sampling = {1, 1, 1}; config.max_bpp = 1.85; config.max_dist = 2.05; if (input_mode == COEFFICIENTS) { diff --git a/third_party/jpeg-xl/lib/jpegli/error_handling_test.cc b/third_party/jpeg-xl/lib/jpegli/error_handling_test.cc index bcd7355124..582c6b170b 100644 --- a/third_party/jpeg-xl/lib/jpegli/error_handling_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/error_handling_test.cc @@ -3,12 +3,20 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +#include <cstddef> +#include <cstdint> +#include <cstdlib> +#include <cstring> +#include <vector> + +#include "lib/jpegli/common.h" #include "lib/jpegli/decode.h" #include "lib/jpegli/encode.h" -#include "lib/jpegli/error.h" +#include "lib/jpegli/libjpeg_test_util.h" +#include "lib/jpegli/test_params.h" #include "lib/jpegli/test_utils.h" #include "lib/jpegli/testing.h" -#include "lib/jxl/sanitizers.h" +#include "lib/jxl/base/status.h" namespace jpegli { namespace { @@ -996,6 +1004,9 @@ TEST(EncoderErrorHandlingTest, AddOnTableNoStringParam) { const uint8_t kCompressed0[] = { // SOI 0xff, 0xd8, // + // SOF + 0xff, 0xc0, 0x00, 0x0b, 0x08, 0x00, 0x01, 0x00, 0x01, 0x01, // + 0x01, 0x11, 0x00, // // DQT 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x03, 0x02, // 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x05, // @@ -1004,9 +1015,6 @@ const uint8_t kCompressed0[] = { 0x0e, 0x12, 0x10, 0x0d, 0x0e, 0x11, 0x0e, 0x0b, 0x0b, 0x10, // 0x16, 0x10, 0x11, 0x13, 0x14, 0x15, 0x15, 0x15, 0x0c, 0x0f, // 0x17, 0x18, 0x16, 0x14, 0x18, 0x12, 0x14, 0x15, 0x14, // - // SOF - 0xff, 0xc0, 0x00, 0x0b, 0x08, 0x00, 0x01, 0x00, 0x01, 0x01, // - 0x01, 0x11, 0x00, // // DHT 0xff, 0xc4, 0x00, 0xd2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, // 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // @@ -1039,8 +1047,8 @@ const uint8_t kCompressed0[] = { }; const size_t kLen0 = sizeof(kCompressed0); -const size_t kDQTOffset = 2; -const size_t kSOFOffset = 71; +const size_t kSOFOffset = 2; +const size_t kDQTOffset = 15; const size_t kDHTOffset = 84; const size_t kSOSOffset = 296; diff --git a/third_party/jpeg-xl/lib/jpegli/input_suspension_test.cc b/third_party/jpeg-xl/lib/jpegli/input_suspension_test.cc index 6546b7b087..dc5aee2fc5 100644 --- a/third_party/jpeg-xl/lib/jpegli/input_suspension_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/input_suspension_test.cc @@ -3,16 +3,24 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#include <cmath> +#include <jxl/types.h> + +#include <algorithm> +#include <cstddef> #include <cstdint> +#include <cstring> +#include <ostream> +#include <sstream> +#include <string> +#include <utility> #include <vector> #include "lib/jpegli/decode.h" +#include "lib/jpegli/libjpeg_test_util.h" +#include "lib/jpegli/test_params.h" #include "lib/jpegli/test_utils.h" #include "lib/jpegli/testing.h" -#include "lib/jxl/base/byte_order.h" #include "lib/jxl/base/status.h" -#include "lib/jxl/sanitizers.h" namespace jpegli { namespace { diff --git a/third_party/jpeg-xl/lib/jpegli/libjpeg_test_util.cc b/third_party/jpeg-xl/lib/jpegli/libjpeg_test_util.cc index 020adf5e9e..d34ec7e999 100644 --- a/third_party/jpeg-xl/lib/jpegli/libjpeg_test_util.cc +++ b/third_party/jpeg-xl/lib/jpegli/libjpeg_test_util.cc @@ -5,12 +5,7 @@ #include "lib/jpegli/libjpeg_test_util.h" -/* clang-format off */ -#include <stdio.h> -#include <jpeglib.h> -#include <setjmp.h> -/* clang-format on */ - +#include "lib/jxl/base/include_jpeglib.h" // NOLINT #include "lib/jxl/sanitizers.h" namespace jpegli { diff --git a/third_party/jpeg-xl/lib/jpegli/output_suspension_test.cc b/third_party/jpeg-xl/lib/jpegli/output_suspension_test.cc index 3cb2fd3ee4..44d63fdcbb 100644 --- a/third_party/jpeg-xl/lib/jpegli/output_suspension_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/output_suspension_test.cc @@ -3,7 +3,18 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <cstring> +#include <ostream> +#include <sstream> +#include <string> +#include <vector> + #include "lib/jpegli/encode.h" +#include "lib/jpegli/libjpeg_test_util.h" +#include "lib/jpegli/test_params.h" #include "lib/jpegli/test_utils.h" #include "lib/jpegli/testing.h" @@ -130,6 +141,7 @@ TEST_P(OutputSuspensionTestParam, RawData) { cinfo.input_components = input.components; cinfo.in_color_space = JCS_YCbCr; jpegli_set_defaults(&cinfo); + cinfo.comp_info[0].h_samp_factor = config.jparams.h_sampling[0]; cinfo.comp_info[0].v_samp_factor = config.jparams.v_sampling[0]; jpegli_set_progressive_level(&cinfo, 0); cinfo.optimize_coding = FALSE; diff --git a/third_party/jpeg-xl/lib/jpegli/source_manager_test.cc b/third_party/jpeg-xl/lib/jpegli/source_manager_test.cc index a513b7063b..2d49ac16ba 100644 --- a/third_party/jpeg-xl/lib/jpegli/source_manager_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/source_manager_test.cc @@ -3,14 +3,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#include <cmath> #include <cstdint> #include <vector> #include "lib/jpegli/decode.h" +#include "lib/jpegli/libjpeg_test_util.h" #include "lib/jpegli/test_utils.h" #include "lib/jpegli/testing.h" -#include "lib/jxl/base/status.h" namespace jpegli { namespace { diff --git a/third_party/jpeg-xl/lib/jpegli/streaming_test.cc b/third_party/jpeg-xl/lib/jpegli/streaming_test.cc index 1f19dc2045..29a224385f 100644 --- a/third_party/jpeg-xl/lib/jpegli/streaming_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/streaming_test.cc @@ -3,8 +3,18 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <cstring> +#include <ostream> +#include <sstream> +#include <string> +#include <vector> + #include "lib/jpegli/decode.h" #include "lib/jpegli/encode.h" +#include "lib/jpegli/test_params.h" #include "lib/jpegli/test_utils.h" #include "lib/jpegli/testing.h" diff --git a/third_party/jpeg-xl/lib/jpegli/test_utils.cc b/third_party/jpeg-xl/lib/jpegli/test_utils.cc index db5a30e8dc..5315c692a1 100644 --- a/third_party/jpeg-xl/lib/jpegli/test_utils.cc +++ b/third_party/jpeg-xl/lib/jpegli/test_utils.cc @@ -8,6 +8,7 @@ #include <cmath> #include <cstdint> #include <fstream> +#include <sstream> #include "lib/jpegli/decode.h" #include "lib/jpegli/encode.h" @@ -171,6 +172,18 @@ std::string ColorSpaceName(J_COLOR_SPACE colorspace) { return "CMYK"; case JCS_YCCK: return "YCCK"; + case JCS_EXT_RGB: + return "EXT_RGB"; + case JCS_EXT_BGR: + return "EXT_BGR"; + case JCS_EXT_RGBA: + return "EXT_RGBA"; + case JCS_EXT_BGRA: + return "EXT_BGRA"; + case JCS_EXT_ARGB: + return "EXT_ARGB"; + case JCS_EXT_ABGR: + return "EXT_ABGR"; default: return ""; } @@ -301,9 +314,12 @@ std::ostream& operator<<(std::ostream& os, const CompressParams& jparams) { void SetNumChannels(J_COLOR_SPACE colorspace, size_t* channels) { if (colorspace == JCS_GRAYSCALE) { *channels = 1; - } else if (colorspace == JCS_RGB || colorspace == JCS_YCbCr) { + } else if (colorspace == JCS_RGB || colorspace == JCS_YCbCr || + colorspace == JCS_EXT_RGB || colorspace == JCS_EXT_BGR) { *channels = 3; - } else if (colorspace == JCS_CMYK || colorspace == JCS_YCCK) { + } else if (colorspace == JCS_CMYK || colorspace == JCS_YCCK || + colorspace == JCS_EXT_RGBA || colorspace == JCS_EXT_BGRA || + colorspace == JCS_EXT_ARGB || colorspace == JCS_EXT_ABGR) { *channels = 4; } else if (colorspace == JCS_UNKNOWN) { JXL_CHECK(*channels <= 4); @@ -330,7 +346,28 @@ void ConvertPixel(const uint8_t* input_rgb, uint8_t* out, if (colorspace == JCS_GRAYSCALE) { const float Y = 0.299f * r + 0.587f * g + 0.114f * b; out8[0] = static_cast<uint8_t>(std::round(Y * kMul)); - } else if (colorspace == JCS_RGB || colorspace == JCS_UNKNOWN) { + } else if (colorspace == JCS_RGB || colorspace == JCS_EXT_RGB || + colorspace == JCS_EXT_RGBA) { + out8[0] = input_rgb[0]; + out8[1] = input_rgb[1]; + out8[2] = input_rgb[2]; + if (colorspace == JCS_EXT_RGBA) out8[3] = 255; + } else if (colorspace == JCS_EXT_BGR || colorspace == JCS_EXT_BGRA) { + out8[2] = input_rgb[0]; + out8[1] = input_rgb[1]; + out8[0] = input_rgb[2]; + if (colorspace == JCS_EXT_BGRA) out8[3] = 255; + } else if (colorspace == JCS_EXT_ABGR) { + out8[0] = 255; + out8[3] = input_rgb[0]; + out8[2] = input_rgb[1]; + out8[1] = input_rgb[2]; + } else if (colorspace == JCS_EXT_ARGB) { + out8[0] = 255; + out8[1] = input_rgb[0]; + out8[2] = input_rgb[1]; + out8[3] = input_rgb[2]; + } else if (colorspace == JCS_UNKNOWN) { for (size_t c = 0; c < num_channels; ++c) { out8[c] = input_rgb[std::min<size_t>(2, c)]; } @@ -390,9 +427,23 @@ void ConvertPixel(const uint8_t* input_rgb, uint8_t* out, void ConvertToGrayscale(TestImage* img) { if (img->color_space == JCS_GRAYSCALE) return; JXL_CHECK(img->data_type == JPEGLI_TYPE_UINT8); - for (size_t i = 0; i < img->pixels.size(); i += 3) { - if (img->color_space == JCS_RGB) { - ConvertPixel(&img->pixels[i], &img->pixels[i / 3], JCS_GRAYSCALE, 1); + bool rgb_pre_alpha = + img->color_space == JCS_EXT_ARGB || img->color_space == JCS_EXT_ABGR; + bool rgb_post_alpha = + img->color_space == JCS_EXT_RGBA || img->color_space == JCS_EXT_BGRA; + bool rgb_alpha = rgb_pre_alpha || rgb_post_alpha; + bool is_rgb = img->color_space == JCS_RGB || + img->color_space == JCS_EXT_RGB || + img->color_space == JCS_EXT_BGR || rgb_alpha; + bool switch_br = img->color_space == JCS_EXT_BGR || + img->color_space == JCS_EXT_ABGR || + img->color_space == JCS_EXT_BGRA; + size_t stride = rgb_alpha ? 4 : 3; + size_t offset = rgb_pre_alpha ? 1 : 0; + for (size_t i = offset; i < img->pixels.size(); i += stride) { + if (is_rgb) { + if (switch_br) std::swap(img->pixels[i], img->pixels[i + 2]); + ConvertPixel(&img->pixels[i], &img->pixels[i / stride], JCS_GRAYSCALE, 1); } else if (img->color_space == JCS_YCbCr) { img->pixels[i / 3] = img->pixels[i]; } diff --git a/third_party/jpeg-xl/lib/jpegli/test_utils.h b/third_party/jpeg-xl/lib/jpegli/test_utils.h index 132cfd042a..22c620c46c 100644 --- a/third_party/jpeg-xl/lib/jpegli/test_utils.h +++ b/third_party/jpeg-xl/lib/jpegli/test_utils.h @@ -6,22 +6,15 @@ #ifndef LIB_JPEGLI_TEST_UTILS_H_ #define LIB_JPEGLI_TEST_UTILS_H_ -#include <stddef.h> -#include <stdint.h> - -#include <algorithm> +#include <cstddef> +#include <cstdint> #include <string> #include <vector> -/* clang-format off */ -#include <stdio.h> -#include <jpeglib.h> -#include <setjmp.h> -/* clang-format on */ - -#include "lib/jpegli/common.h" -#include "lib/jpegli/libjpeg_test_util.h" #include "lib/jpegli/test_params.h" +#include "lib/jpegli/types.h" +#include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/include_jpeglib.h" // NOLINT namespace jpegli { @@ -127,4 +120,15 @@ void VerifyOutputImage(const TestImage& input, const TestImage& output, } // namespace jpegli +#if !defined(FUZZ_TEST) +struct FuzzTestSink { + template <typename F> + FuzzTestSink WithSeeds(F) { + return *this; + } +}; +#define FUZZ_TEST(A, B) \ + const JXL_MAYBE_UNUSED FuzzTestSink unused##A##B = FuzzTestSink() +#endif + #endif // LIB_JPEGLI_TEST_UTILS_H_ diff --git a/third_party/jpeg-xl/lib/jpegli/transcode_api_test.cc b/third_party/jpeg-xl/lib/jpegli/transcode_api_test.cc index 13c81a1119..413d5ae996 100644 --- a/third_party/jpeg-xl/lib/jpegli/transcode_api_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/transcode_api_test.cc @@ -3,10 +3,19 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +#include <cstddef> +#include <cstdint> +#include <cstdlib> +#include <cstring> +#include <ostream> +#include <sstream> +#include <string> #include <vector> #include "lib/jpegli/decode.h" #include "lib/jpegli/encode.h" +#include "lib/jpegli/libjpeg_test_util.h" +#include "lib/jpegli/test_params.h" #include "lib/jpegli/test_utils.h" #include "lib/jpegli/testing.h" #include "lib/jxl/base/status.h" diff --git a/third_party/jpeg-xl/lib/jxl/ac_context.h b/third_party/jpeg-xl/lib/jxl/ac_context.h index a2b9e046d1..6529a9bb88 100644 --- a/third_party/jpeg-xl/lib/jxl/ac_context.h +++ b/third_party/jpeg-xl/lib/jxl/ac_context.h @@ -62,7 +62,8 @@ static JXL_INLINE size_t ZeroDensityContext(size_t nonzeros_left, size_t k, size_t covered_blocks, size_t log2_covered_blocks, size_t prev) { - JXL_DASSERT((1u << log2_covered_blocks) == covered_blocks); + JXL_DASSERT((static_cast<size_t>(1) << log2_covered_blocks) == + covered_blocks); nonzeros_left = (nonzeros_left + covered_blocks - 1) >> log2_covered_blocks; k >>= log2_covered_blocks; JXL_DASSERT(k > 0); @@ -109,7 +110,8 @@ struct BlockCtxMap { // Non-zero context is based on number of non-zeros and block context. // For better clustering, contexts with same number of non-zeros are grouped. constexpr uint32_t ZeroDensityContextsOffset(uint32_t block_ctx) const { - return num_ctxs * kNonZeroBuckets + kZeroDensityContextCount * block_ctx; + return static_cast<uint32_t>(num_ctxs * kNonZeroBuckets + + kZeroDensityContextCount * block_ctx); } // Context map for AC coefficients consists of 2 blocks: @@ -121,7 +123,8 @@ struct BlockCtxMap { // number of non-zeros left and // index in scan order constexpr uint32_t NumACContexts() const { - return num_ctxs * (kNonZeroBuckets + kZeroDensityContextCount); + return static_cast<uint32_t>(num_ctxs * + (kNonZeroBuckets + kZeroDensityContextCount)); } // Non-zero context is based on number of non-zeros and block context. @@ -134,7 +137,7 @@ struct BlockCtxMap { } else { ctx = 4 + non_zeros / 2; } - return ctx * num_ctxs + block_ctx; + return static_cast<uint32_t>(ctx * num_ctxs + block_ctx); } BlockCtxMap() { diff --git a/third_party/jpeg-xl/lib/jxl/ac_strategy.h b/third_party/jpeg-xl/lib/jxl/ac_strategy.h index 9e5917ff1b..fd40b0ced8 100644 --- a/third_party/jpeg-xl/lib/jxl/ac_strategy.h +++ b/third_party/jpeg-xl/lib/jxl/ac_strategy.h @@ -11,9 +11,12 @@ #include <hwy/base.h> // kMaxVectorSize +#include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/coeff_order_fwd.h" #include "lib/jxl/frame_dimensions.h" +#include "lib/jxl/image.h" #include "lib/jxl/image_ops.h" // Defines the different kinds of transforms, and heuristics to choose between diff --git a/third_party/jpeg-xl/lib/jxl/ac_strategy_test.cc b/third_party/jpeg-xl/lib/jxl/ac_strategy_test.cc index b1d9103466..dc25c89898 100644 --- a/third_party/jpeg-xl/lib/jxl/ac_strategy_test.cc +++ b/third_party/jpeg-xl/lib/jxl/ac_strategy_test.cc @@ -5,16 +5,14 @@ #include "lib/jxl/ac_strategy.h" -#include <string.h> - -#include <cmath> +#include <algorithm> +#include <cstring> #include <hwy/aligned_allocator.h> #include <hwy/base.h> // HWY_ALIGN_MAX #include <hwy/tests/hwy_gtest.h> -#include <utility> #include "lib/jxl/base/random.h" -#include "lib/jxl/dct_scales.h" +#include "lib/jxl/coeff_order_fwd.h" #include "lib/jxl/dec_transforms_testonly.h" #include "lib/jxl/enc_transforms.h" #include "lib/jxl/simd_util.h" diff --git a/third_party/jpeg-xl/lib/jxl/ans_common.h b/third_party/jpeg-xl/lib/jxl/ans_common.h index 44b8e3fba1..8236bb20ec 100644 --- a/third_party/jpeg-xl/lib/jxl/ans_common.h +++ b/third_party/jpeg-xl/lib/jxl/ans_common.h @@ -6,23 +6,24 @@ #ifndef LIB_JXL_ANS_COMMON_H_ #define LIB_JXL_ANS_COMMON_H_ -#include <stdint.h> - #include <algorithm> +#include <cstddef> +#include <cstdint> +#include <cstring> +#include <hwy/base.h> #include <hwy/cache_control.h> // Prefetch #include <vector> #include "lib/jxl/ans_params.h" #include "lib/jxl/base/byte_order.h" #include "lib/jxl/base/compiler_specific.h" -#include "lib/jxl/base/status.h" namespace jxl { // Returns the precision (number of bits) that should be used to store // a histogram count such that Log2Floor(count) == logcount. -static JXL_INLINE uint32_t GetPopulationCountPrecision(uint32_t logcount, - uint32_t shift) { +static JXL_MAYBE_UNUSED JXL_INLINE uint32_t +GetPopulationCountPrecision(uint32_t logcount, uint32_t shift) { int32_t r = std::min<int>( logcount, static_cast<int>(shift) - static_cast<int>((ANS_LOG_TAB_SIZE - logcount) >> 1)); diff --git a/third_party/jpeg-xl/lib/jxl/ans_test.cc b/third_party/jpeg-xl/lib/jxl/ans_test.cc index 5d6a5ef090..83a2e732f8 100644 --- a/third_party/jpeg-xl/lib/jxl/ans_test.cc +++ b/third_party/jpeg-xl/lib/jxl/ans_test.cc @@ -10,11 +10,10 @@ #include "lib/jxl/ans_params.h" #include "lib/jxl/base/random.h" -#include "lib/jxl/base/span.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/dec_ans.h" #include "lib/jxl/dec_bit_reader.h" #include "lib/jxl/enc_ans.h" -#include "lib/jxl/enc_aux_out.h" #include "lib/jxl/enc_bit_writer.h" #include "lib/jxl/testing.h" diff --git a/third_party/jpeg-xl/lib/jxl/base/compiler_specific.h b/third_party/jpeg-xl/lib/jxl/base/compiler_specific.h index 702ff8e058..52f88c50f8 100644 --- a/third_party/jpeg-xl/lib/jxl/base/compiler_specific.h +++ b/third_party/jpeg-xl/lib/jxl/base/compiler_specific.h @@ -8,7 +8,6 @@ // Macros for compiler version + nonstandard keywords, e.g. __builtin_expect. -#include <stdint.h> #include <sys/types.h> #include "lib/jxl/base/sanitizer_definitions.h" @@ -97,6 +96,11 @@ #define JXL_UNLIKELY(expr) __builtin_expect(!!(expr), 0) #endif +#if JXL_COMPILER_MSVC +#include <stdint.h> +using ssize_t = intptr_t; +#endif + // Returns a void* pointer which the compiler then assumes is N-byte aligned. // Example: float* JXL_RESTRICT aligned = (float*)JXL_ASSUME_ALIGNED(in, 32); // @@ -150,8 +154,4 @@ #define JXL_FORMAT(idx_fmt, idx_arg) #endif -#if JXL_COMPILER_MSVC -using ssize_t = intptr_t; -#endif - #endif // LIB_JXL_BASE_COMPILER_SPECIFIC_H_ diff --git a/third_party/jpeg-xl/lib/jxl/base/exif.h b/third_party/jpeg-xl/lib/jxl/base/exif.h index a3574a16ff..acaa1a1ce4 100644 --- a/third_party/jpeg-xl/lib/jxl/base/exif.h +++ b/third_party/jpeg-xl/lib/jxl/base/exif.h @@ -3,8 +3,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#ifndef LIB_JXL_EXIF_H_ -#define LIB_JXL_EXIF_H_ +#ifndef LIB_JXL_BASE_EXIF_H_ +#define LIB_JXL_BASE_EXIF_H_ // Basic parsing of Exif (just enough for the render-impacting things // like orientation) @@ -87,4 +87,4 @@ JXL_INLINE void InterpretExif(const std::vector<uint8_t>& exif, } // namespace jxl -#endif // LIB_JXL_EXIF_H_ +#endif // LIB_JXL_BASE_EXIF_H_ diff --git a/third_party/jpeg-xl/lib/jxl/base/include_jpeglib.h b/third_party/jpeg-xl/lib/jxl/base/include_jpeglib.h new file mode 100644 index 0000000000..f72d13d04b --- /dev/null +++ b/third_party/jpeg-xl/lib/jxl/base/include_jpeglib.h @@ -0,0 +1,20 @@ +// Copyright (c) the JPEG XL Project Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#ifndef LIB_JXL_BASE_INCLUDE_JPEGLIB_H_ +#define LIB_JXL_BASE_INCLUDE_JPEGLIB_H_ + +// Using this header ensures that includes go in the right order, +// not alphabetically sorted. + +// NOLINTBEGIN +/* clang-format off */ +#include <stdio.h> // IWYU pragma: keep +#include <jpeglib.h> // IWYU pragma: keep +#include <setjmp.h> // IWYU pragma: keep +/* clang-format on */ +// NOLINTEND + +#endif // LIB_JXL_BASE_INCLUDE_JPEGLIB_H_ diff --git a/third_party/jpeg-xl/lib/jxl/base/matrix_ops.h b/third_party/jpeg-xl/lib/jxl/base/matrix_ops.h index cde6a64b1e..e1f8753932 100644 --- a/third_party/jpeg-xl/lib/jxl/base/matrix_ops.h +++ b/third_party/jpeg-xl/lib/jxl/base/matrix_ops.h @@ -3,8 +3,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#ifndef LIB_JXL_MATRIX_OPS_H_ -#define LIB_JXL_MATRIX_OPS_H_ +#ifndef LIB_JXL_BASE_MATRIX_OPS_H_ +#define LIB_JXL_BASE_MATRIX_OPS_H_ // 3x3 matrix operations. @@ -83,4 +83,4 @@ Status Inv3x3Matrix(Matrix& matrix) { } // namespace jxl -#endif // LIB_JXL_MATRIX_OPS_H_ +#endif // LIB_JXL_BASE_MATRIX_OPS_H_ diff --git a/third_party/jpeg-xl/lib/jxl/base/rect.h b/third_party/jpeg-xl/lib/jxl/base/rect.h new file mode 100644 index 0000000000..666c3d73ec --- /dev/null +++ b/third_party/jpeg-xl/lib/jxl/base/rect.h @@ -0,0 +1,194 @@ +// Copyright (c) the JPEG XL Project Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#ifndef LIB_JXL_BASE_RECT_H_ +#define LIB_JXL_BASE_RECT_H_ + +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <cstring> +#include <sstream> +#include <string> +#include <utility> // std::move + +#include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/status.h" + +namespace jxl { + +// Rectangular region in image(s). Factoring this out of Image instead of +// shifting the pointer by x0/y0 allows this to apply to multiple images with +// different resolutions (e.g. color transform and quantization field). +// Can compare using SameSize(rect1, rect2). +template <typename T> +class RectT { + public: + // Most windows are xsize_max * ysize_max, except those on the borders where + // begin + size_max > end. + constexpr RectT(T xbegin, T ybegin, size_t xsize_max, size_t ysize_max, + T xend, T yend) + : x0_(xbegin), + y0_(ybegin), + xsize_(ClampedSize(xbegin, xsize_max, xend)), + ysize_(ClampedSize(ybegin, ysize_max, yend)) {} + + // Construct with origin and known size (typically from another Rect). + constexpr RectT(T xbegin, T ybegin, size_t xsize, size_t ysize) + : x0_(xbegin), y0_(ybegin), xsize_(xsize), ysize_(ysize) {} + + // Construct a rect that covers a whole image/plane/ImageBundle etc. + template <typename ImageT> + explicit RectT(const ImageT& image) + : RectT(0, 0, image.xsize(), image.ysize()) {} + + RectT() : RectT(0, 0, 0, 0) {} + + RectT(const RectT&) = default; + RectT& operator=(const RectT&) = default; + + // Construct a subrect that resides in an image/plane/ImageBundle etc. + template <typename ImageT> + RectT Crop(const ImageT& image) const { + return Intersection(RectT(image)); + } + + // Construct a subrect that resides in the [0, ysize) x [0, xsize) region of + // the current rect. + RectT Crop(size_t area_xsize, size_t area_ysize) const { + return Intersection(RectT(0, 0, area_xsize, area_ysize)); + } + + // Returns a rect that only contains `num` lines with offset `y` from `y0()`. + RectT Lines(size_t y, size_t num) const { + JXL_DASSERT(y + num <= ysize_); + return RectT(x0_, y0_ + y, xsize_, num); + } + + RectT Line(size_t y) const { return Lines(y, 1); } + + JXL_MUST_USE_RESULT RectT Intersection(const RectT& other) const { + return RectT(std::max(x0_, other.x0_), std::max(y0_, other.y0_), xsize_, + ysize_, std::min(x1(), other.x1()), + std::min(y1(), other.y1())); + } + + JXL_MUST_USE_RESULT RectT Translate(int64_t x_offset, + int64_t y_offset) const { + return RectT(x0_ + x_offset, y0_ + y_offset, xsize_, ysize_); + } + + template <template <class> class P, typename V> + V* Row(P<V>* image, size_t y) const { + JXL_DASSERT(y + y0_ >= 0); + return image->Row(y + y0_) + x0_; + } + + template <template <class> class P, typename V> + const V* Row(const P<V>* image, size_t y) const { + JXL_DASSERT(y + y0_ >= 0); + return image->Row(y + y0_) + x0_; + } + + template <template <class> class MP, typename V> + V* PlaneRow(MP<V>* image, const size_t c, size_t y) const { + JXL_DASSERT(y + y0_ >= 0); + return image->PlaneRow(c, y + y0_) + x0_; + } + + template <template <class> class P, typename V> + const V* ConstRow(const P<V>& image, size_t y) const { + JXL_DASSERT(y + y0_ >= 0); + return image.ConstRow(y + y0_) + x0_; + } + + template <template <class> class MP, typename V> + const V* ConstPlaneRow(const MP<V>& image, size_t c, size_t y) const { + JXL_DASSERT(y + y0_ >= 0); + return image.ConstPlaneRow(c, y + y0_) + x0_; + } + + bool IsInside(const RectT& other) const { + return x0_ >= other.x0() && x1() <= other.x1() && y0_ >= other.y0() && + y1() <= other.y1(); + } + + // Returns true if this Rect fully resides in the given image. ImageT could be + // Plane<T> or Image3<T>; however if ImageT is Rect, results are nonsensical. + template <class ImageT> + bool IsInside(const ImageT& image) const { + return IsInside(RectT(image)); + } + + T x0() const { return x0_; } + T y0() const { return y0_; } + size_t xsize() const { return xsize_; } + size_t ysize() const { return ysize_; } + T x1() const { return x0_ + xsize_; } + T y1() const { return y0_ + ysize_; } + + RectT<T> ShiftLeft(size_t shiftx, size_t shifty) const { + return RectT<T>(x0_ * (1 << shiftx), y0_ * (1 << shifty), xsize_ << shiftx, + ysize_ << shifty); + } + RectT<T> ShiftLeft(size_t shift) const { return ShiftLeft(shift, shift); } + + // Requires x0(), y0() to be multiples of 1<<shiftx, 1<<shifty. + RectT<T> CeilShiftRight(size_t shiftx, size_t shifty) const { + JXL_ASSERT(x0_ % (1 << shiftx) == 0); + JXL_ASSERT(y0_ % (1 << shifty) == 0); + return RectT<T>(x0_ / (1 << shiftx), y0_ / (1 << shifty), + DivCeil(xsize_, T{1} << shiftx), + DivCeil(ysize_, T{1} << shifty)); + } + RectT<T> CeilShiftRight(std::pair<size_t, size_t> shift) const { + return CeilShiftRight(shift.first, shift.second); + } + RectT<T> CeilShiftRight(size_t shift) const { + return CeilShiftRight(shift, shift); + } + + RectT<T> Extend(T border, RectT<T> parent) const { + T new_x0 = x0() > parent.x0() + border ? x0() - border : parent.x0(); + T new_y0 = y0() > parent.y0() + border ? y0() - border : parent.y0(); + T new_x1 = x1() + border > parent.x1() ? parent.x1() : x1() + border; + T new_y1 = y1() + border > parent.y1() ? parent.y1() : y1() + border; + return RectT<T>(new_x0, new_y0, new_x1 - new_x0, new_y1 - new_y0); + } + + template <typename U> + RectT<U> As() const { + return RectT<U>(static_cast<U>(x0_), static_cast<U>(y0_), + static_cast<U>(xsize_), static_cast<U>(ysize_)); + } + + private: + // Returns size_max, or whatever is left in [begin, end). + static constexpr size_t ClampedSize(T begin, size_t size_max, T end) { + return (static_cast<T>(begin + size_max) <= end) + ? size_max + : (end > begin ? end - begin : 0); + } + + T x0_; + T y0_; + + size_t xsize_; + size_t ysize_; +}; + +template <typename T> +std::string Description(RectT<T> r) { + std::ostringstream os; + os << "[" << r.x0() << ".." << r.x1() << ")x" + << "[" << r.y0() << ".." << r.y1() << ")"; + return os.str(); +} + +using Rect = RectT<size_t>; + +} // namespace jxl + +#endif // LIB_JXL_BASE_RECT_H_ diff --git a/third_party/jpeg-xl/lib/jxl/base/span.h b/third_party/jpeg-xl/lib/jxl/base/span.h index ba09d62316..7515b7b1ef 100644 --- a/third_party/jpeg-xl/lib/jxl/base/span.h +++ b/third_party/jpeg-xl/lib/jxl/base/span.h @@ -11,6 +11,7 @@ #include <cstddef> #include <cstdint> +#include <type_traits> #include <vector> #include "lib/jxl/base/status.h" @@ -41,6 +42,8 @@ class Span { "Incompatible type of source."); } + using NCT = typename std::remove_const<T>::type; + constexpr T* data() const noexcept { return ptr_; } constexpr size_t size() const noexcept { return len_; } @@ -62,12 +65,12 @@ class Span { len_ -= n; } - // NCT == non-const-T; compiler will complain if NCT is not compatible with T. - template <typename NCT> void AppendTo(std::vector<NCT>& dst) const { dst.insert(dst.end(), begin(), end()); } + std::vector<NCT> Copy() const { return std::vector<NCT>(begin(), end()); } + private: T* ptr_; size_t len_; diff --git a/third_party/jpeg-xl/lib/jxl/bit_reader_test.cc b/third_party/jpeg-xl/lib/jxl/bit_reader_test.cc index 802da855fa..b2d5773d15 100644 --- a/third_party/jpeg-xl/lib/jxl/bit_reader_test.cc +++ b/third_party/jpeg-xl/lib/jxl/bit_reader_test.cc @@ -7,6 +7,7 @@ #include <stdint.h> #include <array> +#include <utility> #include <vector> #include "lib/jxl/base/common.h" diff --git a/third_party/jpeg-xl/lib/jxl/bits_test.cc b/third_party/jpeg-xl/lib/jxl/bits_test.cc index 45db8c0d6e..8340db5a38 100644 --- a/third_party/jpeg-xl/lib/jxl/bits_test.cc +++ b/third_party/jpeg-xl/lib/jxl/bits_test.cc @@ -5,6 +5,9 @@ #include "lib/jxl/base/bits.h" +#include <cstddef> +#include <cstdint> + #include "lib/jxl/testing.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/blending.cc b/third_party/jpeg-xl/lib/jxl/blending.cc index 7575ec6e4a..0e26980816 100644 --- a/third_party/jpeg-xl/lib/jxl/blending.cc +++ b/third_party/jpeg-xl/lib/jxl/blending.cc @@ -5,7 +5,16 @@ #include "lib/jxl/blending.h" +#include <cstddef> +#include <cstring> +#include <vector> + #include "lib/jxl/alpha.h" +#include "lib/jxl/base/status.h" +#include "lib/jxl/dec_patch_dictionary.h" +#include "lib/jxl/frame_header.h" +#include "lib/jxl/image.h" +#include "lib/jxl/image_metadata.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/blending.h b/third_party/jpeg-xl/lib/jxl/blending.h index 94bead8dd6..6ed862ac1c 100644 --- a/third_party/jpeg-xl/lib/jxl/blending.h +++ b/third_party/jpeg-xl/lib/jxl/blending.h @@ -6,8 +6,10 @@ #ifndef LIB_JXL_BLENDING_H_ #define LIB_JXL_BLENDING_H_ +#include <cstddef> #include <vector> +#include "lib/jxl/base/status.h" #include "lib/jxl/dec_patch_dictionary.h" #include "lib/jxl/frame_header.h" #include "lib/jxl/image_metadata.h" diff --git a/third_party/jpeg-xl/lib/jxl/butteraugli/butteraugli.cc b/third_party/jpeg-xl/lib/jxl/butteraugli/butteraugli.cc index 2e06d79eba..4e49f18df8 100644 --- a/third_party/jpeg-xl/lib/jxl/butteraugli/butteraugli.cc +++ b/third_party/jpeg-xl/lib/jxl/butteraugli/butteraugli.cc @@ -22,13 +22,12 @@ #include "lib/jxl/butteraugli/butteraugli.h" -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - #include <algorithm> #include <cmath> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <cstring> #include <memory> #include <vector> @@ -40,6 +39,7 @@ #include "lib/jxl/base/fast_math-inl.h" #include "lib/jxl/base/printf_macros.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/convolve.h" #include "lib/jxl/image_ops.h" diff --git a/third_party/jpeg-xl/lib/jxl/cache_aligned.h b/third_party/jpeg-xl/lib/jxl/cache_aligned.h index 8480471e5c..c9cac17339 100644 --- a/third_party/jpeg-xl/lib/jxl/cache_aligned.h +++ b/third_party/jpeg-xl/lib/jxl/cache_aligned.h @@ -13,8 +13,6 @@ #include <memory> -#include "lib/jxl/base/compiler_specific.h" - namespace jxl { // Functions that depend on the cache line size. diff --git a/third_party/jpeg-xl/lib/jxl/chroma_from_luma.h b/third_party/jpeg-xl/lib/jxl/chroma_from_luma.h index 1f2353d9af..090d95165c 100644 --- a/third_party/jpeg-xl/lib/jxl/chroma_from_luma.h +++ b/third_party/jpeg-xl/lib/jxl/chroma_from_luma.h @@ -9,11 +9,12 @@ // Chroma-from-luma, computed using heuristics to determine the best linear // model for the X and B channels from the Y channel. -#include <stddef.h> -#include <stdint.h> - +#include <cmath> +#include <cstddef> +#include <cstdint> #include <limits> +#include "lib/jxl/base/common.h" #include "lib/jxl/base/status.h" #include "lib/jxl/cms/opsin_params.h" #include "lib/jxl/dec_bit_reader.h" diff --git a/third_party/jpeg-xl/lib/jxl/cms/jxl_cms_internal.h b/third_party/jpeg-xl/lib/jxl/cms/jxl_cms_internal.h index a787bd11d8..69a5dc434e 100644 --- a/third_party/jpeg-xl/lib/jxl/cms/jxl_cms_internal.h +++ b/third_party/jpeg-xl/lib/jxl/cms/jxl_cms_internal.h @@ -405,7 +405,7 @@ static Status WriteICCS15Fixed16(float value, size_t pos, // Even the first value works well,... bool ok = (-32767.995f <= value) && (value <= 32767.995f); if (!ok) return JXL_FAILURE("ICC value is out of range / NaN"); - int32_t i = value * 65536.0f + 0.5f; + int32_t i = static_cast<int32_t>(std::lround(value * 65536.0f)); // Use two's complement uint32_t u = static_cast<uint32_t>(i); WriteICCUint32(u, pos, icc); @@ -849,6 +849,20 @@ static std::string ToString(JxlRenderingIntent rendering_intent) { } static std::string ColorEncodingDescriptionImpl(const JxlColorEncoding& c) { + if (c.color_space == JXL_COLOR_SPACE_RGB && + c.white_point == JXL_WHITE_POINT_D65) { + if (c.rendering_intent == JXL_RENDERING_INTENT_PERCEPTUAL && + c.transfer_function == JXL_TRANSFER_FUNCTION_SRGB) { + if (c.primaries == JXL_PRIMARIES_SRGB) return "sRGB"; + if (c.primaries == JXL_PRIMARIES_P3) return "DisplayP3"; + } + if (c.rendering_intent == JXL_RENDERING_INTENT_RELATIVE && + c.primaries == JXL_PRIMARIES_2100) { + if (c.transfer_function == JXL_TRANSFER_FUNCTION_PQ) return "Rec2100PQ"; + if (c.transfer_function == JXL_TRANSFER_FUNCTION_HLG) return "Rec2100HLG"; + } + } + std::string d = ToString(c.color_space); bool explicit_wp_tf = (c.color_space != JXL_COLOR_SPACE_XYB); diff --git a/third_party/jpeg-xl/lib/jxl/cms/opsin_params.h b/third_party/jpeg-xl/lib/jxl/cms/opsin_params.h index 69dcd0b512..0af852c745 100644 --- a/third_party/jpeg-xl/lib/jxl/cms/opsin_params.h +++ b/third_party/jpeg-xl/lib/jxl/cms/opsin_params.h @@ -6,6 +6,9 @@ #ifndef LIB_JXL_CMS_OPSIN_PARAMS_H_ #define LIB_JXL_CMS_OPSIN_PARAMS_H_ +#include <array> +#include <cstddef> + #include "lib/jxl/base/matrix_ops.h" // Constants that define the XYB color space. diff --git a/third_party/jpeg-xl/lib/jxl/cms/tone_mapping.h b/third_party/jpeg-xl/lib/jxl/cms/tone_mapping.h index 1f85dcca41..c1f43f4d31 100644 --- a/third_party/jpeg-xl/lib/jxl/cms/tone_mapping.h +++ b/third_party/jpeg-xl/lib/jxl/cms/tone_mapping.h @@ -8,6 +8,7 @@ #include <algorithm> #include <cmath> +#include <cstddef> #include <utility> #include "lib/jxl/base/common.h" diff --git a/third_party/jpeg-xl/lib/jxl/coeff_order.h b/third_party/jpeg-xl/lib/jxl/coeff_order.h index 79c0c976c9..395e296642 100644 --- a/third_party/jpeg-xl/lib/jxl/coeff_order.h +++ b/third_party/jpeg-xl/lib/jxl/coeff_order.h @@ -6,11 +6,11 @@ #ifndef LIB_JXL_COEFF_ORDER_H_ #define LIB_JXL_COEFF_ORDER_H_ -#include <stddef.h> -#include <stdint.h> +#include <array> +#include <cstddef> +#include <cstdint> #include "lib/jxl/ac_strategy.h" -#include "lib/jxl/base/common.h" #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/status.h" #include "lib/jxl/coeff_order_fwd.h" @@ -24,11 +24,12 @@ class BitReader; static constexpr size_t kCoeffOrderLimit = 6156; -static constexpr std::array<size_t, 3 * kNumOrders + 1> kCoeffOrderOffset = { - 0, 1, 2, 3, 4, 5, 6, 10, 14, 18, - 34, 50, 66, 68, 70, 72, 76, 80, 84, 92, - 100, 108, 172, 236, 300, 332, 364, 396, 652, 908, - 1164, 1292, 1420, 1548, 2572, 3596, 4620, 5132, 5644, kCoeffOrderLimit}; +static constexpr std::array<size_t, 3 * kNumOrders + 1> JXL_MAYBE_UNUSED + kCoeffOrderOffset = { + 0, 1, 2, 3, 4, 5, 6, 10, 14, 18, + 34, 50, 66, 68, 70, 72, 76, 80, 84, 92, + 100, 108, 172, 236, 300, 332, 364, 396, 652, 908, + 1164, 1292, 1420, 1548, 2572, 3596, 4620, 5132, 5644, kCoeffOrderLimit}; // TODO(eustas): rollback to constexpr once modern C++ becomes reuired. #define CoeffOrderOffset(O, C) \ diff --git a/third_party/jpeg-xl/lib/jxl/coeff_order_fwd.h b/third_party/jpeg-xl/lib/jxl/coeff_order_fwd.h index 26306575c1..e5e72a4913 100644 --- a/third_party/jpeg-xl/lib/jxl/coeff_order_fwd.h +++ b/third_party/jpeg-xl/lib/jxl/coeff_order_fwd.h @@ -8,8 +8,8 @@ // Breaks circular dependency between ac_strategy and coeff_order. -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include "lib/jxl/base/compiler_specific.h" diff --git a/third_party/jpeg-xl/lib/jxl/color_encoding_internal.h b/third_party/jpeg-xl/lib/jxl/color_encoding_internal.h index 61e4628dbd..afcd5a4c1c 100644 --- a/third_party/jpeg-xl/lib/jxl/color_encoding_internal.h +++ b/third_party/jpeg-xl/lib/jxl/color_encoding_internal.h @@ -10,6 +10,7 @@ #include <jxl/cms_interface.h> #include <jxl/color_encoding.h> +#include <jxl/types.h> #include <stddef.h> #include <stdint.h> diff --git a/third_party/jpeg-xl/lib/jxl/color_management_test.cc b/third_party/jpeg-xl/lib/jxl/color_management_test.cc index 77cbe56926..b6a45b0a85 100644 --- a/third_party/jpeg-xl/lib/jxl/color_management_test.cc +++ b/third_party/jpeg-xl/lib/jxl/color_management_test.cc @@ -8,6 +8,7 @@ #include <stdint.h> #include <algorithm> +#include <cmath> #include <cstddef> #include <cstdint> #include <cstdio> @@ -20,6 +21,7 @@ #include "lib/jxl/base/common.h" #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/span.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/cms/color_encoding_cms.h" #include "lib/jxl/cms/opsin_params.h" #include "lib/jxl/color_encoding_internal.h" @@ -417,7 +419,7 @@ TEST_F(ColorManagementTest, XYBProfile) { } } } - static float kMaxError[3] = {9e-4, 4e-4, 5e-4}; + static float kMaxError[3] = {8.7e-4, 4.4e-4, 5.2e-4}; printf("Maximum errors:\n"); for (size_t c = 0; c < 3; ++c) { debug_print_color(max_err_i[c]); diff --git a/third_party/jpeg-xl/lib/jxl/compressed_dc.cc b/third_party/jpeg-xl/lib/jxl/compressed_dc.cc index 250be9e9a6..ec78afbd41 100644 --- a/third_party/jpeg-xl/lib/jxl/compressed_dc.cc +++ b/third_party/jpeg-xl/lib/jxl/compressed_dc.cc @@ -20,6 +20,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/image.h" HWY_BEFORE_NAMESPACE(); diff --git a/third_party/jpeg-xl/lib/jxl/compressed_dc.h b/third_party/jpeg-xl/lib/jxl/compressed_dc.h index 30259ebd56..d8846a8f04 100644 --- a/third_party/jpeg-xl/lib/jxl/compressed_dc.h +++ b/third_party/jpeg-xl/lib/jxl/compressed_dc.h @@ -6,11 +6,10 @@ #ifndef LIB_JXL_COMPRESSED_DC_H_ #define LIB_JXL_COMPRESSED_DC_H_ -#include <stddef.h> -#include <stdint.h> - #include "lib/jxl/ac_context.h" #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/frame_header.h" #include "lib/jxl/image.h" #include "lib/jxl/modular/modular_image.h" diff --git a/third_party/jpeg-xl/lib/jxl/convolve-inl.h b/third_party/jpeg-xl/lib/jxl/convolve-inl.h index 949fd8ad67..3efd8f6335 100644 --- a/third_party/jpeg-xl/lib/jxl/convolve-inl.h +++ b/third_party/jpeg-xl/lib/jxl/convolve-inl.h @@ -12,6 +12,8 @@ #include <hwy/highway.h> +#include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/image_ops.h" diff --git a/third_party/jpeg-xl/lib/jxl/convolve.h b/third_party/jpeg-xl/lib/jxl/convolve.h index 5231ae2640..da7cab6ffb 100644 --- a/third_party/jpeg-xl/lib/jxl/convolve.h +++ b/third_party/jpeg-xl/lib/jxl/convolve.h @@ -12,6 +12,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/image.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/convolve_separable5.cc b/third_party/jpeg-xl/lib/jxl/convolve_separable5.cc index ae618b9990..d6b388698c 100644 --- a/third_party/jpeg-xl/lib/jxl/convolve_separable5.cc +++ b/third_party/jpeg-xl/lib/jxl/convolve_separable5.cc @@ -10,6 +10,7 @@ #include <hwy/foreach_target.h> #include <hwy/highway.h> +#include "lib/jxl/base/rect.h" #include "lib/jxl/convolve-inl.h" HWY_BEFORE_NAMESPACE(); diff --git a/third_party/jpeg-xl/lib/jxl/convolve_slow.cc b/third_party/jpeg-xl/lib/jxl/convolve_slow.cc index 655e040885..aa4c07f60b 100644 --- a/third_party/jpeg-xl/lib/jxl/convolve_slow.cc +++ b/third_party/jpeg-xl/lib/jxl/convolve_slow.cc @@ -3,9 +3,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#include "lib/jxl/convolve.h" - +#include "lib/jxl/base/rect.h" #include "lib/jxl/convolve-inl.h" +#include "lib/jxl/convolve.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/convolve_symmetric3.cc b/third_party/jpeg-xl/lib/jxl/convolve_symmetric3.cc index 618ad03a86..012a9be97e 100644 --- a/third_party/jpeg-xl/lib/jxl/convolve_symmetric3.cc +++ b/third_party/jpeg-xl/lib/jxl/convolve_symmetric3.cc @@ -10,6 +10,7 @@ #include <hwy/foreach_target.h> #include <hwy/highway.h> +#include "lib/jxl/base/rect.h" #include "lib/jxl/convolve-inl.h" HWY_BEFORE_NAMESPACE(); diff --git a/third_party/jpeg-xl/lib/jxl/convolve_symmetric5.cc b/third_party/jpeg-xl/lib/jxl/convolve_symmetric5.cc index 7ed384894e..4c8451f847 100644 --- a/third_party/jpeg-xl/lib/jxl/convolve_symmetric5.cc +++ b/third_party/jpeg-xl/lib/jxl/convolve_symmetric5.cc @@ -11,6 +11,7 @@ #include <hwy/highway.h> #include "lib/jxl/base/common.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/convolve-inl.h" HWY_BEFORE_NAMESPACE(); diff --git a/third_party/jpeg-xl/lib/jxl/convolve_test.cc b/third_party/jpeg-xl/lib/jxl/convolve_test.cc index 084398c5e1..5ba36b33fe 100644 --- a/third_party/jpeg-xl/lib/jxl/convolve_test.cc +++ b/third_party/jpeg-xl/lib/jxl/convolve_test.cc @@ -8,6 +8,8 @@ #include <jxl/types.h> #include <time.h> +#include <cinttypes> // PRIx64 + #undef HWY_TARGET_INCLUDE #define HWY_TARGET_INCLUDE "lib/jxl/convolve_test.cc" #include <hwy/foreach_target.h> @@ -20,6 +22,7 @@ #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/printf_macros.h" #include "lib/jxl/base/random.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/image_ops.h" #include "lib/jxl/image_test_utils.h" #include "lib/jxl/test_utils.h" diff --git a/third_party/jpeg-xl/lib/jxl/dct_for_test.h b/third_party/jpeg-xl/lib/jxl/dct_for_test.h index b0cbffacad..29c189261d 100644 --- a/third_party/jpeg-xl/lib/jxl/dct_for_test.h +++ b/third_party/jpeg-xl/lib/jxl/dct_for_test.h @@ -8,9 +8,8 @@ // Unoptimized DCT only for use in tests. -#include <string.h> // memcpy - #include <cmath> +#include <cstring> // memcpy #include <vector> #include "lib/jxl/base/common.h" diff --git a/third_party/jpeg-xl/lib/jxl/dct_util.h b/third_party/jpeg-xl/lib/jxl/dct_util.h index 90a02658af..077c17bd77 100644 --- a/third_party/jpeg-xl/lib/jxl/dct_util.h +++ b/third_party/jpeg-xl/lib/jxl/dct_util.h @@ -6,9 +6,10 @@ #ifndef LIB_JXL_DCT_UTIL_H_ #define LIB_JXL_DCT_UTIL_H_ -#include <stddef.h> - +#include <cstddef> +#include <cstdint> #include <memory> +#include <type_traits> #include "lib/jxl/base/common.h" #include "lib/jxl/base/status.h" diff --git a/third_party/jpeg-xl/lib/jxl/dec_ans.h b/third_party/jpeg-xl/lib/jxl/dec_ans.h index cbff1deebe..dc56df1216 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_ans.h +++ b/third_party/jpeg-xl/lib/jxl/dec_ans.h @@ -10,17 +10,18 @@ // decoding table from them. #include <jxl/types.h> -#include <stddef.h> -#include <stdint.h> +#include <algorithm> +#include <cstddef> +#include <cstdint> #include <cstring> #include <vector> #include "lib/jxl/ans_common.h" #include "lib/jxl/ans_params.h" #include "lib/jxl/base/bits.h" -#include "lib/jxl/base/byte_order.h" #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/cache_aligned.h" #include "lib/jxl/dec_bit_reader.h" #include "lib/jxl/dec_huffman.h" diff --git a/third_party/jpeg-xl/lib/jxl/dec_frame.cc b/third_party/jpeg-xl/lib/jxl/dec_frame.cc index a2a82ad1fb..ab51c1841f 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_frame.cc +++ b/third_party/jpeg-xl/lib/jxl/dec_frame.cc @@ -23,6 +23,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/printf_macros.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/chroma_from_luma.h" #include "lib/jxl/coeff_order.h" diff --git a/third_party/jpeg-xl/lib/jxl/dec_group.cc b/third_party/jpeg-xl/lib/jxl/dec_group.cc index 7dc4772eba..d1b03969c8 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_group.cc +++ b/third_party/jpeg-xl/lib/jxl/dec_group.cc @@ -5,10 +5,9 @@ #include "lib/jxl/dec_group.h" -#include <stdint.h> -#include <string.h> - #include <algorithm> +#include <cstdint> +#include <cstring> #include <memory> #include <utility> @@ -24,6 +23,7 @@ #include "lib/jxl/base/bits.h" #include "lib/jxl/base/common.h" #include "lib/jxl/base/printf_macros.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/coeff_order.h" #include "lib/jxl/common.h" // kMaxNumPasses diff --git a/third_party/jpeg-xl/lib/jxl/dec_group_border.cc b/third_party/jpeg-xl/lib/jxl/dec_group_border.cc index 4bee3ae6ef..0f55a4053f 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_group_border.cc +++ b/third_party/jpeg-xl/lib/jxl/dec_group_border.cc @@ -6,6 +6,13 @@ #include "lib/jxl/dec_group_border.h" #include <atomic> +#include <cstddef> +#include <cstdint> +#include <utility> + +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" +#include "lib/jxl/frame_dimensions.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/dec_group_border.h b/third_party/jpeg-xl/lib/jxl/dec_group_border.h index cb3ecbefae..829f513d16 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_group_border.h +++ b/third_party/jpeg-xl/lib/jxl/dec_group_border.h @@ -6,14 +6,13 @@ #ifndef LIB_JXL_DEC_GROUP_BORDER_H_ #define LIB_JXL_DEC_GROUP_BORDER_H_ -#include <stddef.h> - #include <atomic> +#include <cstddef> +#include <cstdint> +#include <memory> -#include "lib/jxl/base/arch_macros.h" -#include "lib/jxl/base/status.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/frame_dimensions.h" -#include "lib/jxl/image.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/dec_modular.cc b/third_party/jpeg-xl/lib/jxl/dec_modular.cc index 80cc9d1360..049d6e4f91 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_modular.cc +++ b/third_party/jpeg-xl/lib/jxl/dec_modular.cc @@ -5,9 +5,8 @@ #include "lib/jxl/dec_modular.h" -#include <stdint.h> - #include <atomic> +#include <cstdint> #include <vector> #include "lib/jxl/frame_header.h" @@ -19,6 +18,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/printf_macros.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/compressed_dc.h" #include "lib/jxl/epf.h" diff --git a/third_party/jpeg-xl/lib/jxl/dec_modular.h b/third_party/jpeg-xl/lib/jxl/dec_modular.h index 23caad0c16..70eab8af89 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_modular.h +++ b/third_party/jpeg-xl/lib/jxl/dec_modular.h @@ -6,18 +6,23 @@ #ifndef LIB_JXL_DEC_MODULAR_H_ #define LIB_JXL_DEC_MODULAR_H_ -#include <stddef.h> - +#include <cstddef> +#include <cstdint> #include <string> +#include <vector> #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/dec_bit_reader.h" #include "lib/jxl/dec_cache.h" +#include "lib/jxl/frame_dimensions.h" #include "lib/jxl/frame_header.h" -#include "lib/jxl/image.h" +#include "lib/jxl/modular/encoding/dec_ma.h" #include "lib/jxl/modular/encoding/encoding.h" #include "lib/jxl/modular/modular_image.h" +#include "lib/jxl/quant_weights.h" +#include "lib/jxl/render_pipeline/render_pipeline.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/dec_noise.cc b/third_party/jpeg-xl/lib/jxl/dec_noise.cc index 24f0136490..ed5668f26b 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_noise.cc +++ b/third_party/jpeg-xl/lib/jxl/dec_noise.cc @@ -5,11 +5,8 @@ #include "lib/jxl/dec_noise.h" -#include <stdint.h> -#include <stdlib.h> - -#include <algorithm> -#include <numeric> +#include <cstdint> +#include <cstdlib> #include <utility> #undef HWY_TARGET_INCLUDE @@ -18,10 +15,10 @@ #include <hwy/highway.h> #include "lib/jxl/base/compiler_specific.h" -#include "lib/jxl/chroma_from_luma.h" -#include "lib/jxl/image_ops.h" -#include "lib/jxl/sanitizers.h" +#include "lib/jxl/base/rect.h" +#include "lib/jxl/frame_dimensions.h" #include "lib/jxl/xorshift128plus-inl.h" + HWY_BEFORE_NAMESPACE(); namespace jxl { namespace HWY_NAMESPACE { diff --git a/third_party/jpeg-xl/lib/jxl/dec_noise.h b/third_party/jpeg-xl/lib/jxl/dec_noise.h index ac05866470..39a3a8b8e3 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_noise.h +++ b/third_party/jpeg-xl/lib/jxl/dec_noise.h @@ -8,11 +8,11 @@ // Noise synthesis. Currently disabled. -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <utility> +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" -#include "lib/jxl/chroma_from_luma.h" #include "lib/jxl/dec_bit_reader.h" #include "lib/jxl/image.h" #include "lib/jxl/noise.h" diff --git a/third_party/jpeg-xl/lib/jxl/dec_patch_dictionary.h b/third_party/jpeg-xl/lib/jxl/dec_patch_dictionary.h index 72dca8f057..ad0f5d6a04 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_patch_dictionary.h +++ b/third_party/jpeg-xl/lib/jxl/dec_patch_dictionary.h @@ -8,10 +8,12 @@ // Chooses reference patches, and avoids encoding them once per occurrence. -#include <stddef.h> -#include <string.h> #include <sys/types.h> +#include <cstddef> +#include <cstdint> +#include <cstring> +#include <utility> #include <vector> #include "lib/jxl/base/status.h" diff --git a/third_party/jpeg-xl/lib/jxl/dec_transforms-inl.h b/third_party/jpeg-xl/lib/jxl/dec_transforms-inl.h index 9c90550625..51b0c80727 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_transforms-inl.h +++ b/third_party/jpeg-xl/lib/jxl/dec_transforms-inl.h @@ -10,12 +10,10 @@ #define LIB_JXL_DEC_TRANSFORMS_INL_H_ #endif -#include <stddef.h> - +#include <cstddef> #include <hwy/highway.h> #include "lib/jxl/ac_strategy.h" -#include "lib/jxl/coeff_order_fwd.h" #include "lib/jxl/dct-inl.h" #include "lib/jxl/dct_scales.h" HWY_BEFORE_NAMESPACE(); diff --git a/third_party/jpeg-xl/lib/jxl/dec_transforms_testonly.cc b/third_party/jpeg-xl/lib/jxl/dec_transforms_testonly.cc index 6451c41f6d..294d10f504 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_transforms_testonly.cc +++ b/third_party/jpeg-xl/lib/jxl/dec_transforms_testonly.cc @@ -10,7 +10,6 @@ #include <hwy/foreach_target.h> #include <hwy/highway.h> -#include "lib/jxl/dct_scales.h" #include "lib/jxl/dec_transforms-inl.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/dec_transforms_testonly.h b/third_party/jpeg-xl/lib/jxl/dec_transforms_testonly.h index 2cbf6bd5f6..b7f3e8825d 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_transforms_testonly.h +++ b/third_party/jpeg-xl/lib/jxl/dec_transforms_testonly.h @@ -8,8 +8,7 @@ // Facade for (non-inlined) inverse integral transforms. -#include <stddef.h> -#include <stdint.h> +#include <cstddef> #include "lib/jxl/ac_strategy.h" #include "lib/jxl/base/compiler_specific.h" diff --git a/third_party/jpeg-xl/lib/jxl/dec_xyb.cc b/third_party/jpeg-xl/lib/jxl/dec_xyb.cc index a719b3eb8c..009c078fae 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_xyb.cc +++ b/third_party/jpeg-xl/lib/jxl/dec_xyb.cc @@ -5,7 +5,7 @@ #include "lib/jxl/dec_xyb.h" -#include <string.h> +#include <cstring> #undef HWY_TARGET_INCLUDE #define HWY_TARGET_INCLUDE "lib/jxl/dec_xyb.cc" @@ -14,13 +14,12 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/matrix_ops.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/cms/jxl_cms_internal.h" #include "lib/jxl/cms/opsin_params.h" #include "lib/jxl/color_encoding_internal.h" -#include "lib/jxl/dec_group_border.h" #include "lib/jxl/dec_xyb-inl.h" -#include "lib/jxl/fields.h" #include "lib/jxl/image.h" #include "lib/jxl/opsin_params.h" #include "lib/jxl/quantizer.h" diff --git a/third_party/jpeg-xl/lib/jxl/dec_xyb.h b/third_party/jpeg-xl/lib/jxl/dec_xyb.h index 65317f2f54..13692456f8 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_xyb.h +++ b/third_party/jpeg-xl/lib/jxl/dec_xyb.h @@ -15,6 +15,8 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/matrix_ops.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/color_encoding_internal.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/decode_test.cc b/third_party/jpeg-xl/lib/jxl/decode_test.cc index 99b5871ccd..bf6723016f 100644 --- a/third_party/jpeg-xl/lib/jxl/decode_test.cc +++ b/third_party/jpeg-xl/lib/jxl/decode_test.cc @@ -1701,7 +1701,7 @@ TEST(DecodeTest, PixelTestWithICCProfileLossy) { EXPECT_SLIGHTLY_BELOW( ButteraugliDistance(io0.frames, io1.frames, ba, *JxlGetDefaultCms(), /*distmap=*/nullptr, nullptr), - 0.56f); + 0.58f); JxlDecoderDestroy(dec); } @@ -2151,7 +2151,7 @@ TEST(DecodeTest, PixelTestOpaqueSrgbLossyNoise) { EXPECT_SLIGHTLY_BELOW( ButteraugliDistance(io0.frames, io1.frames, ba, *JxlGetDefaultCms(), /*distmap=*/nullptr, nullptr), - 1.3f); + 1.9f); JxlDecoderDestroy(dec); } diff --git a/third_party/jpeg-xl/lib/jxl/enc_ac_strategy.cc b/third_party/jpeg-xl/lib/jxl/enc_ac_strategy.cc index 4aafd7a5e5..0be7cdb882 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_ac_strategy.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_ac_strategy.cc @@ -5,12 +5,11 @@ #include "lib/jxl/enc_ac_strategy.h" -#include <stdint.h> -#include <string.h> - #include <algorithm> #include <cmath> +#include <cstdint> #include <cstdio> +#include <cstring> #undef HWY_TARGET_INCLUDE #define HWY_TARGET_INCLUDE "lib/jxl/enc_ac_strategy.cc" @@ -21,6 +20,7 @@ #include "lib/jxl/base/bits.h" #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/fast_math-inl.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/dec_transforms-inl.h" #include "lib/jxl/enc_aux_out.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_ac_strategy.h b/third_party/jpeg-xl/lib/jxl/enc_ac_strategy.h index 31eb73c6a0..05103e78ab 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_ac_strategy.h +++ b/third_party/jpeg-xl/lib/jxl/enc_ac_strategy.h @@ -7,9 +7,12 @@ #define LIB_JXL_ENC_AC_STRATEGY_H_ #include <cstddef> +#include <cstdint> +#include <hwy/aligned_allocator.h> #include "lib/jxl/ac_strategy.h" #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/chroma_from_luma.h" #include "lib/jxl/enc_cache.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_adaptive_quantization.cc b/third_party/jpeg-xl/lib/jxl/enc_adaptive_quantization.cc index 4c2ddba95b..fa0570d937 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_adaptive_quantization.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_adaptive_quantization.cc @@ -24,6 +24,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/fast_math-inl.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/butteraugli/butteraugli.h" #include "lib/jxl/cms/opsin_params.h" @@ -765,7 +766,7 @@ StatusOr<ImageF> TileDistMap(const ImageF& distmap, int tile_size, int margin, const float kDcQuantPow = 0.83f; const float kDcQuant = 1.095924047623553f; -const float kAcQuant = 0.7381485255235064f; +const float kAcQuant = 0.725f; // Computes the decoded image for a given set of compression parameters. StatusOr<ImageBundle> RoundtripImage(const FrameHeader& frame_header, diff --git a/third_party/jpeg-xl/lib/jxl/enc_adaptive_quantization.h b/third_party/jpeg-xl/lib/jxl/enc_adaptive_quantization.h index 26ed3f26ca..30849dba4e 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_adaptive_quantization.h +++ b/third_party/jpeg-xl/lib/jxl/enc_adaptive_quantization.h @@ -7,10 +7,11 @@ #define LIB_JXL_ENC_ADAPTIVE_QUANTIZATION_H_ #include <jxl/cms_interface.h> -#include <stddef.h> #include "lib/jxl/ac_strategy.h" #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/enc_cache.h" #include "lib/jxl/frame_header.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_ar_control_field.cc b/third_party/jpeg-xl/lib/jxl/enc_ar_control_field.cc index 4f1d2dadb5..c323dc68bb 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_ar_control_field.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_ar_control_field.cc @@ -5,10 +5,9 @@ #include "lib/jxl/enc_ar_control_field.h" -#include <stdint.h> -#include <stdlib.h> - #include <algorithm> +#include <cstdint> +#include <cstdlib> #undef HWY_TARGET_INCLUDE #define HWY_TARGET_INCLUDE "lib/jxl/enc_ar_control_field.cc" @@ -17,6 +16,7 @@ #include "lib/jxl/ac_strategy.h" #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/enc_params.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_ar_control_field.h b/third_party/jpeg-xl/lib/jxl/enc_ar_control_field.h index f3c5a97a1b..fef5a51d05 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_ar_control_field.h +++ b/third_party/jpeg-xl/lib/jxl/enc_ar_control_field.h @@ -6,11 +6,12 @@ #ifndef LIB_JXL_ENC_AR_CONTROL_FIELD_H_ #define LIB_JXL_ENC_AR_CONTROL_FIELD_H_ -#include <stddef.h> - +#include <cstddef> #include <vector> #include "lib/jxl/ac_strategy.h" +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/enc_params.h" #include "lib/jxl/frame_header.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_cache.cc b/third_party/jpeg-xl/lib/jxl/enc_cache.cc index 200ec83b65..91d0046c29 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_cache.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_cache.cc @@ -5,13 +5,13 @@ #include "lib/jxl/enc_cache.h" -#include <stddef.h> -#include <stdint.h> - +#include <cstddef> +#include <cstdint> #include <memory> #include "lib/jxl/base/common.h" #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/span.h" #include "lib/jxl/base/status.h" #include "lib/jxl/color_encoding_internal.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_cache.h b/third_party/jpeg-xl/lib/jxl/enc_cache.h index 43ee7bc9c8..76b7e3ddae 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_cache.h +++ b/third_party/jpeg-xl/lib/jxl/enc_cache.h @@ -7,13 +7,14 @@ #define LIB_JXL_ENC_CACHE_H_ #include <jxl/cms_interface.h> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <memory> #include <vector> #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/dct_util.h" #include "lib/jxl/enc_ans.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_chroma_from_luma.cc b/third_party/jpeg-xl/lib/jxl/enc_chroma_from_luma.cc index 4039da2858..d45899936b 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_chroma_from_luma.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_chroma_from_luma.cc @@ -5,11 +5,10 @@ #include "lib/jxl/enc_chroma_from_luma.h" -#include <float.h> -#include <stdlib.h> - #include <algorithm> +#include <cfloat> #include <cmath> +#include <cstdlib> #undef HWY_TARGET_INCLUDE #define HWY_TARGET_INCLUDE "lib/jxl/enc_chroma_from_luma.cc" @@ -18,6 +17,7 @@ #include <hwy/highway.h> #include "lib/jxl/base/common.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/cms/opsin_params.h" #include "lib/jxl/dec_transforms-inl.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_chroma_from_luma.h b/third_party/jpeg-xl/lib/jxl/enc_chroma_from_luma.h index c6481a0ec9..514202bf8b 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_chroma_from_luma.h +++ b/third_party/jpeg-xl/lib/jxl/enc_chroma_from_luma.h @@ -13,6 +13,8 @@ #include <hwy/aligned_allocator.h> #include "lib/jxl/ac_strategy.h" +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/chroma_from_luma.h" #include "lib/jxl/enc_bit_writer.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_cluster.h b/third_party/jpeg-xl/lib/jxl/enc_cluster.h index 7ddc003cf2..3b157c9c9d 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_cluster.h +++ b/third_party/jpeg-xl/lib/jxl/enc_cluster.h @@ -8,13 +8,11 @@ #ifndef LIB_JXL_ENC_CLUSTER_H_ #define LIB_JXL_ENC_CLUSTER_H_ -#include <stddef.h> -#include <stdint.h> -#include <string.h> - +#include <cstddef> +#include <cstdint> +#include <cstring> #include <vector> -#include "lib/jxl/ans_params.h" #include "lib/jxl/base/common.h" #include "lib/jxl/enc_ans_params.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_coeff_order.cc b/third_party/jpeg-xl/lib/jxl/enc_coeff_order.cc index 49129f5d9e..abe404ce9e 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_coeff_order.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_coeff_order.cc @@ -3,13 +3,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#include <stdint.h> - #include <algorithm> #include <cmath> +#include <cstdint> #include <hwy/aligned_allocator.h> #include <vector> +#include "lib/jxl/base/rect.h" #include "lib/jxl/coeff_order.h" #include "lib/jxl/coeff_order_fwd.h" #include "lib/jxl/dct_util.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_coeff_order.h b/third_party/jpeg-xl/lib/jxl/enc_coeff_order.h index 25e0f17a8d..65f497e882 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_coeff_order.h +++ b/third_party/jpeg-xl/lib/jxl/enc_coeff_order.h @@ -6,18 +6,16 @@ #ifndef LIB_JXL_ENC_COEFF_ORDER_H_ #define LIB_JXL_ENC_COEFF_ORDER_H_ -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include "lib/jxl/ac_strategy.h" #include "lib/jxl/base/compiler_specific.h" -#include "lib/jxl/base/status.h" -#include "lib/jxl/coeff_order.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/coeff_order_fwd.h" +#include "lib/jxl/common.h" #include "lib/jxl/dct_util.h" -#include "lib/jxl/dec_bit_reader.h" #include "lib/jxl/enc_bit_writer.h" -#include "lib/jxl/enc_params.h" #include "lib/jxl/frame_dimensions.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/enc_comparator.h b/third_party/jpeg-xl/lib/jxl/enc_comparator.h index ee62ab6f28..6ae6913abe 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_comparator.h +++ b/third_party/jpeg-xl/lib/jxl/enc_comparator.h @@ -6,6 +6,8 @@ #ifndef LIB_JXL_ENC_COMPARATOR_H_ #define LIB_JXL_ENC_COMPARATOR_H_ +#include <jxl/cms_interface.h> + #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/status.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_debug_image.cc b/third_party/jpeg-xl/lib/jxl/enc_debug_image.cc index d67ab7db46..6b4d115e7f 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_debug_image.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_debug_image.cc @@ -5,9 +5,10 @@ #include "lib/jxl/enc_debug_image.h" -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/color_encoding_internal.h" #include "lib/jxl/dec_external_image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_debug_image.h b/third_party/jpeg-xl/lib/jxl/enc_debug_image.h index 428293f8bc..98d27e705c 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_debug_image.h +++ b/third_party/jpeg-xl/lib/jxl/enc_debug_image.h @@ -8,9 +8,9 @@ // Optional output images for debugging. -#include <stddef.h> -#include <stdint.h> +#include <cstdint> +#include "lib/jxl/base/status.h" #include "lib/jxl/enc_params.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_detect_dots.cc b/third_party/jpeg-xl/lib/jxl/enc_detect_dots.cc index 94e6fefb61..81dd2f2b67 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_detect_dots.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_detect_dots.cc @@ -5,11 +5,10 @@ #include "lib/jxl/enc_detect_dots.h" -#include <stdint.h> - #include <algorithm> #include <array> #include <cmath> +#include <cstdint> #include <cstdio> #include <utility> #include <vector> @@ -23,6 +22,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/printf_macros.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/convolve.h" #include "lib/jxl/enc_linalg.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_detect_dots.h b/third_party/jpeg-xl/lib/jxl/enc_detect_dots.h index 59def59f8f..91174463f7 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_detect_dots.h +++ b/third_party/jpeg-xl/lib/jxl/enc_detect_dots.h @@ -7,13 +7,14 @@ #ifndef LIB_JXL_ENC_DETECT_DOTS_H_ #define LIB_JXL_ENC_DETECT_DOTS_H_ -#include <stddef.h> -#include <stdint.h> - #include <array> +#include <cstddef> +#include <cstdint> #include <vector> #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/enc_patch_dictionary.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_dot_dictionary.cc b/third_party/jpeg-xl/lib/jxl/enc_dot_dictionary.cc index 7d76ba9002..bf9c15ef4e 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_dot_dictionary.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_dot_dictionary.cc @@ -5,12 +5,12 @@ #include "lib/jxl/enc_dot_dictionary.h" -#include <stddef.h> -#include <string.h> - #include <array> +#include <cstddef> +#include <cstring> #include "lib/jxl/base/override.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/chroma_from_luma.h" #include "lib/jxl/enc_detect_dots.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_dot_dictionary.h b/third_party/jpeg-xl/lib/jxl/enc_dot_dictionary.h index d348fb73b8..cd7691e202 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_dot_dictionary.h +++ b/third_party/jpeg-xl/lib/jxl/enc_dot_dictionary.h @@ -9,10 +9,10 @@ // Dots are stored in a dictionary to avoid storing similar dots multiple // times. -#include <stddef.h> - #include <vector> +#include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/chroma_from_luma.h" #include "lib/jxl/enc_params.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_entropy_coder.cc b/third_party/jpeg-xl/lib/jxl/enc_entropy_coder.cc index b71bb07bc9..461713058c 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_entropy_coder.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_entropy_coder.cc @@ -5,11 +5,8 @@ #include "lib/jxl/enc_entropy_coder.h" -#include <stddef.h> -#include <stdint.h> - -#include <algorithm> -#include <utility> +#include <cstddef> +#include <cstdint> #include <vector> #undef HWY_TARGET_INCLUDE @@ -24,13 +21,8 @@ #include "lib/jxl/base/status.h" #include "lib/jxl/coeff_order.h" #include "lib/jxl/coeff_order_fwd.h" -#include "lib/jxl/dec_ans.h" -#include "lib/jxl/dec_bit_reader.h" -#include "lib/jxl/dec_context_map.h" #include "lib/jxl/entropy_coder.h" -#include "lib/jxl/epf.h" #include "lib/jxl/image.h" -#include "lib/jxl/image_ops.h" #include "lib/jxl/pack_signed.h" HWY_BEFORE_NAMESPACE(); diff --git a/third_party/jpeg-xl/lib/jxl/enc_entropy_coder.h b/third_party/jpeg-xl/lib/jxl/enc_entropy_coder.h index 6df3e8e770..2321a1d831 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_entropy_coder.h +++ b/third_party/jpeg-xl/lib/jxl/enc_entropy_coder.h @@ -6,20 +6,17 @@ #ifndef LIB_JXL_ENC_ENTROPY_CODER_H_ #define LIB_JXL_ENC_ENTROPY_CODER_H_ -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> #include <sys/types.h> -#include <memory> -#include <utility> +#include <cstdint> #include <vector> #include "lib/jxl/ac_context.h" // BlockCtxMap #include "lib/jxl/ac_strategy.h" +#include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" +#include "lib/jxl/coeff_order_fwd.h" #include "lib/jxl/enc_ans.h" -#include "lib/jxl/field_encodings.h" #include "lib/jxl/frame_header.h" // YCbCrChromaSubsampling #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_fast_lossless.cc b/third_party/jpeg-xl/lib/jxl/enc_fast_lossless.cc index 1797139428..a5884301b6 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_fast_lossless.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_fast_lossless.cc @@ -3612,7 +3612,8 @@ bool detect_palette(const unsigned char* r, size_t width, size_t x = 0; bool collided = false; // this is just an unrolling of the next loop - for (; x + 7 < width; x += 8) { + size_t look_ahead = 7 + ((nb_chans == 1) ? 3 : ((nb_chans < 4) ? 1 : 0)); + for (; x + look_ahead < width; x += 8) { uint32_t p[8] = {}, index[8]; for (int i = 0; i < 8; i++) memcpy(&p[i], r + (x + i) * nb_chans, 4); for (int i = 0; i < 8; i++) p[i] &= ((1llu << (8 * nb_chans)) - 1); diff --git a/third_party/jpeg-xl/lib/jxl/enc_fields.cc b/third_party/jpeg-xl/lib/jxl/enc_fields.cc index fa513297fd..e1bf9d2ad8 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_fields.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_fields.cc @@ -5,7 +5,7 @@ #include "lib/jxl/enc_fields.h" -#include <cinttypes> +#include <cinttypes> // PRIu64 #include "lib/jxl/enc_aux_out.h" #include "lib/jxl/fields.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_frame.cc b/third_party/jpeg-xl/lib/jxl/enc_frame.cc index 2a3389921b..ec0af1e8e5 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_frame.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_frame.cc @@ -5,13 +5,12 @@ #include "lib/jxl/enc_frame.h" -#include <stddef.h> -#include <stdint.h> - #include <algorithm> #include <array> #include <atomic> #include <cmath> +#include <cstddef> +#include <cstdint> #include <memory> #include <numeric> #include <utility> @@ -25,6 +24,7 @@ #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/override.h" #include "lib/jxl/base/printf_macros.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/chroma_from_luma.h" #include "lib/jxl/coeff_order.h" @@ -583,10 +583,13 @@ struct PixelStatsForChromacityAdjustment { CalcExposedBlue(&opsin->Plane(1), &opsin->Plane(2), rect); } int HowMuchIsXChannelPixelized() const { - if (dx >= 0.03) { + if (dx >= 0.026) { + return 3; + } + if (dx >= 0.022) { return 2; } - if (dx >= 0.017) { + if (dx >= 0.015) { return 1; } return 0; @@ -614,18 +617,13 @@ void ComputeChromacityAdjustments(const CompressParams& cparams, return; } // 1) Distance based approach for chromacity adjustment: - float x_qm_scale_steps[4] = {1.25f, 7.0f, 15.0f, 24.0f}; - frame_header->x_qm_scale = 2; + float x_qm_scale_steps[3] = {2.5f, 5.5f, 9.5f}; + frame_header->x_qm_scale = 3; for (float x_qm_scale_step : x_qm_scale_steps) { if (cparams.original_butteraugli_distance > x_qm_scale_step) { frame_header->x_qm_scale++; } } - if (cparams.butteraugli_distance < 0.299f) { - // Favor chromacity preservation for making images appear more - // faithful to original even with extreme (5-10x) zooming. - frame_header->x_qm_scale++; - } // 2) Pixel-based approach for chromacity adjustment: // look at the individual pixels and make a guess how difficult // the image would be based on the worst case pixel. diff --git a/third_party/jpeg-xl/lib/jxl/enc_gaborish.cc b/third_party/jpeg-xl/lib/jxl/enc_gaborish.cc index 7467a4d669..ba1181e285 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_gaborish.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_gaborish.cc @@ -5,12 +5,13 @@ #include "lib/jxl/enc_gaborish.h" -#include <stddef.h> - #include <hwy/base.h> +#include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/convolve.h" +#include "lib/jxl/image.h" #include "lib/jxl/image_ops.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/enc_gaborish.h b/third_party/jpeg-xl/lib/jxl/enc_gaborish.h index 041edcec96..ce1c211ffa 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_gaborish.h +++ b/third_party/jpeg-xl/lib/jxl/enc_gaborish.h @@ -9,6 +9,7 @@ // Linear smoothing (3x3 convolution) for deblocking without too much blur. #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_gaborish_test.cc b/third_party/jpeg-xl/lib/jxl/enc_gaborish_test.cc index 0d173c5eb8..074c547287 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_gaborish_test.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_gaborish_test.cc @@ -11,6 +11,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/convolve.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_group.cc b/third_party/jpeg-xl/lib/jxl/enc_group.cc index 2b60643e7c..6e4e05335a 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_group.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_group.cc @@ -6,7 +6,6 @@ #include "lib/jxl/enc_group.h" #include <hwy/aligned_allocator.h> -#include <utility> #undef HWY_TARGET_INCLUDE #define HWY_TARGET_INCLUDE "lib/jxl/enc_group.cc" @@ -16,6 +15,7 @@ #include "lib/jxl/ac_strategy.h" #include "lib/jxl/base/bits.h" #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/common.h" // kMaxNumPasses #include "lib/jxl/dct_util.h" #include "lib/jxl/dec_transforms-inl.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_group.h b/third_party/jpeg-xl/lib/jxl/enc_group.h index 78484c2e9b..c9c4b77a5b 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_group.h +++ b/third_party/jpeg-xl/lib/jxl/enc_group.h @@ -6,8 +6,9 @@ #ifndef LIB_JXL_ENC_GROUP_H_ #define LIB_JXL_ENC_GROUP_H_ -#include <stddef.h> +#include <cstddef> +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/enc_bit_writer.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_heuristics.cc b/third_party/jpeg-xl/lib/jxl/enc_heuristics.cc index 685558ac7c..152468255f 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_heuristics.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_heuristics.cc @@ -6,10 +6,10 @@ #include "lib/jxl/enc_heuristics.h" #include <jxl/cms_interface.h> -#include <stddef.h> -#include <stdint.h> #include <algorithm> +#include <cstddef> +#include <cstdint> #include <cstdlib> #include <limits> #include <memory> @@ -24,6 +24,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/override.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/butteraugli/butteraugli.h" #include "lib/jxl/chroma_from_luma.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_heuristics.h b/third_party/jpeg-xl/lib/jxl/enc_heuristics.h index 0dd93e4288..75a196748c 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_heuristics.h +++ b/third_party/jpeg-xl/lib/jxl/enc_heuristics.h @@ -9,9 +9,9 @@ // Hook for custom encoder heuristics (VarDCT only for now). #include <jxl/cms_interface.h> -#include <stddef.h> #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/frame_header.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_image_bundle.cc b/third_party/jpeg-xl/lib/jxl/enc_image_bundle.cc index 044f763363..db3c497cde 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_image_bundle.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_image_bundle.cc @@ -10,6 +10,7 @@ #include <atomic> #include <utility> +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/color_encoding_internal.h" #include "lib/jxl/image_bundle.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_image_bundle.h b/third_party/jpeg-xl/lib/jxl/enc_image_bundle.h index 38536c8c7a..c1180a6da8 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_image_bundle.h +++ b/third_party/jpeg-xl/lib/jxl/enc_image_bundle.h @@ -9,6 +9,7 @@ #include <jxl/cms_interface.h> #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/color_encoding_internal.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_linalg_test.cc b/third_party/jpeg-xl/lib/jxl/enc_linalg_test.cc index c02f009ca7..1056c4f06c 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_linalg_test.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_linalg_test.cc @@ -5,6 +5,8 @@ #include "lib/jxl/enc_linalg.h" +#include <cstddef> + #include "lib/jxl/base/random.h" #include "lib/jxl/testing.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_modular.cc b/third_party/jpeg-xl/lib/jxl/enc_modular.cc index 35fac3c827..25464737b8 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_modular.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_modular.cc @@ -5,11 +5,9 @@ #include "lib/jxl/enc_modular.h" -#include <stddef.h> -#include <stdint.h> - #include <array> #include <atomic> +#include <cstddef> #include <cstdint> #include <limits> #include <utility> @@ -17,6 +15,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/printf_macros.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/compressed_dc.h" #include "lib/jxl/dec_ans.h" @@ -998,7 +997,9 @@ Status ModularFrameEncoder::ComputeEncodingData( pool, 0, stream_params_.size(), ThreadPool::NoInit, [&](const uint32_t i, size_t /* thread */) { size_t stream = stream_params_[i].id.ID(frame_dim_); - stream_options_[stream] = stream_options_[0]; + if (stream != 0) { + stream_options_[stream] = stream_options_[0]; + } JXL_CHECK(PrepareStreamParams( stream_params_[i].rect, cparams_, stream_params_[i].minShift, stream_params_[i].maxShift, stream_params_[i].id, do_color, diff --git a/third_party/jpeg-xl/lib/jxl/enc_modular.h b/third_party/jpeg-xl/lib/jxl/enc_modular.h index c7a8421982..cac6483a00 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_modular.h +++ b/third_party/jpeg-xl/lib/jxl/enc_modular.h @@ -14,6 +14,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/dec_modular.h" #include "lib/jxl/enc_ans.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_optimize_test.cc b/third_party/jpeg-xl/lib/jxl/enc_optimize_test.cc index 9184765be2..4270116ee8 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_optimize_test.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_optimize_test.cc @@ -5,6 +5,10 @@ #include "lib/jxl/enc_optimize.h" +#include <cmath> +#include <cstddef> +#include <vector> + #include "lib/jxl/testing.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/enc_patch_dictionary.cc b/third_party/jpeg-xl/lib/jxl/enc_patch_dictionary.cc index 6fc5f7f49e..2586692c4e 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_patch_dictionary.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_patch_dictionary.cc @@ -6,12 +6,12 @@ #include "lib/jxl/enc_patch_dictionary.h" #include <jxl/types.h> -#include <stdint.h> -#include <stdlib.h> #include <sys/types.h> #include <algorithm> #include <atomic> +#include <cstdint> +#include <cstdlib> #include <utility> #include <vector> @@ -20,6 +20,7 @@ #include "lib/jxl/base/override.h" #include "lib/jxl/base/printf_macros.h" #include "lib/jxl/base/random.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/dec_cache.h" #include "lib/jxl/dec_frame.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_patch_dictionary.h b/third_party/jpeg-xl/lib/jxl/enc_patch_dictionary.h index ac236d7f17..ba2e3ba6b2 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_patch_dictionary.h +++ b/third_party/jpeg-xl/lib/jxl/enc_patch_dictionary.h @@ -8,12 +8,16 @@ // Chooses reference patches, and avoids encoding them once per occurrence. -#include <stddef.h> -#include <string.h> +#include <jxl/cms_interface.h> #include <sys/types.h> +#include <cstddef> +#include <cstdint> +#include <cstring> +#include <utility> #include <vector> +#include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/status.h" #include "lib/jxl/dec_patch_dictionary.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_photon_noise.h b/third_party/jpeg-xl/lib/jxl/enc_photon_noise.h index f43e14d560..d3c6d843af 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_photon_noise.h +++ b/third_party/jpeg-xl/lib/jxl/enc_photon_noise.h @@ -6,8 +6,8 @@ #ifndef LIB_JXL_ENC_PHOTON_NOISE_H_ #define LIB_JXL_ENC_PHOTON_NOISE_H_ -#include "lib/jxl/dec_xyb.h" -#include "lib/jxl/image.h" +#include <cstddef> + #include "lib/jxl/noise.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/enc_photon_noise_test.cc b/third_party/jpeg-xl/lib/jxl/enc_photon_noise_test.cc index 2e10dd5457..db172fb699 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_photon_noise_test.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_photon_noise_test.cc @@ -5,7 +5,6 @@ #include "lib/jxl/enc_photon_noise.h" -#include "lib/jxl/base/common.h" #include "lib/jxl/noise.h" #include "lib/jxl/testing.h" diff --git a/third_party/jpeg-xl/lib/jxl/enc_quant_weights.h b/third_party/jpeg-xl/lib/jxl/enc_quant_weights.h index 82d8278b72..897ace6c7e 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_quant_weights.h +++ b/third_party/jpeg-xl/lib/jxl/enc_quant_weights.h @@ -7,7 +7,9 @@ #define LIB_JXL_ENC_QUANT_WEIGHTS_H_ #include <cstddef> +#include <vector> +#include "lib/jxl/base/status.h" #include "lib/jxl/quant_weights.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/enc_xyb.cc b/third_party/jpeg-xl/lib/jxl/enc_xyb.cc index 9fc68d8474..89bb4de37c 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_xyb.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_xyb.cc @@ -17,6 +17,7 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/fast_math-inl.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/cms/opsin_params.h" #include "lib/jxl/cms/transfer_functions-inl.h" diff --git a/third_party/jpeg-xl/lib/jxl/encode_internal.h b/third_party/jpeg-xl/lib/jxl/encode_internal.h index 001df5fed5..8030c8314a 100644 --- a/third_party/jpeg-xl/lib/jxl/encode_internal.h +++ b/third_party/jpeg-xl/lib/jxl/encode_internal.h @@ -214,7 +214,7 @@ class JxlEncoderChunkedFrameAdapter { } // TODO(szabadka) Move instead of copy. - void SetJPEGData(const jpeg::JPEGData jpeg_data) { + void SetJPEGData(const jpeg::JPEGData& jpeg_data) { jpeg_data_ = jpeg_data; has_jpeg_data_ = true; } diff --git a/third_party/jpeg-xl/lib/jxl/encode_test.cc b/third_party/jpeg-xl/lib/jxl/encode_test.cc index 0aef5f8aff..7400b237de 100644 --- a/third_party/jpeg-xl/lib/jxl/encode_test.cc +++ b/third_party/jpeg-xl/lib/jxl/encode_test.cc @@ -233,7 +233,7 @@ void VerifyFrameEncoding(size_t xsize, size_t ysize, JxlEncoder* enc, static constexpr double kMaxButteraugli = #if JXL_HIGH_PRECISION - 1.84; + 3.2; #else 8.7; #endif @@ -461,7 +461,7 @@ TEST(EncodeTest, FrameSettingsTest) { JxlEncoderFrameSettings* frame_settings = JxlEncoderFrameSettingsCreate(enc.get(), nullptr); EXPECT_EQ(JXL_ENC_SUCCESS, JxlEncoderSetFrameDistance(frame_settings, 0.5)); - VerifyFrameEncoding(63, 129, enc.get(), frame_settings, 3130, false); + VerifyFrameEncoding(63, 129, enc.get(), frame_settings, 3200, false); EXPECT_EQ(0.5, enc->last_used_cparams.butteraugli_distance); } @@ -1888,7 +1888,7 @@ TEST_P(EncoderStreamingTest, OutputCallback) { p.color_includes_alpha(), p.is_lossless()); std::vector<uint8_t> compressed = std::vector<uint8_t>(64); - // without sreaming + // without streaming { JxlEncoderPtr enc = JxlEncoderMake(nullptr); ASSERT_NE(nullptr, enc.get()); diff --git a/third_party/jpeg-xl/lib/jxl/epf.cc b/third_party/jpeg-xl/lib/jxl/epf.cc index 78ef38bfd5..042aa8c591 100644 --- a/third_party/jpeg-xl/lib/jxl/epf.cc +++ b/third_party/jpeg-xl/lib/jxl/epf.cc @@ -7,27 +7,17 @@ #include "lib/jxl/epf.h" -#include <math.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - #include <algorithm> -#include <atomic> -#include <numeric> // std::accumulate -#include <vector> +#include <cstddef> +#include <cstdint> +#include <cstring> #include "lib/jxl/ac_strategy.h" #include "lib/jxl/base/compiler_specific.h" -#include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" -#include "lib/jxl/convolve.h" #include "lib/jxl/dec_cache.h" -#include "lib/jxl/image.h" -#include "lib/jxl/image_bundle.h" -#include "lib/jxl/image_ops.h" #include "lib/jxl/loop_filter.h" -#include "lib/jxl/quant_weights.h" #include "lib/jxl/quantizer.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/epf.h b/third_party/jpeg-xl/lib/jxl/epf.h index 808dde10dc..e372deaa6b 100644 --- a/third_party/jpeg-xl/lib/jxl/epf.h +++ b/third_party/jpeg-xl/lib/jxl/epf.h @@ -8,8 +8,8 @@ // Fast SIMD "in-loop" edge preserving filter (adaptive, nonlinear). +#include "lib/jxl/base/rect.h" #include "lib/jxl/dec_cache.h" -#include "lib/jxl/image.h" #include "lib/jxl/loop_filter.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/fake_parallel_runner_testonly.h b/third_party/jpeg-xl/lib/jxl/fake_parallel_runner_testonly.h index 508d808cc5..4ca422e9a4 100644 --- a/third_party/jpeg-xl/lib/jxl/fake_parallel_runner_testonly.h +++ b/third_party/jpeg-xl/lib/jxl/fake_parallel_runner_testonly.h @@ -7,8 +7,8 @@ #define LIB_JXL_FAKE_PARALLEL_RUNNER_TESTONLY_H_ #include <jxl/parallel_runner.h> -#include <stdint.h> +#include <cstdint> #include <vector> #include "lib/jxl/base/compiler_specific.h" diff --git a/third_party/jpeg-xl/lib/jxl/fields.cc b/third_party/jpeg-xl/lib/jxl/fields.cc index 6bb5eae25d..e11166877b 100644 --- a/third_party/jpeg-xl/lib/jxl/fields.cc +++ b/third_party/jpeg-xl/lib/jxl/fields.cc @@ -6,7 +6,7 @@ #include "lib/jxl/fields.h" #include <algorithm> -#include <cinttypes> +#include <cinttypes> // PRIu64 #include <cmath> #include <cstddef> #include <hwy/base.h> diff --git a/third_party/jpeg-xl/lib/jxl/fields.h b/third_party/jpeg-xl/lib/jxl/fields.h index a8d8d8671a..cb9554213a 100644 --- a/third_party/jpeg-xl/lib/jxl/fields.h +++ b/third_party/jpeg-xl/lib/jxl/fields.h @@ -8,14 +8,11 @@ // Forward/backward-compatible 'bundles' with auto-serialized 'fields'. -#include <cmath> // abs -#include <cstdarg> #include <cstddef> #include <cstdint> #include <cstdlib> #include <cstring> -#include "lib/jxl/base/bits.h" #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/status.h" #include "lib/jxl/dec_bit_reader.h" diff --git a/third_party/jpeg-xl/lib/jxl/fields_test.cc b/third_party/jpeg-xl/lib/jxl/fields_test.cc index 0584458d07..5af68d2d5f 100644 --- a/third_party/jpeg-xl/lib/jxl/fields_test.cc +++ b/third_party/jpeg-xl/lib/jxl/fields_test.cc @@ -5,18 +5,21 @@ #include "lib/jxl/fields.h" -#include <stddef.h> -#include <stdint.h> - #include <array> -#include <utility> +#include <cstddef> +#include <cstdint> #include "lib/jxl/base/common.h" +#include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/span.h" +#include "lib/jxl/base/status.h" +#include "lib/jxl/dec_bit_reader.h" #include "lib/jxl/enc_aux_out.h" #include "lib/jxl/enc_fields.h" +#include "lib/jxl/field_encodings.h" #include "lib/jxl/frame_header.h" #include "lib/jxl/headers.h" +#include "lib/jxl/image_metadata.h" #include "lib/jxl/testing.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/frame_dimensions.h b/third_party/jpeg-xl/lib/jxl/frame_dimensions.h index 8440a95463..f7493f88b2 100644 --- a/third_party/jpeg-xl/lib/jxl/frame_dimensions.h +++ b/third_party/jpeg-xl/lib/jxl/frame_dimensions.h @@ -11,7 +11,7 @@ #include <cstddef> #include "lib/jxl/base/common.h" -#include "lib/jxl/image.h" +#include "lib/jxl/base/rect.h" namespace jxl { // Some enums and typedefs used by more than one header file. diff --git a/third_party/jpeg-xl/lib/jxl/frame_header.h b/third_party/jpeg-xl/lib/jxl/frame_header.h index 30c62d5f27..68c4684a58 100644 --- a/third_party/jpeg-xl/lib/jxl/frame_header.h +++ b/third_party/jpeg-xl/lib/jxl/frame_header.h @@ -9,18 +9,20 @@ // Frame header with backward and forward-compatible extension capability and // compressed integer fields. -#include <stddef.h> -#include <stdint.h> - #include <algorithm> +#include <array> +#include <cstddef> +#include <cstdint> #include <string> +#include <vector> +#include "lib/jxl/base/common.h" #include "lib/jxl/base/compiler_specific.h" -#include "lib/jxl/base/override.h" #include "lib/jxl/base/status.h" #include "lib/jxl/coeff_order_fwd.h" #include "lib/jxl/common.h" // kMaxNumPasses #include "lib/jxl/dec_bit_reader.h" +#include "lib/jxl/field_encodings.h" #include "lib/jxl/fields.h" #include "lib/jxl/frame_dimensions.h" #include "lib/jxl/image_metadata.h" diff --git a/third_party/jpeg-xl/lib/jxl/icc_codec.h b/third_party/jpeg-xl/lib/jxl/icc_codec.h index 3b0b0c041b..e57018b4c3 100644 --- a/third_party/jpeg-xl/lib/jxl/icc_codec.h +++ b/third_party/jpeg-xl/lib/jxl/icc_codec.h @@ -10,8 +10,8 @@ #include <cstddef> #include <cstdint> +#include <vector> -#include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/status.h" #include "lib/jxl/dec_ans.h" #include "lib/jxl/dec_bit_reader.h" diff --git a/third_party/jpeg-xl/lib/jxl/image.h b/third_party/jpeg-xl/lib/jxl/image.h index be97b929e3..347e070336 100644 --- a/third_party/jpeg-xl/lib/jxl/image.h +++ b/third_party/jpeg-xl/lib/jxl/image.h @@ -10,16 +10,13 @@ #if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \ defined(THREAD_SANITIZER) -#include <inttypes.h> +#include <cinttypes> // PRIu64 #endif -#include <stddef.h> -#include <stdint.h> -#include <string.h> - #include <algorithm> -#include <sstream> -#include <string> +#include <cstddef> +#include <cstdint> +#include <cstring> #include <utility> // std::move #include "lib/jxl/base/compiler_specific.h" @@ -184,179 +181,6 @@ using ImageI = Plane<int32_t>; using ImageF = Plane<float>; using ImageD = Plane<double>; -template <typename T> -class Image3; - -// Rectangular region in image(s). Factoring this out of Image instead of -// shifting the pointer by x0/y0 allows this to apply to multiple images with -// different resolutions (e.g. color transform and quantization field). -// Can compare using SameSize(rect1, rect2). -template <typename T> -class RectT { - public: - // Most windows are xsize_max * ysize_max, except those on the borders where - // begin + size_max > end. - constexpr RectT(T xbegin, T ybegin, size_t xsize_max, size_t ysize_max, - T xend, T yend) - : x0_(xbegin), - y0_(ybegin), - xsize_(ClampedSize(xbegin, xsize_max, xend)), - ysize_(ClampedSize(ybegin, ysize_max, yend)) {} - - // Construct with origin and known size (typically from another Rect). - constexpr RectT(T xbegin, T ybegin, size_t xsize, size_t ysize) - : x0_(xbegin), y0_(ybegin), xsize_(xsize), ysize_(ysize) {} - - // Construct a rect that covers a whole image/plane/ImageBundle etc. - template <typename ImageT> - explicit RectT(const ImageT& image) - : RectT(0, 0, image.xsize(), image.ysize()) {} - - RectT() : RectT(0, 0, 0, 0) {} - - RectT(const RectT&) = default; - RectT& operator=(const RectT&) = default; - - // Construct a subrect that resides in an image/plane/ImageBundle etc. - template <typename ImageT> - RectT Crop(const ImageT& image) const { - return Intersection(RectT(image)); - } - - // Construct a subrect that resides in the [0, ysize) x [0, xsize) region of - // the current rect. - RectT Crop(size_t area_xsize, size_t area_ysize) const { - return Intersection(RectT(0, 0, area_xsize, area_ysize)); - } - - // Returns a rect that only contains `num` lines with offset `y` from `y0()`. - RectT Lines(size_t y, size_t num) const { - JXL_DASSERT(y + num <= ysize_); - return RectT(x0_, y0_ + y, xsize_, num); - } - - RectT Line(size_t y) const { return Lines(y, 1); } - - JXL_MUST_USE_RESULT RectT Intersection(const RectT& other) const { - return RectT(std::max(x0_, other.x0_), std::max(y0_, other.y0_), xsize_, - ysize_, std::min(x1(), other.x1()), - std::min(y1(), other.y1())); - } - - JXL_MUST_USE_RESULT RectT Translate(int64_t x_offset, - int64_t y_offset) const { - return RectT(x0_ + x_offset, y0_ + y_offset, xsize_, ysize_); - } - - template <typename V> - V* Row(Plane<V>* image, size_t y) const { - JXL_DASSERT(y + y0_ >= 0); - return image->Row(y + y0_) + x0_; - } - - template <typename V> - const V* Row(const Plane<V>* image, size_t y) const { - JXL_DASSERT(y + y0_ >= 0); - return image->Row(y + y0_) + x0_; - } - - template <typename V> - V* PlaneRow(Image3<V>* image, const size_t c, size_t y) const { - JXL_DASSERT(y + y0_ >= 0); - return image->PlaneRow(c, y + y0_) + x0_; - } - - template <typename V> - const V* ConstRow(const Plane<V>& image, size_t y) const { - JXL_DASSERT(y + y0_ >= 0); - return image.ConstRow(y + y0_) + x0_; - } - - template <typename V> - const V* ConstPlaneRow(const Image3<V>& image, size_t c, size_t y) const { - JXL_DASSERT(y + y0_ >= 0); - return image.ConstPlaneRow(c, y + y0_) + x0_; - } - - bool IsInside(const RectT& other) const { - return x0_ >= other.x0() && x1() <= other.x1() && y0_ >= other.y0() && - y1() <= other.y1(); - } - - // Returns true if this Rect fully resides in the given image. ImageT could be - // Plane<T> or Image3<T>; however if ImageT is Rect, results are nonsensical. - template <class ImageT> - bool IsInside(const ImageT& image) const { - return IsInside(RectT(image)); - } - - T x0() const { return x0_; } - T y0() const { return y0_; } - size_t xsize() const { return xsize_; } - size_t ysize() const { return ysize_; } - T x1() const { return x0_ + xsize_; } - T y1() const { return y0_ + ysize_; } - - RectT<T> ShiftLeft(size_t shiftx, size_t shifty) const { - return RectT<T>(x0_ * (1 << shiftx), y0_ * (1 << shifty), xsize_ << shiftx, - ysize_ << shifty); - } - RectT<T> ShiftLeft(size_t shift) const { return ShiftLeft(shift, shift); } - - // Requires x0(), y0() to be multiples of 1<<shiftx, 1<<shifty. - RectT<T> CeilShiftRight(size_t shiftx, size_t shifty) const { - JXL_ASSERT(x0_ % (1 << shiftx) == 0); - JXL_ASSERT(y0_ % (1 << shifty) == 0); - return RectT<T>(x0_ / (1 << shiftx), y0_ / (1 << shifty), - DivCeil(xsize_, T{1} << shiftx), - DivCeil(ysize_, T{1} << shifty)); - } - RectT<T> CeilShiftRight(std::pair<size_t, size_t> shift) const { - return CeilShiftRight(shift.first, shift.second); - } - RectT<T> CeilShiftRight(size_t shift) const { - return CeilShiftRight(shift, shift); - } - - RectT<T> Extend(T border, RectT<T> parent) const { - T new_x0 = x0() > parent.x0() + border ? x0() - border : parent.x0(); - T new_y0 = y0() > parent.y0() + border ? y0() - border : parent.y0(); - T new_x1 = x1() + border > parent.x1() ? parent.x1() : x1() + border; - T new_y1 = y1() + border > parent.y1() ? parent.y1() : y1() + border; - return RectT<T>(new_x0, new_y0, new_x1 - new_x0, new_y1 - new_y0); - } - - template <typename U> - RectT<U> As() const { - return RectT<U>(static_cast<U>(x0_), static_cast<U>(y0_), - static_cast<U>(xsize_), static_cast<U>(ysize_)); - } - - private: - // Returns size_max, or whatever is left in [begin, end). - static constexpr size_t ClampedSize(T begin, size_t size_max, T end) { - return (static_cast<T>(begin + size_max) <= end) - ? size_max - : (end > begin ? end - begin : 0); - } - - T x0_; - T y0_; - - size_t xsize_; - size_t ysize_; -}; - -template <typename T> -std::string Description(RectT<T> r) { - std::ostringstream os; - os << "[" << r.x0() << ".." << r.x1() << ")x" - << "[" << r.y0() << ".." << r.y1() << ")"; - return os.str(); -} - -using Rect = RectT<size_t>; - // Currently, we abuse Image to either refer to an image that owns its storage // or one that doesn't. In similar vein, we abuse Image* function parameters to // either mean "assign to me" or "fill the provided image with data". diff --git a/third_party/jpeg-xl/lib/jxl/image_bundle.h b/third_party/jpeg-xl/lib/jxl/image_bundle.h index c8a76a9f59..00f1eb81bd 100644 --- a/third_party/jpeg-xl/lib/jxl/image_bundle.h +++ b/third_party/jpeg-xl/lib/jxl/image_bundle.h @@ -9,9 +9,9 @@ // The main image or frame consists of a bundle of associated images. #include <jxl/cms_interface.h> -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> #include <memory> #include <string> #include <utility> @@ -19,6 +19,7 @@ #include "lib/jxl/base/common.h" #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/color_encoding_internal.h" #include "lib/jxl/common.h" // JPEGXL_ENABLE_TRANSCODE_JPEG diff --git a/third_party/jpeg-xl/lib/jxl/image_metadata.h b/third_party/jpeg-xl/lib/jxl/image_metadata.h index 2b647cfa30..37b5aedcfa 100644 --- a/third_party/jpeg-xl/lib/jxl/image_metadata.h +++ b/third_party/jpeg-xl/lib/jxl/image_metadata.h @@ -17,6 +17,7 @@ #include <vector> #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/matrix_ops.h" #include "lib/jxl/base/status.h" #include "lib/jxl/color_encoding_internal.h" #include "lib/jxl/dec_bit_reader.h" diff --git a/third_party/jpeg-xl/lib/jxl/image_ops.h b/third_party/jpeg-xl/lib/jxl/image_ops.h index 84cf7dad76..bee4eb56bd 100644 --- a/third_party/jpeg-xl/lib/jxl/image_ops.h +++ b/third_party/jpeg-xl/lib/jxl/image_ops.h @@ -14,6 +14,7 @@ #include <limits> #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/frame_dimensions.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/image_ops_test.cc b/third_party/jpeg-xl/lib/jxl/image_ops_test.cc index 6b308baab4..0d16864282 100644 --- a/third_party/jpeg-xl/lib/jxl/image_ops_test.cc +++ b/third_party/jpeg-xl/lib/jxl/image_ops_test.cc @@ -5,14 +5,14 @@ #include "lib/jxl/image_ops.h" -#include <stdint.h> -#include <stdlib.h> - +#include <cstdint> +#include <cstdlib> #include <cstring> #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/printf_macros.h" #include "lib/jxl/base/random.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/cache_aligned.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/image_test_utils.h b/third_party/jpeg-xl/lib/jxl/image_test_utils.h index 7bb146866e..0b8b79a7dd 100644 --- a/third_party/jpeg-xl/lib/jxl/image_test_utils.h +++ b/third_party/jpeg-xl/lib/jxl/image_test_utils.h @@ -6,17 +6,15 @@ #ifndef LIB_JXL_IMAGE_TEST_UTILS_H_ #define LIB_JXL_IMAGE_TEST_UTILS_H_ -#include <inttypes.h> -#include <stddef.h> -#include <stdint.h> - #include <cmath> +#include <cstddef> +#include <cstdint> #include <limits> #include <sstream> #include "lib/jxl/base/compiler_specific.h" -#include "lib/jxl/base/printf_macros.h" #include "lib/jxl/base/random.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/image.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/jpeg/enc_jpeg_data.cc b/third_party/jpeg-xl/lib/jxl/jpeg/enc_jpeg_data.cc index d7c6c2ad78..d4a5e1d577 100644 --- a/third_party/jpeg-xl/lib/jxl/jpeg/enc_jpeg_data.cc +++ b/third_party/jpeg-xl/lib/jxl/jpeg/enc_jpeg_data.cc @@ -88,7 +88,7 @@ Status DetectBlobs(jpeg::JPEGData& jpeg_data) { // Something is wrong with this marker; does not care. continue; } - if (!have_exif && payload.size() >= sizeof kExifTag && + if (!have_exif && payload.size() > sizeof kExifTag && !memcmp(payload.data(), kExifTag, sizeof kExifTag)) { jpeg_data.app_marker_type[i] = AppMarkerType::kExif; have_exif = true; diff --git a/third_party/jpeg-xl/lib/jxl/jxl_test.cc b/third_party/jpeg-xl/lib/jxl/jxl_test.cc index cf9857f462..be43d5a237 100644 --- a/third_party/jpeg-xl/lib/jxl/jxl_test.cc +++ b/third_party/jpeg-xl/lib/jxl/jxl_test.cc @@ -120,7 +120,7 @@ TEST(JxlTest, RoundtripSmallD1) { { PackedPixelFile ppf_out; EXPECT_NEAR(Roundtrip(t.ppf(), {}, {}, pool, &ppf_out), 916, 40); - EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.888); + EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.92); } // With a lower intensity target than the default, the bitrate should be @@ -179,7 +179,7 @@ TEST(JxlTest, RoundtripResample2MT) { cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 3); // kFalcon PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf_out), 203300, + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf_out), 206917, 2000); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 340); } @@ -201,7 +201,7 @@ TEST(JxlTest, RoundtripOutOfOrderProcessing) { cparams.AddOption(JXL_ENC_FRAME_SETTING_EPF, 3); PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 27444, 400); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 26933, 400); EXPECT_LE(ButteraugliDistance(t.ppf(), ppf_out), 1.35); } @@ -221,7 +221,7 @@ TEST(JxlTest, RoundtripOutOfOrderProcessingBorder) { cparams.AddOption(JXL_ENC_FRAME_SETTING_RESAMPLING, 2); PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 10065, 200); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 9747, 200); EXPECT_LE(ButteraugliDistance(t.ppf(), ppf_out), 2.9); } @@ -236,7 +236,7 @@ TEST(JxlTest, RoundtripResample4) { cparams.AddOption(JXL_ENC_FRAME_SETTING_RESAMPLING, 4); PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 5758, 100); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 5888, 100); EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 22); } @@ -296,7 +296,7 @@ TEST(JxlTest, RoundtripMultiGroup) { auto run_kitten = std::async(std::launch::async, test, SpeedTier::kKitten, 1.0f, 63624u, 8.5); auto run_wombat = std::async(std::launch::async, test, SpeedTier::kWombat, - 2.0f, 39620u, 15.5); + 2.0f, 38536u, 15.7); } TEST(JxlTest, RoundtripRGBToGrayscale) { @@ -505,7 +505,7 @@ TEST(JxlTest, RoundtripSmallNL) { PackedPixelFile ppf_out; EXPECT_NEAR(Roundtrip(t.ppf(), {}, {}, pool, &ppf_out), 916, 45); - EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.82); + EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.92); } TEST(JxlTest, RoundtripNoGaborishNoAR) { @@ -539,7 +539,7 @@ TEST(JxlTest, RoundtripSmallNoGaborish) { PackedPixelFile ppf_out; EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 1006, 20); - EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.1); + EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.2); } TEST(JxlTest, RoundtripSmallPatchesAlpha) { @@ -895,7 +895,7 @@ TEST(JxlTest, RoundtripAlphaPremultiplied) { ButteraugliDistance(io_nopremul.frames, io2.frames, ButteraugliParams(), *JxlGetDefaultCms(), /*distmap=*/nullptr), - 1.0); + 1.1); } } } @@ -936,7 +936,7 @@ TEST(JxlTest, RoundtripAlphaResamplingOnlyAlpha) { cparams.AddOption(JXL_ENC_FRAME_SETTING_EXTRA_CHANNEL_RESAMPLING, 2); PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 32000, 1000); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 33179, 1000); EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.52); } @@ -1316,8 +1316,13 @@ size_t RoundtripJpeg(const std::vector<uint8_t>& jpeg_in, ThreadPool* pool) { &compressed)); jxl::JXLDecompressParams dparams; - test::DefaultAcceptedFormats(dparams); test::SetThreadParallelRunner(dparams, pool); + { + std::vector<uint8_t> out; + jxl::PackedPixelFile ppf; + EXPECT_FALSE(DecodeImageJXL(compressed.data(), compressed.size() - 1, + dparams, nullptr, &ppf, &out)); + } std::vector<uint8_t> out; jxl::PackedPixelFile ppf; EXPECT_TRUE(DecodeImageJXL(compressed.data(), compressed.size(), dparams, @@ -1504,6 +1509,57 @@ JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionMetadata) { EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 1334u, 100); } +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionEmptyExif) { + ThreadPoolForTests pool(8); + const std::vector<uint8_t> orig = { + // SOI + 0xff, 0xd8, // + // APP1 + 0xff, 0xe1, 0x00, 0x08, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00, // + // DQT + 0xff, 0xdb, 0x00, 0x43, 0x00, 0x03, 0x02, 0x02, 0x03, 0x02, // + 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x05, // + 0x08, 0x05, 0x05, 0x04, 0x04, 0x05, 0x0a, 0x07, 0x07, 0x06, // + 0x08, 0x0c, 0x0a, 0x0c, 0x0c, 0x0b, 0x0a, 0x0b, 0x0b, 0x0d, // + 0x0e, 0x12, 0x10, 0x0d, 0x0e, 0x11, 0x0e, 0x0b, 0x0b, 0x10, // + 0x16, 0x10, 0x11, 0x13, 0x14, 0x15, 0x15, 0x15, 0x0c, 0x0f, // + 0x17, 0x18, 0x16, 0x14, 0x18, 0x12, 0x14, 0x15, 0x14, // + // SOF + 0xff, 0xc0, 0x00, 0x0b, 0x08, 0x00, 0x01, 0x00, 0x01, 0x01, // + 0x01, 0x11, 0x00, // + // DHT + 0xff, 0xc4, 0x00, 0xd2, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, // + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // + 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // + 0x09, 0x0a, 0x0b, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, // + 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, // + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, // + 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, // + 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, // + 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, // + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, // + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, // + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, // + 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, // + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, // + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, // + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, // + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, // + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, // + 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, // + 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, // + 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, // + 0xf9, 0xfa, // + // SOS + 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, // + // entropy coded data + 0xfc, 0xaa, 0xaf, // + // EOI + 0xff, 0xd9, // + }; + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 466u, 100); +} + JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionRestarts) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = diff --git a/third_party/jpeg-xl/lib/jxl/lehmer_code_test.cc b/third_party/jpeg-xl/lib/jxl/lehmer_code_test.cc index c7752d8cfc..ba4651430f 100644 --- a/third_party/jpeg-xl/lib/jxl/lehmer_code_test.cc +++ b/third_party/jpeg-xl/lib/jxl/lehmer_code_test.cc @@ -5,16 +5,15 @@ #include "lib/jxl/lehmer_code.h" -#include <stdint.h> -#include <string.h> - -#include <algorithm> +#include <cstdint> +#include <cstring> #include <numeric> #include <vector> #include "lib/jxl/base/bits.h" #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/random.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/test_utils.h" #include "lib/jxl/testing.h" diff --git a/third_party/jpeg-xl/lib/jxl/modular/encoding/context_predict.h b/third_party/jpeg-xl/lib/jxl/modular/encoding/context_predict.h index df54a9425e..0a71bec24f 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/encoding/context_predict.h +++ b/third_party/jpeg-xl/lib/jxl/modular/encoding/context_predict.h @@ -6,9 +6,17 @@ #ifndef LIB_JXL_MODULAR_ENCODING_CONTEXT_PREDICT_H_ #define LIB_JXL_MODULAR_ENCODING_CONTEXT_PREDICT_H_ -#include <utility> +#include <algorithm> +#include <array> +#include <cmath> +#include <cstddef> +#include <cstdint> #include <vector> +#include "lib/jxl/base/bits.h" +#include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/status.h" +#include "lib/jxl/field_encodings.h" #include "lib/jxl/fields.h" #include "lib/jxl/image_ops.h" #include "lib/jxl/modular/modular_image.h" diff --git a/third_party/jpeg-xl/lib/jxl/modular/encoding/enc_debug_tree.cc b/third_party/jpeg-xl/lib/jxl/modular/encoding/enc_debug_tree.cc index f863823629..04f8812750 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/encoding/enc_debug_tree.cc +++ b/third_party/jpeg-xl/lib/jxl/modular/encoding/enc_debug_tree.cc @@ -5,8 +5,7 @@ #include "lib/jxl/modular/encoding/enc_debug_tree.h" -#include <cinttypes> -#include <cstdint> +#include <cinttypes> // PRId64 #include <cstdlib> #include "lib/jxl/base/os_macros.h" diff --git a/third_party/jpeg-xl/lib/jxl/modular/options.h b/third_party/jpeg-xl/lib/jxl/modular/options.h index 6613b513de..5b08236ff2 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/options.h +++ b/third_party/jpeg-xl/lib/jxl/modular/options.h @@ -6,9 +6,9 @@ #ifndef LIB_JXL_MODULAR_OPTIONS_H_ #define LIB_JXL_MODULAR_OPTIONS_H_ -#include <stdint.h> - #include <array> +#include <cstddef> +#include <cstdint> #include <vector> #include "lib/jxl/enc_ans_params.h" diff --git a/third_party/jpeg-xl/lib/jxl/modular/transform/enc_palette.cc b/third_party/jpeg-xl/lib/jxl/modular/transform/enc_palette.cc index 7f9399d3c4..86d161e891 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/enc_palette.cc +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/enc_palette.cc @@ -170,6 +170,7 @@ Status FwdPaletteIteration(Image &input, uint32_t begin_c, uint32_t end_c, size_t w = input.channel[begin_c].w; size_t h = input.channel[begin_c].h; + if (input.bitdepth >= 32) return false; if (!lossy && nb_colors < 2) return false; if (!lossy && nb == 1) { diff --git a/third_party/jpeg-xl/lib/jxl/modular/transform/palette.cc b/third_party/jpeg-xl/lib/jxl/modular/transform/palette.cc index 1ab499ccf6..7726fd8ff3 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/palette.cc +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/palette.cc @@ -5,6 +5,10 @@ #include "lib/jxl/modular/transform/palette.h" +#include <atomic> + +#include "lib/jxl/modular/transform/transform.h" // CheckEqualChannels + namespace jxl { Status InvPalette(Image &input, uint32_t begin_c, uint32_t nb_colors, diff --git a/third_party/jpeg-xl/lib/jxl/modular/transform/palette.h b/third_party/jpeg-xl/lib/jxl/modular/transform/palette.h index 2a9e5c71f4..ee51d4c556 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/palette.h +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/palette.h @@ -6,13 +6,17 @@ #ifndef LIB_JXL_MODULAR_TRANSFORM_PALETTE_H_ #define LIB_JXL_MODULAR_TRANSFORM_PALETTE_H_ -#include <atomic> +#include <algorithm> +#include <array> +#include <cstddef> +#include <cstdint> +#include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/status.h" #include "lib/jxl/modular/encoding/context_predict.h" #include "lib/jxl/modular/modular_image.h" -#include "lib/jxl/modular/transform/transform.h" // CheckEqualChannels +#include "lib/jxl/modular/options.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.h b/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.h index f0333da6fd..f56d6dd7e9 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.h +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.h @@ -23,9 +23,11 @@ // wavelet transform", IEEE Transactions on Image Processing, vol. 1, no. 2, pp. // 205-220, April 1992, doi: 10.1109/83.136597. -#include <stdlib.h> +#include <cstdlib> +#include <vector> #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/modular/modular_image.h" #include "lib/jxl/modular/transform/transform.h" diff --git a/third_party/jpeg-xl/lib/jxl/modular/transform/transform.cc b/third_party/jpeg-xl/lib/jxl/modular/transform/transform.cc index a609cfb3fb..05a18215d1 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/transform.cc +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/transform.cc @@ -5,7 +5,7 @@ #include "lib/jxl/modular/transform/transform.h" -#include <cinttypes> +#include <cinttypes> // PRIu32 #include "lib/jxl/base/printf_macros.h" #include "lib/jxl/fields.h" diff --git a/third_party/jpeg-xl/lib/jxl/modular/transform/transform.h b/third_party/jpeg-xl/lib/jxl/modular/transform/transform.h index 70c383834a..cb46d0888f 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/transform.h +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/transform.h @@ -6,13 +6,17 @@ #ifndef LIB_JXL_MODULAR_TRANSFORM_TRANSFORM_H_ #define LIB_JXL_MODULAR_TRANSFORM_TRANSFORM_H_ +#include <cstddef> #include <cstdint> -#include <string> #include <vector> +#include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/status.h" +#include "lib/jxl/field_encodings.h" #include "lib/jxl/fields.h" #include "lib/jxl/modular/encoding/context_predict.h" +#include "lib/jxl/modular/modular_image.h" #include "lib/jxl/modular/options.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/opsin_image_test.cc b/third_party/jpeg-xl/lib/jxl/opsin_image_test.cc index b8ea839b9e..dff257f9bc 100644 --- a/third_party/jpeg-xl/lib/jxl/opsin_image_test.cc +++ b/third_party/jpeg-xl/lib/jxl/opsin_image_test.cc @@ -10,6 +10,8 @@ #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/matrix_ops.h" +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/cms/opsin_params.h" #include "lib/jxl/dec_xyb.h" #include "lib/jxl/enc_xyb.h" diff --git a/third_party/jpeg-xl/lib/jxl/opsin_inverse_test.cc b/third_party/jpeg-xl/lib/jxl/opsin_inverse_test.cc index b8f9aa13df..4407658ddf 100644 --- a/third_party/jpeg-xl/lib/jxl/opsin_inverse_test.cc +++ b/third_party/jpeg-xl/lib/jxl/opsin_inverse_test.cc @@ -8,6 +8,8 @@ #include <utility> #include "lib/jxl/base/data_parallel.h" +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/codec_in_out.h" #include "lib/jxl/color_encoding_internal.h" #include "lib/jxl/dec_xyb.h" diff --git a/third_party/jpeg-xl/lib/jxl/passes_test.cc b/third_party/jpeg-xl/lib/jxl/passes_test.cc index e7a7547a0c..a525987018 100644 --- a/third_party/jpeg-xl/lib/jxl/passes_test.cc +++ b/third_party/jpeg-xl/lib/jxl/passes_test.cc @@ -4,8 +4,8 @@ // license that can be found in the LICENSE file. #include <jxl/cms.h> -#include <stddef.h> +#include <cstddef> #include <cstdint> #include <future> #include <string> @@ -16,6 +16,7 @@ #include "lib/extras/dec/jxl.h" #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/override.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/span.h" #include "lib/jxl/enc_params.h" #include "lib/jxl/image.h" @@ -51,7 +52,7 @@ TEST(PassesTest, RoundtripSmallPasses) { ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(), *JxlGetDefaultCms(), /*distmap=*/nullptr), - 0.8222); + 1.0); } TEST(PassesTest, RoundtripUnalignedPasses) { diff --git a/third_party/jpeg-xl/lib/jxl/preview_test.cc b/third_party/jpeg-xl/lib/jxl/preview_test.cc index c482db9fd8..fab8943e10 100644 --- a/third_party/jpeg-xl/lib/jxl/preview_test.cc +++ b/third_party/jpeg-xl/lib/jxl/preview_test.cc @@ -12,7 +12,9 @@ #include "lib/extras/codec.h" #include "lib/jxl/base/span.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/codec_in_out.h" +#include "lib/jxl/common.h" #include "lib/jxl/enc_params.h" #include "lib/jxl/headers.h" #include "lib/jxl/image_bundle.h" diff --git a/third_party/jpeg-xl/lib/jxl/quant_weights.h b/third_party/jpeg-xl/lib/jxl/quant_weights.h index 0fa23ffddb..8192f71443 100644 --- a/third_party/jpeg-xl/lib/jxl/quant_weights.h +++ b/third_party/jpeg-xl/lib/jxl/quant_weights.h @@ -11,16 +11,14 @@ #include <array> #include <hwy/aligned_allocator.h> -#include <utility> #include <vector> #include "lib/jxl/ac_strategy.h" #include "lib/jxl/base/common.h" #include "lib/jxl/base/compiler_specific.h" -#include "lib/jxl/base/span.h" #include "lib/jxl/base/status.h" #include "lib/jxl/dec_bit_reader.h" -#include "lib/jxl/image.h" +#include "lib/jxl/frame_dimensions.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/quant_weights_test.cc b/third_party/jpeg-xl/lib/jxl/quant_weights_test.cc index 776a1c776d..61c812d620 100644 --- a/third_party/jpeg-xl/lib/jxl/quant_weights_test.cc +++ b/third_party/jpeg-xl/lib/jxl/quant_weights_test.cc @@ -10,14 +10,21 @@ #include <cmath> #include <hwy/base.h> // HWY_ALIGN_MAX #include <hwy/tests/hwy_gtest.h> +#include <iterator> #include <numeric> +#include <vector> +#include "lib/jxl/ac_strategy.h" #include "lib/jxl/base/random.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/dct_for_test.h" #include "lib/jxl/dec_transforms_testonly.h" #include "lib/jxl/enc_modular.h" +#include "lib/jxl/enc_params.h" #include "lib/jxl/enc_quant_weights.h" #include "lib/jxl/enc_transforms.h" +#include "lib/jxl/frame_header.h" +#include "lib/jxl/image_metadata.h" #include "lib/jxl/testing.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/quantizer.cc b/third_party/jpeg-xl/lib/jxl/quantizer.cc index b9ea43e0d6..f63c6a589d 100644 --- a/third_party/jpeg-xl/lib/jxl/quantizer.cc +++ b/third_party/jpeg-xl/lib/jxl/quantizer.cc @@ -5,11 +5,11 @@ #include "lib/jxl/quantizer.h" -#include <string.h> - #include <algorithm> +#include <cstring> #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/field_encodings.h" #include "lib/jxl/fields.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/quantizer.h b/third_party/jpeg-xl/lib/jxl/quantizer.h index 602d12bdfa..b61c8acde6 100644 --- a/third_party/jpeg-xl/lib/jxl/quantizer.h +++ b/third_party/jpeg-xl/lib/jxl/quantizer.h @@ -6,21 +6,17 @@ #ifndef LIB_JXL_QUANTIZER_H_ #define LIB_JXL_QUANTIZER_H_ -#include <stddef.h> -#include <stdint.h> -#include <stdlib.h> - #include <algorithm> #include <cmath> -#include <utility> -#include <vector> +#include <cstddef> +#include <cstdint> +#include <cstdlib> -#include "lib/jxl/ac_strategy.h" -#include "lib/jxl/base/bits.h" #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" -#include "lib/jxl/dct_util.h" #include "lib/jxl/dec_bit_reader.h" +#include "lib/jxl/field_encodings.h" #include "lib/jxl/fields.h" #include "lib/jxl/image.h" #include "lib/jxl/quant_weights.h" diff --git a/third_party/jpeg-xl/lib/jxl/quantizer_test.cc b/third_party/jpeg-xl/lib/jxl/quantizer_test.cc index eeaac9ba53..5b965b78ca 100644 --- a/third_party/jpeg-xl/lib/jxl/quantizer_test.cc +++ b/third_party/jpeg-xl/lib/jxl/quantizer_test.cc @@ -5,9 +5,17 @@ #include "lib/jxl/quantizer.h" +#include <cstddef> +#include <cstdint> + +#include "lib/jxl/base/status.h" #include "lib/jxl/dec_bit_reader.h" +#include "lib/jxl/enc_bit_writer.h" #include "lib/jxl/enc_fields.h" +#include "lib/jxl/fields.h" +#include "lib/jxl/image.h" #include "lib/jxl/image_test_utils.h" +#include "lib/jxl/quant_weights.h" #include "lib/jxl/testing.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.cc b/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.cc index 27718e6413..f95237dea5 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.cc +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.cc @@ -6,9 +6,16 @@ #include "lib/jxl/render_pipeline/low_memory_render_pipeline.h" #include <algorithm> +#include <cstddef> +#include <cstdint> +#include <utility> +#include <vector> #include "lib/jxl/base/arch_macros.h" +#include "lib/jxl/base/common.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" +#include "lib/jxl/image.h" #include "lib/jxl/image_ops.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.h b/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.h index f0b21d3dca..5f88a34b5e 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.h +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/low_memory_render_pipeline.h @@ -6,9 +6,16 @@ #ifndef LIB_JXL_RENDER_PIPELINE_LOW_MEMORY_RENDER_PIPELINE_H_ #define LIB_JXL_RENDER_PIPELINE_LOW_MEMORY_RENDER_PIPELINE_H_ -#include <stdint.h> +#include <cstddef> +#include <cstdint> +#include <utility> +#include <vector> +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/dec_group_border.h" +#include "lib/jxl/frame_header.h" +#include "lib/jxl/image.h" #include "lib/jxl/render_pipeline/render_pipeline.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline.cc b/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline.cc index 09e3dbab76..ed27a2efa0 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline.cc +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline.cc @@ -5,6 +5,10 @@ #include "lib/jxl/render_pipeline/render_pipeline.h" +#include <memory> +#include <utility> + +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/render_pipeline/low_memory_render_pipeline.h" #include "lib/jxl/render_pipeline/simple_render_pipeline.h" diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline.h b/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline.h index c61420be4b..fa7a1e58c4 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline.h +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline.h @@ -6,8 +6,16 @@ #ifndef LIB_JXL_RENDER_PIPELINE_RENDER_PIPELINE_H_ #define LIB_JXL_RENDER_PIPELINE_RENDER_PIPELINE_H_ -#include <stdint.h> - +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <memory> +#include <utility> +#include <vector> + +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" +#include "lib/jxl/frame_dimensions.h" #include "lib/jxl/image.h" #include "lib/jxl/render_pipeline/render_pipeline_stage.h" diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline_stage.h b/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline_stage.h index d054027ba7..3c9b83addd 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline_stage.h +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline_stage.h @@ -6,7 +6,9 @@ #ifndef LIB_JXL_RENDER_PIPELINE_RENDER_PIPELINE_STAGE_H_ #define LIB_JXL_RENDER_PIPELINE_RENDER_PIPELINE_STAGE_H_ -#include <stdint.h> +#include <cstddef> +#include <utility> +#include <vector> #include "lib/jxl/base/arch_macros.h" #include "lib/jxl/base/status.h" diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline_test.cc b/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline_test.cc index e9cb913983..f5d7635206 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline_test.cc +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/render_pipeline_test.cc @@ -247,7 +247,7 @@ TEST_P(RenderPipelineTestParam, PipelineTest) { ASSERT_EQ(io_default.frames.size(), io_slow_pipeline.frames.size()); for (size_t i = 0; i < io_default.frames.size(); i++) { #if JXL_HIGH_PRECISION - constexpr float kMaxError = 5e-5; + constexpr float kMaxError = 2e-4; #else constexpr float kMaxError = 5e-4; #endif diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/simple_render_pipeline.cc b/third_party/jpeg-xl/lib/jxl/render_pipeline/simple_render_pipeline.cc index 77ddb3d430..88cc04ed0c 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/simple_render_pipeline.cc +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/simple_render_pipeline.cc @@ -5,8 +5,14 @@ #include "lib/jxl/render_pipeline/simple_render_pipeline.h" +#include <algorithm> +#include <cstddef> +#include <cstdint> #include <hwy/base.h> +#include <utility> +#include <vector> +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/image_ops.h" #include "lib/jxl/render_pipeline/render_pipeline_stage.h" diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/simple_render_pipeline.h b/third_party/jpeg-xl/lib/jxl/render_pipeline/simple_render_pipeline.h index 1240b9fa46..4fd81755f3 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/simple_render_pipeline.h +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/simple_render_pipeline.h @@ -6,8 +6,13 @@ #ifndef LIB_JXL_RENDER_PIPELINE_SIMPLE_RENDER_PIPELINE_H_ #define LIB_JXL_RENDER_PIPELINE_SIMPLE_RENDER_PIPELINE_H_ -#include <stdint.h> +#include <cstddef> +#include <utility> +#include <vector> +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" +#include "lib/jxl/image.h" #include "lib/jxl/render_pipeline/render_pipeline.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_noise.h b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_noise.h index bd7797f991..ebdc9be992 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_noise.h +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_noise.h @@ -5,15 +5,12 @@ #ifndef LIB_JXL_RENDER_PIPELINE_STAGE_NOISE_H_ #define LIB_JXL_RENDER_PIPELINE_STAGE_NOISE_H_ -#include <math.h> -#include <stdint.h> -#include <stdio.h> -#include <algorithm> -#include <utility> -#include <vector> +#include <cstddef> +#include <memory> -#include "lib/jxl/dec_noise.h" +#include "lib/jxl/chroma_from_luma.h" +#include "lib/jxl/noise.h" #include "lib/jxl/render_pipeline/render_pipeline_stage.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_splines.cc b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_splines.cc index 92a13090a7..9473ff3dbe 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_splines.cc +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_splines.cc @@ -5,11 +5,19 @@ #include "lib/jxl/render_pipeline/stage_splines.h" +#include <cstddef> +#include <memory> + #undef HWY_TARGET_INCLUDE #define HWY_TARGET_INCLUDE "lib/jxl/render_pipeline/stage_splines.cc" #include <hwy/foreach_target.h> #include <hwy/highway.h> +#include "lib/jxl/base/rect.h" +#include "lib/jxl/base/status.h" +#include "lib/jxl/render_pipeline/render_pipeline_stage.h" +#include "lib/jxl/splines.h" + HWY_BEFORE_NAMESPACE(); namespace jxl { namespace HWY_NAMESPACE { diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_write.h b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_write.h index ba2c51ee97..32e5fba932 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_write.h +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_write.h @@ -6,11 +6,15 @@ #ifndef LIB_JXL_RENDER_PIPELINE_STAGE_WRITE_H_ #define LIB_JXL_RENDER_PIPELINE_STAGE_WRITE_H_ -#include <functional> +#include <cstddef> +#include <memory> +#include <vector> #include "lib/jxl/dec_cache.h" #include "lib/jxl/dec_xyb.h" +#include "lib/jxl/image.h" #include "lib/jxl/image_bundle.h" +#include "lib/jxl/image_metadata.h" #include "lib/jxl/render_pipeline/render_pipeline_stage.h" namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/test_render_pipeline_stages.h b/third_party/jpeg-xl/lib/jxl/render_pipeline/test_render_pipeline_stages.h index c2c25c46c3..54d40671d6 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/test_render_pipeline_stages.h +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/test_render_pipeline_stages.h @@ -3,9 +3,9 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#include <math.h> -#include <stdint.h> -#include <stdio.h> +#include <cmath> +#include <cstdint> +#include <cstdio> #include "lib/jxl/base/status.h" #include "lib/jxl/render_pipeline/render_pipeline_stage.h" diff --git a/third_party/jpeg-xl/lib/jxl/roundtrip_test.cc b/third_party/jpeg-xl/lib/jxl/roundtrip_test.cc index 07e43e4ddf..fa23956995 100644 --- a/third_party/jpeg-xl/lib/jxl/roundtrip_test.cc +++ b/third_party/jpeg-xl/lib/jxl/roundtrip_test.cc @@ -23,6 +23,7 @@ #include "lib/extras/codec.h" #include "lib/jxl/base/common.h" #include "lib/jxl/base/span.h" +#include "lib/jxl/base/status.h" #include "lib/jxl/butteraugli/butteraugli.h" #include "lib/jxl/color_encoding_internal.h" #include "lib/jxl/dec_bit_reader.h" @@ -432,7 +433,7 @@ void VerifyRoundtripCompression( float butteraugli_score = ButteraugliDistance( original_io.frames, decoded_io.frames, ba, *JxlGetDefaultCms(), /*distmap=*/nullptr, nullptr); - float target_score = 1.3f; + float target_score = 1.4f; // upsampling mode 1 (unlike default and NN) does not downscale back to the // already downsampled image if (upsampling_mode == 1 && resampling >= 4 && already_downsampled) diff --git a/third_party/jpeg-xl/lib/jxl/sanitizers.h b/third_party/jpeg-xl/lib/jxl/sanitizers.h index bb133e9203..e05f79737b 100644 --- a/third_party/jpeg-xl/lib/jxl/sanitizers.h +++ b/third_party/jpeg-xl/lib/jxl/sanitizers.h @@ -6,20 +6,20 @@ #ifndef LIB_JXL_SANITIZERS_H_ #define LIB_JXL_SANITIZERS_H_ -#include <stddef.h> +#include <cstddef> #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/sanitizer_definitions.h" #include "lib/jxl/image.h" #if JXL_MEMORY_SANITIZER -#include <inttypes.h> -#include <stdio.h> - #include <algorithm> +#include <cinttypes> // PRId64 +#include <cstdio> #include <string> #include <vector> +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "sanitizer/msan_interface.h" #endif diff --git a/third_party/jpeg-xl/lib/jxl/speed_tier_test.cc b/third_party/jpeg-xl/lib/jxl/speed_tier_test.cc index 8783faec8f..aefbbc559e 100644 --- a/third_party/jpeg-xl/lib/jxl/speed_tier_test.cc +++ b/third_party/jpeg-xl/lib/jxl/speed_tier_test.cc @@ -15,7 +15,7 @@ #include "lib/extras/dec/jxl.h" #include "lib/extras/enc/jxl.h" -#include "lib/jxl/enc_params.h" +#include "lib/jxl/common.h" #include "lib/jxl/test_image.h" #include "lib/jxl/test_utils.h" #include "lib/jxl/testing.h" diff --git a/third_party/jpeg-xl/lib/jxl/splines.cc b/third_party/jpeg-xl/lib/jxl/splines.cc index 2df2160d76..fd68c15493 100644 --- a/third_party/jpeg-xl/lib/jxl/splines.cc +++ b/third_party/jpeg-xl/lib/jxl/splines.cc @@ -6,12 +6,13 @@ #include "lib/jxl/splines.h" #include <algorithm> -#include <cinttypes> +#include <cinttypes> // PRIu64 #include <cmath> #include <limits> #include "lib/jxl/base/common.h" #include "lib/jxl/base/printf_macros.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/chroma_from_luma.h" #include "lib/jxl/common.h" // JXL_HIGH_PRECISION diff --git a/third_party/jpeg-xl/lib/jxl/splines.h b/third_party/jpeg-xl/lib/jxl/splines.h index af51ec937e..b292d6952b 100644 --- a/third_party/jpeg-xl/lib/jxl/splines.h +++ b/third_party/jpeg-xl/lib/jxl/splines.h @@ -14,6 +14,7 @@ #include <vector> #include "lib/jxl/base/compiler_specific.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/status.h" #include "lib/jxl/chroma_from_luma.h" #include "lib/jxl/image.h" diff --git a/third_party/jpeg-xl/lib/jxl/splines_gbench.cc b/third_party/jpeg-xl/lib/jxl/splines_gbench.cc index 903c5b6328..95f890e3ce 100644 --- a/third_party/jpeg-xl/lib/jxl/splines_gbench.cc +++ b/third_party/jpeg-xl/lib/jxl/splines_gbench.cc @@ -3,9 +3,12 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -#include <array> +#include <cstddef> +#include <vector> #include "benchmark/benchmark.h" +#include "lib/jxl/base/rect.h" +#include "lib/jxl/chroma_from_luma.h" #include "lib/jxl/image_ops.h" #include "lib/jxl/splines.h" diff --git a/third_party/jpeg-xl/lib/jxl/splines_test.cc b/third_party/jpeg-xl/lib/jxl/splines_test.cc index 83cc524234..56f2344b4a 100644 --- a/third_party/jpeg-xl/lib/jxl/splines_test.cc +++ b/third_party/jpeg-xl/lib/jxl/splines_test.cc @@ -18,6 +18,7 @@ #include "lib/jxl/base/common.h" #include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/printf_macros.h" +#include "lib/jxl/base/rect.h" #include "lib/jxl/base/span.h" #include "lib/jxl/base/status.h" #include "lib/jxl/chroma_from_luma.h" diff --git a/third_party/jpeg-xl/lib/jxl/test_image.cc b/third_party/jpeg-xl/lib/jxl/test_image.cc index d2e17c6ab0..eab5ccca14 100644 --- a/third_party/jpeg-xl/lib/jxl/test_image.cc +++ b/third_party/jpeg-xl/lib/jxl/test_image.cc @@ -8,8 +8,11 @@ #include <jxl/encode.h> #include <algorithm> +#include <cstddef> +#include <cstdint> #include <cstring> #include <utility> +#include <vector> #include "lib/extras/dec/color_description.h" #include "lib/extras/dec/color_hints.h" diff --git a/third_party/jpeg-xl/lib/jxl/test_image.h b/third_party/jpeg-xl/lib/jxl/test_image.h index 13d0806ec8..ae62047052 100644 --- a/third_party/jpeg-xl/lib/jxl/test_image.h +++ b/third_party/jpeg-xl/lib/jxl/test_image.h @@ -8,14 +8,13 @@ #include <jxl/codestream_header.h> #include <jxl/types.h> -#include <stddef.h> +#include <cstddef> #include <cstdint> #include <string> #include <vector> #include "lib/extras/packed_image.h" -#include "lib/jxl/base/span.h" namespace jxl { namespace test { diff --git a/third_party/jpeg-xl/lib/jxl/test_utils.h b/third_party/jpeg-xl/lib/jxl/test_utils.h index dc50490174..0d0d8004c1 100644 --- a/third_party/jpeg-xl/lib/jxl/test_utils.h +++ b/third_party/jpeg-xl/lib/jxl/test_utils.h @@ -21,6 +21,7 @@ #include "lib/extras/dec/jxl.h" #include "lib/extras/enc/jxl.h" #include "lib/extras/packed_image.h" +#include "lib/jxl/base/compiler_specific.h" #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/span.h" #include "lib/jxl/base/status.h" @@ -210,4 +211,15 @@ bool operator!=(const jxl::Bytes& a, const jxl::Bytes& b); } // namespace jxl +#if !defined(FUZZ_TEST) +struct FuzzTestSink { + template <typename F> + FuzzTestSink WithSeeds(F) { + return *this; + } +}; +#define FUZZ_TEST(A, B) \ + const JXL_MAYBE_UNUSED FuzzTestSink unused##A##B = FuzzTestSink() +#endif + #endif // LIB_JXL_TEST_UTILS_H_ diff --git a/third_party/jpeg-xl/lib/jxl/xorshift128plus-inl.h b/third_party/jpeg-xl/lib/jxl/xorshift128plus-inl.h index a473d591f2..f7967655df 100644 --- a/third_party/jpeg-xl/lib/jxl/xorshift128plus-inl.h +++ b/third_party/jpeg-xl/lib/jxl/xorshift128plus-inl.h @@ -12,8 +12,8 @@ #define LIB_JXL_XORSHIFT128PLUS_INL_H_ #endif -#include <stddef.h> - +#include <cstddef> +#include <cstdint> #include <hwy/highway.h> HWY_BEFORE_NAMESPACE(); namespace jxl { diff --git a/third_party/jpeg-xl/lib/jxl_extras.cmake b/third_party/jpeg-xl/lib/jxl_extras.cmake index 747c07eb9c..3a45d9c971 100644 --- a/third_party/jpeg-xl/lib/jxl_extras.cmake +++ b/third_party/jpeg-xl/lib/jxl_extras.cmake @@ -151,7 +151,7 @@ endif() ### Library that does not depend on internal parts of jxl library. ### Used by cjxl and djxl binaries. -add_library(jxl_extras_codec +add_library(jxl_extras_codec STATIC $<TARGET_OBJECTS:jxl_extras_core-obj> ) target_link_libraries(jxl_extras_codec PRIVATE diff --git a/third_party/jpeg-xl/lib/jxl_lists.bzl b/third_party/jpeg-xl/lib/jxl_lists.bzl index a66706aa83..41f97e4347 100644 --- a/third_party/jpeg-xl/lib/jxl_lists.bzl +++ b/third_party/jpeg-xl/lib/jxl_lists.bzl @@ -20,12 +20,14 @@ libjxl_base_sources = [ "jxl/base/fast_math-inl.h", "jxl/base/float.h", "jxl/base/iaca.h", + "jxl/base/include_jpeglib.h", "jxl/base/matrix_ops.h", "jxl/base/os_macros.h", "jxl/base/override.h", "jxl/base/printf_macros.h", "jxl/base/random.h", "jxl/base/rational_polynomial-inl.h", + "jxl/base/rect.h", "jxl/base/sanitizer_definitions.h", "jxl/base/scope_guard.h", "jxl/base/span.h", diff --git a/third_party/jpeg-xl/lib/jxl_lists.cmake b/third_party/jpeg-xl/lib/jxl_lists.cmake index d1a56f9ca8..f7e36692df 100644 --- a/third_party/jpeg-xl/lib/jxl_lists.cmake +++ b/third_party/jpeg-xl/lib/jxl_lists.cmake @@ -17,12 +17,14 @@ set(JPEGXL_INTERNAL_BASE_SOURCES jxl/base/fast_math-inl.h jxl/base/float.h jxl/base/iaca.h + jxl/base/include_jpeglib.h jxl/base/matrix_ops.h jxl/base/os_macros.h jxl/base/override.h jxl/base/printf_macros.h jxl/base/random.h jxl/base/rational_polynomial-inl.h + jxl/base/rect.h jxl/base/sanitizer_definitions.h jxl/base/scope_guard.h jxl/base/span.h diff --git a/third_party/jpeg-xl/lib/jxl_tests.cmake b/third_party/jpeg-xl/lib/jxl_tests.cmake index 64f807cb82..5613dffdde 100644 --- a/third_party/jpeg-xl/lib/jxl_tests.cmake +++ b/third_party/jpeg-xl/lib/jxl_tests.cmake @@ -46,7 +46,7 @@ if (EMSCRIPTEN) -s EXIT_RUNTIME=1 \ -s NODERAWFS=1 \ ") - if (JPEGXL_ENABLE_WASM_TRHEADS) + if (JPEGXL_ENABLE_WASM_THREADS) set(JXL_WASM_TEST_LINK_FLAGS "${JXL_WASM_TEST_LINK_FLAGS} \ -s PROXY_TO_PTHREAD \ -s USE_PTHREADS=1 \ diff --git a/third_party/jpeg-xl/lib/threads/thread_parallel_runner_test.cc b/third_party/jpeg-xl/lib/threads/thread_parallel_runner_test.cc index 0762b3299b..effe5d5feb 100644 --- a/third_party/jpeg-xl/lib/threads/thread_parallel_runner_test.cc +++ b/third_party/jpeg-xl/lib/threads/thread_parallel_runner_test.cc @@ -3,7 +3,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +#include <algorithm> #include <atomic> +#include <cstdint> +#include <vector> #include "lib/jxl/base/data_parallel.h" #include "lib/jxl/test_utils.h" |