diff options
Diffstat (limited to 'third_party/jpeg-xl/lib')
96 files changed, 756 insertions, 652 deletions
diff --git a/third_party/jpeg-xl/lib/BUILD b/third_party/jpeg-xl/lib/BUILD index d93858f22d..3d48919f77 100644 --- a/third_party/jpeg-xl/lib/BUILD +++ b/third_party/jpeg-xl/lib/BUILD @@ -3,6 +3,9 @@ # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. +load("@bazel_skylib//rules:copy_file.bzl", "copy_file") +load("@bazel_skylib//rules:expand_template.bzl", "expand_template") + # Load sources/headers/tests lists. load( "jxl_lists.bzl", @@ -57,8 +60,6 @@ load( "libjxl_test_shards", "libjxl_test_timeouts", ) -load("@bazel_skylib//rules:copy_file.bzl", "copy_file") -load("@bazel_skylib//rules:expand_template.bzl", "expand_template") DEFAULT_VISIBILITY = ["//:__subpackages__"] diff --git a/third_party/jpeg-xl/lib/CMakeLists.txt b/third_party/jpeg-xl/lib/CMakeLists.txt index 1e6f4abf74..a178e02f67 100644 --- a/third_party/jpeg-xl/lib/CMakeLists.txt +++ b/third_party/jpeg-xl/lib/CMakeLists.txt @@ -5,7 +5,7 @@ set(JPEGXL_MAJOR_VERSION 0) set(JPEGXL_MINOR_VERSION 10) -set(JPEGXL_PATCH_VERSION 0) +set(JPEGXL_PATCH_VERSION 2) set(JPEGXL_LIBRARY_VERSION "${JPEGXL_MAJOR_VERSION}.${JPEGXL_MINOR_VERSION}.${JPEGXL_PATCH_VERSION}") diff --git a/third_party/jpeg-xl/lib/extras/codec_test.cc b/third_party/jpeg-xl/lib/extras/codec_test.cc index 50d5e37bc9..1357b5a616 100644 --- a/third_party/jpeg-xl/lib/extras/codec_test.cc +++ b/third_party/jpeg-xl/lib/extras/codec_test.cc @@ -26,6 +26,7 @@ #include "lib/extras/enc/encode.h" #include "lib/extras/packed_image.h" #include "lib/jxl/base/byte_order.h" +#include "lib/jxl/base/data_parallel.h" #include "lib/jxl/base/random.h" #include "lib/jxl/base/span.h" #include "lib/jxl/base/status.h" @@ -333,10 +334,10 @@ TEST(CodecTest, TestRoundTrip) { params.add_alpha = add_alpha; params.big_endian = big_endian; params.add_extra_channels = false; - TestRoundTrip(params, &pool); + TestRoundTrip(params, pool.get()); if (codec == Codec::kPNM && add_alpha) { params.add_extra_channels = true; - TestRoundTrip(params, &pool); + TestRoundTrip(params, pool.get()); } } } @@ -369,7 +370,7 @@ TEST(CodecTest, LosslessPNMRoundtrip) { EncodedImage encoded; auto encoder = Encoder::FromExtension(extension); ASSERT_TRUE(encoder.get()); - ASSERT_TRUE(encoder->Encode(ppf, &encoded, &pool)); + ASSERT_TRUE(encoder->Encode(ppf, &encoded, pool.get())); ASSERT_EQ(encoded.bitstreams.size(), 1); ASSERT_EQ(orig.size(), encoded.bitstreams[0].size()); EXPECT_EQ(0, diff --git a/third_party/jpeg-xl/lib/extras/dec/apng.cc b/third_party/jpeg-xl/lib/extras/dec/apng.cc index 8b0da06eb1..c607a71d08 100644 --- a/third_party/jpeg-xl/lib/extras/dec/apng.cc +++ b/third_party/jpeg-xl/lib/extras/dec/apng.cc @@ -381,9 +381,11 @@ class BlobsReaderPNG { // We need 2*bytes for the hex values plus 1 byte every 36 values, // plus terminal \n for length. - const unsigned long needed_bytes = - bytes_to_decode * 2 + 1 + DivCeil(bytes_to_decode, 36); - if (needed_bytes != static_cast<size_t>(encoded_end - pos)) { + 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); } @@ -439,7 +441,7 @@ struct APNGFrame { Status Resize(size_t new_size) { if (new_size > pixels_size) { pixels.reset(malloc(new_size)); - if (!pixels.get()) { + if (!pixels) { // TODO(szabadka): use specialized OOM error code return JXL_FAILURE("Failed to allocate memory for image buffer"); } @@ -462,7 +464,7 @@ struct Reader { bool Eof() const { return next == last; } }; -const unsigned long cMaxPNGSize = 1000000UL; +const uint32_t cMaxPNGSize = 1000000UL; const size_t kMaxPNGChunkSize = 1lu << 30; // 1 GB void info_fn(png_structp png_ptr, png_infop info_ptr) { @@ -641,17 +643,17 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes, bool have_srgb = false; bool errorstate = true; if (id == kId_IHDR && chunkIHDR.size() == 25) { - unsigned int x0 = 0; - unsigned int y0 = 0; - unsigned int delay_num = 1; - unsigned int delay_den = 10; - unsigned int dop = 0; - unsigned int bop = 0; - - unsigned int w = png_get_uint_32(chunkIHDR.data() + 8); - unsigned int h = png_get_uint_32(chunkIHDR.data() + 12); - unsigned int w0 = w; - unsigned int h0 = h; + 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) { return false; } diff --git a/third_party/jpeg-xl/lib/extras/dec/pnm.cc b/third_party/jpeg-xl/lib/extras/dec/pnm.cc index 040c0bff81..e64d7e95f9 100644 --- a/third_party/jpeg-xl/lib/extras/dec/pnm.cc +++ b/third_party/jpeg-xl/lib/extras/dec/pnm.cc @@ -332,7 +332,7 @@ struct PNMChunkedInputFrame { METHOD_TO_C_CALLBACK(&PNMChunkedInputFrame::ReleaseCurrentData)}; } - void GetColorChannelsPixelFormat(JxlPixelFormat* pixel_format) { + void /* NOLINT */ GetColorChannelsPixelFormat(JxlPixelFormat* pixel_format) { *pixel_format = format; } @@ -349,12 +349,14 @@ struct PNMChunkedInputFrame { void GetExtraChannelPixelFormat(size_t ec_index, JxlPixelFormat* pixel_format) { + (void)this; JXL_ABORT("Not implemented"); } const void* GetExtraChannelDataAt(size_t ec_index, size_t xpos, size_t ypos, size_t xsize, size_t ysize, size_t* row_offset) { + (void)this; JXL_ABORT("Not implemented"); } diff --git a/third_party/jpeg-xl/lib/extras/enc/apng.cc b/third_party/jpeg-xl/lib/extras/enc/apng.cc index 40aa876e84..a28408a7f2 100644 --- a/third_party/jpeg-xl/lib/extras/enc/apng.cc +++ b/third_party/jpeg-xl/lib/extras/enc/apng.cc @@ -73,17 +73,30 @@ class APNGEncoder : public Encoder { } Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image, ThreadPool* pool) const override { + // Encode main image frames JXL_RETURN_IF_ERROR(VerifyBasicInfo(ppf.info)); encoded_image->icc.clear(); encoded_image->bitstreams.resize(1); - return EncodePackedPixelFileToAPNG(ppf, pool, - &encoded_image->bitstreams.front()); + JXL_RETURN_IF_ERROR(EncodePackedPixelFileToAPNG( + ppf, pool, &encoded_image->bitstreams.front())); + + // Encode extra channels + for (size_t i = 0; i < ppf.extra_channels_info.size(); ++i) { + encoded_image->extra_channel_bitstreams.emplace_back(); + auto& ec_bitstreams = encoded_image->extra_channel_bitstreams.back(); + ec_bitstreams.emplace_back(); + JXL_RETURN_IF_ERROR(EncodePackedPixelFileToAPNG( + ppf, pool, &ec_bitstreams.back(), true, i)); + } + return true; } private: Status EncodePackedPixelFileToAPNG(const PackedPixelFile& ppf, ThreadPool* pool, - std::vector<uint8_t>* bytes) const; + std::vector<uint8_t>* bytes, + bool encode_extra_channels = false, + size_t extra_channel_index = 0) const; }; void PngWrite(png_structp png_ptr, png_bytep data, png_size_t length) { @@ -266,15 +279,21 @@ void MaybeAddCLLi(const JxlColorEncoding& c_enc, const float intensity_target, } Status APNGEncoder::EncodePackedPixelFileToAPNG( - const PackedPixelFile& ppf, ThreadPool* pool, - std::vector<uint8_t>* bytes) const { - size_t xsize = ppf.info.xsize; - size_t ysize = ppf.info.ysize; - bool has_alpha = ppf.info.alpha_bits != 0; - bool is_gray = ppf.info.num_color_channels == 1; - size_t color_channels = ppf.info.num_color_channels; + const PackedPixelFile& ppf, ThreadPool* pool, std::vector<uint8_t>* bytes, + bool encode_extra_channels, size_t extra_channel_index) const { + JxlExtraChannelInfo ec_info{}; + if (encode_extra_channels) { + if (ppf.extra_channels_info.size() <= extra_channel_index) { + return JXL_FAILURE("Invalid index for extra channel"); + } + ec_info = ppf.extra_channels_info[extra_channel_index].ec_info; + } + + bool has_alpha = !encode_extra_channels && (ppf.info.alpha_bits != 0); + bool is_gray = encode_extra_channels || (ppf.info.num_color_channels == 1); + size_t color_channels = + encode_extra_channels ? 1 : ppf.info.num_color_channels; size_t num_channels = color_channels + (has_alpha ? 1 : 0); - size_t num_samples = num_channels * xsize * ysize; if (!ppf.info.have_animation && ppf.frames.size() != 1) { return JXL_FAILURE("Invalid number of frames"); @@ -284,9 +303,24 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG( size_t anim_chunks = 0; for (const auto& frame : ppf.frames) { - JXL_RETURN_IF_ERROR(VerifyPackedImage(frame.color, ppf.info)); - - const PackedImage& color = frame.color; + const PackedImage& color = encode_extra_channels + ? frame.extra_channels[extra_channel_index] + : frame.color; + + size_t xsize = color.xsize; + size_t ysize = color.ysize; + size_t num_samples = num_channels * xsize * ysize; + + uint32_t bits_per_sample = encode_extra_channels ? ec_info.bits_per_sample + : ppf.info.bits_per_sample; + if (!encode_extra_channels) { + JXL_RETURN_IF_ERROR(VerifyPackedImage(color, ppf.info)); + } else { + JXL_RETURN_IF_ERROR(VerifyFormat(color.format)); + JXL_RETURN_IF_ERROR(VerifyBitDepth(color.format.data_type, + bits_per_sample, + ec_info.exponent_bits_per_sample)); + } const JxlPixelFormat format = color.format; const uint8_t* in = reinterpret_cast<const uint8_t*>(color.pixels()); size_t data_bits_per_sample = PackedImage::BitsPerChannel(format.data_type); @@ -297,24 +331,23 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG( std::vector<uint8_t> out(out_size); if (format.data_type == JXL_TYPE_UINT8) { - if (ppf.info.bits_per_sample < 8) { - float mul = 255.0 / ((1u << ppf.info.bits_per_sample) - 1); + if (bits_per_sample < 8) { + float mul = 255.0 / ((1u << bits_per_sample) - 1); for (size_t i = 0; i < num_samples; ++i) { - out[i] = static_cast<uint8_t>(in[i] * mul + 0.5); + out[i] = static_cast<uint8_t>(std::lroundf(in[i] * mul)); } } else { memcpy(out.data(), in, out_size); } } else if (format.data_type == JXL_TYPE_UINT16) { - if (ppf.info.bits_per_sample < 16 || - format.endianness != JXL_BIG_ENDIAN) { - float mul = 65535.0 / ((1u << ppf.info.bits_per_sample) - 1); + if (bits_per_sample < 16 || format.endianness != JXL_BIG_ENDIAN) { + float mul = 65535.0 / ((1u << bits_per_sample) - 1); const uint8_t* p_in = in; uint8_t* p_out = out.data(); for (size_t i = 0; i < num_samples; ++i, p_in += 2, p_out += 2) { uint32_t val = (format.endianness == JXL_BIG_ENDIAN ? LoadBE16(p_in) : LoadLE16(p_in)); - StoreBE16(static_cast<uint32_t>(val * mul + 0.5), p_out); + StoreBE16(static_cast<uint32_t>(std::lroundf(val * mul)), p_out); } } else { memcpy(out.data(), in, out_size); @@ -344,7 +377,7 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG( png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - if (count == 0) { + if (count == 0 && !encode_extra_channels) { if (!MaybeAddSRGB(ppf.color_encoding, png_ptr, info_ptr)) { MaybeAddCICP(ppf.color_encoding, png_ptr, info_ptr); if (!ppf.icc.empty()) { diff --git a/third_party/jpeg-xl/lib/extras/enc/jpegli.cc b/third_party/jpeg-xl/lib/extras/enc/jpegli.cc index aa10b584d0..cb473a1290 100644 --- a/third_party/jpeg-xl/lib/extras/enc/jpegli.cc +++ b/third_party/jpeg-xl/lib/extras/enc/jpegli.cc @@ -390,7 +390,7 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings, // before the call to setjmp(). std::vector<uint8_t> pixels; unsigned char* output_buffer = nullptr; - unsigned long output_size = 0; + unsigned long output_size = 0; // NOLINT std::vector<uint8_t> row_bytes; size_t rowlen = RoundUpTo(ppf.info.xsize, MaxVectorSize()); hwy::AlignedFreeUniquePtr<float[]> xyb_tmp = diff --git a/third_party/jpeg-xl/lib/extras/enc/jpg.cc b/third_party/jpeg-xl/lib/extras/enc/jpg.cc index de0228fc0d..0095ac9294 100644 --- a/third_party/jpeg-xl/lib/extras/enc/jpg.cc +++ b/third_party/jpeg-xl/lib/extras/enc/jpg.cc @@ -276,7 +276,7 @@ Status EncodeWithLibJpeg(const PackedImage& image, const JxlBasicInfo& info, cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); unsigned char* buffer = nullptr; - unsigned long size = 0; + unsigned long size = 0; // NOLINT jpeg_mem_dest(&cinfo, &buffer, &size); cinfo.image_width = image.xsize; cinfo.image_height = image.ysize; diff --git a/third_party/jpeg-xl/lib/extras/enc/pnm.cc b/third_party/jpeg-xl/lib/extras/enc/pnm.cc index 966611cfca..d2d67ae52a 100644 --- a/third_party/jpeg-xl/lib/extras/enc/pnm.cc +++ b/third_party/jpeg-xl/lib/extras/enc/pnm.cc @@ -87,8 +87,8 @@ class PNMEncoder : public BasePNMEncoder { } private: - Status EncodeImage(const PackedImage& image, size_t bits_per_sample, - std::vector<uint8_t>* bytes) const { + static Status EncodeImage(const PackedImage& image, size_t bits_per_sample, + std::vector<uint8_t>* bytes) { uint32_t maxval = (1u << bits_per_sample) - 1; char type = image.format.num_channels == 1 ? '5' : '6'; char header[kMaxHeaderSize]; @@ -161,8 +161,8 @@ class PFMEncoder : public BasePNMEncoder { } private: - Status EncodeImage(const PackedImage& image, - std::vector<uint8_t>* bytes) const { + static Status EncodeImage(const PackedImage& image, + std::vector<uint8_t>* bytes) { char type = image.format.num_channels == 1 ? 'f' : 'F'; double scale = image.format.endianness == JXL_LITTLE_ENDIAN ? -1.0 : 1.0; char header[kMaxHeaderSize]; diff --git a/third_party/jpeg-xl/lib/extras/mmap.h b/third_party/jpeg-xl/lib/extras/mmap.h index 8bc023dec0..60cc215993 100644 --- a/third_party/jpeg-xl/lib/extras/mmap.h +++ b/third_party/jpeg-xl/lib/extras/mmap.h @@ -18,10 +18,10 @@ class MemoryMappedFile { static StatusOr<MemoryMappedFile> Init(const char* path); const uint8_t* data() const; size_t size() const; - MemoryMappedFile(); - ~MemoryMappedFile(); - MemoryMappedFile(MemoryMappedFile&&) noexcept; - MemoryMappedFile& operator=(MemoryMappedFile&&) noexcept; + MemoryMappedFile(); // NOLINT + ~MemoryMappedFile(); // NOLINT + MemoryMappedFile(MemoryMappedFile&&) noexcept; // NOLINT + MemoryMappedFile& operator=(MemoryMappedFile&&) noexcept; // NOLINT private: std::unique_ptr<MemoryMappedFileImpl> impl_; diff --git a/third_party/jpeg-xl/lib/jpegli/color_transform.cc b/third_party/jpeg-xl/lib/jpegli/color_transform.cc index 020a6fd80c..60a0dc83bb 100644 --- a/third_party/jpeg-xl/lib/jpegli/color_transform.cc +++ b/third_party/jpeg-xl/lib/jpegli/color_transform.cc @@ -135,19 +135,25 @@ bool CheckColorSpaceComponents(int num_components, J_COLOR_SPACE colorspace) { return num_components == 1; case JCS_RGB: case JCS_YCbCr: +#ifdef JCS_EXTENSIONS case JCS_EXT_RGB: case JCS_EXT_BGR: +#endif return num_components == 3; 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 return num_components == 4; default: // Unrecognized colorspaces can have any number of channels, since no diff --git a/third_party/jpeg-xl/lib/jpegli/decode.h b/third_party/jpeg-xl/lib/jpegli/decode.h index 9800ebf67a..f5b099eda3 100644 --- a/third_party/jpeg-xl/lib/jpegli/decode.h +++ b/third_party/jpeg-xl/lib/jpegli/decode.h @@ -36,7 +36,7 @@ void jpegli_CreateDecompress(j_decompress_ptr cinfo, int version, void jpegli_stdio_src(j_decompress_ptr cinfo, FILE *infile); void jpegli_mem_src(j_decompress_ptr cinfo, const unsigned char *inbuffer, - unsigned long insize); + unsigned long insize /* NOLINT */); int jpegli_read_header(j_decompress_ptr cinfo, boolean require_image); 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 0cc5a194d7..3ecd479951 100644 --- a/third_party/jpeg-xl/lib/jpegli/decode_api_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/decode_api_test.cc @@ -3,8 +3,8 @@ // 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 <cstdio> #include <vector> #include "lib/jpegli/decode.h" @@ -78,7 +78,8 @@ class SourceManager { return TRUE; } - static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) { + static void skip_input_data(j_decompress_ptr cinfo, + long num_bytes /* NOLINT */) { auto* src = reinterpret_cast<SourceManager*>(cinfo->src); if (num_bytes <= 0) { return; @@ -447,7 +448,7 @@ std::vector<TestConfig> GenerateBasicConfigs() { TEST(DecodeAPITest, ReuseCinfoSameMemSource) { std::vector<TestConfig> all_configs = GenerateBasicConfigs(); uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT { jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { @@ -502,7 +503,7 @@ TEST(DecodeAPITest, ReuseCinfoSameStdSource) { EXPECT_TRUE(try_catch_block()); jpegli_destroy_compress(&cinfo); } - rewind(tmpf); + fseek(tmpf, 0, SEEK_SET); std::vector<TestImage> all_outputs(all_configs.size()); { jpeg_decompress_struct cinfo; @@ -527,9 +528,9 @@ TEST(DecodeAPITest, ReuseCinfoSameStdSource) { TEST(DecodeAPITest, AbbreviatedStreams) { uint8_t* table_stream = nullptr; - unsigned long table_stream_size = 0; + unsigned long table_stream_size = 0; // NOLINT uint8_t* data_stream = nullptr; - unsigned long data_stream_size = 0; + unsigned long data_stream_size = 0; // NOLINT { jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { diff --git a/third_party/jpeg-xl/lib/jpegli/destination_manager.cc b/third_party/jpeg-xl/lib/jpegli/destination_manager.cc index 6548130866..05d35797b8 100644 --- a/third_party/jpeg-xl/lib/jpegli/destination_manager.cc +++ b/third_party/jpeg-xl/lib/jpegli/destination_manager.cc @@ -52,7 +52,7 @@ struct MemoryDestinationManager { jpeg_destination_mgr pub; // Output buffer supplied by the application uint8_t** output; - unsigned long* output_size; + unsigned long* output_size; // NOLINT // Output buffer allocated by us. uint8_t* temp_buffer; // Current output buffer (either application supplied or allocated by us). @@ -113,7 +113,7 @@ void jpegli_stdio_dest(j_compress_ptr cinfo, FILE* outfile) { } void jpegli_mem_dest(j_compress_ptr cinfo, unsigned char** outbuffer, - unsigned long* outsize) { + unsigned long* outsize /* NOLINT */) { if (outbuffer == nullptr || outsize == nullptr) { JPEGLI_ERROR("jpegli_mem_dest: Invalid destination."); } diff --git a/third_party/jpeg-xl/lib/jpegli/encode.h b/third_party/jpeg-xl/lib/jpegli/encode.h index 320dfaaf8d..ed34838450 100644 --- a/third_party/jpeg-xl/lib/jpegli/encode.h +++ b/third_party/jpeg-xl/lib/jpegli/encode.h @@ -35,7 +35,7 @@ void jpegli_CreateCompress(j_compress_ptr cinfo, int version, void jpegli_stdio_dest(j_compress_ptr cinfo, FILE* outfile); void jpegli_mem_dest(j_compress_ptr cinfo, unsigned char** outbuffer, - unsigned long* outsize); + unsigned long* outsize /* NOLINT */); void jpegli_set_defaults(j_compress_ptr cinfo); 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 1afdcf610d..2978b3f35d 100644 --- a/third_party/jpeg-xl/lib/jpegli/encode_api_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/encode_api_test.cc @@ -69,7 +69,7 @@ TEST(EncodeAPITest, ReuseCinfoSameImageTwice) { CompressParams jparams; GenerateInput(PIXELS, jparams, &input); uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT std::vector<uint8_t> compressed0; std::vector<uint8_t> compressed1; jpeg_compress_struct cinfo; @@ -117,7 +117,7 @@ std::vector<TestConfig> GenerateBasicConfigs() { TEST(EncodeAPITest, ReuseCinfoSameMemOutput) { std::vector<TestConfig> all_configs = GenerateBasicConfigs(); uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT { jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { @@ -161,7 +161,7 @@ TEST(EncodeAPITest, ReuseCinfoSameStdOutput) { jpegli_destroy_compress(&cinfo); } size_t total_size = ftell(tmpf); - rewind(tmpf); + fseek(tmpf, 0, SEEK_SET); std::vector<uint8_t> compressed(total_size); JXL_CHECK(total_size == fread(compressed.data(), 1, total_size, tmpf)); fclose(tmpf); @@ -181,7 +181,7 @@ TEST(EncodeAPITest, ReuseCinfoChangeParams) { CompressParams jparams; DecompressParams dparams; uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT std::vector<uint8_t> compressed; jpeg_compress_struct cinfo; const auto max_rms = [](int q, int hs, int vs) { @@ -246,9 +246,9 @@ TEST(EncodeAPITest, ReuseCinfoChangeParams) { TEST(EncodeAPITest, AbbreviatedStreams) { uint8_t* table_stream = nullptr; - unsigned long table_stream_size = 0; + unsigned long table_stream_size = 0; // NOLINT uint8_t* data_stream = nullptr; - unsigned long data_stream_size = 0; + unsigned long data_stream_size = 0; // NOLINT { jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { 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 3eaf6a313b..bcd7355124 100644 --- a/third_party/jpeg-xl/lib/jpegli/error_handling_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/error_handling_test.cc @@ -15,7 +15,7 @@ namespace { TEST(EncoderErrorHandlingTest, MinimalSuccess) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT { jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { @@ -64,7 +64,7 @@ TEST(EncoderErrorHandlingTest, NoDestination) { TEST(EncoderErrorHandlingTest, NoImageDimensions) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -82,7 +82,7 @@ TEST(EncoderErrorHandlingTest, NoImageDimensions) { TEST(EncoderErrorHandlingTest, ImageTooBig) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -102,7 +102,7 @@ TEST(EncoderErrorHandlingTest, ImageTooBig) { TEST(EncoderErrorHandlingTest, NoInputComponents) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -121,7 +121,7 @@ TEST(EncoderErrorHandlingTest, NoInputComponents) { TEST(EncoderErrorHandlingTest, TooManyInputComponents) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -141,7 +141,7 @@ TEST(EncoderErrorHandlingTest, TooManyInputComponents) { TEST(EncoderErrorHandlingTest, NoSetDefaults) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -164,7 +164,7 @@ TEST(EncoderErrorHandlingTest, NoSetDefaults) { TEST(EncoderErrorHandlingTest, NoStartCompress) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -186,7 +186,7 @@ TEST(EncoderErrorHandlingTest, NoStartCompress) { TEST(EncoderErrorHandlingTest, NoWriteScanlines) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -207,7 +207,7 @@ TEST(EncoderErrorHandlingTest, NoWriteScanlines) { TEST(EncoderErrorHandlingTest, NoWriteAllScanlines) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -231,7 +231,7 @@ TEST(EncoderErrorHandlingTest, NoWriteAllScanlines) { TEST(EncoderErrorHandlingTest, InvalidQuantValue) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -260,7 +260,7 @@ TEST(EncoderErrorHandlingTest, InvalidQuantValue) { TEST(EncoderErrorHandlingTest, InvalidQuantTableIndex) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -285,7 +285,7 @@ TEST(EncoderErrorHandlingTest, InvalidQuantTableIndex) { TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch1) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -306,7 +306,7 @@ TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch1) { TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch2) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -327,7 +327,7 @@ TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch2) { TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch3) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -353,7 +353,7 @@ TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch3) { TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch4) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -378,7 +378,7 @@ TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch4) { TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch5) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -403,7 +403,7 @@ TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch5) { TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch6) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -429,7 +429,7 @@ TEST(EncoderErrorHandlingTest, NumberOfComponentsMismatch6) { TEST(EncoderErrorHandlingTest, InvalidColorTransform) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -455,7 +455,7 @@ TEST(EncoderErrorHandlingTest, InvalidColorTransform) { TEST(EncoderErrorHandlingTest, DuplicateComponentIds) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -477,7 +477,7 @@ TEST(EncoderErrorHandlingTest, DuplicateComponentIds) { TEST(EncoderErrorHandlingTest, InvalidComponentIndex) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -498,7 +498,7 @@ TEST(EncoderErrorHandlingTest, InvalidComponentIndex) { TEST(EncoderErrorHandlingTest, ArithmeticCoding) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -519,7 +519,7 @@ TEST(EncoderErrorHandlingTest, ArithmeticCoding) { TEST(EncoderErrorHandlingTest, CCIR601Sampling) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -540,7 +540,7 @@ TEST(EncoderErrorHandlingTest, CCIR601Sampling) { TEST(EncoderErrorHandlingTest, InvalidScanScript1) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -563,7 +563,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript1) { TEST(EncoderErrorHandlingTest, InvalidScanScript2) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -586,7 +586,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript2) { TEST(EncoderErrorHandlingTest, InvalidScanScript3) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -609,7 +609,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript3) { TEST(EncoderErrorHandlingTest, InvalidScanScript4) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -632,7 +632,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript4) { TEST(EncoderErrorHandlingTest, InvalidScanScript5) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -655,7 +655,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript5) { TEST(EncoderErrorHandlingTest, InvalidScanScript6) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -678,7 +678,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript6) { TEST(EncoderErrorHandlingTest, InvalidScanScript7) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -701,7 +701,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript7) { TEST(EncoderErrorHandlingTest, InvalidScanScript8) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -726,7 +726,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript8) { TEST(EncoderErrorHandlingTest, InvalidScanScript9) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -751,7 +751,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript9) { TEST(EncoderErrorHandlingTest, InvalidScanScript10) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -776,7 +776,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript10) { TEST(EncoderErrorHandlingTest, InvalidScanScript11) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -801,7 +801,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript11) { TEST(EncoderErrorHandlingTest, InvalidScanScript12) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -826,7 +826,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript12) { TEST(EncoderErrorHandlingTest, InvalidScanScript13) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -854,7 +854,7 @@ TEST(EncoderErrorHandlingTest, InvalidScanScript13) { TEST(EncoderErrorHandlingTest, MCUSizeTooBig) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -877,7 +877,7 @@ TEST(EncoderErrorHandlingTest, MCUSizeTooBig) { TEST(EncoderErrorHandlingTest, RestartIntervalTooBig) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -898,7 +898,7 @@ TEST(EncoderErrorHandlingTest, RestartIntervalTooBig) { TEST(EncoderErrorHandlingTest, SamplingFactorTooBig) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); @@ -919,7 +919,7 @@ TEST(EncoderErrorHandlingTest, SamplingFactorTooBig) { TEST(EncoderErrorHandlingTest, NonIntegralSamplingRatio) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); 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 eb8b7ebc26..6546b7b087 100644 --- a/third_party/jpeg-xl/lib/jpegli/input_suspension_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/input_suspension_test.cc @@ -80,7 +80,8 @@ struct SourceManager { static boolean fill_input_buffer(j_decompress_ptr cinfo) { return FALSE; } - static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) { + static void skip_input_data(j_decompress_ptr cinfo, + long num_bytes /* NOLINT*/) { auto* src = reinterpret_cast<SourceManager*>(cinfo->src); if (num_bytes <= 0) { return; diff --git a/third_party/jpeg-xl/lib/jpegli/libjpeg_wrapper.cc b/third_party/jpeg-xl/lib/jpegli/libjpeg_wrapper.cc index 471b7c7192..a2b333afef 100644 --- a/third_party/jpeg-xl/lib/jpegli/libjpeg_wrapper.cc +++ b/third_party/jpeg-xl/lib/jpegli/libjpeg_wrapper.cc @@ -38,7 +38,7 @@ void jpeg_stdio_src(j_decompress_ptr cinfo, FILE *infile) { } void jpeg_mem_src(j_decompress_ptr cinfo, const unsigned char *inbuffer, - unsigned long insize) { + unsigned long insize /* NOLINT */) { jpegli_mem_src(cinfo, inbuffer, insize); } @@ -138,7 +138,7 @@ void jpeg_stdio_dest(j_compress_ptr cinfo, FILE *outfile) { } void jpeg_mem_dest(j_compress_ptr cinfo, unsigned char **outbuffer, - unsigned long *outsize) { + unsigned long *outsize /* NOLINT */) { jpegli_mem_dest(cinfo, outbuffer, outsize); } diff --git a/third_party/jpeg-xl/lib/jpegli/source_manager.cc b/third_party/jpeg-xl/lib/jpegli/source_manager.cc index 58adf803b1..e0f0b4c275 100644 --- a/third_party/jpeg-xl/lib/jpegli/source_manager.cc +++ b/third_party/jpeg-xl/lib/jpegli/source_manager.cc @@ -12,9 +12,10 @@ namespace jpegli { void init_mem_source(j_decompress_ptr cinfo) {} void init_stdio_source(j_decompress_ptr cinfo) {} -void skip_input_data(j_decompress_ptr cinfo, long num_bytes) { +void skip_input_data(j_decompress_ptr cinfo, long num_bytes /* NOLINT */) { if (num_bytes <= 0) return; - while (num_bytes > static_cast<long>(cinfo->src->bytes_in_buffer)) { + while (num_bytes > + static_cast<long>(cinfo->src->bytes_in_buffer)) { // NOLINT num_bytes -= cinfo->src->bytes_in_buffer; (*cinfo->src->fill_input_buffer)(cinfo); } @@ -53,7 +54,7 @@ struct StdioSourceManager { } // namespace jpegli void jpegli_mem_src(j_decompress_ptr cinfo, const unsigned char* inbuffer, - unsigned long insize) { + unsigned long insize /* NOLINT */) { if (cinfo->src && cinfo->src->init_source != jpegli::init_mem_source) { JPEGLI_ERROR("jpegli_mem_src: a different source manager was already set"); } 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 59d12b001b..a513b7063b 100644 --- a/third_party/jpeg-xl/lib/jpegli/source_manager_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/source_manager_test.cc @@ -43,7 +43,7 @@ FILE* MemOpen(const std::vector<uint8_t>& data) { FILE* src = tmpfile(); if (!src) return nullptr; fwrite(data.data(), 1, data.size(), src); - rewind(src); + fseek(src, 0, SEEK_SET); return src; } } // namespace diff --git a/third_party/jpeg-xl/lib/jpegli/streaming_test.cc b/third_party/jpeg-xl/lib/jpegli/streaming_test.cc index 2e6f7029b0..1f19dc2045 100644 --- a/third_party/jpeg-xl/lib/jpegli/streaming_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/streaming_test.cc @@ -28,7 +28,8 @@ struct SourceManager { static void init_source(j_decompress_ptr cinfo) {} static boolean fill_input_buffer(j_decompress_ptr cinfo) { return FALSE; } - static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) {} + static void skip_input_data(j_decompress_ptr cinfo, + long num_bytes /* NOLINT */) {} static void term_source(j_decompress_ptr cinfo) {} }; diff --git a/third_party/jpeg-xl/lib/jpegli/test_utils.cc b/third_party/jpeg-xl/lib/jpegli/test_utils.cc index 4e675070cf..db5a30e8dc 100644 --- a/third_party/jpeg-xl/lib/jpegli/test_utils.cc +++ b/third_party/jpeg-xl/lib/jpegli/test_utils.cc @@ -673,7 +673,7 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams, bool EncodeWithJpegli(const TestImage& input, const CompressParams& jparams, std::vector<uint8_t>* compressed) { uint8_t* buffer = nullptr; - unsigned long buffer_size = 0; + unsigned long buffer_size = 0; // NOLINT jpeg_compress_struct cinfo; const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); 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 1d99ce37fa..13c81a1119 100644 --- a/third_party/jpeg-xl/lib/jpegli/transcode_api_test.cc +++ b/third_party/jpeg-xl/lib/jpegli/transcode_api_test.cc @@ -20,7 +20,7 @@ void TranscodeWithJpegli(const std::vector<uint8_t>& jpeg_input, jpeg_decompress_struct dinfo = {}; jpeg_compress_struct cinfo = {}; uint8_t* transcoded_data = nullptr; - unsigned long transcoded_size; + unsigned long transcoded_size; // NOLINT const auto try_catch_block = [&]() -> bool { ERROR_HANDLER_SETUP(jpegli); dinfo.err = cinfo.err; diff --git a/third_party/jpeg-xl/lib/jxl.cmake b/third_party/jpeg-xl/lib/jxl.cmake index 86fa37151d..82a2716978 100644 --- a/third_party/jpeg-xl/lib/jxl.cmake +++ b/third_party/jpeg-xl/lib/jxl.cmake @@ -80,10 +80,10 @@ foreach(path ${JPEGXL_INTERNAL_PUBLIC_HEADERS}) endforeach() add_library(jxl_base INTERFACE) -target_include_directories(jxl_base SYSTEM INTERFACE +target_include_directories(jxl_base SYSTEM BEFORE INTERFACE "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>" ) -target_include_directories(jxl_base INTERFACE +target_include_directories(jxl_base BEFORE INTERFACE ${PROJECT_SOURCE_DIR} ${JXL_HWY_INCLUDE_DIRS} ) @@ -104,7 +104,7 @@ add_library(jxl_dec-obj OBJECT ${JPEGXL_INTERNAL_DEC_SOURCES}) target_compile_options(jxl_dec-obj PRIVATE ${JPEGXL_INTERNAL_FLAGS}) target_compile_options(jxl_dec-obj PUBLIC ${JPEGXL_COVERAGE_FLAGS}) set_property(TARGET jxl_dec-obj PROPERTY POSITION_INDEPENDENT_CODE ON) -target_include_directories(jxl_dec-obj PUBLIC +target_include_directories(jxl_dec-obj BEFORE PUBLIC "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>" "${JXL_HWY_INCLUDE_DIRS}" "$<BUILD_INTERFACE:$<TARGET_PROPERTY:brotlicommon,INTERFACE_INCLUDE_DIRECTORIES>>" @@ -119,7 +119,7 @@ add_library(jxl_enc-obj OBJECT ${JPEGXL_INTERNAL_ENC_SOURCES}) target_compile_options(jxl_enc-obj PRIVATE ${JPEGXL_INTERNAL_FLAGS}) target_compile_options(jxl_enc-obj PUBLIC ${JPEGXL_COVERAGE_FLAGS}) set_property(TARGET jxl_enc-obj PROPERTY POSITION_INDEPENDENT_CODE ON) -target_include_directories(jxl_enc-obj PUBLIC +target_include_directories(jxl_enc-obj BEFORE PUBLIC ${PROJECT_SOURCE_DIR} ${JXL_HWY_INCLUDE_DIRS} $<TARGET_PROPERTY:brotlicommon,INTERFACE_INCLUDE_DIRECTORIES> @@ -172,7 +172,7 @@ target_link_libraries(jxl-internal PUBLIC jxl_cms jxl_base ) -target_include_directories(jxl-internal PUBLIC +target_include_directories(jxl-internal BEFORE PUBLIC "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>") target_compile_definitions(jxl-internal INTERFACE -DJXL_STATIC_DEFINE) diff --git a/third_party/jpeg-xl/lib/jxl/alpha_test.cc b/third_party/jpeg-xl/lib/jxl/alpha_test.cc index a93254f3dd..6e26e77be6 100644 --- a/third_party/jpeg-xl/lib/jxl/alpha_test.cc +++ b/third_party/jpeg-xl/lib/jxl/alpha_test.cc @@ -13,6 +13,16 @@ namespace jxl { namespace { +AlphaBlendingInputLayer makeAbil(const Color& rgb, const float& a) { + const float* data = rgb.data(); + return {data, data + 1, data + 2, &a}; +} + +AlphaBlendingOutput makeAbo(Color& rgb, float& a) { + float* data = rgb.data(); + return {data, data + 1, data + 2, &a}; +} + TEST(AlphaTest, BlendingWithNonPremultiplied) { const Color bg_rgb{100, 110, 120}; const float bg_a = 180.f / 255; @@ -22,16 +32,16 @@ TEST(AlphaTest, BlendingWithNonPremultiplied) { Color out_rgb; float out_a; PerformAlphaBlending( - /*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a}, - /*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a}, - /*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1, + /*bg=*/makeAbil(bg_rgb, bg_a), + /*fg=*/makeAbil(fg_rgb, fg_a), + /*out=*/makeAbo(out_rgb, out_a), 1, /*alpha_is_premultiplied=*/false, /*clamp=*/false); EXPECT_ARRAY_NEAR(out_rgb, (Color{77.2f, 83.0f, 90.6f}), 0.05f); EXPECT_NEAR(out_a, 3174.f / 4095, 1e-5); PerformAlphaBlending( - /*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a}, - /*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a2}, - /*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1, + /*bg=*/makeAbil(bg_rgb, bg_a), + /*fg=*/makeAbil(fg_rgb, fg_a2), + /*out=*/makeAbo(out_rgb, out_a), 1, /*alpha_is_premultiplied=*/false, /*clamp=*/true); EXPECT_ARRAY_NEAR(out_rgb, fg_rgb, 0.05f); EXPECT_NEAR(out_a, 1.0f, 1e-5); @@ -46,16 +56,16 @@ TEST(AlphaTest, BlendingWithPremultiplied) { Color out_rgb; float out_a; PerformAlphaBlending( - /*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a}, - /*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a}, - /*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1, + /*bg=*/makeAbil(bg_rgb, bg_a), + /*fg=*/makeAbil(fg_rgb, fg_a), + /*out=*/makeAbo(out_rgb, out_a), 1, /*alpha_is_premultiplied=*/true, /*clamp=*/false); EXPECT_ARRAY_NEAR(out_rgb, (Color{101.5f, 105.1f, 114.8f}), 0.05f); EXPECT_NEAR(out_a, 3174.f / 4095, 1e-5); PerformAlphaBlending( - /*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a}, - /*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a2}, - /*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1, + /*bg=*/makeAbil(bg_rgb, bg_a), + /*fg=*/makeAbil(fg_rgb, fg_a2), + /*out=*/makeAbo(out_rgb, out_a), 1, /*alpha_is_premultiplied=*/true, /*clamp=*/true); EXPECT_ARRAY_NEAR(out_rgb, fg_rgb, 0.05f); EXPECT_NEAR(out_a, 1.0f, 1e-5); 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 22a20649e0..802da855fa 100644 --- a/third_party/jpeg-xl/lib/jxl/bit_reader_test.cc +++ b/third_party/jpeg-xl/lib/jxl/bit_reader_test.cc @@ -53,7 +53,7 @@ struct Symbol { TEST(BitReaderTest, TestRoundTrip) { test::ThreadPoolForTests pool(8); EXPECT_TRUE(RunOnPool( - &pool, 0, 1000, ThreadPool::NoInit, + pool.get(), 0, 1000, ThreadPool::NoInit, [](const uint32_t task, size_t /* thread */) { constexpr size_t kMaxBits = 8000; BitWriter writer; @@ -87,7 +87,7 @@ TEST(BitReaderTest, TestRoundTrip) { TEST(BitReaderTest, TestSkip) { test::ThreadPoolForTests pool(8); EXPECT_TRUE(RunOnPool( - &pool, 0, 96, ThreadPool::NoInit, + pool.get(), 0, 96, ThreadPool::NoInit, [](const uint32_t task, size_t /* thread */) { constexpr size_t kSize = 100; diff --git a/third_party/jpeg-xl/lib/jxl/butteraugli/butteraugli.h b/third_party/jpeg-xl/lib/jxl/butteraugli/butteraugli.h index e0bfd354e1..487db2bdce 100644 --- a/third_party/jpeg-xl/lib/jxl/butteraugli/butteraugli.h +++ b/third_party/jpeg-xl/lib/jxl/butteraugli/butteraugli.h @@ -8,12 +8,10 @@ #ifndef LIB_JXL_BUTTERAUGLI_BUTTERAUGLI_H_ #define LIB_JXL_BUTTERAUGLI_BUTTERAUGLI_H_ -#include <stdint.h> #include <stdlib.h> #include <string.h> #include <atomic> -#include <cmath> #include <cstddef> #include <memory> @@ -21,7 +19,10 @@ #include "lib/jxl/base/status.h" #include "lib/jxl/image.h" +#if !defined(BUTTERAUGLI_ENABLE_CHECKS) #define BUTTERAUGLI_ENABLE_CHECKS 0 +#endif + #define BUTTERAUGLI_RESTRICT JXL_RESTRICT // This is the main interface to butteraugli image similarity diff --git a/third_party/jpeg-xl/lib/jxl/cache_aligned.cc b/third_party/jpeg-xl/lib/jxl/cache_aligned.cc index 8a95634d68..814b538cf6 100644 --- a/third_party/jpeg-xl/lib/jxl/cache_aligned.cc +++ b/third_party/jpeg-xl/lib/jxl/cache_aligned.cc @@ -128,11 +128,12 @@ void* CacheAligned::Allocate(const size_t payload_size, size_t offset) { const uintptr_t payload = aligned + offset; // still aligned // Stash `allocated` and payload_size inside header for use by Free(). - AllocationHeader* header = reinterpret_cast<AllocationHeader*>(payload) - 1; + AllocationHeader* header = + reinterpret_cast<AllocationHeader*>(payload) - 1; // NOLINT header->allocated = allocated; header->allocated_size = allocated_size; - return JXL_ASSUME_ALIGNED(reinterpret_cast<void*>(payload), 64); + return JXL_ASSUME_ALIGNED(reinterpret_cast<void*>(payload), 64); // NOLINT } void CacheAligned::Free(const void* aligned_pointer) { @@ -142,7 +143,7 @@ void CacheAligned::Free(const void* aligned_pointer) { const uintptr_t payload = reinterpret_cast<uintptr_t>(aligned_pointer); JXL_ASSERT(payload % kAlignment == 0); const AllocationHeader* header = - reinterpret_cast<const AllocationHeader*>(payload) - 1; + reinterpret_cast<const AllocationHeader*>(payload) - 1; // NOLINT // Subtract (2's complement negation). bytes_in_use.fetch_add(~header->allocated_size + 1, 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 7f59e688d0..a787bd11d8 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 @@ -183,12 +183,12 @@ static Status ToneMapPixel(const JxlColorEncoding& c, const float in[3], const float f_y = lab_f(xyz[1] / kYn); const float f_z = lab_f(xyz[2] / kZn); - pcslab_out[0] = - static_cast<uint8_t>(.5f + 255.f * Clamp1(1.16f * f_y - .16f, 0.f, 1.f)); + pcslab_out[0] = static_cast<uint8_t>( + std::lroundf(255.f * Clamp1(1.16f * f_y - .16f, 0.f, 1.f))); pcslab_out[1] = static_cast<uint8_t>( - .5f + 128.f + Clamp1(500 * (f_x - f_y), -128.f, 127.f)); + std::lroundf(128.f + Clamp1(500 * (f_x - f_y), -128.f, 127.f))); pcslab_out[2] = static_cast<uint8_t>( - .5f + 128.f + Clamp1(200 * (f_y - f_z), -128.f, 127.f)); + std::lroundf(128.f + Clamp1(200 * (f_y - f_z), -128.f, 127.f))); return true; } @@ -581,7 +581,8 @@ static void CreateICCCurvCurvTag(const std::vector<uint16_t>& curve, } // Writes 12 + 4*params.size() bytes -static Status CreateICCCurvParaTag(std::vector<float> params, size_t curve_type, +static Status CreateICCCurvParaTag(const std::vector<float>& params, + size_t curve_type, std::vector<uint8_t>* tags) { WriteICCTag("para", tags->size(), tags); WriteICCUint32(0, tags->size(), tags); @@ -637,7 +638,7 @@ static Status CreateICCLutAtoBTagForXYB(std::vector<uint8_t>* tags) { for (size_t ib = 0; ib < 2; ++ib) { const jxl::cms::ColorCube0D& out_f = cube[ix][iy][ib]; for (int i = 0; i < 3; ++i) { - int32_t val = static_cast<int32_t>(0.5f + 65535 * out_f[i]); + int32_t val = static_cast<int32_t>(std::lroundf(65535 * out_f[i])); JXL_DASSERT(val >= 0 && val <= 65535); WriteICCUint16(val, tags->size(), tags); } 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 81f301a31d..1f85dcca41 100644 --- a/third_party/jpeg-xl/lib/jxl/cms/tone_mapping.h +++ b/third_party/jpeg-xl/lib/jxl/cms/tone_mapping.h @@ -22,8 +22,8 @@ class Rec2408ToneMapperBase { explicit Rec2408ToneMapperBase(std::pair<float, float> source_range, std::pair<float, float> target_range, const Vector3& primaries_luminances) - : source_range_(source_range), - target_range_(target_range), + : source_range_(std::move(source_range)), + target_range_(std::move(target_range)), red_Y_(primaries_luminances[0]), green_Y_(primaries_luminances[1]), blue_Y_(primaries_luminances[2]) {} @@ -56,7 +56,7 @@ class Rec2408ToneMapperBase { } protected: - float InvEOTF(const float luminance) const { + static float InvEOTF(const float luminance) { return TF_PQ_Base::EncodedFromDisplay(/*display_intensity_target=*/1.0, luminance); } diff --git a/third_party/jpeg-xl/lib/jxl/cms/transfer_functions-inl.h b/third_party/jpeg-xl/lib/jxl/cms/transfer_functions-inl.h index 84bcbb45ed..133e624c08 100644 --- a/third_party/jpeg-xl/lib/jxl/cms/transfer_functions-inl.h +++ b/third_party/jpeg-xl/lib/jxl/cms/transfer_functions-inl.h @@ -69,7 +69,7 @@ class TF_HLG : TF_HLG_Base { class TF_709 { public: - JXL_INLINE double EncodedFromDisplay(const double d) const { + static JXL_INLINE double EncodedFromDisplay(const double d) { if (d < kThresh) return kMulLow * d; return kMulHi * std::pow(d, kPowHi) + kSub; } 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 b2d47c73f9..77cbe56926 100644 --- a/third_party/jpeg-xl/lib/jxl/color_management_test.cc +++ b/third_party/jpeg-xl/lib/jxl/color_management_test.cc @@ -434,7 +434,7 @@ TEST_F(ColorManagementTest, GoldenXYBCube) { for (size_t ib = 0; ib < 2; ++ib) { const jxl::cms::ColorCube0D& out_f = cube[ix][iy][ib]; for (int i = 0; i < 3; ++i) { - int32_t val = static_cast<int32_t>(0.5f + 65535 * out_f[i]); + int32_t val = static_cast<int32_t>(std::lroundf(65535 * out_f[i])); ASSERT_TRUE(val >= 0 && val <= 65535); actual.push_back(val); } diff --git a/third_party/jpeg-xl/lib/jxl/convolve_test.cc b/third_party/jpeg-xl/lib/jxl/convolve_test.cc index 09cbdc12a6..084398c5e1 100644 --- a/third_party/jpeg-xl/lib/jxl/convolve_test.cc +++ b/third_party/jpeg-xl/lib/jxl/convolve_test.cc @@ -161,7 +161,7 @@ void TestConvolve() { test::ThreadPoolForTests pool(4); EXPECT_EQ(true, RunOnPool( - &pool, kConvolveMaxRadius, 40, ThreadPool::NoInit, + pool.get(), kConvolveMaxRadius, 40, ThreadPool::NoInit, [](const uint32_t task, size_t /*thread*/) { const size_t xsize = task; Rng rng(129 + 13 * xsize); @@ -176,15 +176,15 @@ void TestConvolve() { JXL_DEBUG(JXL_DEBUG_CONVOLVE, "Sym3------------------"); VerifySymmetric3(xsize, ysize, null_pool, &rng); - VerifySymmetric3(xsize, ysize, &pool3, &rng); + VerifySymmetric3(xsize, ysize, pool3.get(), &rng); JXL_DEBUG(JXL_DEBUG_CONVOLVE, "Sym5------------------"); VerifySymmetric5(xsize, ysize, null_pool, &rng); - VerifySymmetric5(xsize, ysize, &pool3, &rng); + VerifySymmetric5(xsize, ysize, pool3.get(), &rng); JXL_DEBUG(JXL_DEBUG_CONVOLVE, "Sep5------------------"); VerifySeparable5(xsize, ysize, null_pool, &rng); - VerifySeparable5(xsize, ysize, &pool3, &rng); + VerifySeparable5(xsize, ysize, pool3.get(), &rng); } }, "TestConvolve")); 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 58dd75e20e..b0cbffacad 100644 --- a/third_party/jpeg-xl/lib/jxl/dct_for_test.h +++ b/third_party/jpeg-xl/lib/jxl/dct_for_test.h @@ -22,7 +22,7 @@ static inline double alpha(int u) { return u == 0 ? 0.7071067811865475 : 1.0; } // N-DCT on M columns, divided by sqrt(N). Matches the definition in the spec. template <size_t N, size_t M> -void DCT1D(double block[N * M], double out[N * M]) { +void DCT1D(const double block[N * M], double out[N * M]) { std::vector<double> matrix(N * N); const double scale = std::sqrt(2.0) / N; for (size_t y = 0; y < N; y++) { @@ -43,7 +43,7 @@ void DCT1D(double block[N * M], double out[N * M]) { // N-IDCT on M columns, multiplied by sqrt(N). Matches the definition in the // spec. template <size_t N, size_t M> -void IDCT1D(double block[N * M], double out[N * M]) { +void IDCT1D(const double block[N * M], double out[N * M]) { std::vector<double> matrix(N * N); const double scale = std::sqrt(2.0); for (size_t y = 0; y < N; y++) { @@ -63,7 +63,7 @@ void IDCT1D(double block[N * M], double out[N * M]) { } template <size_t N, size_t M> -void TransposeBlock(double in[N * M], double out[M * N]) { +void TransposeBlock(const double in[N * M], double out[M * N]) { for (size_t x = 0; x < N; x++) { for (size_t y = 0; y < M; y++) { out[y * N + x] = in[x * M + y]; diff --git a/third_party/jpeg-xl/lib/jxl/dct_test.cc b/third_party/jpeg-xl/lib/jxl/dct_test.cc index e4982e2f45..57ce9291e2 100644 --- a/third_party/jpeg-xl/lib/jxl/dct_test.cc +++ b/third_party/jpeg-xl/lib/jxl/dct_test.cc @@ -160,7 +160,7 @@ void TestInverseT(float accuracy) { test::ThreadPoolForTests pool(N < 32 ? 0 : 8); enum { kBlockSize = N * N }; EXPECT_TRUE(RunOnPool( - &pool, 0, kBlockSize, ThreadPool::NoInit, + pool.get(), 0, kBlockSize, ThreadPool::NoInit, [accuracy](const uint32_t task, size_t /*thread*/) { const size_t i = static_cast<size_t>(task); HWY_ALIGN float x[kBlockSize] = {0.0f}; diff --git a/third_party/jpeg-xl/lib/jxl/dec_cache.cc b/third_party/jpeg-xl/lib/jxl/dec_cache.cc index 2a89420018..639857d4f8 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_cache.cc +++ b/third_party/jpeg-xl/lib/jxl/dec_cache.cc @@ -125,8 +125,8 @@ Status PassesDecoderState::PreparePipeline(const FrameHeader& frame_header, if (frame_header.CanBeReferenced() && frame_header.save_before_color_transform) { - builder.AddStage(GetWriteToImageBundleStage( - &frame_storage_for_referencing, output_encoding_info.color_encoding)); + builder.AddStage(GetWriteToImageBundleStage(&frame_storage_for_referencing, + output_encoding_info)); } bool has_alpha = false; @@ -181,7 +181,7 @@ Status PassesDecoderState::PreparePipeline(const FrameHeader& frame_header, linear = false; } builder.AddStage(GetWriteToImageBundleStage( - &frame_storage_for_referencing, output_encoding_info.color_encoding)); + &frame_storage_for_referencing, output_encoding_info)); } if (options.render_spotcolors && @@ -228,7 +228,7 @@ Status PassesDecoderState::PreparePipeline(const FrameHeader& frame_header, if ((output_encoding_info.color_encoding_is_original) || (!output_encoding_info.cms_set) || mixing_color_and_grey) { // in those cases we only need a linear stage in other cases we attempt - // to obtain an cms stage: the cases are + // to obtain a cms stage: the cases are // - output_encoding_info.color_encoding_is_original: no cms stage // needed because it would be a no-op // - !output_encoding_info.cms_set: can't use the cms, so no point in @@ -255,8 +255,8 @@ Status PassesDecoderState::PreparePipeline(const FrameHeader& frame_header, has_alpha, unpremul_alpha, alpha_c, undo_orientation, extra_output)); } else { - builder.AddStage(GetWriteToImageBundleStage( - decoded, output_encoding_info.color_encoding)); + builder.AddStage( + GetWriteToImageBundleStage(decoded, output_encoding_info)); } } JXL_ASSIGN_OR_RETURN(render_pipeline, diff --git a/third_party/jpeg-xl/lib/jxl/dec_modular.cc b/third_party/jpeg-xl/lib/jxl/dec_modular.cc index 49561e6ec2..80cc9d1360 100644 --- a/third_party/jpeg-xl/lib/jxl/dec_modular.cc +++ b/third_party/jpeg-xl/lib/jxl/dec_modular.cc @@ -362,7 +362,7 @@ Status ModularFrameDecoder::DecodeGroup( // Undo global transforms that have been pushed to the group level if (!use_full_image) { JXL_ASSERT(render_pipeline_input); - for (auto t : global_transform) { + for (const auto& t : global_transform) { JXL_RETURN_IF_ERROR(t.Inverse(gi, global_header.wp_header)); } JXL_RETURN_IF_ERROR(ModularImageToDecodedRect( diff --git a/third_party/jpeg-xl/lib/jxl/decode_test.cc b/third_party/jpeg-xl/lib/jxl/decode_test.cc index 33176cfd66..99b5871ccd 100644 --- a/third_party/jpeg-xl/lib/jxl/decode_test.cc +++ b/third_party/jpeg-xl/lib/jxl/decode_test.cc @@ -2475,7 +2475,7 @@ void TestPartialStream(bool reconstructible_jpeg) { TEST(DecodeTest, PixelPartialTest) { TestPartialStream(false); } // Tests the return status when trying to decode JPEG bytes on incomplete file. -TEST(DecodeTest, JXL_TRANSCODE_JPEG_TEST(JPEGPartialTest)) { +JXL_TRANSCODE_JPEG_TEST(DecodeTest, JPEGPartialTest) { TEST_LIBJPEG_SUPPORT(); TestPartialStream(true); } @@ -4195,7 +4195,7 @@ TEST(DecodeTest, InputHandlingTestOneShot) { } } -TEST(DecodeTest, JXL_TRANSCODE_JPEG_TEST(InputHandlingTestJPEGOneshot)) { +JXL_TRANSCODE_JPEG_TEST(DecodeTest, InputHandlingTestJPEGOneshot) { TEST_LIBJPEG_SUPPORT(); size_t xsize = 123; size_t ysize = 77; @@ -4976,7 +4976,7 @@ void VerifyJPEGReconstruction(jxl::Span<const uint8_t> container, EXPECT_EQ(0, memcmp(reconstructed_buffer.data(), jpeg_bytes.data(), used)); } -TEST(DecodeTest, JXL_TRANSCODE_JPEG_TEST(JPEGReconstructTestCodestream)) { +JXL_TRANSCODE_JPEG_TEST(DecodeTest, JPEGReconstructTestCodestream) { TEST_LIBJPEG_SUPPORT(); size_t xsize = 123; size_t ysize = 77; @@ -4994,7 +4994,7 @@ TEST(DecodeTest, JXL_TRANSCODE_JPEG_TEST(JPEGReconstructTestCodestream)) { VerifyJPEGReconstruction(jxl::Bytes(compressed), jxl::Bytes(jpeg_codestream)); } -TEST(DecodeTest, JXL_TRANSCODE_JPEG_TEST(JPEGReconstructionTest)) { +JXL_TRANSCODE_JPEG_TEST(DecodeTest, JPEGReconstructionTest) { const std::string jpeg_path = "jxl/flower/flower.png.im_q85_420.jpg"; const std::vector<uint8_t> orig = jxl::test::ReadTestData(jpeg_path); jxl::CodecInOut orig_io; @@ -5024,7 +5024,7 @@ TEST(DecodeTest, JXL_TRANSCODE_JPEG_TEST(JPEGReconstructionTest)) { VerifyJPEGReconstruction(jxl::Bytes(container), jxl::Bytes(orig)); } -TEST(DecodeTest, JXL_TRANSCODE_JPEG_TEST(JPEGReconstructionMetadataTest)) { +JXL_TRANSCODE_JPEG_TEST(DecodeTest, JPEGReconstructionMetadataTest) { const std::string jpeg_path = "jxl/jpeg_reconstruction/1x1_exif_xmp.jpg"; const std::string jxl_path = "jxl/jpeg_reconstruction/1x1_exif_xmp.jxl"; const std::vector<uint8_t> jpeg = jxl::test::ReadTestData(jpeg_path); @@ -5135,7 +5135,7 @@ TEST(DecodeTest, ExtentedBoxSizeTest) { JxlDecoderDestroy(dec); } -TEST(DecodeTest, JXL_BOXES_TEST(BoxTest)) { +JXL_BOXES_TEST(DecodeTest, BoxTest) { size_t xsize = 1; size_t ysize = 1; std::vector<uint8_t> pixels = jxl::test::GetSomeTestImage(xsize, ysize, 4, 0); @@ -5212,7 +5212,7 @@ TEST(DecodeTest, JXL_BOXES_TEST(BoxTest)) { JxlDecoderDestroy(dec); } -TEST(DecodeTest, JXL_BOXES_TEST(ExifBrobBoxTest)) { +JXL_BOXES_TEST(DecodeTest, ExifBrobBoxTest) { size_t xsize = 1; size_t ysize = 1; std::vector<uint8_t> pixels = jxl::test::GetSomeTestImage(xsize, ysize, 4, 0); @@ -5394,7 +5394,7 @@ TEST(DecodeTest, JXL_BOXES_TEST(ExifBrobBoxTest)) { } } -TEST(DecodeTest, JXL_BOXES_TEST(PartialCodestreamBoxTest)) { +JXL_BOXES_TEST(DecodeTest, PartialCodestreamBoxTest) { size_t xsize = 23; size_t ysize = 81; std::vector<uint8_t> pixels = jxl::test::GetSomeTestImage(xsize, ysize, 4, 0); 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 e80771248e..4f1d2dadb5 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 @@ -149,9 +149,9 @@ Status ProcessTile(const CompressParams& cparams, float* JXL_RESTRICT row_out = sqrsum_00_row + y * sqrsum_00_stride; for (size_t x = 0; x < rect.xsize() * 2; x++) { auto sum = Zero(df4); - for (size_t iy = 0; iy < 4; iy++) { + for (auto& row : rows_in) { for (size_t ix = 0; ix < 4; ix += Lanes(df4)) { - sum = Add(sum, LoadU(df4, rows_in[iy] + x * 4 + ix + 2)); + sum = Add(sum, LoadU(df4, row + x * 4 + ix + 2)); } } row_out[x] = GetLane(Sqrt(SumOfLanes(df4, sum))) * (1.0f / 4.0f); 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 58d0d00eaa..1797139428 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_fast_lossless.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_fast_lossless.cc @@ -202,8 +202,8 @@ size_t TOCBucket(size_t group_size) { size_t TOCSize(const std::vector<size_t>& group_sizes) { size_t toc_bits = 0; - for (size_t i = 0; i < group_sizes.size(); i++) { - toc_bits += kTOCBits[TOCBucket(group_sizes[i])]; + for (size_t group_size : group_sizes) { + toc_bits += kTOCBits[TOCBucket(group_size)]; } return (toc_bits + 7) / 8; } @@ -328,8 +328,8 @@ struct PrefixCode { template <typename T> static void ComputeCodeLengthsNonZeroImpl(const uint64_t* freqs, size_t n, size_t precision, T infty, - uint8_t* min_limit, - uint8_t* max_limit, + const uint8_t* min_limit, + const uint8_t* max_limit, uint8_t* nbits) { assert(precision < 15); assert(n <= kMaxNumSymbols); @@ -454,8 +454,8 @@ struct PrefixCode { uint8_t min_lengths[kNumLZ77] = {}; uint8_t l = 15 - level1_nbits[numraw]; uint8_t max_lengths[kNumLZ77]; - for (size_t i = 0; i < kNumLZ77; i++) { - max_lengths[i] = l; + for (uint8_t& max_length : max_lengths) { + max_length = l; } size_t num_lz77 = kNumLZ77; while (num_lz77 > 0 && lz77_counts[num_lz77 - 1] == 0) num_lz77--; @@ -487,11 +487,11 @@ struct PrefixCode { void WriteTo(BitWriter* writer) const { uint64_t code_length_counts[18] = {}; code_length_counts[17] = 3 + 2 * (kNumLZ77 - 1); - for (size_t i = 0; i < kNumRawSymbols; i++) { - code_length_counts[raw_nbits[i]]++; + for (uint8_t raw_nbit : raw_nbits) { + code_length_counts[raw_nbit]++; } - for (size_t i = 0; i < kNumLZ77; i++) { - code_length_counts[lz77_nbits[i]]++; + for (uint8_t lz77_nbit : lz77_nbits) { + code_length_counts[lz77_nbit]++; } uint8_t code_length_nbits[18] = {}; uint8_t code_length_nbits_min[18] = {}; @@ -527,9 +527,8 @@ struct PrefixCode { code_length_bits, 18); // Encode raw bit code lengths. // Max bits written in this loop: 19 * 5 = 95 - for (size_t i = 0; i < kNumRawSymbols; i++) { - writer->Write(code_length_nbits[raw_nbits[i]], - code_length_bits[raw_nbits[i]]); + for (uint8_t raw_nbit : raw_nbits) { + writer->Write(code_length_nbits[raw_nbit], code_length_bits[raw_nbit]); } size_t num_lz77 = kNumLZ77; while (lz77_nbits[num_lz77 - 1] == 0) { @@ -590,8 +589,8 @@ struct JxlFastLosslessFrameState { size_t JxlFastLosslessOutputSize(const JxlFastLosslessFrameState* frame) { size_t total_size_groups = 0; - for (size_t i = 0; i < frame->group_data.size(); i++) { - total_size_groups += SectionSize(frame->group_data[i]); + for (const auto& section : frame->group_data) { + total_size_groups += SectionSize(section); } return frame->header.bytes_written + total_size_groups; } @@ -719,11 +718,10 @@ void JxlFastLosslessPrepareHeader(JxlFastLosslessFrameState* frame, output->Write(1, 0); // No TOC permutation output->ZeroPadToByte(); // TOC is byte-aligned. assert(add_image_header || output->bytes_written <= kMaxFrameHeaderSize); - for (size_t i = 0; i < frame->group_sizes.size(); i++) { - size_t sz = frame->group_sizes[i]; - size_t bucket = TOCBucket(sz); + for (size_t group_size : frame->group_sizes) { + size_t bucket = TOCBucket(group_size); output->Write(2, bucket); - output->Write(kTOCBits[bucket] - 2, sz - kGroupSizeOffset[bucket]); + output->Write(kTOCBits[bucket] - 2, group_size - kGroupSizeOffset[bucket]); } output->ZeroPadToByte(); // Groups are byte-aligned. } diff --git a/third_party/jpeg-xl/lib/jxl/enc_frame.cc b/third_party/jpeg-xl/lib/jxl/enc_frame.cc index 8587e1aed2..2a3389921b 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_frame.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_frame.cc @@ -1786,8 +1786,8 @@ size_t TOCBucket(size_t group_size) { size_t TOCSize(const std::vector<size_t>& group_sizes) { size_t toc_bits = 0; - for (size_t i = 0; i < group_sizes.size(); i++) { - toc_bits += kTOCBits[TOCBucket(group_sizes[i])]; + for (size_t group_size : group_sizes) { + toc_bits += kTOCBits[TOCBucket(group_size)]; } return (toc_bits + 7) / 8; } @@ -1795,8 +1795,8 @@ size_t TOCSize(const std::vector<size_t>& group_sizes) { PaddedBytes EncodeTOC(const std::vector<size_t>& group_sizes, AuxOut* aux_out) { BitWriter writer; BitWriter::Allotment allotment(&writer, 32 * group_sizes.size()); - for (size_t i = 0; i < group_sizes.size(); i++) { - JXL_CHECK(U32Coder::Write(kTocDist, group_sizes[i], &writer)); + for (size_t group_size : group_sizes) { + JXL_CHECK(U32Coder::Write(kTocDist, group_size, &writer)); } writer.ZeroPadToByte(); // before first group allotment.ReclaimAndCharge(&writer, kLayerTOC, aux_out); @@ -1854,13 +1854,13 @@ void RemoveUnusedHistograms(std::vector<uint8_t>& context_map, EntropyEncodingData& codes) { std::vector<int> remap(256, -1); std::vector<uint8_t> inv_remap; - for (size_t i = 0; i < context_map.size(); ++i) { - const uint8_t histo_ix = context_map[i]; + for (uint8_t& context : context_map) { + const uint8_t histo_ix = context; if (remap[histo_ix] == -1) { remap[histo_ix] = inv_remap.size(); inv_remap.push_back(histo_ix); } - context_map[i] = remap[histo_ix]; + context = remap[histo_ix]; } EntropyEncodingData new_codes; new_codes.use_prefix_code = codes.use_prefix_code; diff --git a/third_party/jpeg-xl/lib/jxl/enc_group.cc b/third_party/jpeg-xl/lib/jxl/enc_group.cc index 1967fdaba9..2b60643e7c 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_group.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_group.cc @@ -43,7 +43,7 @@ using hwy::HWY_NAMESPACE::Round; void QuantizeBlockAC(const Quantizer& quantizer, const bool error_diffusion, size_t c, float qm_multiplier, size_t quant_kind, size_t xsize, size_t ysize, float* thresholds, - const float* JXL_RESTRICT block_in, int32_t* quant, + const float* JXL_RESTRICT block_in, const int32_t* quant, int32_t* JXL_RESTRICT block_out) { const float* JXL_RESTRICT qm = quantizer.InvDequantMatrix(quant_kind, c); float qac = quantizer.Scale() * (*quant); @@ -322,10 +322,8 @@ void QuantizeRoundtripYBlockAC(PassesEncoderState* enc_state, const size_t size, int quant_orig = *quant; float val[3] = {enc_state->x_qm_multiplier, 1.0f, enc_state->b_qm_multiplier}; - int clut[3] = {1, 0, 2}; - for (int ii = 0; ii < 3; ++ii) { + for (int c : {1, 0, 2}) { float thres[4] = {0.58f, 0.64f, 0.64f, 0.64f}; - int c = clut[ii]; *quant = quant_orig; AdjustQuantBlockAC(quantizer, c, val[c], quant_kind, xsize, ysize, &thres[0], inout + c * size, quant); diff --git a/third_party/jpeg-xl/lib/jxl/enc_icc_codec.cc b/third_party/jpeg-xl/lib/jxl/enc_icc_codec.cc index a29fb3f299..c3899600e5 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_icc_codec.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_icc_codec.cc @@ -127,8 +127,8 @@ Status PredictICC(const uint8_t* icc, size_t size, PaddedBytes* result) { } if (size <= kICCHeaderSize) { EncodeVarInt(0, result); // 0 commands - for (size_t i = 0; i < data.size(); i++) { - result->push_back(data[i]); + for (uint8_t b : data) { + result->push_back(b); } return true; } @@ -403,11 +403,11 @@ Status PredictICC(const uint8_t* icc, size_t size, PaddedBytes* result) { data.push_back(icc[last0++]); } } - for (size_t i = 0; i < commands_add.size(); i++) { - commands.push_back(commands_add[i]); + for (uint8_t b : commands_add) { + commands.push_back(b); } - for (size_t i = 0; i < data_add.size(); i++) { - data.push_back(data_add[i]); + for (uint8_t b : data_add) { + data.push_back(b); } last0 = pos; } @@ -417,11 +417,11 @@ Status PredictICC(const uint8_t* icc, size_t size, PaddedBytes* result) { } EncodeVarInt(commands.size(), result); - for (size_t i = 0; i < commands.size(); i++) { - result->push_back(commands[i]); + for (uint8_t b : commands) { + result->push_back(b); } - for (size_t i = 0; i < data.size(); i++) { - result->push_back(data[i]); + for (uint8_t b : data) { + result->push_back(b); } return true; diff --git a/third_party/jpeg-xl/lib/jxl/enc_modular.cc b/third_party/jpeg-xl/lib/jxl/enc_modular.cc index dbd62d4a01..35fac3c827 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_modular.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_modular.cc @@ -300,13 +300,12 @@ bool do_transform(Image& image, const Transform& tr, bool maybe_do_transform(Image& image, const Transform& tr, const CompressParams& cparams, - const weighted::Header& wp_header, + const weighted::Header& wp_header, float cost_before, jxl::ThreadPool* pool = nullptr, bool force_jxlart = false) { if (force_jxlart || cparams.speed_tier >= SpeedTier::kSquirrel) { return do_transform(image, tr, wp_header, pool, force_jxlart); } - float cost_before = EstimateCost(image); bool did_it = do_transform(image, tr, wp_header, pool); if (did_it) { float cost_after = EstimateCost(image); @@ -321,6 +320,110 @@ bool maybe_do_transform(Image& image, const Transform& tr, return did_it; } +void try_palettes(Image& gi, int& max_bitdepth, int& maxval, + const CompressParams& cparams_, float channel_colors_percent, + jxl::ThreadPool* pool = nullptr) { + float cost_before = 0.f; + size_t did_palette = 0; + float nb_pixels = gi.channel[0].w * gi.channel[0].h; + int nb_chans = gi.channel.size() - gi.nb_meta_channels; + // arbitrary estimate: 4.8 bpp for 8-bit RGB + float arbitrary_bpp_estimate = 0.2f * gi.bitdepth * nb_chans; + + if (cparams_.palette_colors != 0 || cparams_.lossy_palette) { + // when not estimating, assume some arbitrary bpp + cost_before = cparams_.speed_tier <= SpeedTier::kSquirrel + ? EstimateCost(gi) + : nb_pixels * arbitrary_bpp_estimate; + // all-channel palette (e.g. RGBA) + if (nb_chans > 1) { + Transform maybe_palette(TransformId::kPalette); + maybe_palette.begin_c = gi.nb_meta_channels; + maybe_palette.num_c = nb_chans; + // Heuristic choice of max colors for a palette: + // max_colors = nb_pixels * estimated_bpp_without_palette * 0.0005 + + // + nb_pixels / 128 + 128 + // (estimated_bpp_without_palette = cost_before / nb_pixels) + // Rationale: small image with large palette is not effective; + // also if the entropy (estimated bpp) is low (e.g. mostly solid/gradient + // areas), palette is less useful and may even be counterproductive. + maybe_palette.nb_colors = std::min( + static_cast<int>(cost_before * 0.0005f + nb_pixels / 128 + 128), + std::abs(cparams_.palette_colors)); + maybe_palette.ordered_palette = cparams_.palette_colors >= 0; + maybe_palette.lossy_palette = + (cparams_.lossy_palette && maybe_palette.num_c == 3); + if (maybe_palette.lossy_palette) { + maybe_palette.predictor = Predictor::Average4; + } + // TODO(veluca): use a custom weighted header if using the weighted + // predictor. + if (maybe_do_transform(gi, maybe_palette, cparams_, weighted::Header(), + cost_before, pool, cparams_.options.zero_tokens)) { + did_palette = 1; + }; + } + // all-minus-one-channel palette (RGB with separate alpha, or CMY with + // separate K) + if (!did_palette && nb_chans > 3) { + Transform maybe_palette_3(TransformId::kPalette); + maybe_palette_3.begin_c = gi.nb_meta_channels; + maybe_palette_3.num_c = nb_chans - 1; + maybe_palette_3.nb_colors = std::min( + static_cast<int>(cost_before * 0.0005f + nb_pixels / 128 + 128), + std::abs(cparams_.palette_colors)); + maybe_palette_3.ordered_palette = cparams_.palette_colors >= 0; + maybe_palette_3.lossy_palette = cparams_.lossy_palette; + if (maybe_palette_3.lossy_palette) { + maybe_palette_3.predictor = Predictor::Average4; + } + if (maybe_do_transform(gi, maybe_palette_3, cparams_, weighted::Header(), + cost_before, pool, cparams_.options.zero_tokens)) { + did_palette = 1; + } + } + } + + if (channel_colors_percent > 0) { + // single channel palette (like FLIF's ChannelCompact) + size_t nb_channels = gi.channel.size() - gi.nb_meta_channels - did_palette; + int orig_bitdepth = max_bitdepth; + max_bitdepth = 0; + if (nb_channels > 0 && (did_palette || cost_before == 0)) { + cost_before = + cparams_.speed_tier < SpeedTier::kSquirrel ? EstimateCost(gi) : 0; + } + for (size_t i = did_palette; i < nb_channels + did_palette; i++) { + int32_t min; + int32_t max; + compute_minmax(gi.channel[gi.nb_meta_channels + i], &min, &max); + int64_t colors = static_cast<int64_t>(max) - min + 1; + JXL_DEBUG_V(10, "Channel %" PRIuS ": range=%i..%i", i, min, max); + Transform maybe_palette_1(TransformId::kPalette); + maybe_palette_1.begin_c = i + gi.nb_meta_channels; + maybe_palette_1.num_c = 1; + // simple heuristic: if less than X percent of the values in the range + // actually occur, it is probably worth it to do a compaction + // (but only if the channel palette is less than 6% the size of the + // image itself) + maybe_palette_1.nb_colors = + std::min(static_cast<int>(nb_pixels / 16), + static_cast<int>(channel_colors_percent / 100. * colors)); + if (maybe_do_transform(gi, maybe_palette_1, cparams_, weighted::Header(), + cost_before, pool)) { + // effective bit depth is lower, adjust quantization accordingly + compute_minmax(gi.channel[gi.nb_meta_channels + i], &min, &max); + if (max < maxval) maxval = max; + int ch_bitdepth = + (max > 0 ? CeilLog2Nonzero(static_cast<uint32_t>(max)) : 0); + if (ch_bitdepth > max_bitdepth) max_bitdepth = ch_bitdepth; + } else { + max_bitdepth = orig_bitdepth; + } + } + } +} + } // namespace ModularFrameEncoder::ModularFrameEncoder(const FrameHeader& frame_header, @@ -479,7 +582,6 @@ ModularFrameEncoder::ModularFrameEncoder(const FrameHeader& frame_header, cparams_.options.predictor = Predictor::Gradient; } } else { - delta_pred_ = cparams_.options.predictor; if (cparams_.lossy_palette) cparams_.options.predictor = Predictor::Zero; } if (!cparams_.ModularPartIsLossless()) { @@ -624,6 +726,7 @@ Status ModularFrameEncoder::ComputeEncodingData( pixel_type* const JXL_RESTRICT row_out = gi.channel[c_out].Row(y); pixel_type* const JXL_RESTRICT row_Y = gi.channel[0].Row(y); for (size_t x = 0; x < xsize; ++x) { + // TODO(eustas): check if std::roundf is appropriate row_out[x] = row_in[x] * factor + 0.5f; row_out[x] -= row_Y[x]; // zero the lsb of B @@ -720,81 +823,16 @@ Status ModularFrameEncoder::ComputeEncodingData( cparams_.lossy_palette = false; } - // Global palette - if ((cparams_.palette_colors != 0 || cparams_.lossy_palette) && !groupwise) { - // all-channel palette (e.g. RGBA) - if (gi.channel.size() - gi.nb_meta_channels > 1) { - Transform maybe_palette(TransformId::kPalette); - maybe_palette.begin_c = gi.nb_meta_channels; - maybe_palette.num_c = gi.channel.size() - gi.nb_meta_channels; - maybe_palette.nb_colors = std::min(static_cast<int>(xsize * ysize / 2), - std::abs(cparams_.palette_colors)); - maybe_palette.ordered_palette = cparams_.palette_colors >= 0; - maybe_palette.lossy_palette = - (cparams_.lossy_palette && maybe_palette.num_c == 3); - if (maybe_palette.lossy_palette) { - maybe_palette.predictor = delta_pred_; - } - // TODO(veluca): use a custom weighted header if using the weighted - // predictor. - maybe_do_transform(gi, maybe_palette, cparams_, weighted::Header(), pool, - cparams_.options.zero_tokens); - } - // all-minus-one-channel palette (RGB with separate alpha, or CMY with - // separate K) - if (gi.channel.size() - gi.nb_meta_channels > 3) { - Transform maybe_palette_3(TransformId::kPalette); - maybe_palette_3.begin_c = gi.nb_meta_channels; - maybe_palette_3.num_c = gi.channel.size() - gi.nb_meta_channels - 1; - maybe_palette_3.nb_colors = std::min(static_cast<int>(xsize * ysize / 3), - std::abs(cparams_.palette_colors)); - maybe_palette_3.ordered_palette = cparams_.palette_colors >= 0; - maybe_palette_3.lossy_palette = cparams_.lossy_palette; - if (maybe_palette_3.lossy_palette) { - maybe_palette_3.predictor = delta_pred_; - } - maybe_do_transform(gi, maybe_palette_3, cparams_, weighted::Header(), - pool, cparams_.options.zero_tokens); - } - } - - // Global channel palette - if (!groupwise && cparams_.channel_colors_pre_transform_percent > 0 && - !cparams_.lossy_palette && + // Global palette transforms + float channel_colors_percent = 0; + if (!cparams_.lossy_palette && (cparams_.speed_tier <= SpeedTier::kThunder || (do_color && metadata.bit_depth.bits_per_sample > 8))) { - // single channel palette (like FLIF's ChannelCompact) - size_t nb_channels = gi.channel.size() - gi.nb_meta_channels; - int orig_bitdepth = max_bitdepth; - max_bitdepth = 0; - for (size_t i = 0; i < nb_channels; i++) { - int32_t min; - int32_t max; - compute_minmax(gi.channel[gi.nb_meta_channels + i], &min, &max); - int64_t colors = static_cast<int64_t>(max) - min + 1; - JXL_DEBUG_V(10, "Channel %" PRIuS ": range=%i..%i", i, min, max); - Transform maybe_palette_1(TransformId::kPalette); - maybe_palette_1.begin_c = i + gi.nb_meta_channels; - maybe_palette_1.num_c = 1; - // simple heuristic: if less than X percent of the values in the range - // actually occur, it is probably worth it to do a compaction - // (but only if the channel palette is less than 6% the size of the - // image itself) - maybe_palette_1.nb_colors = std::min( - static_cast<int>(xsize * ysize / 16), - static_cast<int>(cparams_.channel_colors_pre_transform_percent / - 100. * colors)); - if (maybe_do_transform(gi, maybe_palette_1, cparams_, weighted::Header(), - pool)) { - // effective bit depth is lower, adjust quantization accordingly - compute_minmax(gi.channel[gi.nb_meta_channels + i], &min, &max); - if (max < maxval) maxval = max; - int ch_bitdepth = - (max > 0 ? CeilLog2Nonzero(static_cast<uint32_t>(max)) : 0); - if (ch_bitdepth > max_bitdepth) max_bitdepth = ch_bitdepth; - } else - max_bitdepth = orig_bitdepth; - } + channel_colors_percent = cparams_.channel_colors_pre_transform_percent; + } + if (!groupwise) { + try_palettes(gi, max_bitdepth, maxval, cparams_, channel_colors_percent, + pool); } // don't do an RCT if we're short on bits @@ -1318,61 +1356,17 @@ Status ModularFrameEncoder::PrepareStreamParams(const Rect& rect, if (gi.channel.empty()) return true; // Do some per-group transforms - // Local palette + // Local palette transforms // TODO(veluca): make this work with quantize-after-prediction in lossy // mode. - if (cparams_.butteraugli_distance == 0.f && cparams_.palette_colors != 0 && + if (cparams_.butteraugli_distance == 0.f && !cparams_.lossy_palette && cparams_.speed_tier < SpeedTier::kCheetah) { - // all-channel palette (e.g. RGBA) - if (gi.channel.size() - gi.nb_meta_channels > 1) { - Transform maybe_palette(TransformId::kPalette); - maybe_palette.begin_c = gi.nb_meta_channels; - maybe_palette.num_c = gi.channel.size() - gi.nb_meta_channels; - maybe_palette.nb_colors = std::abs(cparams_.palette_colors); - maybe_palette.ordered_palette = cparams_.palette_colors >= 0; - maybe_do_transform(gi, maybe_palette, cparams_, weighted::Header()); - } - // all-minus-one-channel palette (RGB with separate alpha, or CMY with - // separate K) - if (gi.channel.size() - gi.nb_meta_channels > 3) { - Transform maybe_palette_3(TransformId::kPalette); - maybe_palette_3.begin_c = gi.nb_meta_channels; - maybe_palette_3.num_c = gi.channel.size() - gi.nb_meta_channels - 1; - maybe_palette_3.nb_colors = std::abs(cparams_.palette_colors); - maybe_palette_3.ordered_palette = cparams_.palette_colors >= 0; - maybe_palette_3.lossy_palette = cparams_.lossy_palette; - if (maybe_palette_3.lossy_palette) { - maybe_palette_3.predictor = Predictor::Weighted; - } - maybe_do_transform(gi, maybe_palette_3, cparams_, weighted::Header()); - } - } - - // Local channel palette - if (cparams_.channel_colors_percent > 0 && - cparams_.butteraugli_distance == 0.f && !cparams_.lossy_palette && - cparams_.speed_tier < SpeedTier::kCheetah && - !(cparams_.responsive && cparams_.decoding_speed_tier >= 1)) { - // single channel palette (like FLIF's ChannelCompact) - size_t nb_channels = gi.channel.size() - gi.nb_meta_channels; - for (size_t i = 0; i < nb_channels; i++) { - int32_t min; - int32_t max; - compute_minmax(gi.channel[gi.nb_meta_channels + i], &min, &max); - int64_t colors = static_cast<int64_t>(max) - min + 1; - JXL_DEBUG_V(10, "Channel %" PRIuS ": range=%i..%i", i, min, max); - Transform maybe_palette_1(TransformId::kPalette); - maybe_palette_1.begin_c = i + gi.nb_meta_channels; - maybe_palette_1.num_c = 1; - // simple heuristic: if less than X percent of the values in the range - // actually occur, it is probably worth it to do a compaction - // (but only if the channel palette is less than 80% the size of the - // image itself) - maybe_palette_1.nb_colors = std::min( - static_cast<int>(xsize * ysize * 0.8), - static_cast<int>(cparams_.channel_colors_percent / 100. * colors)); - maybe_do_transform(gi, maybe_palette_1, cparams_, weighted::Header()); + int max_bitdepth = 0, maxval = 0; // don't care about that here + float channel_color_percent = 0; + if (!(cparams_.responsive && cparams_.decoding_speed_tier >= 1)) { + channel_color_percent = cparams_.channel_colors_percent; } + try_palettes(gi, max_bitdepth, maxval, cparams_, channel_color_percent); } } diff --git a/third_party/jpeg-xl/lib/jxl/enc_modular.h b/third_party/jpeg-xl/lib/jxl/enc_modular.h index 8e2015b226..c7a8421982 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_modular.h +++ b/third_party/jpeg-xl/lib/jxl/enc_modular.h @@ -107,7 +107,6 @@ class ModularFrameEncoder { std::vector<size_t> tree_splits_; std::vector<std::vector<uint32_t>> gi_channel_; std::vector<size_t> image_widths_; - Predictor delta_pred_ = Predictor::Average4; struct GroupParams { Rect rect; diff --git a/third_party/jpeg-xl/lib/jxl/enc_params.h b/third_party/jpeg-xl/lib/jxl/enc_params.h index 162c59d04c..5e3ff7789c 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_params.h +++ b/third_party/jpeg-xl/lib/jxl/enc_params.h @@ -106,9 +106,12 @@ struct CompressParams { // modular mode options below ModularOptions options; + + // TODO(eustas): use Override? int responsive = -1; int colorspace = -1; int move_to_front_from_channel = -1; + // Use Global channel palette if #colors < this percentage of range float channel_colors_pre_transform_percent = 95.f; // Use Local channel palette if #colors < this percentage of range 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 f19ba0dd9e..6fc5f7f49e 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_patch_dictionary.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_patch_dictionary.cc @@ -237,9 +237,9 @@ StatusOr<std::vector<PatchInfo>> FindTextLikePatches( auto is_same = [&opsin_rows, opsin_stride](std::pair<uint32_t, uint32_t> p1, std::pair<uint32_t, uint32_t> p2) { - for (size_t c = 0; c < 3; c++) { - float v1 = opsin_rows[c][p1.second * opsin_stride + p1.first]; - float v2 = opsin_rows[c][p2.second * opsin_stride + p2.first]; + for (auto& opsin_row : opsin_rows) { + float v1 = opsin_row[p1.second * opsin_stride + p1.first]; + float v2 = opsin_row[p2.second * opsin_stride + p2.first]; if (std::fabs(v1 - v2) > 1e-4) { return false; } @@ -556,8 +556,8 @@ StatusOr<std::vector<PatchInfo>> FindTextLikePatches( size_t max_patch_size = 0; - for (size_t i = 0; i < info.size(); i++) { - size_t pixels = info[i].first.xsize * info[i].first.ysize; + for (const auto& patch : info) { + size_t pixels = patch.first.xsize * patch.first.ysize; if (pixels > max_patch_size) max_patch_size = pixels; } @@ -605,10 +605,10 @@ Status FindBestPatchDictionary(const Image3F& opsin, size_t max_y_size = 0; size_t total_pixels = 0; - for (size_t i = 0; i < info.size(); i++) { - size_t pixels = info[i].first.xsize * info[i].first.ysize; - if (max_x_size < info[i].first.xsize) max_x_size = info[i].first.xsize; - if (max_y_size < info[i].first.ysize) max_y_size = info[i].first.ysize; + for (const auto& patch : info) { + size_t pixels = patch.first.xsize * patch.first.ysize; + if (max_x_size < patch.first.xsize) max_x_size = patch.first.xsize; + if (max_y_size < patch.first.ysize) max_y_size = patch.first.ysize; total_pixels += pixels; } diff --git a/third_party/jpeg-xl/lib/jxl/enc_quant_weights.cc b/third_party/jpeg-xl/lib/jxl/enc_quant_weights.cc index 35e49d5993..978dfd5925 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_quant_weights.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_quant_weights.cc @@ -116,9 +116,9 @@ Status DequantMatricesEncode(const DequantMatrices& matrices, BitWriter* writer, bool all_default = true; const std::vector<QuantEncoding>& encodings = matrices.encodings(); - for (size_t i = 0; i < encodings.size(); i++) { - if (encodings[i].mode != QuantEncoding::kQuantModeLibrary || - encodings[i].predefined != 0) { + for (const auto& encoding : encodings) { + if (encoding.mode != QuantEncoding::kQuantModeLibrary || + encoding.predefined != 0) { all_default = false; } } diff --git a/third_party/jpeg-xl/lib/jxl/enc_splines.cc b/third_party/jpeg-xl/lib/jxl/enc_splines.cc index fa15648ca5..186f19da93 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_splines.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_splines.cc @@ -34,8 +34,8 @@ class QuantizedSplineEncoder { tokens->emplace_back(kDCTContext, PackSigned(dct[i])); } }; - for (int c = 0; c < 3; ++c) { - encode_dct(spline.color_dct_[c]); + for (const auto& dct : spline.color_dct_) { + encode_dct(dct); } encode_dct(spline.sigma_dct_); } diff --git a/third_party/jpeg-xl/lib/jxl/enc_toc.cc b/third_party/jpeg-xl/lib/jxl/enc_toc.cc index e79298ef31..4ecba8fdb1 100644 --- a/third_party/jpeg-xl/lib/jxl/enc_toc.cc +++ b/third_party/jpeg-xl/lib/jxl/enc_toc.cc @@ -32,9 +32,9 @@ Status WriteGroupOffsets(const std::vector<BitWriter>& group_codes, } writer->ZeroPadToByte(); // before TOC entries - for (size_t i = 0; i < group_codes.size(); i++) { - JXL_ASSERT(group_codes[i].BitsWritten() % kBitsPerByte == 0); - const size_t group_size = group_codes[i].BitsWritten() / kBitsPerByte; + for (const auto& bw : group_codes) { + JXL_ASSERT(bw.BitsWritten() % kBitsPerByte == 0); + const size_t group_size = bw.BitsWritten() / kBitsPerByte; JXL_RETURN_IF_ERROR(U32Coder::Write(kTocDist, group_size, writer)); } writer->ZeroPadToByte(); // before first group diff --git a/third_party/jpeg-xl/lib/jxl/encode.cc b/third_party/jpeg-xl/lib/jxl/encode.cc index 4dbbeba4e7..28a925dfc1 100644 --- a/third_party/jpeg-xl/lib/jxl/encode.cc +++ b/third_party/jpeg-xl/lib/jxl/encode.cc @@ -549,8 +549,8 @@ int VerifyLevelSettings(const JxlEncoder* enc, std::string* debug_string) { if (debug_string) *debug_string = "Too many extra channels"; return 10; } - for (size_t i = 0; i < m.extra_channel_info.size(); ++i) { - if (m.extra_channel_info[i].type == jxl::ExtraChannel::kBlack) { + for (const auto& eci : m.extra_channel_info) { + if (eci.type == jxl::ExtraChannel::kBlack) { if (debug_string) *debug_string = "CMYK channel not allowed"; return 10; } @@ -1514,6 +1514,10 @@ float JxlEncoderDistanceFromQuality(float quality) { JxlEncoderStatus JxlEncoderFrameSettingsSetOption( JxlEncoderFrameSettings* frame_settings, JxlEncoderFrameSettingId option, int64_t value) { + // Tri-state to bool convertors. + const auto default_to_true = [](int64_t v) { return v != 0; }; + const auto default_to_false = [](int64_t v) { return v == 1; }; + // check if value is -1, 0 or 1 for Override-type options switch (option) { case JXL_ENC_FRAME_SETTING_NOISE: @@ -1680,7 +1684,7 @@ JxlEncoderStatus JxlEncoderFrameSettingsSetOption( // See the logic in cjxl. Similar for other settings. This should be // handled in the encoder during JxlEncoderProcessOutput (or, // alternatively, in the cjxl binary like now) - frame_settings->values.cparams.lossy_palette = (value == 1); + frame_settings->values.cparams.lossy_palette = default_to_false(value); break; case JXL_ENC_FRAME_SETTING_COLOR_TRANSFORM: if (value < -1 || value > 2) { @@ -1734,11 +1738,8 @@ JxlEncoderStatus JxlEncoderFrameSettingsSetOption( } break; case JXL_ENC_FRAME_SETTING_JPEG_RECON_CFL: - if (value == -1) { - frame_settings->values.cparams.force_cfl_jpeg_recompression = true; - } else { - frame_settings->values.cparams.force_cfl_jpeg_recompression = value; - } + frame_settings->values.cparams.force_cfl_jpeg_recompression = + default_to_true(value); break; case JXL_ENC_FRAME_INDEX_BOX: if (value < 0 || value > 1) { @@ -1752,7 +1753,8 @@ JxlEncoderStatus JxlEncoderFrameSettingsSetOption( "Float option, try setting it with " "JxlEncoderFrameSettingsSetFloatOption"); case JXL_ENC_FRAME_SETTING_JPEG_COMPRESS_BOXES: - frame_settings->values.cparams.jpeg_compress_boxes = value; + frame_settings->values.cparams.jpeg_compress_boxes = + default_to_true(value); break; case JXL_ENC_FRAME_SETTING_BUFFERING: if (value < -1 || value > 3) { @@ -1762,20 +1764,21 @@ JxlEncoderStatus JxlEncoderFrameSettingsSetOption( frame_settings->values.cparams.buffering = value; break; case JXL_ENC_FRAME_SETTING_JPEG_KEEP_EXIF: - frame_settings->values.cparams.jpeg_keep_exif = value; + frame_settings->values.cparams.jpeg_keep_exif = default_to_true(value); break; case JXL_ENC_FRAME_SETTING_JPEG_KEEP_XMP: - frame_settings->values.cparams.jpeg_keep_xmp = value; + frame_settings->values.cparams.jpeg_keep_xmp = default_to_true(value); break; case JXL_ENC_FRAME_SETTING_JPEG_KEEP_JUMBF: - frame_settings->values.cparams.jpeg_keep_jumbf = value; + frame_settings->values.cparams.jpeg_keep_jumbf = default_to_true(value); break; case JXL_ENC_FRAME_SETTING_USE_FULL_IMAGE_HEURISTICS: if (value < 0 || value > 1) { return JXL_API_ERROR(frame_settings->enc, JXL_ENC_ERR_NOT_SUPPORTED, "Option value has to be 0 or 1"); } - frame_settings->values.cparams.use_full_image_heuristics = value; + frame_settings->values.cparams.use_full_image_heuristics = + default_to_false(value); break; default: diff --git a/third_party/jpeg-xl/lib/jxl/encode_test.cc b/third_party/jpeg-xl/lib/jxl/encode_test.cc index 3e519cc45d..0aef5f8aff 100644 --- a/third_party/jpeg-xl/lib/jxl/encode_test.cc +++ b/third_party/jpeg-xl/lib/jxl/encode_test.cc @@ -304,7 +304,7 @@ TEST(EncodeTest, CmsTest) { EXPECT_TRUE(cms_called); } -TEST(EncodeTest, frame_settingsTest) { +TEST(EncodeTest, FrameSettingsTest) { { JxlEncoderPtr enc = JxlEncoderMake(nullptr); EXPECT_NE(nullptr, enc.get()); @@ -451,7 +451,7 @@ TEST(EncodeTest, frame_settingsTest) { JxlEncoderFrameSettingsCreate(enc.get(), nullptr); EXPECT_EQ(JXL_ENC_SUCCESS, JxlEncoderSetFrameLossless(frame_settings, JXL_TRUE)); - VerifyFrameEncoding(63, 129, enc.get(), frame_settings, 3000, false); + VerifyFrameEncoding(63, 129, enc.get(), frame_settings, 3600, false); EXPECT_EQ(true, enc->last_used_cparams.IsLossless()); } @@ -838,20 +838,20 @@ TEST(EncodeTest, SingleFrameBoundedJXLCTest) { bool found_jxlc = false; bool found_jxlp = false; // The encoder is allowed to either emit a jxlc or one or more jxlp. - for (size_t i = 0; i < container.boxes.size(); ++i) { - if (memcmp("jxlc", container.boxes[i].type, 4) == 0) { + for (const auto& box : container.boxes) { + if (memcmp("jxlc", box.type, 4) == 0) { EXPECT_EQ(false, found_jxlc); // Max 1 jxlc EXPECT_EQ(false, found_jxlp); // Can't mix jxlc and jxlp found_jxlc = true; } - if (memcmp("jxlp", container.boxes[i].type, 4) == 0) { + if (memcmp("jxlp", box.type, 4) == 0) { EXPECT_EQ(false, found_jxlc); // Can't mix jxlc and jxlp found_jxlp = true; } // The encoder shouldn't create an unbounded box in this case, with the // single frame it knows the full size in time, so can help make decoding // more efficient by giving the full box size of the final box. - EXPECT_EQ(true, container.boxes[i].data_size_given); + EXPECT_EQ(true, box.data_size_given); } EXPECT_EQ(true, found_jxlc || found_jxlp); } @@ -940,7 +940,7 @@ TEST(EncodeTest, CodestreamLevelVerificationTest) { EXPECT_EQ(JXL_ENC_ERROR, JxlEncoderSetBasicInfo(enc.get(), &basic_info)); } -TEST(EncodeTest, JXL_TRANSCODE_JPEG_TEST(JPEGReconstructionTest)) { +JXL_TRANSCODE_JPEG_TEST(EncodeTest, JPEGReconstructionTest) { const std::string jpeg_path = "jxl/flower/flower.png.im_q85_420.jpg"; const std::vector<uint8_t> orig = jxl::test::ReadTestData(jpeg_path); @@ -980,7 +980,7 @@ TEST(EncodeTest, JXL_TRANSCODE_JPEG_TEST(JPEGReconstructionTest)) { EXPECT_EQ(0, memcmp(decoded_jpeg_bytes.data(), orig.data(), orig.size())); } -TEST(EncodeTest, JXL_TRANSCODE_JPEG_TEST(ProgressiveJPEGReconstructionTest)) { +JXL_TRANSCODE_JPEG_TEST(EncodeTest, ProgressiveJPEGReconstructionTest) { const std::string jpeg_path = "jxl/flower/flower.png.im_q85_420.jpg"; const std::vector<uint8_t> orig = jxl::test::ReadTestData(jpeg_path); @@ -1345,7 +1345,7 @@ TEST(EncodeTest, CroppedFrameTest) { struct EncodeBoxTest : public testing::TestWithParam<std::tuple<bool, size_t>> { }; -TEST_P(EncodeBoxTest, JXL_BOXES_TEST(BoxTest)) { +JXL_BOXES_TEST_P(EncodeBoxTest, BoxTest) { // Test with uncompressed boxes and with brob boxes bool compress_box = std::get<0>(GetParam()); size_t xml_box_size = std::get<1>(GetParam()); @@ -1485,7 +1485,7 @@ JXL_GTEST_INSTANTIATE_TEST_SUITE_P( jxl::kLargeBoxContentSizeThreshold + 77)), nameBoxTest); -TEST(EncodeTest, JXL_TRANSCODE_JPEG_TEST(JPEGFrameTest)) { +JXL_TRANSCODE_JPEG_TEST(EncodeTest, JPEGFrameTest) { TEST_LIBJPEG_SUPPORT(); for (int skip_basic_info = 0; skip_basic_info < 2; skip_basic_info++) { for (int skip_color_encoding = 0; skip_color_encoding < 2; diff --git a/third_party/jpeg-xl/lib/jxl/entropy_coder_test.cc b/third_party/jpeg-xl/lib/jxl/entropy_coder_test.cc index d32fe1b26b..0389490d8e 100644 --- a/third_party/jpeg-xl/lib/jxl/entropy_coder_test.cc +++ b/third_party/jpeg-xl/lib/jxl/entropy_coder_test.cc @@ -27,7 +27,7 @@ TEST(EntropyCoderTest, PackUnpack) { struct MockBitReader { uint32_t nbits, bits; void Consume(uint32_t nbits) {} - uint32_t PeekBits(uint32_t n) { + uint32_t PeekBits(uint32_t n) const { EXPECT_EQ(n, nbits); return bits; } diff --git a/third_party/jpeg-xl/lib/jxl/gradient_test.cc b/third_party/jpeg-xl/lib/jxl/gradient_test.cc index d2c83619fc..e09b34603f 100644 --- a/third_party/jpeg-xl/lib/jxl/gradient_test.cc +++ b/third_party/jpeg-xl/lib/jxl/gradient_test.cc @@ -186,13 +186,13 @@ constexpr bool fast_mode = true; TEST(GradientTest, SteepGradient) { test::ThreadPoolForTests pool(8); // Relatively steep gradients, colors from the sky of stp.png - TestGradient(&pool, 0xd99d58, 0x889ab1, 512, 512, 90, fast_mode, 3.0); + TestGradient(pool.get(), 0xd99d58, 0x889ab1, 512, 512, 90, fast_mode, 3.0); } TEST(GradientTest, SubtleGradient) { test::ThreadPoolForTests pool(8); // Very subtle gradient - TestGradient(&pool, 0xb89b7b, 0xa89b8d, 512, 512, 90, fast_mode, 4.0); + TestGradient(pool.get(), 0xb89b7b, 0xa89b8d, 512, 512, 90, fast_mode, 4.0); } } // namespace diff --git a/third_party/jpeg-xl/lib/jxl/icc_codec.h b/third_party/jpeg-xl/lib/jxl/icc_codec.h index 8b880c7d3b..3b0b0c041b 100644 --- a/third_party/jpeg-xl/lib/jxl/icc_codec.h +++ b/third_party/jpeg-xl/lib/jxl/icc_codec.h @@ -28,7 +28,7 @@ struct ICCReader { } private: - Status CheckEOI(BitReader* reader); + static Status CheckEOI(BitReader* reader); size_t i_ = 0; size_t bits_to_skip_ = 0; size_t used_bits_base_ = 0; diff --git a/third_party/jpeg-xl/lib/jxl/jpeg/dec_jpeg_data.cc b/third_party/jpeg-xl/lib/jxl/jpeg/dec_jpeg_data.cc index 9763786453..a971eb3dcc 100644 --- a/third_party/jpeg-xl/lib/jxl/jpeg/dec_jpeg_data.cc +++ b/third_party/jpeg-xl/lib/jxl/jpeg/dec_jpeg_data.cc @@ -106,15 +106,14 @@ Status DecodeJPEGData(Span<const uint8_t> encoded, JPEGData* jpeg_data) { } } // TODO(eustas): actually inject ICC profile and check it fits perfectly. - for (size_t i = 0; i < jpeg_data->com_data.size(); i++) { - auto& marker = jpeg_data->com_data[i]; + for (auto& marker : jpeg_data->com_data) { JXL_RETURN_IF_ERROR(br_read(marker)); if (marker[1] * 256u + marker[2] + 1u != marker.size()) { return JXL_FAILURE("Incorrect marker size"); } } - for (size_t i = 0; i < jpeg_data->inter_marker_data.size(); i++) { - JXL_RETURN_IF_ERROR(br_read(jpeg_data->inter_marker_data[i])); + for (auto& data : jpeg_data->inter_marker_data) { + JXL_RETURN_IF_ERROR(br_read(data)); } JXL_RETURN_IF_ERROR(br_read(jpeg_data->tail_data)); diff --git a/third_party/jpeg-xl/lib/jxl/jpeg/dec_jpeg_data_writer.cc b/third_party/jpeg-xl/lib/jxl/jpeg/dec_jpeg_data_writer.cc index 31bb2dda23..77c8b885e1 100644 --- a/third_party/jpeg-xl/lib/jxl/jpeg/dec_jpeg_data_writer.cc +++ b/third_party/jpeg-xl/lib/jxl/jpeg/dec_jpeg_data_writer.cc @@ -385,8 +385,8 @@ bool EncodeDHT(const JPEGData& jpg, SerializationState* state) { for (size_t i = state->dht_index; i < huffman_code.size(); ++i) { const JPEGHuffmanCode& huff = huffman_code[i]; marker_len += kJpegHuffmanMaxBitLength; - for (size_t j = 0; j < huff.counts.size(); ++j) { - marker_len += huff.counts[j]; + for (uint32_t count : huff.counts) { + marker_len += count; } if (huff.is_last) break; } 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 d311908415..d7c6c2ad78 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 @@ -173,8 +173,7 @@ Status ParseChunkedMarker(const jpeg::JPEGData& src, uint8_t marker_type, } Status SetBlobsFromJpegData(const jpeg::JPEGData& jpeg_data, Blobs* blobs) { - for (size_t i = 0; i < jpeg_data.app_data.size(); i++) { - const auto& marker = jpeg_data.app_data[i]; + for (const auto& marker : jpeg_data.app_data) { if (marker.empty() || marker[0] != kApp1) { continue; } @@ -318,11 +317,11 @@ Status EncodeJPEGData(JPEGData& jpeg_data, std::vector<uint8_t>* bytes, } total_data += jpeg_data.app_data[i].size(); } - for (size_t i = 0; i < jpeg_data.com_data.size(); i++) { - total_data += jpeg_data.com_data[i].size(); + for (const auto& data : jpeg_data.com_data) { + total_data += data.size(); } - for (size_t i = 0; i < jpeg_data.inter_marker_data.size(); i++) { - total_data += jpeg_data.inter_marker_data[i].size(); + for (const auto& data : jpeg_data.inter_marker_data) { + total_data += data.size(); } total_data += jpeg_data.tail_data.size(); size_t brotli_capacity = BrotliEncoderMaxCompressedSize(total_data); @@ -365,11 +364,11 @@ Status EncodeJPEGData(JPEGData& jpeg_data, std::vector<uint8_t>* bytes, } br_append(jpeg_data.app_data[i], /*last=*/false); } - for (size_t i = 0; i < jpeg_data.com_data.size(); i++) { - br_append(jpeg_data.com_data[i], /*last=*/false); + for (const auto& data : jpeg_data.com_data) { + br_append(data, /*last=*/false); } - for (size_t i = 0; i < jpeg_data.inter_marker_data.size(); i++) { - br_append(jpeg_data.inter_marker_data[i], /*last=*/false); + for (const auto& data : jpeg_data.inter_marker_data) { + br_append(data, /*last=*/false); } br_append(jpeg_data.tail_data, /*last=*/true); BrotliEncoderDestroyInstance(brotli_enc); diff --git a/third_party/jpeg-xl/lib/jxl/jpeg/enc_jpeg_data_reader.cc b/third_party/jpeg-xl/lib/jxl/jpeg/enc_jpeg_data_reader.cc index d1e8476db6..8208bba675 100644 --- a/third_party/jpeg-xl/lib/jxl/jpeg/enc_jpeg_data_reader.cc +++ b/third_party/jpeg-xl/lib/jxl/jpeg/enc_jpeg_data_reader.cc @@ -92,21 +92,21 @@ bool ProcessSOF(const uint8_t* data, const size_t len, JpegReadMode mode, std::vector<bool> ids_seen(256, false); int max_h_samp_factor = 1; int max_v_samp_factor = 1; - for (size_t i = 0; i < jpg->components.size(); ++i) { + for (auto& component : jpg->components) { const int id = ReadUint8(data, pos); if (ids_seen[id]) { // (cf. section B.2.2, syntax of Ci) return JXL_FAILURE("Duplicate ID %d in SOF.", id); } ids_seen[id] = true; - jpg->components[i].id = id; + component.id = id; int factor = ReadUint8(data, pos); int h_samp_factor = factor >> 4; int v_samp_factor = factor & 0xf; JXL_JPEG_VERIFY_INPUT(h_samp_factor, 1, kBrunsliMaxSampling, SAMP_FACTOR); JXL_JPEG_VERIFY_INPUT(v_samp_factor, 1, kBrunsliMaxSampling, SAMP_FACTOR); - jpg->components[i].h_samp_factor = h_samp_factor; - jpg->components[i].v_samp_factor = v_samp_factor; - jpg->components[i].quant_idx = ReadUint8(data, pos); + component.h_samp_factor = h_samp_factor; + component.v_samp_factor = v_samp_factor; + component.quant_idx = ReadUint8(data, pos); max_h_samp_factor = std::max(max_h_samp_factor, h_samp_factor); max_v_samp_factor = std::max(max_v_samp_factor, v_samp_factor); } @@ -116,18 +116,17 @@ bool ProcessSOF(const uint8_t* data, const size_t len, JpegReadMode mode, int MCU_rows = DivCeil(jpg->height, max_v_samp_factor * 8); int MCU_cols = DivCeil(jpg->width, max_h_samp_factor * 8); // Compute the block dimensions for each component. - for (size_t i = 0; i < jpg->components.size(); ++i) { - JPEGComponent* c = &jpg->components[i]; - if (max_h_samp_factor % c->h_samp_factor != 0 || - max_v_samp_factor % c->v_samp_factor != 0) { + for (JPEGComponent& c : jpg->components) { + if (max_h_samp_factor % c.h_samp_factor != 0 || + max_v_samp_factor % c.v_samp_factor != 0) { return JXL_FAILURE("Non-integral subsampling ratios."); } - c->width_in_blocks = MCU_cols * c->h_samp_factor; - c->height_in_blocks = MCU_rows * c->v_samp_factor; + c.width_in_blocks = MCU_cols * c.h_samp_factor; + c.height_in_blocks = MCU_rows * c.v_samp_factor; const uint64_t num_blocks = - static_cast<uint64_t>(c->width_in_blocks) * c->height_in_blocks; + static_cast<uint64_t>(c.width_in_blocks) * c.height_in_blocks; if (mode == JpegReadMode::kReadAll) { - c->coeffs.resize(num_blocks * kDCTBlockSize); + c.coeffs.resize(num_blocks * kDCTBlockSize); } } JXL_JPEG_VERIFY_MARKER_END(); @@ -192,8 +191,8 @@ bool ProcessSOS(const uint8_t* data, const size_t len, size_t* pos, for (size_t i = 0; i < comps_in_scan; ++i) { bool found_dc_table = false; bool found_ac_table = false; - for (size_t j = 0; j < jpg->huffman_code.size(); ++j) { - uint32_t slot_id = jpg->huffman_code[j].slot_id; + for (const auto& code : jpg->huffman_code) { + uint32_t slot_id = code.slot_id; if (slot_id == scan_info.components[i].dc_tbl_idx) { found_dc_table = true; } else if (slot_id == scan_info.components[i].ac_tbl_idx + 16) { @@ -757,11 +756,9 @@ bool ProcessScan(const uint8_t* data, const size_t len, bool is_interleaved = (scan_info->num_components > 1); int max_h_samp_factor = 1; int max_v_samp_factor = 1; - for (size_t i = 0; i < jpg->components.size(); ++i) { - max_h_samp_factor = - std::max(max_h_samp_factor, jpg->components[i].h_samp_factor); - max_v_samp_factor = - std::max(max_v_samp_factor, jpg->components[i].v_samp_factor); + for (const auto& component : jpg->components) { + max_h_samp_factor = std::max(max_h_samp_factor, component.h_samp_factor); + max_v_samp_factor = std::max(max_v_samp_factor, component.v_samp_factor); } int MCU_rows = DivCeil(jpg->height, max_v_samp_factor * 8); diff --git a/third_party/jpeg-xl/lib/jxl/jpeg/jpeg_data.cc b/third_party/jpeg-xl/lib/jxl/jpeg/jpeg_data.cc index aeb9914cca..3217115acb 100644 --- a/third_party/jpeg-xl/lib/jxl/jpeg/jpeg_data.cc +++ b/third_party/jpeg-xl/lib/jxl/jpeg/jpeg_data.cc @@ -78,8 +78,8 @@ Status JPEGData::VisitFields(Visitor* visitor) { if (marker_order.size() > 16384) { return JXL_FAILURE("Too many markers: %" PRIuS "\n", marker_order.size()); } - for (size_t i = 0; i < marker_order.size(); i++) { - JXL_RETURN_IF_ERROR(VisitMarker(&marker_order[i], visitor, &info)); + for (uint8_t& marker : marker_order) { + JXL_RETURN_IF_ERROR(VisitMarker(&marker, visitor, &info)); } if (!marker_order.empty()) { // Last marker should always be EOI marker. @@ -175,8 +175,8 @@ Status JPEGData::VisitFields(Visitor* visitor) { components.resize(num_components); } if (component_type == JPEGComponentType::kCustom) { - for (size_t i = 0; i < components.size(); i++) { - JXL_RETURN_IF_ERROR(visitor->Bits(8, 0, &components[i].id)); + for (auto& component : components) { + JXL_RETURN_IF_ERROR(visitor->Bits(8, 0, &component.id)); } } else if (component_type == JPEGComponentType::kGray) { components[0].id = 1; @@ -322,11 +322,11 @@ Status JPEGData::VisitFields(Visitor* visitor) { scan.extra_zero_runs.resize(num_extra_zero_runs); } last_block_idx = -1; - for (size_t i = 0; i < scan.extra_zero_runs.size(); ++i) { - uint32_t& block_idx = scan.extra_zero_runs[i].block_idx; - JXL_RETURN_IF_ERROR(visitor->U32( - Val(1), BitsOffset(2, 2), BitsOffset(4, 5), BitsOffset(8, 20), 1, - &scan.extra_zero_runs[i].num_extra_zero_runs)); + for (auto& extra_zero_run : scan.extra_zero_runs) { + uint32_t& block_idx = extra_zero_run.block_idx; + JXL_RETURN_IF_ERROR(visitor->U32(Val(1), BitsOffset(2, 2), + BitsOffset(4, 5), BitsOffset(8, 20), 1, + &extra_zero_run.num_extra_zero_runs)); block_idx -= last_block_idx + 1; JXL_RETURN_IF_ERROR(visitor->U32(Val(0), BitsOffset(3, 1), BitsOffset(5, 9), BitsOffset(28, 41), 0, diff --git a/third_party/jpeg-xl/lib/jxl/jxl_test.cc b/third_party/jpeg-xl/lib/jxl/jxl_test.cc index b0933d5d50..cf9857f462 100644 --- a/third_party/jpeg-xl/lib/jxl/jxl_test.cc +++ b/third_party/jpeg-xl/lib/jxl/jxl_test.cc @@ -179,7 +179,8 @@ TEST(JxlTest, RoundtripResample2MT) { cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 3); // kFalcon PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 203300, 2000); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf_out), 203300, + 2000); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 340); } @@ -286,8 +287,8 @@ TEST(JxlTest, RoundtripMultiGroup) { cparams.distance = target_distance; PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), expected_size, - 700); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf_out), + expected_size, 700); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), expected_distance); }; @@ -302,7 +303,7 @@ TEST(JxlTest, RoundtripRGBToGrayscale) { ThreadPoolForTests pool(4); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png"); CodecInOut io; - ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, &pool)); + ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, pool.get())); io.ShrinkTo(600, 1024); CompressParams cparams; @@ -316,7 +317,7 @@ TEST(JxlTest, RoundtripRGBToGrayscale) { EXPECT_FALSE(io.Main().IsGray()); size_t compressed_size; JXL_EXPECT_OK( - Roundtrip(&io, cparams, dparams, &io2, _, &compressed_size, &pool)); + Roundtrip(&io, cparams, dparams, &io2, _, &compressed_size, pool.get())); EXPECT_LE(compressed_size, 65000u); EXPECT_TRUE(io2.Main().IsGray()); @@ -341,7 +342,7 @@ TEST(JxlTest, RoundtripRGBToGrayscale) { EXPECT_SLIGHTLY_BELOW( ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(), *JxlGetDefaultCms(), - /*distmap=*/nullptr, &pool), + /*distmap=*/nullptr, pool.get()), 1.4); } @@ -355,11 +356,12 @@ TEST(JxlTest, RoundtripLargeFast) { cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 7); // kSquirrel PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 503000, 12000); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf_out), 503000, + 12000); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 78); } -TEST(JxlTest, JXL_X86_64_TEST(RoundtripLargeEmptyModular)) { +JXL_X86_64_TEST(JxlTest, RoundtripLargeEmptyModular) { ThreadPoolForTests pool(8); TestImage t; t.SetDimensions(4096, 4096).SetDataType(JXL_TYPE_UINT8).SetChannels(4); @@ -380,7 +382,7 @@ TEST(JxlTest, JXL_X86_64_TEST(RoundtripLargeEmptyModular)) { cparams.AddOption(JXL_ENC_FRAME_SETTING_DECODING_SPEED, 2); PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 3474795, + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf_out), 3474795, 100000); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), #if JXL_HIGH_PRECISION @@ -403,8 +405,8 @@ TEST(JxlTest, RoundtripOutputColorSpace) { JXLDecompressParams dparams; dparams.color_space = "RGB_D65_DCI_Rel_709"; PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, dparams, &pool, &ppf_out), 503000, - 12000); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, dparams, pool.get(), &ppf_out), + 503000, 12000); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 78); } @@ -421,7 +423,8 @@ TEST(JxlTest, RoundtripDotsForceEpf) { cparams.AddOption(JXL_ENC_FRAME_SETTING_DOTS, 1); PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 41355, 300); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf_out), 41355, + 300); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 18); } @@ -443,10 +446,10 @@ TEST(JxlTest, RoundtripD2Consistent) { t.SetDimensions(xsize, 15); PackedPixelFile ppf2; - const size_t size2 = Roundtrip(t.ppf(), cparams, {}, &pool, &ppf2); + const size_t size2 = Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf2); PackedPixelFile ppf3; - const size_t size3 = Roundtrip(t.ppf(), cparams, {}, &pool, &ppf3); + const size_t size3 = Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf3); // Exact same compressed size. EXPECT_EQ(size2, size3); @@ -471,7 +474,7 @@ TEST(JxlTest, RoundtripLargeConsistent) { auto roundtrip_and_compare = [&]() { ThreadPoolForTests pool(8); PackedPixelFile ppf2; - size_t size = Roundtrip(t.ppf(), cparams, {}, &pool, &ppf2); + size_t size = Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf2); double dist = ComputeDistance2(t.ppf(), ppf2); return std::tuple<size_t, double>(size, dist); }; @@ -985,7 +988,7 @@ TEST(JxlTest, RoundtripAlpha16) { PackedPixelFile ppf_out; // TODO(szabadka) Investigate big size difference on i686 // This still keeps happening (2023-04-18). - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 3666, 120); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf_out), 3666, 120); EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.65); } @@ -1000,7 +1003,7 @@ JXLCompressParams CompressParamsForLossless() { } } // namespace -TEST(JxlTest, JXL_SLOW_TEST(RoundtripLossless8)) { +JXL_SLOW_TEST(JxlTest, RoundtripLossless8) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("external/wesaturate/500px/tmshre_riaphotographs_srgb8.png"); @@ -1012,11 +1015,11 @@ TEST(JxlTest, JXL_SLOW_TEST(RoundtripLossless8)) { dparams.accepted_formats.push_back(t.ppf().frames[0].color.format); PackedPixelFile ppf_out; - EXPECT_EQ(Roundtrip(t.ppf(), cparams, dparams, &pool, &ppf_out), 223058); + EXPECT_EQ(Roundtrip(t.ppf(), cparams, dparams, pool.get(), &ppf_out), 223058); EXPECT_EQ(ComputeDistance2(t.ppf(), ppf_out), 0.0); } -TEST(JxlTest, JXL_SLOW_TEST(RoundtripLossless8ThunderGradient)) { +JXL_SLOW_TEST(JxlTest, RoundtripLossless8ThunderGradient) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("external/wesaturate/500px/tmshre_riaphotographs_srgb8.png"); @@ -1030,11 +1033,11 @@ TEST(JxlTest, JXL_SLOW_TEST(RoundtripLossless8ThunderGradient)) { dparams.accepted_formats.push_back(t.ppf().frames[0].color.format); PackedPixelFile ppf_out; - EXPECT_EQ(Roundtrip(t.ppf(), cparams, dparams, &pool, &ppf_out), 261684); + EXPECT_EQ(Roundtrip(t.ppf(), cparams, dparams, pool.get(), &ppf_out), 261684); EXPECT_EQ(ComputeDistance2(t.ppf(), ppf_out), 0.0); } -TEST(JxlTest, JXL_SLOW_TEST(RoundtripLossless8LightningGradient)) { +JXL_SLOW_TEST(JxlTest, RoundtripLossless8LightningGradient) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("external/wesaturate/500px/tmshre_riaphotographs_srgb8.png"); @@ -1048,12 +1051,12 @@ TEST(JxlTest, JXL_SLOW_TEST(RoundtripLossless8LightningGradient)) { PackedPixelFile ppf_out; // Lax comparison because different SIMD will cause different compression. - EXPECT_SLIGHTLY_BELOW(Roundtrip(t.ppf(), cparams, dparams, &pool, &ppf_out), - 286848u); + EXPECT_SLIGHTLY_BELOW( + Roundtrip(t.ppf(), cparams, dparams, pool.get(), &ppf_out), 286848u); EXPECT_EQ(ComputeDistance2(t.ppf(), ppf_out), 0.0); } -TEST(JxlTest, JXL_SLOW_TEST(RoundtripLossless8Falcon)) { +JXL_SLOW_TEST(JxlTest, RoundtripLossless8Falcon) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("external/wesaturate/500px/tmshre_riaphotographs_srgb8.png"); @@ -1066,7 +1069,7 @@ TEST(JxlTest, JXL_SLOW_TEST(RoundtripLossless8Falcon)) { dparams.accepted_formats.push_back(t.ppf().frames[0].color.format); PackedPixelFile ppf_out; - EXPECT_EQ(Roundtrip(t.ppf(), cparams, dparams, &pool, &ppf_out), 230766); + EXPECT_EQ(Roundtrip(t.ppf(), cparams, dparams, pool.get(), &ppf_out), 230766); EXPECT_EQ(ComputeDistance2(t.ppf(), ppf_out), 0.0); } @@ -1348,15 +1351,15 @@ void RoundtripJpegToPixels(const std::vector<uint8_t>& jpeg_in, nullptr, ppf_out, nullptr)); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression444)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompression444) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png.im_q85_444.jpg"); // JPEG size is 696,659 bytes. - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 568891u, 20); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 568891u, 20); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionToPixels) { TEST_LIBJPEG_SUPPORT(); ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = @@ -1365,11 +1368,11 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels)) { t.DecodeFromBytes(orig); PackedPixelFile ppf_out; - RoundtripJpegToPixels(orig, {}, &pool, &ppf_out); + RoundtripJpegToPixels(orig, {}, pool.get(), &ppf_out); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 12); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels420)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionToPixels420) { TEST_LIBJPEG_SUPPORT(); ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = @@ -1378,12 +1381,12 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels420)) { t.DecodeFromBytes(orig); PackedPixelFile ppf_out; - RoundtripJpegToPixels(orig, {}, &pool, &ppf_out); + RoundtripJpegToPixels(orig, {}, pool.get(), &ppf_out); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 11); } -TEST(JxlTest, - JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels420EarlyFlush)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, + RoundtripJpegRecompressionToPixels420EarlyFlush) { TEST_LIBJPEG_SUPPORT(); ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = @@ -1395,12 +1398,11 @@ TEST(JxlTest, dparams.max_downsampling = 8; PackedPixelFile ppf_out; - RoundtripJpegToPixels(orig, dparams, &pool, &ppf_out); + RoundtripJpegToPixels(orig, dparams, pool.get(), &ppf_out); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 4410); } -TEST(JxlTest, - JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels420Mul16)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionToPixels420Mul16) { TEST_LIBJPEG_SUPPORT(); ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = @@ -1409,12 +1411,11 @@ TEST(JxlTest, t.DecodeFromBytes(orig); PackedPixelFile ppf_out; - RoundtripJpegToPixels(orig, {}, &pool, &ppf_out); + RoundtripJpegToPixels(orig, {}, pool.get(), &ppf_out); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 4); } -TEST(JxlTest, - JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels_asymmetric)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionToPixelsAsymmetric) { TEST_LIBJPEG_SUPPORT(); ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = @@ -1423,102 +1424,100 @@ TEST(JxlTest, t.DecodeFromBytes(orig); PackedPixelFile ppf_out; - RoundtripJpegToPixels(orig, {}, &pool, &ppf_out); + RoundtripJpegToPixels(orig, {}, pool.get(), &ppf_out); EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 10); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionGray)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionGray) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png.im_q85_gray.jpg"); // JPEG size is 456,528 bytes. - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 387496u, 200); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 387496u, 200); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression420)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompression420) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png.im_q85_420.jpg"); // JPEG size is 546,797 bytes. - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 455510u, 20); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 455510u, 20); } -TEST(JxlTest, - JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression_luma_subsample)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionLumaSubsample) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png.im_q85_luma_subsample.jpg"); // JPEG size is 400,724 bytes. - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 325310u, 20); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 325310u, 20); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression444_12)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompression444wh12) { // 444 JPEG that has an interesting sampling-factor (1x2, 1x2, 1x2). ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png.im_q85_444_1x2.jpg"); // JPEG size is 703,874 bytes. - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 569630u, 20); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 569630u, 20); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression422)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompression422) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png.im_q85_422.jpg"); // JPEG size is 522,057 bytes. - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 499236u, 20); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 499236u, 20); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression440)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompression440) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png.im_q85_440.jpg"); // JPEG size is 603,623 bytes. - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 501101u, 20); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 501101u, 20); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression_asymmetric)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionAsymmetric) { // 2x vertical downsample of one chroma channel, 2x horizontal downsample of // the other. ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png.im_q85_asymmetric.jpg"); // JPEG size is 604,601 bytes. - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 500548u, 20); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 500548u, 20); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression420Progr)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompression420Progr) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png.im_q85_420_progr.jpg"); // JPEG size is 522,057 bytes. - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 455454u, 20); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 455454u, 20); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionMetadata)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionMetadata) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/jpeg_reconstruction/1x1_exif_xmp.jpg"); // JPEG size is 4290 bytes // 1370 on 386, so higher margin. - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 1334u, 100); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 1334u, 100); } -TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionRestarts)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionRestarts) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/jpeg_reconstruction/bicycles_restarts.jpg"); // JPEG size is 87478 bytes - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 76054u, 30); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 76054u, 30); } -TEST(JxlTest, - JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionOrientationICC)) { +JXL_TRANSCODE_JPEG_TEST(JxlTest, RoundtripJpegRecompressionOrientationICC) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/jpeg_reconstruction/sideways_bench.jpg"); // JPEG size is 15252 bytes - EXPECT_NEAR(RoundtripJpeg(orig, &pool), 12000u, 470); + EXPECT_NEAR(RoundtripJpeg(orig, pool.get()), 12000u, 470); // TODO(jon): investigate why 'Cross-compiling i686-linux-gnu' produces a // larger result } @@ -1535,7 +1534,8 @@ TEST(JxlTest, RoundtripProgressive) { cparams.AddOption(JXL_ENC_FRAME_SETTING_RESPONSIVE, 1); PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 70544, 750); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf_out), 70544, + 750); EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.4); } @@ -1552,7 +1552,8 @@ TEST(JxlTest, RoundtripProgressiveLevel2Slow) { cparams.AddOption(JXL_ENC_FRAME_SETTING_RESPONSIVE, 1); PackedPixelFile ppf_out; - EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 76666, 1000); + EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool.get(), &ppf_out), 76666, + 1000); EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.17); } @@ -1639,7 +1640,7 @@ TEST_P(JxlTest, LosslessSmallFewColors) { dparams.accepted_formats.push_back(t.ppf().frames[0].color.format); PackedPixelFile ppf_out; - Roundtrip(t.ppf(), cparams, dparams, &pool, &ppf_out); + Roundtrip(t.ppf(), cparams, dparams, pool.get(), &ppf_out); EXPECT_EQ(ComputeDistance2(t.ppf(), ppf_out), 0.0); } @@ -1708,7 +1709,7 @@ TEST_P(JxlStreamingTest, Roundtrip) { ThreadPoolForTests pool(8); PackedPixelFile ppf_out; - Roundtrip(image.ppf(), cparams, {}, &pool, &ppf_out); + Roundtrip(image.ppf(), cparams, {}, pool.get(), &ppf_out); EXPECT_GT(jxl::test::ComputePSNR(image.ppf(), ppf_out), p.max_psnr()); } @@ -1763,7 +1764,7 @@ class JxlStreamingEncodingTest : public ::testing::TestWithParam<StreamingEncodingTestParam> {}; // This is broken on mingw32, so we only enable it for x86_64 now. -TEST_P(JxlStreamingEncodingTest, JXL_X86_64_TEST(StreamingSamePixels)) { +JXL_X86_64_TEST_P(JxlStreamingEncodingTest, StreamingSamePixels) { const auto param = GetParam(); const std::vector<uint8_t> orig = ReadTestData(param.file); @@ -1780,11 +1781,11 @@ TEST_P(JxlStreamingEncodingTest, JXL_X86_64_TEST(StreamingSamePixels)) { ThreadPoolForTests pool(8); PackedPixelFile ppf_out; - Roundtrip(image.ppf(), cparams, {}, &pool, &ppf_out); + Roundtrip(image.ppf(), cparams, {}, pool.get(), &ppf_out); cparams.AddOption(JXL_ENC_FRAME_SETTING_BUFFERING, 3); PackedPixelFile ppf_out_streaming; - Roundtrip(image.ppf(), cparams, {}, &pool, &ppf_out_streaming); + Roundtrip(image.ppf(), cparams, {}, pool.get(), &ppf_out_streaming); EXPECT_TRUE(jxl::test::SamePixels(ppf_out, ppf_out_streaming)); } 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 acda762545..c7752d8cfc 100644 --- a/third_party/jpeg-xl/lib/jxl/lehmer_code_test.cc +++ b/third_party/jpeg-xl/lib/jxl/lehmer_code_test.cc @@ -88,10 +88,10 @@ void RoundtripSizeRange(ThreadPool* pool, uint32_t begin, uint32_t end) { TEST(LehmerCodeTest, TestRoundtrips) { test::ThreadPoolForTests pool(8); - RoundtripSizeRange<uint16_t>(&pool, 1, 1026); + RoundtripSizeRange<uint16_t>(pool.get(), 1, 1026); // Ensures PermutationT can fit > 16 bit values. - RoundtripSizeRange<uint32_t>(&pool, 65536, 65540); + RoundtripSizeRange<uint32_t>(pool.get(), 65536, 65540); } } // namespace 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 7bec5128fc..df54a9425e 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 @@ -63,7 +63,7 @@ struct State { pixel_type_w pred = 0; // *before* removing the added bits. std::vector<uint32_t> pred_errors[kNumPredictors]; std::vector<int32_t> error; - const Header header; + const Header &header; // Allows to approximate division by a number from 1 to 64. // for (int i = 0; i < 64; i++) divlookup[i] = (1 << 24) / (i + 1); @@ -82,7 +82,7 @@ struct State { return static_cast<uint64_t>(x) << kPredExtraBits; } - State(Header header, size_t xsize, size_t ysize) : header(header) { + State(const Header &header, size_t xsize, size_t ysize) : header(header) { // Extra margin to avoid out-of-bounds writes. // All have space for two rows of data. for (auto &pred_error : pred_errors) { diff --git a/third_party/jpeg-xl/lib/jxl/modular/encoding/enc_ma.cc b/third_party/jpeg-xl/lib/jxl/modular/encoding/enc_ma.cc index de629ad038..23100bba8b 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/encoding/enc_ma.cc +++ b/third_party/jpeg-xl/lib/jxl/modular/encoding/enc_ma.cc @@ -197,7 +197,7 @@ void FindBestSplit(TreeSamples &tree_samples, float threshold, float rcost = std::numeric_limits<float>::max(); Predictor lpred = Predictor::Zero; Predictor rpred = Predictor::Zero; - float Cost() { return lcost + rcost; } + float Cost() const { return lcost + rcost; } }; SplitInfo best_split_static_constant; @@ -242,14 +242,14 @@ void FindBestSplit(TreeSamples &tree_samples, float threshold, // The multiplier ranges cut halfway through the current ranges of static // properties. We do this even if the current node is not a leaf, to // minimize the number of nodes in the resulting tree. - for (size_t i = 0; i < mul_info.size(); i++) { + for (const auto &mmi : mul_info) { uint32_t axis; uint32_t val; IntersectionType t = - BoxIntersects(static_prop_range, mul_info[i].range, axis, val); + BoxIntersects(static_prop_range, mmi.range, axis, val); if (t == IntersectionType::kNone) continue; if (t == IntersectionType::kInside) { - (*tree)[pos].multiplier = mul_info[i].multiplier; + (*tree)[pos].multiplier = mmi.multiplier; break; } if (t == IntersectionType::kPartial) { diff --git a/third_party/jpeg-xl/lib/jxl/modular/encoding/encoding.cc b/third_party/jpeg-xl/lib/jxl/modular/encoding/encoding.cc index bb690b74ba..7e7aa019e3 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/encoding/encoding.cc +++ b/third_party/jpeg-xl/lib/jxl/modular/encoding/encoding.cc @@ -113,7 +113,7 @@ FlatTree FilterTree(const Tree &global_tree, } } - for (size_t j = 0; j < 2; j++) mark_property(flat.properties[j]); + for (int16_t property : flat.properties) mark_property(property); mark_property(flat.property0); output.push_back(flat); } @@ -159,9 +159,9 @@ Status DecodeModularChannelMAANS(BitReader *br, ANSSymbolReader *reader, // From here on, tree lookup returns a *clustered* context ID. // This avoids an extra memory lookup after tree traversal. - for (size_t i = 0; i < tree.size(); i++) { - if (tree[i].property0 == -1) { - tree[i].childID = context_map[tree[i].childID]; + for (auto &node : tree) { + if (node.property0 == -1) { + node.childID = context_map[node.childID]; } } @@ -538,8 +538,8 @@ Status ModularDecode(BitReader *br, Image &image, GroupHeader &header, // Don't do/undo transforms if header is incomplete. header.transforms.clear(); image.transform = header.transforms; - for (size_t c = 0; c < image.channel.size(); c++) { - ZeroFillImage(&image.channel[c].plane); + for (auto &ch : image.channel) { + ZeroFillImage(&ch.plane); } return Status(StatusCode::kNotEnoughBytes); } 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 24c64f5aad..7f9399d3c4 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 @@ -68,8 +68,8 @@ static int QuantizeColorToImplicitPaletteIndex( int index = 0; if (high_quality) { int multiplier = 1; - for (size_t c = 0; c < color.size(); c++) { - int quantized = ((kLargeCube - 1) * color[c] + (1 << (bit_depth - 1))) / + for (int value : color) { + int quantized = ((kLargeCube - 1) * value + (1 << (bit_depth - 1))) / ((1 << bit_depth) - 1); JXL_ASSERT((quantized % kLargeCube) == quantized); index += quantized * multiplier; @@ -78,8 +78,7 @@ static int QuantizeColorToImplicitPaletteIndex( return index + palette_size + kLargeCubeOffset; } else { int multiplier = 1; - for (size_t c = 0; c < color.size(); c++) { - int value = color[c]; + for (int value : color) { value -= 1 << (std::max(0, bit_depth - 3)); value = std::max(0, value); int quantized = ((kLargeCube - 1) * value + (1 << (bit_depth - 1))) / @@ -171,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 (!lossy && nb_colors < 2) return false; if (!lossy && nb == 1) { // Channel palette special case @@ -321,6 +321,20 @@ Status FwdPaletteIteration(Image &input, uint32_t begin_c, uint32_t end_c, } } + std::map<std::vector<pixel_type>, bool> implicit_color; + std::vector<std::vector<pixel_type>> implicit_colors; + implicit_colors.reserve(palette_internal::kImplicitPaletteSize); + for (size_t k = 0; k < palette_internal::kImplicitPaletteSize; k++) { + for (size_t i = 0; i < nb; i++) { + color[i] = palette_internal::GetPaletteValue(nullptr, k, i, 0, 0, + input.bitdepth); + } + implicit_color[color] = true; + implicit_colors.push_back(color); + } + + std::map<std::vector<pixel_type>, size_t> color_freq_map; + uint32_t implicit_colors_used = 0; for (size_t y = 0; y < h; y++) { for (uint32_t c = 0; c < nb; c++) { p_in[c] = input.channel[begin_c + c].Row(y); @@ -332,15 +346,39 @@ Status FwdPaletteIteration(Image &input, uint32_t begin_c, uint32_t end_c, } const bool new_color = candidate_palette.insert(color).second; if (new_color) { - candidate_palette_imageorder.push_back(color); - } - if (candidate_palette.size() > nb_colors) { - return false; // too many colors + if (implicit_color[color]) { + implicit_colors_used++; + } else { + candidate_palette_imageorder.push_back(color); + if (candidate_palette_imageorder.size() > nb_colors) { + return false; // too many colors + } + } } + color_freq_map[color] += 1; } } - nb_colors = nb_deltas + candidate_palette.size(); + nb_colors = nb_deltas + candidate_palette_imageorder.size(); + + // not useful to make a single-color palette + if (!lossy && nb_colors + implicit_colors_used == 1) return false; + // TODO(jon): if this happens (e.g. solid white group), special-case it for + // faster encode + + for (size_t k = 0; k < palette_internal::kImplicitPaletteSize; k++) { + color = implicit_colors[k]; + // still add the color to the explicit palette if it is frequent enough + if (color_freq_map[color] > 10) { + nb_colors++; + candidate_palette_imageorder.push_back(color); + } + } + for (size_t k = 0; k < palette_internal::kImplicitPaletteSize; k++) { + color = implicit_colors[k]; + inv_palette[color] = nb_colors + k; + } + JXL_DEBUG_V(6, "Channels %i-%i can be represented using a %i-color palette.", begin_c, end_c, nb_colors); @@ -360,25 +398,33 @@ Status FwdPaletteIteration(Image &input, uint32_t begin_c, uint32_t end_c, } } } - + // Separate the palette in two buckets, first the common colors, then the + // rare colors. + // Within each bucket, the colors are sorted on luma (times alpha). + float freq_threshold = 4; // arbitrary threshold int x = 0; if (ordered && nb >= 3) { JXL_DEBUG_V(7, "Palette of %i colors, using luma order", nb_colors); // sort on luma (multiplied by alpha if available) std::sort(candidate_palette_imageorder.begin(), candidate_palette_imageorder.end(), - [](std::vector<pixel_type> ap, std::vector<pixel_type> bp) { + [&](std::vector<pixel_type> ap, std::vector<pixel_type> bp) { float ay; float by; ay = (0.299f * ap[0] + 0.587f * ap[1] + 0.114f * ap[2] + 0.1f); if (ap.size() > 3) ay *= 1.f + ap[3]; by = (0.299f * bp[0] + 0.587f * bp[1] + 0.114f * bp[2] + 0.1f); if (bp.size() > 3) by *= 1.f + bp[3]; + // put common colors first, transparent dark to opaque bright, + // then rare colors, bright to dark + ay = color_freq_map[ap] > freq_threshold ? -ay : ay; + by = color_freq_map[bp] > freq_threshold ? -by : by; return ay < by; }); } else { JXL_DEBUG_V(7, "Palette of %i colors, using image order", nb_colors); } + for (auto pcol : candidate_palette_imageorder) { JXL_DEBUG_V(9, " Color %i : ", x); for (size_t i = 0; i < nb; i++) { @@ -398,10 +444,10 @@ Status FwdPaletteIteration(Image &input, uint32_t begin_c, uint32_t end_c, // beneficial for both precision and encoding speed. std::vector<std::vector<float>> error_row[3]; if (lossy) { - for (int i = 0; i < 3; ++i) { - error_row[i].resize(nb); + for (auto &row : error_row) { + row.resize(nb); for (size_t c = 0; c < nb; ++c) { - error_row[i][c].resize(w + 4); + row[c].resize(w + 4); } } } @@ -424,13 +470,11 @@ Status FwdPaletteIteration(Image &input, uint32_t begin_c, uint32_t end_c, std::vector<pixel_type> ideal_residual(nb, 0); std::vector<pixel_type> quantized_val(nb); std::vector<pixel_type> predictions(nb); - static const double kDiffusionMultiplier[] = {0.55, 0.75}; - for (int diffusion_index = 0; diffusion_index < 2; ++diffusion_index) { + for (double diffusion_multiplier : {0.55, 0.75}) { for (size_t c = 0; c < nb; c++) { color_with_error[c] = p_in[c][x] + (palette_iteration_data.final_run ? 1 : 0) * - kDiffusionMultiplier[diffusion_index] * - error_row[0][c][x + 2]; + diffusion_multiplier * error_row[0][c][x + 2]; color[c] = Clamp1(lroundf(color_with_error[c]), 0l, (1l << input.bitdepth) - 1); } diff --git a/third_party/jpeg-xl/lib/jxl/modular/transform/enc_squeeze.cc b/third_party/jpeg-xl/lib/jxl/modular/transform/enc_squeeze.cc index 0d924c0ace..7371830743 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/enc_squeeze.cc +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/enc_squeeze.cc @@ -124,13 +124,13 @@ Status FwdSqueeze(Image &input, std::vector<SqueezeParams> parameters, } // if nothing to do, don't do squeeze if (parameters.empty()) return false; - for (size_t i = 0; i < parameters.size(); i++) { + for (auto ¶meter : parameters) { JXL_RETURN_IF_ERROR( - CheckMetaSqueezeParams(parameters[i], input.channel.size())); - bool horizontal = parameters[i].horizontal; - bool in_place = parameters[i].in_place; - uint32_t beginc = parameters[i].begin_c; - uint32_t endc = parameters[i].begin_c + parameters[i].num_c - 1; + CheckMetaSqueezeParams(parameter, input.channel.size())); + bool horizontal = parameter.horizontal; + bool in_place = parameter.in_place; + uint32_t beginc = parameter.begin_c; + uint32_t endc = parameter.begin_c + parameter.num_c - 1; uint32_t offset; if (in_place) { offset = endc + 1; 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 e0405a2162..2a9e5c71f4 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/palette.h +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/palette.h @@ -30,6 +30,8 @@ static constexpr int kSmallCube = 4; static constexpr int kSmallCubeBits = 2; // kSmallCube ** 3 static constexpr int kLargeCubeOffset = kSmallCube * kSmallCube * kSmallCube; +static constexpr int kImplicitPaletteSize = + kLargeCubeOffset + kLargeCube * kLargeCube * kLargeCube; static inline pixel_type Scale(uint64_t value, uint64_t bit_depth, uint64_t denom) { diff --git a/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.cc b/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.cc index 580829741a..b71c8dc248 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.cc +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.cc @@ -385,21 +385,21 @@ void DefaultSqueezeParameters(std::vector<SqueezeParams> *parameters, params.in_place = true; if (!wide) { - if (h > JXL_MAX_FIRST_PREVIEW_SIZE) { + if (h > kMaxFirstPreviewSize) { params.horizontal = false; parameters->push_back(params); h = (h + 1) / 2; JXL_DEBUG_V(7, "Vertical (%" PRIuS "x%" PRIuS "), ", w, h); } } - while (w > JXL_MAX_FIRST_PREVIEW_SIZE || h > JXL_MAX_FIRST_PREVIEW_SIZE) { - if (w > JXL_MAX_FIRST_PREVIEW_SIZE) { + while (w > kMaxFirstPreviewSize || h > kMaxFirstPreviewSize) { + if (w > kMaxFirstPreviewSize) { params.horizontal = true; parameters->push_back(params); w = (w + 1) / 2; JXL_DEBUG_V(7, "Horizontal (%" PRIuS "x%" PRIuS "), ", w, h); } - if (h > JXL_MAX_FIRST_PREVIEW_SIZE) { + if (h > kMaxFirstPreviewSize) { params.horizontal = false; parameters->push_back(params); h = (h + 1) / 2; @@ -424,13 +424,13 @@ Status MetaSqueeze(Image &image, std::vector<SqueezeParams> *parameters) { DefaultSqueezeParameters(parameters, image); } - for (size_t i = 0; i < parameters->size(); i++) { + for (auto ¶meter : *parameters) { JXL_RETURN_IF_ERROR( - CheckMetaSqueezeParams((*parameters)[i], image.channel.size())); - bool horizontal = (*parameters)[i].horizontal; - bool in_place = (*parameters)[i].in_place; - uint32_t beginc = (*parameters)[i].begin_c; - uint32_t endc = (*parameters)[i].begin_c + (*parameters)[i].num_c - 1; + CheckMetaSqueezeParams(parameter, image.channel.size())); + bool horizontal = parameter.horizontal; + bool in_place = parameter.in_place; + uint32_t beginc = parameter.begin_c; + uint32_t endc = parameter.begin_c + parameter.num_c - 1; uint32_t offset; if (beginc < image.nb_meta_channels) { @@ -441,7 +441,7 @@ Status MetaSqueeze(Image &image, std::vector<SqueezeParams> *parameters) { return JXL_FAILURE( "Invalid squeeze: meta channels require in-place residuals"); } - image.nb_meta_channels += (*parameters)[i].num_c; + image.nb_meta_channels += parameter.num_c; } if (in_place) { offset = endc + 1; 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 bbd16c59c0..f0333da6fd 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.h +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.h @@ -29,10 +29,10 @@ #include "lib/jxl/modular/modular_image.h" #include "lib/jxl/modular/transform/transform.h" -#define JXL_MAX_FIRST_PREVIEW_SIZE 8 - namespace jxl { +constexpr size_t kMaxFirstPreviewSize = 8; + /* int avg=(A+B)>>1; int diff=(A-B); 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 33f7a10cc9..a609cfb3fb 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/transform.cc +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/transform.cc @@ -23,7 +23,7 @@ Transform::Transform(TransformId id) { } Status Transform::Inverse(Image &input, const weighted::Header &wp_header, - ThreadPool *pool) { + ThreadPool *pool) const { JXL_DEBUG_V(6, "Input channels (%" PRIuS ", %" PRIuS " meta): ", input.channel.size(), input.nb_meta_channels); switch (id) { 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 b68861706f..70c383834a 100644 --- a/third_party/jpeg-xl/lib/jxl/modular/transform/transform.h +++ b/third_party/jpeg-xl/lib/jxl/modular/transform/transform.h @@ -134,7 +134,7 @@ class Transform : public Fields { JXL_FIELDS_NAME(Transform) Status Inverse(Image &input, const weighted::Header &wp_header, - ThreadPool *pool = nullptr); + ThreadPool *pool = nullptr) const; Status MetaApply(Image &input); }; diff --git a/third_party/jpeg-xl/lib/jxl/modular_test.cc b/third_party/jpeg-xl/lib/jxl/modular_test.cc index bd1a947493..ceebf59c0b 100644 --- a/third_party/jpeg-xl/lib/jxl/modular_test.cc +++ b/third_party/jpeg-xl/lib/jxl/modular_test.cc @@ -80,15 +80,15 @@ void TestLosslessGroups(size_t group_size_shift) { TEST(ModularTest, RoundtripLosslessGroups128) { TestLosslessGroups(0); } -TEST(ModularTest, JXL_TSAN_SLOW_TEST(RoundtripLosslessGroups512)) { +JXL_TSAN_SLOW_TEST(ModularTest, RoundtripLosslessGroups512) { TestLosslessGroups(2); } -TEST(ModularTest, JXL_TSAN_SLOW_TEST(RoundtripLosslessGroups1024)) { +JXL_TSAN_SLOW_TEST(ModularTest, RoundtripLosslessGroups1024) { TestLosslessGroups(3); } -TEST(ModularTest, RoundtripLosslessCustomWP_PermuteRCT) { +TEST(ModularTest, RoundtripLosslessCustomWpPermuteRCT) { const std::vector<uint8_t> orig = ReadTestData("external/wesaturate/500px/u76c0g_bliznaca_srgb8.png"); TestImage t; @@ -144,6 +144,7 @@ TEST(ModularTest, RoundtripLossyDeltaPaletteWP) { cparams.SetLossless(); cparams.lossy_palette = true; cparams.palette_colors = 0; + // TODO(jon): this is currently ignored, and Avg4 is always used instead cparams.options.predictor = jxl::Predictor::Weighted; CodecInOut io_out; @@ -154,12 +155,12 @@ TEST(ModularTest, RoundtripLossyDeltaPaletteWP) { size_t compressed_size; JXL_EXPECT_OK(Roundtrip(&io, cparams, {}, &io_out, _, &compressed_size)); - EXPECT_LE(compressed_size, 7000u); + EXPECT_LE(compressed_size, 6500u); EXPECT_SLIGHTLY_BELOW( ButteraugliDistance(io.frames, io_out.frames, ButteraugliParams(), *JxlGetDefaultCms(), /*distmap=*/nullptr), - 10.1); + 1.5); } TEST(ModularTest, RoundtripLossy) { @@ -346,8 +347,8 @@ TEST_P(ModularTestParam, RoundtripLossless) { const float* in = io.Main().color()->PlaneRow(c, y); const float* out = io2.Main().color()->PlaneRow(c, y); for (size_t x = 0; x < xsize; x++) { - uint32_t uin = in[x] * factor + 0.5; - uint32_t uout = out[x] * factor + 0.5; + uint32_t uin = std::lroundf(in[x] * factor); + uint32_t uout = std::lroundf(out[x] * factor); // check that the integer values are identical if (uin != uout) different++; } diff --git a/third_party/jpeg-xl/lib/jxl/passes_test.cc b/third_party/jpeg-xl/lib/jxl/passes_test.cc index cb9164706f..e7a7547a0c 100644 --- a/third_party/jpeg-xl/lib/jxl/passes_test.cc +++ b/third_party/jpeg-xl/lib/jxl/passes_test.cc @@ -80,7 +80,7 @@ TEST(PassesTest, RoundtripMultiGroupPasses) { CodecInOut io; { ThreadPoolForTests pool(4); - ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, &pool)); + ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, pool.get())); } io.ShrinkTo(600, 1024); // partial X, full Y group @@ -92,11 +92,11 @@ TEST(PassesTest, RoundtripMultiGroupPasses) { cparams.SetCms(*JxlGetDefaultCms()); CodecInOut io2; JXL_EXPECT_OK(Roundtrip(&io, cparams, {}, &io2, _, - /* compressed_size */ nullptr, &pool)); + /* compressed_size */ nullptr, pool.get())); EXPECT_SLIGHTLY_BELOW( ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(), *JxlGetDefaultCms(), - /*distmap=*/nullptr, &pool), + /*distmap=*/nullptr, pool.get()), target_distance + threshold); }; @@ -108,7 +108,7 @@ TEST(PassesTest, RoundtripLargeFastPasses) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png"); CodecInOut io; - ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, &pool)); + ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, pool.get())); CompressParams cparams; cparams.speed_tier = SpeedTier::kSquirrel; @@ -117,7 +117,7 @@ TEST(PassesTest, RoundtripLargeFastPasses) { CodecInOut io2; JXL_EXPECT_OK(Roundtrip(&io, cparams, {}, &io2, _, - /* compressed_size */ nullptr, &pool)); + /* compressed_size */ nullptr, pool.get())); } // Checks for differing size/distance in two consecutive runs of distance 2, @@ -127,7 +127,7 @@ TEST(PassesTest, RoundtripProgressiveConsistent) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png"); CodecInOut io; - ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, &pool)); + ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, pool.get())); CompressParams cparams; cparams.speed_tier = SpeedTier::kSquirrel; @@ -141,11 +141,11 @@ TEST(PassesTest, RoundtripProgressiveConsistent) { CodecInOut io2; size_t size2; - JXL_EXPECT_OK(Roundtrip(&io, cparams, {}, &io2, _, &size2, &pool)); + JXL_EXPECT_OK(Roundtrip(&io, cparams, {}, &io2, _, &size2, pool.get())); CodecInOut io3; size_t size3; - JXL_EXPECT_OK(Roundtrip(&io, cparams, {}, &io3, _, &size3, &pool)); + JXL_EXPECT_OK(Roundtrip(&io, cparams, {}, &io3, _, &size3, pool.get())); // Exact same compressed size. EXPECT_EQ(size2, size3); @@ -153,10 +153,10 @@ TEST(PassesTest, RoundtripProgressiveConsistent) { // Exact same distance. const float dist2 = ButteraugliDistance( io.frames, io2.frames, ButteraugliParams(), *JxlGetDefaultCms(), - /*distmap=*/nullptr, &pool); + /*distmap=*/nullptr, pool.get()); const float dist3 = ButteraugliDistance( io.frames, io3.frames, ButteraugliParams(), *JxlGetDefaultCms(), - /*distmap=*/nullptr, &pool); + /*distmap=*/nullptr, pool.get()); EXPECT_EQ(dist2, dist3); } } @@ -166,7 +166,7 @@ TEST(PassesTest, AllDownsampleFeasible) { const std::vector<uint8_t> orig = ReadTestData("external/wesaturate/500px/u76c0g_bliznaca_srgb8.png"); CodecInOut io; - ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, &pool)); + ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, pool.get())); std::vector<uint8_t> compressed; @@ -174,7 +174,7 @@ TEST(PassesTest, AllDownsampleFeasible) { cparams.speed_tier = SpeedTier::kSquirrel; cparams.progressive_mode = Override::kOn; cparams.butteraugli_distance = 1.0; - ASSERT_TRUE(test::EncodeFile(cparams, &io, &compressed, &pool)); + ASSERT_TRUE(test::EncodeFile(cparams, &io, &compressed, pool.get())); EXPECT_LE(compressed.size(), 240000u); float target_butteraugli[9] = {}; @@ -202,7 +202,7 @@ TEST(PassesTest, AllDownsampleFeasible) { target_butteraugli[downsampling]) << "downsampling: " << downsampling; }; - EXPECT_TRUE(RunOnPool(&pool, 0, downsamplings.size(), ThreadPool::NoInit, + EXPECT_TRUE(RunOnPool(pool.get(), 0, downsamplings.size(), ThreadPool::NoInit, check, "TestDownsampling")); } @@ -211,7 +211,7 @@ TEST(PassesTest, AllDownsampleFeasibleQProgressive) { const std::vector<uint8_t> orig = ReadTestData("external/wesaturate/500px/u76c0g_bliznaca_srgb8.png"); CodecInOut io; - ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, &pool)); + ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, pool.get())); std::vector<uint8_t> compressed; @@ -219,7 +219,7 @@ TEST(PassesTest, AllDownsampleFeasibleQProgressive) { cparams.speed_tier = SpeedTier::kSquirrel; cparams.qprogressive_mode = Override::kOn; cparams.butteraugli_distance = 1.0; - ASSERT_TRUE(test::EncodeFile(cparams, &io, &compressed, &pool)); + ASSERT_TRUE(test::EncodeFile(cparams, &io, &compressed, pool.get())); EXPECT_LE(compressed.size(), 220000u); @@ -247,7 +247,7 @@ TEST(PassesTest, AllDownsampleFeasibleQProgressive) { target_butteraugli[downsampling]) << "downsampling: " << downsampling; }; - EXPECT_TRUE(RunOnPool(&pool, 0, downsamplings.size(), ThreadPool::NoInit, + EXPECT_TRUE(RunOnPool(pool.get(), 0, downsamplings.size(), ThreadPool::NoInit, check, "TestQProgressive")); } @@ -256,7 +256,7 @@ TEST(PassesTest, ProgressiveDownsample2DegradesCorrectlyGrayscale) { const std::vector<uint8_t> orig = ReadTestData( "external/wesaturate/500px/cvo9xd_keong_macan_grayscale.png"); CodecInOut io_orig; - ASSERT_TRUE(SetFromBytes(Bytes(orig), &io_orig, &pool)); + ASSERT_TRUE(SetFromBytes(Bytes(orig), &io_orig, pool.get())); Rect rect(0, 0, io_orig.xsize(), 128); // need 2 DC groups for the DC frame to actually be progressive. JXL_ASSIGN_OR_DIE(Image3F large, Image3F::Create(4242, rect.ysize())); @@ -274,7 +274,7 @@ TEST(PassesTest, ProgressiveDownsample2DegradesCorrectlyGrayscale) { cparams.responsive = JXL_TRUE; cparams.qprogressive_mode = Override::kOn; cparams.butteraugli_distance = 1.0; - ASSERT_TRUE(test::EncodeFile(cparams, &io, &compressed, &pool)); + ASSERT_TRUE(test::EncodeFile(cparams, &io, &compressed, pool.get())); EXPECT_LE(compressed.size(), 10000u); @@ -300,7 +300,7 @@ TEST(PassesTest, ProgressiveDownsample2DegradesCorrectly) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png"); CodecInOut io_orig; - ASSERT_TRUE(SetFromBytes(Bytes(orig), &io_orig, &pool)); + ASSERT_TRUE(SetFromBytes(Bytes(orig), &io_orig, pool.get())); Rect rect(0, 0, io_orig.xsize(), 128); // need 2 DC groups for the DC frame to actually be progressive. JXL_ASSIGN_OR_DIE(Image3F large, Image3F::Create(4242, rect.ysize())); @@ -317,7 +317,7 @@ TEST(PassesTest, ProgressiveDownsample2DegradesCorrectly) { cparams.responsive = JXL_TRUE; cparams.qprogressive_mode = Override::kOn; cparams.butteraugli_distance = 1.0; - ASSERT_TRUE(test::EncodeFile(cparams, &io, &compressed, &pool)); + ASSERT_TRUE(test::EncodeFile(cparams, &io, &compressed, pool.get())); EXPECT_LE(compressed.size(), 220000u); @@ -343,7 +343,7 @@ TEST(PassesTest, NonProgressiveDCImage) { ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png"); CodecInOut io; - ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, &pool)); + ASSERT_TRUE(SetFromBytes(Bytes(orig), &io, pool.get())); std::vector<uint8_t> compressed; @@ -351,14 +351,15 @@ TEST(PassesTest, NonProgressiveDCImage) { cparams.speed_tier = SpeedTier::kSquirrel; cparams.progressive_mode = Override::kOff; cparams.butteraugli_distance = 2.0; - ASSERT_TRUE(test::EncodeFile(cparams, &io, &compressed, &pool)); + ASSERT_TRUE(test::EncodeFile(cparams, &io, &compressed, pool.get())); // Even in non-progressive mode, it should be possible to return a DC-only // image. extras::JXLDecompressParams dparams; dparams.max_downsampling = 100; CodecInOut output; - ASSERT_TRUE(test::DecodeFile(dparams, Bytes(compressed), &output, &pool)); + ASSERT_TRUE( + test::DecodeFile(dparams, Bytes(compressed), &output, pool.get())); EXPECT_EQ(output.xsize(), io.xsize()); EXPECT_EQ(output.ysize(), io.ysize()); } 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 e92cbf2151..776a1c776d 100644 --- a/third_party/jpeg-xl/lib/jxl/quant_weights_test.cc +++ b/third_party/jpeg-xl/lib/jxl/quant_weights_test.cc @@ -164,7 +164,7 @@ TEST(QuantWeightsTest, RAW) { QuantEncoding::Library(0)); std::vector<int> matrix(3 * 32 * 32); Rng rng(0); - for (size_t i = 0; i < matrix.size(); i++) matrix[i] = rng.UniformI(1, 256); + for (int& v : matrix) v = rng.UniformI(1, 256); encodings[DequantMatrices::kQuantTable[AcStrategy::DCT32X32]] = QuantEncoding::RAW(matrix, 2); RoundtripMatrices(encodings); 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 14bd363110..09e3dbab76 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 @@ -20,7 +20,7 @@ void RenderPipeline::Builder::AddStage( StatusOr<std::unique_ptr<RenderPipeline>> RenderPipeline::Builder::Finalize( FrameDimensions frame_dimensions) && { #if JXL_ENABLE_ASSERT - // Check that the last stage is not an kInOut stage for any channel, and that + // Check that the last stage is not a kInOut stage for any channel, and that // there is at least one stage. JXL_ASSERT(!stages_.empty()); for (size_t c = 0; c < num_c_; c++) { 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 7f5a8ef00f..77ddb3d430 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 @@ -22,12 +22,12 @@ Status SimpleRenderPipeline::PrepareForThreadsInternal(size_t num, auto ch_size = [](size_t frame_size, size_t shift) { return DivCeil(frame_size, 1 << shift) + kRenderPipelineXOffset * 2; }; - for (size_t c = 0; c < channel_shifts_[0].size(); c++) { + for (auto& entry : channel_shifts_[0]) { JXL_ASSIGN_OR_RETURN( - ImageF ch, ImageF::Create(ch_size(frame_dimensions_.xsize_upsampled, - channel_shifts_[0][c].first), - ch_size(frame_dimensions_.ysize_upsampled, - channel_shifts_[0][c].second))); + ImageF ch, + ImageF::Create( + ch_size(frame_dimensions_.xsize_upsampled, entry.first), + ch_size(frame_dimensions_.ysize_upsampled, entry.second))); channel_data_.push_back(std::move(ch)); msan::PoisonImage(channel_data_.back()); } diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_cms.cc b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_cms.cc index 3202a03e44..9ce65e1644 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_cms.cc +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_cms.cc @@ -45,7 +45,7 @@ class CmsStage : public RenderPipelineStage { size_t xextra, size_t xsize, size_t xpos, size_t ypos, size_t thread_id) const final { JXL_ASSERT(xsize <= xsize_); - // TODO(firsching): handle grey case seperately + // TODO(firsching): handle grey case separately // interleave float* JXL_RESTRICT row0 = GetInputRow(input_rows, 0, 0); float* JXL_RESTRICT row1 = GetInputRow(input_rows, 1, 0); diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_epf.cc b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_epf.cc index d3030b02cb..b281e41794 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_epf.cc +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_epf.cc @@ -40,10 +40,10 @@ JXL_INLINE Vec<DF> Weight(Vec<DF> sad, Vec<DF> inv_sigma, Vec<DF> thres) { // this filter a 7x7 filter. class EPF0Stage : public RenderPipelineStage { public: - EPF0Stage(const LoopFilter& lf, const ImageF& sigma) + EPF0Stage(LoopFilter lf, const ImageF& sigma) : RenderPipelineStage(RenderPipelineStage::Settings::Symmetric( /*shift=*/0, /*border=*/3)), - lf_(lf), + lf_(std::move(lf)), sigma_(&sigma) {} template <bool aligned> @@ -72,7 +72,7 @@ class EPF0Stage : public RenderPipelineStage { DF df; using V = decltype(Zero(df)); - V t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, tA, tB; + V t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, tA, tB; // NOLINT V* sads[12] = {&t0, &t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9, &tA, &tB}; xextra = RoundUpTo(xextra, Lanes(df)); @@ -114,7 +114,7 @@ class EPF0Stage : public RenderPipelineStage { const auto sm = Load(df, sad_mul + ix); const auto inv_sigma = Mul(Set(df, row_sigma[bx]), sm); - for (size_t i = 0; i < 12; i++) *sads[i] = Zero(df); + for (auto& sad : sads) *sad = Zero(df); constexpr std::array<int, 2> sads_off[12] = { {{-2, 0}}, {{-1, -1}}, {{-1, 0}}, {{-1, 1}}, {{0, -2}}, {{0, -1}}, {{0, 1}}, {{0, 2}}, {{1, -1}}, {{1, 0}}, {{1, 1}}, {{2, 0}}, @@ -128,12 +128,10 @@ class EPF0Stage : public RenderPipelineStage { auto sad = Zero(df); constexpr std::array<int, 2> plus_off[] = { {{0, 0}}, {{-1, 0}}, {{0, -1}}, {{1, 0}}, {{0, 1}}}; - for (size_t j = 0; j < 5; j++) { - const auto r11 = - LoadU(df, rows[c][3 + plus_off[j][0]] + x + plus_off[j][1]); - const auto c11 = - LoadU(df, rows[c][3 + sads_off[i][0] + plus_off[j][0]] + x + - sads_off[i][1] + plus_off[j][1]); + for (const auto& off : plus_off) { + const auto r11 = LoadU(df, rows[c][3 + off[0]] + x + off[1]); + const auto c11 = LoadU(df, rows[c][3 + sads_off[i][0] + off[0]] + + x + sads_off[i][1] + off[1]); sad = Add(sad, AbsDiff(r11, c11)); } *sads[i] = MulAdd(sad, scale, *sads[i]); @@ -181,10 +179,10 @@ class EPF0Stage : public RenderPipelineStage { // makes this filter a 5x5 filter. class EPF1Stage : public RenderPipelineStage { public: - EPF1Stage(const LoopFilter& lf, const ImageF& sigma) + EPF1Stage(LoopFilter lf, const ImageF& sigma) : RenderPipelineStage(RenderPipelineStage::Settings::Symmetric( /*shift=*/0, /*border=*/2)), - lf_(lf), + lf_(std::move(lf)), sigma_(&sigma) {} template <bool aligned> @@ -362,10 +360,10 @@ class EPF1Stage : public RenderPipelineStage { // filter. class EPF2Stage : public RenderPipelineStage { public: - EPF2Stage(const LoopFilter& lf, const ImageF& sigma) + EPF2Stage(LoopFilter lf, const ImageF& sigma) : RenderPipelineStage(RenderPipelineStage::Settings::Symmetric( /*shift=*/0, /*border=*/1)), - lf_(lf), + lf_(std::move(lf)), sigma_(&sigma) {} template <bool aligned> diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_upsampling.cc b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_upsampling.cc index 897b20c4c6..e868f9f8e0 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_upsampling.cc +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_upsampling.cc @@ -110,7 +110,7 @@ class UpsamplingStage : public RenderPipelineStage { ssize_t x0, ssize_t x1) const { static HWY_FULL(float) df; using V = hwy::HWY_NAMESPACE::Vec<HWY_FULL(float)>; - V ups0, ups1, ups2, ups3, ups4, ups5, ups6, ups7; + V ups0, ups1, ups2, ups3, ups4, ups5, ups6, ups7; // NOLINT (void)ups2, (void)ups3, (void)ups4, (void)ups5, (void)ups6, (void)ups7; // Once we have C++17 available, change this back to `V* ups[N]` and // initialize using `if constexpr` below. diff --git a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_write.cc b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_write.cc index c5a91e8efd..05cdd786a9 100644 --- a/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_write.cc +++ b/third_party/jpeg-xl/lib/jxl/render_pipeline/stage_write.cc @@ -11,6 +11,7 @@ #include "lib/jxl/base/common.h" #include "lib/jxl/base/status.h" #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/sanitizers.h" @@ -556,11 +557,11 @@ HWY_EXPORT(GetWriteToOutputStage); namespace { class WriteToImageBundleStage : public RenderPipelineStage { public: - explicit WriteToImageBundleStage(ImageBundle* image_bundle, - ColorEncoding color_encoding) + explicit WriteToImageBundleStage( + ImageBundle* image_bundle, const OutputEncodingInfo& output_encoding_info) : RenderPipelineStage(RenderPipelineStage::Settings()), image_bundle_(image_bundle), - color_encoding_(std::move(color_encoding)) {} + color_encoding_(output_encoding_info.color_encoding) {} Status SetInputSizes( const std::vector<std::pair<size_t, size_t>>& input_sizes) override { @@ -658,9 +659,9 @@ class WriteToImage3FStage : public RenderPipelineStage { } // namespace std::unique_ptr<RenderPipelineStage> GetWriteToImageBundleStage( - ImageBundle* image_bundle, ColorEncoding color_encoding) { + ImageBundle* image_bundle, const OutputEncodingInfo& output_encoding_info) { return jxl::make_unique<WriteToImageBundleStage>(image_bundle, - std::move(color_encoding)); + output_encoding_info); } std::unique_ptr<RenderPipelineStage> GetWriteToImage3FStage(Image3F* image) { 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 c5f844ebe8..ba2c51ee97 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 @@ -9,13 +9,14 @@ #include <functional> #include "lib/jxl/dec_cache.h" +#include "lib/jxl/dec_xyb.h" #include "lib/jxl/image_bundle.h" #include "lib/jxl/render_pipeline/render_pipeline_stage.h" namespace jxl { std::unique_ptr<RenderPipelineStage> GetWriteToImageBundleStage( - ImageBundle* image_bundle, ColorEncoding color_encoding); + ImageBundle* image_bundle, const OutputEncodingInfo& output_encoding_info); // Gets a stage to write color channels to an Image3F. std::unique_ptr<RenderPipelineStage> GetWriteToImage3FStage(Image3F* image); diff --git a/third_party/jpeg-xl/lib/jxl/roundtrip_test.cc b/third_party/jpeg-xl/lib/jxl/roundtrip_test.cc index a4a87bebb7..07e43e4ddf 100644 --- a/third_party/jpeg-xl/lib/jxl/roundtrip_test.cc +++ b/third_party/jpeg-xl/lib/jxl/roundtrip_test.cc @@ -941,7 +941,7 @@ TEST(RoundtripTest, TestICCProfile) { JxlDecoderDestroy(dec); } -TEST(RoundtripTest, JXL_TRANSCODE_JPEG_TEST(TestJPEGReconstruction)) { +JXL_TRANSCODE_JPEG_TEST(RoundtripTest, TestJPEGReconstruction) { TEST_LIBJPEG_SUPPORT(); const std::string jpeg_path = "jxl/flower/flower.png.im_q85_420.jpg"; const std::vector<uint8_t> orig = jxl::test::ReadTestData(jpeg_path); 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 381367b54d..8783faec8f 100644 --- a/third_party/jpeg-xl/lib/jxl/speed_tier_test.cc +++ b/third_party/jpeg-xl/lib/jxl/speed_tier_test.cc @@ -82,7 +82,6 @@ JXL_GTEST_INSTANTIATE_TEST_SUITE_P( TEST_P(SpeedTierTest, Roundtrip) { const SpeedTierTestParams& params = GetParam(); - test::ThreadPoolForTests pool(8); const std::vector<uint8_t> orig = jxl::test::ReadTestData( "external/wesaturate/500px/u76c0g_bliznaca_srgb8.png"); test::TestImage t; diff --git a/third_party/jpeg-xl/lib/jxl/splines.cc b/third_party/jpeg-xl/lib/jxl/splines.cc index 1d4fc69e3e..2df2160d76 100644 --- a/third_party/jpeg-xl/lib/jxl/splines.cc +++ b/third_party/jpeg-xl/lib/jxl/splines.cc @@ -94,11 +94,11 @@ void DrawSegment(DF df, const SplineSegment& segment, const bool add, void DrawSegment(const SplineSegment& segment, const bool add, const size_t y, const ssize_t x0, ssize_t x1, float* JXL_RESTRICT rows[3]) { - ssize_t x = - std::max<ssize_t>(x0, segment.center_x - segment.maximum_distance + 0.5f); + ssize_t x = std::max<ssize_t>( + x0, std::llround(segment.center_x - segment.maximum_distance)); // one-past-the-end - x1 = - std::min<ssize_t>(x1, segment.center_x + segment.maximum_distance + 1.5f); + x1 = std::min<ssize_t>( + x1, std::llround(segment.center_x + segment.maximum_distance) + 1); HWY_FULL(float) df; for (; x + static_cast<ssize_t>(Lanes(df)) <= x1; x += Lanes(df)) { DrawSegment(df, segment, add, y, x, rows); @@ -550,8 +550,8 @@ Status QuantizedSpline::Decode(const std::vector<uint8_t>& context_map, } return true; }; - for (int c = 0; c < 3; ++c) { - JXL_RETURN_IF_ERROR(decode_dct(color_dct_[c])); + for (auto& dct : color_dct_) { + JXL_RETURN_IF_ERROR(decode_dct(dct)); } JXL_RETURN_IF_ERROR(decode_dct(sigma_dct_)); return true; diff --git a/third_party/jpeg-xl/lib/jxl/test_image.cc b/third_party/jpeg-xl/lib/jxl/test_image.cc index 42f028d53a..d2e17c6ab0 100644 --- a/third_party/jpeg-xl/lib/jxl/test_image.cc +++ b/third_party/jpeg-xl/lib/jxl/test_image.cc @@ -288,8 +288,7 @@ TestImage& TestImage::SetAllBitDepths(uint32_t bits_per_sample, ppf_.info.alpha_bits = bits_per_sample; ppf_.info.alpha_exponent_bits = exponent_bits_per_sample; } - for (size_t i = 0; i < ppf_.extra_channels_info.size(); ++i) { - extras::PackedExtraChannel& ec = ppf_.extra_channels_info[i]; + for (auto& ec : ppf_.extra_channels_info) { ec.ec_info.bits_per_sample = bits_per_sample; ec.ec_info.exponent_bits_per_sample = exponent_bits_per_sample; } diff --git a/third_party/jpeg-xl/lib/jxl/test_utils.h b/third_party/jpeg-xl/lib/jxl/test_utils.h index 15057cc92d..dc50490174 100644 --- a/third_party/jpeg-xl/lib/jxl/test_utils.h +++ b/third_party/jpeg-xl/lib/jxl/test_utils.h @@ -180,8 +180,7 @@ class ThreadPoolForTests { } ThreadPoolForTests(const ThreadPoolForTests&) = delete; ThreadPoolForTests& operator&(const ThreadPoolForTests&) = delete; - // TODO(eustas): avoid unary `&` overload? - ThreadPool* operator&() { return pool_.get(); } + ThreadPool* get() { return pool_.get(); } private: JxlThreadParallelRunnerPtr runner_; diff --git a/third_party/jpeg-xl/lib/jxl/testing.h b/third_party/jpeg-xl/lib/jxl/testing.h index 1fac352a78..6e4978eb60 100644 --- a/third_party/jpeg-xl/lib/jxl/testing.h +++ b/third_party/jpeg-xl/lib/jxl/testing.h @@ -13,33 +13,37 @@ #include "lib/jxl/common.h" #ifdef JXL_DISABLE_SLOW_TESTS -#define JXL_SLOW_TEST(X) DISABLED_##X +#define JXL_SLOW_TEST(T, C) TEST(T, DISABLED_##C) #else -#define JXL_SLOW_TEST(X) X +#define JXL_SLOW_TEST(T, C) TEST(T, C) #endif // JXL_DISABLE_SLOW_TESTS #if JPEGXL_ENABLE_TRANSCODE_JPEG -#define JXL_TRANSCODE_JPEG_TEST(X) X +#define JXL_TRANSCODE_JPEG_TEST(T, C) TEST(T, C) #else -#define JXL_TRANSCODE_JPEG_TEST(X) DISABLED_##X +#define JXL_TRANSCODE_JPEG_TEST(T, C) TEST(T, DISABLED_##C) #endif // JPEGXL_ENABLE_TRANSCODE_JPEG #if JPEGXL_ENABLE_BOXES -#define JXL_BOXES_TEST(X) X +#define JXL_BOXES_TEST(T, C) TEST(T, C) +#define JXL_BOXES_TEST_P(T, C) TEST_P(T, C) #else -#define JXL_BOXES_TEST(X) DISABLED_##X +#define JXL_BOXES_TEST(T, C) TEST(T, DISABLED_##C) +#define JXL_BOXES_TEST_P(T, C) TEST_P(T, DISABLED_##C) #endif // JPEGXL_ENABLE_BOXES #ifdef THREAD_SANITIZER -#define JXL_TSAN_SLOW_TEST(X) DISABLED_##X +#define JXL_TSAN_SLOW_TEST(T, C) TEST(T, DISABLED_##C) #else -#define JXL_TSAN_SLOW_TEST(X) X +#define JXL_TSAN_SLOW_TEST(T, C) TEST(T, C) #endif // THREAD_SANITIZER #if defined(__x86_64__) -#define JXL_X86_64_TEST(X) X +#define JXL_X86_64_TEST(T, C) TEST(T, C) +#define JXL_X86_64_TEST_P(T, C) TEST_P(T, C) #else -#define JXL_X86_64_TEST(X) DISABLED_##X +#define JXL_X86_64_TEST(T, C) TEST(T, DISABLED_##C) +#define JXL_X86_64_TEST_P(T, C) TEST_P(T, C) #endif // defined(__x86_64__) // googletest before 1.10 didn't define INSTANTIATE_TEST_SUITE_P() but instead diff --git a/third_party/jpeg-xl/lib/jxl/tf_gbench.cc b/third_party/jpeg-xl/lib/jxl/tf_gbench.cc index e93a936c90..6cfd3734bb 100644 --- a/third_party/jpeg-xl/lib/jxl/tf_gbench.cc +++ b/third_party/jpeg-xl/lib/jxl/tf_gbench.cc @@ -46,7 +46,9 @@ namespace { #define RUN_BENCHMARK_SCALAR(F, I) \ constexpr size_t kNum = 1 << 12; \ /* Three parallel runs, as this will run on R, G and B. */ \ - float sum1 = 0, sum2 = 0, sum3 = 0; \ + float sum1 = 0; \ + float sum2 = 0; \ + float sum3 = 0; \ for (auto _ : state) { \ float x = 1e-5; \ float v1 = 1e-5; \ diff --git a/third_party/jpeg-xl/lib/jxl/version.h.in b/third_party/jpeg-xl/lib/jxl/version.h.in index ad1eb24409..b5a462e52e 100644 --- a/third_party/jpeg-xl/lib/jxl/version.h.in +++ b/third_party/jpeg-xl/lib/jxl/version.h.in @@ -32,7 +32,7 @@ #define JPEGXL_COMPUTE_NUMERIC_VERSION(major,minor,patch) (((major)<<24) | ((minor)<<16) | ((patch)<<8) | 0) /* Numeric representation of the version */ -#define JPEGXL_NUMERIC_VERSION JPEGXL_COMPUTE_NUMERIC_VERSION(JPEGXL_MAJOR_VERSION,JPEGXL_MINOR_VERSION,JPEGXL_PATCH_VERSION) +#define JPEGXL_NUMERIC_VERSION JPEGXL_COMPUTE_NUMERIC_VERSION(JPEGXL_MAJOR_VERSION, JPEGXL_MINOR_VERSION, JPEGXL_PATCH_VERSION) #endif /* JXL_VERSION_H_ */ diff --git a/third_party/jpeg-xl/lib/jxl/xorshift128plus_test.cc b/third_party/jpeg-xl/lib/jxl/xorshift128plus_test.cc index 2ee4535284..c68ce4bb3b 100644 --- a/third_party/jpeg-xl/lib/jxl/xorshift128plus_test.cc +++ b/third_party/jpeg-xl/lib/jxl/xorshift128plus_test.cc @@ -294,7 +294,7 @@ void TestFloat() { const uint32_t kMaxSeed = 4096; #endif // JXL_DISABLE_SLOW_TESTS EXPECT_TRUE(RunOnPool( - &pool, 0, kMaxSeed, ThreadPool::NoInit, + pool.get(), 0, kMaxSeed, ThreadPool::NoInit, [](const uint32_t seed, size_t /*thread*/) { HWY_ALIGN Xorshift128Plus rng(seed); @@ -340,7 +340,7 @@ void TestNotZero() { const uint32_t kMaxSeed = 2000; #endif // JXL_DISABLE_SLOW_TESTS EXPECT_TRUE(RunOnPool( - &pool, 0, kMaxSeed, ThreadPool::NoInit, + pool.get(), 0, kMaxSeed, ThreadPool::NoInit, [](const uint32_t task, size_t /*thread*/) { HWY_ALIGN uint64_t lanes[Xorshift128Plus::N]; diff --git a/third_party/jpeg-xl/lib/jxl_cms.cmake b/third_party/jpeg-xl/lib/jxl_cms.cmake index 04980066c1..62d5b651fd 100644 --- a/third_party/jpeg-xl/lib/jxl_cms.cmake +++ b/third_party/jpeg-xl/lib/jxl_cms.cmake @@ -23,7 +23,7 @@ target_include_directories(jxl_cms PRIVATE generate_export_header(jxl_cms BASE_NAME JXL_CMS EXPORT_FILE_NAME include/jxl/jxl_cms_export.h) -target_include_directories(jxl_cms PUBLIC +target_include_directories(jxl_cms BEFORE PUBLIC "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>") set(JPEGXL_CMS_LIBRARY_REQUIRES "") diff --git a/third_party/jpeg-xl/lib/jxl_extras.cmake b/third_party/jpeg-xl/lib/jxl_extras.cmake index 597f691554..747c07eb9c 100644 --- a/third_party/jpeg-xl/lib/jxl_extras.cmake +++ b/third_party/jpeg-xl/lib/jxl_extras.cmake @@ -118,7 +118,7 @@ foreach(LIB ${JXL_EXTRAS_OBJECT_LIBRARIES}) target_compile_options("${LIB}" PRIVATE "${JPEGXL_INTERNAL_FLAGS}") target_compile_definitions("${LIB}" PRIVATE -DJXL_EXPORT=) set_property(TARGET "${LIB}" PROPERTY POSITION_INDEPENDENT_CODE ON) - target_include_directories("${LIB}" PRIVATE + target_include_directories("${LIB}" BEFORE PRIVATE ${PROJECT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include diff --git a/third_party/jpeg-xl/lib/jxl_lists.bzl b/third_party/jpeg-xl/lib/jxl_lists.bzl index 6c98ca15ed..a66706aa83 100644 --- a/third_party/jpeg-xl/lib/jxl_lists.bzl +++ b/third_party/jpeg-xl/lib/jxl_lists.bzl @@ -551,7 +551,7 @@ libjxl_major_version = 0 libjxl_minor_version = 10 -libjxl_patch_version = 0 +libjxl_patch_version = 2 libjxl_public_headers = [ "include/jxl/cms.h", 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 7c8e602764..0762b3299b 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 @@ -34,7 +34,7 @@ TEST(ThreadParallelRunnerTest, TestPool) { for (int begin = 0; begin < 32; ++begin) { std::fill(mementos.begin(), mementos.end(), 0); EXPECT_TRUE(RunOnPool( - &pool, begin, begin + num_tasks, jxl::ThreadPool::NoInit, + pool.get(), begin, begin + num_tasks, jxl::ThreadPool::NoInit, [begin, num_tasks, &mementos](const int task, const int thread) { // Parameter is in the given range EXPECT_GE(task, begin); @@ -63,7 +63,7 @@ TEST(ThreadParallelRunnerTest, TestSmallAssignments) { std::atomic<int> num_calls{0}; EXPECT_TRUE(RunOnPool( - &pool, 0, num_threads, jxl::ThreadPool::NoInit, + pool.get(), 0, num_threads, jxl::ThreadPool::NoInit, [&num_calls, num_threads, &id_bits](const int task, const int thread) { num_calls.fetch_add(1, std::memory_order_relaxed); @@ -101,7 +101,7 @@ TEST(ThreadParallelRunnerTest, TestCounter) { const int kNumTasks = kNumThreads * 19; EXPECT_TRUE(RunOnPool( - &pool, 0, kNumTasks, jxl::ThreadPool::NoInit, + pool.get(), 0, kNumTasks, jxl::ThreadPool::NoInit, [&counters](const int task, const int thread) { counters[thread].counter += task; }, |