From 40a355a42d4a9444dc753c04c6608dade2f06a23 Mon Sep 17 00:00:00 2001
From: Daniel Baumann <daniel.baumann@progress-linux.org>
Date: Fri, 19 Apr 2024 03:13:27 +0200
Subject: Adding upstream version 125.0.1.

Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
---
 third_party/jpeg-xl/lib/extras/enc/apng.cc   | 29 +++++-----
 third_party/jpeg-xl/lib/extras/enc/encode.cc |  2 +-
 third_party/jpeg-xl/lib/extras/enc/encode.h  |  2 +-
 third_party/jpeg-xl/lib/extras/enc/exr.cc    |  4 +-
 third_party/jpeg-xl/lib/extras/enc/jpegli.cc | 82 +++++++++++++++++-----------
 third_party/jpeg-xl/lib/extras/enc/jpg.cc    | 81 ++++++++++++++-------------
 third_party/jpeg-xl/lib/extras/enc/jxl.cc    | 45 +++++++++------
 third_party/jpeg-xl/lib/extras/enc/jxl.h     |  8 +--
 third_party/jpeg-xl/lib/extras/enc/npy.cc    | 35 +++++++-----
 third_party/jpeg-xl/lib/extras/enc/pgx.cc    |  4 +-
 third_party/jpeg-xl/lib/extras/enc/pnm.cc    |  2 +-
 11 files changed, 166 insertions(+), 128 deletions(-)

(limited to 'third_party/jpeg-xl/lib/extras/enc')

diff --git a/third_party/jpeg-xl/lib/extras/enc/apng.cc b/third_party/jpeg-xl/lib/extras/enc/apng.cc
index 413a9c8081..40aa876e84 100644
--- a/third_party/jpeg-xl/lib/extras/enc/apng.cc
+++ b/third_party/jpeg-xl/lib/extras/enc/apng.cc
@@ -86,7 +86,7 @@ class APNGEncoder : public Encoder {
                                      std::vector<uint8_t>* bytes) const;
 };
 
-static void PngWrite(png_structp png_ptr, png_bytep data, png_size_t length) {
+void PngWrite(png_structp png_ptr, png_bytep data, png_size_t length) {
   std::vector<uint8_t>* bytes =
       static_cast<std::vector<uint8_t>*>(png_get_io_ptr(png_ptr));
   bytes->insert(bytes->end(), data, data + length);
@@ -137,7 +137,7 @@ class BlobsWriterPNG {
                              std::vector<std::string>* strings) {
     // Encoding: base16 with newline after 72 chars.
     const size_t base16_size =
-        2 * bytes.size() + DivCeil(bytes.size(), size_t(36)) + 1;
+        2 * bytes.size() + DivCeil(bytes.size(), static_cast<size_t>(36)) + 1;
     std::string base16;
     base16.reserve(base16_size);
     for (size_t i = 0; i < bytes.size(); ++i) {
@@ -155,7 +155,7 @@ class BlobsWriterPNG {
     snprintf(header, sizeof(header), "\n%s\n%8" PRIuS, type.c_str(),
              bytes.size());
 
-    strings->push_back(std::string(key));
+    strings->emplace_back(key);
     strings->push_back(std::string(header) + base16);
     return true;
   }
@@ -303,7 +303,7 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG(
           out[i] = static_cast<uint8_t>(in[i] * mul + 0.5);
         }
       } else {
-        memcpy(&out[0], in, out_size);
+        memcpy(out.data(), in, out_size);
       }
     } else if (format.data_type == JXL_TYPE_UINT16) {
       if (ppf.info.bits_per_sample < 16 ||
@@ -317,20 +317,21 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG(
           StoreBE16(static_cast<uint32_t>(val * mul + 0.5), p_out);
         }
       } else {
-        memcpy(&out[0], in, out_size);
+        memcpy(out.data(), in, out_size);
       }
     }
     png_structp png_ptr;
     png_infop info_ptr;
 
-    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr,
+                                      nullptr);
 
     if (!png_ptr) return JXL_FAILURE("Could not init png encoder");
 
     info_ptr = png_create_info_struct(png_ptr);
     if (!info_ptr) return JXL_FAILURE("Could not init png info struct");
 
-    png_set_write_fn(png_ptr, bytes, PngWrite, NULL);
+    png_set_write_fn(png_ptr, bytes, PngWrite, nullptr);
     png_set_flush(png_ptr, 0);
 
     int width = xsize;
@@ -344,11 +345,13 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG(
                  PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
                  PNG_FILTER_TYPE_BASE);
     if (count == 0) {
-      if (!ppf.icc.empty()) {
-        png_set_benign_errors(png_ptr, 1);
-        png_set_iCCP(png_ptr, info_ptr, "1", 0, ppf.icc.data(), ppf.icc.size());
-      } else if (!MaybeAddSRGB(ppf.color_encoding, png_ptr, info_ptr)) {
+      if (!MaybeAddSRGB(ppf.color_encoding, png_ptr, info_ptr)) {
         MaybeAddCICP(ppf.color_encoding, png_ptr, info_ptr);
+        if (!ppf.icc.empty()) {
+          png_set_benign_errors(png_ptr, 1);
+          png_set_iCCP(png_ptr, info_ptr, "1", 0, ppf.icc.data(),
+                       ppf.icc.size());
+        }
         MaybeAddCHRM(ppf.color_encoding, png_ptr, info_ptr);
         MaybeAddGAMA(ppf.color_encoding, png_ptr, info_ptr);
       }
@@ -404,7 +407,7 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG(
 
     png_write_flush(png_ptr);
     const size_t pos = bytes->size();
-    png_write_image(png_ptr, &rows[0]);
+    png_write_image(png_ptr, rows.data());
     png_write_flush(png_ptr);
     if (count > 0) {
       std::vector<uint8_t> fdata(4);
@@ -428,7 +431,7 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG(
 
     count++;
     if (count == ppf.frames.size() || !ppf.info.have_animation) {
-      png_write_end(png_ptr, NULL);
+      png_write_end(png_ptr, nullptr);
     }
 
     png_destroy_write_struct(&png_ptr, &info_ptr);
diff --git a/third_party/jpeg-xl/lib/extras/enc/encode.cc b/third_party/jpeg-xl/lib/extras/enc/encode.cc
index 8c9a148b27..c5e22d8c7e 100644
--- a/third_party/jpeg-xl/lib/extras/enc/encode.cc
+++ b/third_party/jpeg-xl/lib/extras/enc/encode.cc
@@ -54,7 +54,7 @@ Status Encoder::VerifyBitDepth(JxlDataType data_type, uint32_t bits_per_sample,
        (bits_per_sample > 16 || exponent_bits > 5))) {
     return JXL_FAILURE(
         "Incompatible data_type %d and bit depth %u with exponent bits %u",
-        (int)data_type, bits_per_sample, exponent_bits);
+        static_cast<int>(data_type), bits_per_sample, exponent_bits);
   }
   return true;
 }
diff --git a/third_party/jpeg-xl/lib/extras/enc/encode.h b/third_party/jpeg-xl/lib/extras/enc/encode.h
index da5f509838..2502d9976b 100644
--- a/third_party/jpeg-xl/lib/extras/enc/encode.h
+++ b/third_party/jpeg-xl/lib/extras/enc/encode.h
@@ -56,7 +56,7 @@ class Encoder {
 
   // Any existing data in encoded_image is discarded.
   virtual Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image,
-                        ThreadPool* pool = nullptr) const = 0;
+                        ThreadPool* pool) const = 0;
 
   void SetOption(std::string name, std::string value) {
     options_[std::move(name)] = std::move(value);
diff --git a/third_party/jpeg-xl/lib/extras/enc/exr.cc b/third_party/jpeg-xl/lib/extras/enc/exr.cc
index d4005c3097..5a4f7d768c 100644
--- a/third_party/jpeg-xl/lib/extras/enc/exr.cc
+++ b/third_party/jpeg-xl/lib/extras/enc/exr.cc
@@ -84,7 +84,7 @@ Status EncodeImageEXR(const PackedImage& image, const JxlBasicInfo& info,
   const size_t xsize = info.xsize;
   const size_t ysize = info.ysize;
   const bool has_alpha = info.alpha_bits > 0;
-  const bool alpha_is_premultiplied = info.alpha_premultiplied;
+  const bool alpha_is_premultiplied = FROM_JXL_BOOL(info.alpha_premultiplied);
 
   if (info.num_color_channels != 3 ||
       c_enc.color_space != JXL_COLOR_SPACE_RGB ||
@@ -177,7 +177,7 @@ class EXREncoder : public Encoder {
     return formats;
   }
   Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image,
-                ThreadPool* pool = nullptr) const override {
+                ThreadPool* pool) const override {
     JXL_RETURN_IF_ERROR(VerifyBasicInfo(ppf.info));
     encoded_image->icc.clear();
     encoded_image->bitstreams.clear();
diff --git a/third_party/jpeg-xl/lib/extras/enc/jpegli.cc b/third_party/jpeg-xl/lib/extras/enc/jpegli.cc
index 7e1aa426df..aa10b584d0 100644
--- a/third_party/jpeg-xl/lib/extras/enc/jpegli.cc
+++ b/third_party/jpeg-xl/lib/extras/enc/jpegli.cc
@@ -34,6 +34,7 @@
 #include "lib/jxl/color_encoding_internal.h"
 #include "lib/jxl/enc_xyb.h"
 #include "lib/jxl/image.h"
+#include "lib/jxl/simd_util.h"
 
 namespace jxl {
 namespace extras {
@@ -53,6 +54,10 @@ Status VerifyInput(const PackedPixelFile& ppf) {
   if (ppf.frames.size() != 1) {
     return JXL_FAILURE("JPEG input must have exactly one frame.");
   }
+  if (info.num_color_channels != 1 && info.num_color_channels != 3) {
+    return JXL_FAILURE("Invalid number of color channels %d",
+                       info.num_color_channels);
+  }
   const PackedImage& image = ppf.frames[0].color;
   JXL_RETURN_IF_ERROR(Encoder::VerifyImageSize(image, info));
   if (image.format.data_type == JXL_TYPE_FLOAT16) {
@@ -71,7 +76,7 @@ Status VerifyInput(const PackedPixelFile& ppf) {
 
 Status GetColorEncoding(const PackedPixelFile& ppf,
                         ColorEncoding* color_encoding) {
-  if (!ppf.icc.empty()) {
+  if (ppf.primary_color_representation == PackedPixelFile::kIccIsPrimary) {
     IccBytes icc = ppf.icc;
     JXL_RETURN_IF_ERROR(
         color_encoding->SetICC(std::move(icc), JxlGetDefaultCms()));
@@ -122,12 +127,12 @@ Status WriteAppData(j_compress_ptr cinfo,
   return true;
 }
 
-static constexpr int kICCMarker = 0xe2;
+constexpr int kICCMarker = 0xe2;
 constexpr unsigned char kICCSignature[12] = {
     0x49, 0x43, 0x43, 0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45, 0x00};
-static constexpr uint8_t kUnknownTf = 2;
-static constexpr unsigned char kCICPTagSignature[4] = {0x63, 0x69, 0x63, 0x70};
-static constexpr size_t kCICPTagSize = 12;
+constexpr uint8_t kUnknownTf = 2;
+constexpr unsigned char kCICPTagSignature[4] = {0x63, 0x69, 0x63, 0x70};
+constexpr size_t kCICPTagSize = 12;
 
 bool FindCICPTag(const uint8_t* icc_data, size_t len, bool is_first_chunk,
                  size_t* cicp_offset, size_t* cicp_length, uint8_t* cicp_tag,
@@ -248,32 +253,48 @@ JpegliEndianness ConvertEndianness(JxlEndianness endianness) {
   }
 }
 
-void ToFloatRow(const uint8_t* row_in, JxlPixelFormat format, size_t len,
-                float* row_out) {
+void ToFloatRow(const uint8_t* row_in, JxlPixelFormat format, size_t xsize,
+                size_t c_out, float* row_out) {
   bool is_little_endian =
       (format.endianness == JXL_LITTLE_ENDIAN ||
        (format.endianness == JXL_NATIVE_ENDIAN && IsLittleEndian()));
   static constexpr double kMul8 = 1.0 / 255.0;
   static constexpr double kMul16 = 1.0 / 65535.0;
+  const size_t c_in = format.num_channels;
   if (format.data_type == JXL_TYPE_UINT8) {
-    for (size_t x = 0; x < len; ++x) {
-      row_out[x] = row_in[x] * kMul8;
+    for (size_t x = 0; x < xsize; ++x) {
+      for (size_t c = 0; c < c_out; ++c) {
+        const size_t ix = c_in * x + c;
+        row_out[c_out * x + c] = row_in[ix] * kMul8;
+      }
     }
   } else if (format.data_type == JXL_TYPE_UINT16 && is_little_endian) {
-    for (size_t x = 0; x < len; ++x) {
-      row_out[x] = LoadLE16(&row_in[2 * x]) * kMul16;
+    for (size_t x = 0; x < xsize; ++x) {
+      for (size_t c = 0; c < c_out; ++c) {
+        const size_t ix = c_in * x + c;
+        row_out[c_out * x + c] = LoadLE16(&row_in[2 * ix]) * kMul16;
+      }
     }
   } else if (format.data_type == JXL_TYPE_UINT16 && !is_little_endian) {
-    for (size_t x = 0; x < len; ++x) {
-      row_out[x] = LoadBE16(&row_in[2 * x]) * kMul16;
+    for (size_t x = 0; x < xsize; ++x) {
+      for (size_t c = 0; c < c_out; ++c) {
+        const size_t ix = c_in * x + c;
+        row_out[c_out * x + c] = LoadBE16(&row_in[2 * ix]) * kMul16;
+      }
     }
   } else if (format.data_type == JXL_TYPE_FLOAT && is_little_endian) {
-    for (size_t x = 0; x < len; ++x) {
-      row_out[x] = LoadLEFloat(&row_in[4 * x]);
+    for (size_t x = 0; x < xsize; ++x) {
+      for (size_t c = 0; c < c_out; ++c) {
+        const size_t ix = c_in * x + c;
+        row_out[c_out * x + c] = LoadLEFloat(&row_in[4 * ix]);
+      }
     }
   } else if (format.data_type == JXL_TYPE_FLOAT && !is_little_endian) {
-    for (size_t x = 0; x < len; ++x) {
-      row_out[x] = LoadBEFloat(&row_in[4 * x]);
+    for (size_t x = 0; x < xsize; ++x) {
+      for (size_t c = 0; c < c_out; ++c) {
+        const size_t ix = c_in * x + c;
+        row_out[c_out * x + c] = LoadBEFloat(&row_in[4 * ix]);
+      }
     }
   }
 }
@@ -352,9 +373,6 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
   ColorSpaceTransform c_transform(*JxlGetDefaultCms());
   ColorEncoding xyb_encoding;
   if (jpeg_settings.xyb) {
-    if (ppf.info.num_color_channels != 3) {
-      return JXL_FAILURE("Only RGB input is supported in XYB mode.");
-    }
     if (HasICCProfile(jpeg_settings.app_data)) {
       return JXL_FAILURE("APP data ICC profile is not supported in XYB mode.");
     }
@@ -374,11 +392,11 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
   unsigned char* output_buffer = nullptr;
   unsigned long output_size = 0;
   std::vector<uint8_t> row_bytes;
-  size_t rowlen = RoundUpTo(ppf.info.xsize, VectorSize());
+  size_t rowlen = RoundUpTo(ppf.info.xsize, MaxVectorSize());
   hwy::AlignedFreeUniquePtr<float[]> xyb_tmp =
       hwy::AllocateAligned<float>(6 * rowlen);
   hwy::AlignedFreeUniquePtr<float[]> premul_absorb =
-      hwy::AllocateAligned<float>(VectorSize() * 12);
+      hwy::AllocateAligned<float>(MaxVectorSize() * 12);
   ComputePremulAbsorb(255.0f, premul_absorb.get());
 
   jpeg_compress_struct cinfo;
@@ -401,6 +419,8 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
         cinfo.input_components == 1 ? JCS_GRAYSCALE : JCS_RGB;
     if (jpeg_settings.xyb) {
       jpegli_set_xyb_mode(&cinfo);
+      cinfo.input_components = 3;
+      cinfo.in_color_space = JCS_RGB;
     } else if (jpeg_settings.use_std_quant_tables) {
       jpegli_use_standard_quant_tables(&cinfo);
     }
@@ -436,7 +456,7 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
       }
     }
     jpegli_enable_adaptive_quantization(
-        &cinfo, jpeg_settings.use_adaptive_quantization);
+        &cinfo, TO_JXL_BOOL(jpeg_settings.use_adaptive_quantization));
     if (jpeg_settings.psnr_target > 0.0) {
       jpegli_set_psnr(&cinfo, jpeg_settings.psnr_target,
                       jpeg_settings.search_tolerance,
@@ -448,11 +468,11 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
       jpegli_set_distance(&cinfo, jpeg_settings.distance, TRUE);
     }
     jpegli_set_progressive_level(&cinfo, jpeg_settings.progressive_level);
-    cinfo.optimize_coding = jpeg_settings.optimize_coding;
+    cinfo.optimize_coding = TO_JXL_BOOL(jpeg_settings.optimize_coding);
     if (!jpeg_settings.app_data.empty()) {
       // Make sure jpegli_start_compress() does not write any APP markers.
-      cinfo.write_JFIF_header = false;
-      cinfo.write_Adobe_marker = false;
+      cinfo.write_JFIF_header = JXL_FALSE;
+      cinfo.write_Adobe_marker = JXL_FALSE;
     }
     const PackedImage& image = ppf.frames[0].color;
     if (jpeg_settings.xyb) {
@@ -476,10 +496,10 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
       float* dst_buf = c_transform.BufDst(0);
       for (size_t y = 0; y < image.ysize; ++y) {
         // convert to float
-        ToFloatRow(&pixels[y * image.stride], image.format, 3 * image.xsize,
-                   src_buf);
+        ToFloatRow(&pixels[y * image.stride], image.format, image.xsize,
+                   info.num_color_channels, src_buf);
         // convert to linear srgb
-        if (!c_transform.Run(0, src_buf, dst_buf)) {
+        if (!c_transform.Run(0, src_buf, dst_buf, image.xsize)) {
           return false;
         }
         // deinterleave channels
@@ -508,9 +528,9 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
       }
     } else {
       row_bytes.resize(image.stride);
-      if (cinfo.num_components == (int)image.format.num_channels) {
+      if (cinfo.num_components == static_cast<int>(image.format.num_channels)) {
         for (size_t y = 0; y < info.ysize; ++y) {
-          memcpy(&row_bytes[0], pixels + y * image.stride, image.stride);
+          memcpy(row_bytes.data(), pixels + y * image.stride, image.stride);
           JSAMPROW row[] = {row_bytes.data()};
           jpegli_write_scanlines(&cinfo, row, 1);
         }
diff --git a/third_party/jpeg-xl/lib/extras/enc/jpg.cc b/third_party/jpeg-xl/lib/extras/enc/jpg.cc
index c34dc6c13f..de0228fc0d 100644
--- a/third_party/jpeg-xl/lib/extras/enc/jpg.cc
+++ b/third_party/jpeg-xl/lib/extras/enc/jpg.cc
@@ -23,6 +23,7 @@
 #include <vector>
 
 #include "lib/extras/exif.h"
+#include "lib/jxl/base/common.h"
 #include "lib/jxl/base/status.h"
 #include "lib/jxl/sanitizers.h"
 #if JPEGXL_ENABLE_SJPEG
@@ -50,23 +51,21 @@ enum class JpegEncoder {
   kSJpeg,
 };
 
-#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
-
 // Popular jpeg scan scripts
 // The fields of the individual scans are:
 // comps_in_scan, component_index[], Ss, Se, Ah, Al
-static constexpr jpeg_scan_info kScanScript1[] = {
+constexpr auto kScanScript1 = to_array<jpeg_scan_info>({
     {1, {0}, 0, 0, 0, 0},   //
     {1, {1}, 0, 0, 0, 0},   //
     {1, {2}, 0, 0, 0, 0},   //
     {1, {0}, 1, 8, 0, 0},   //
     {1, {0}, 9, 63, 0, 0},  //
     {1, {1}, 1, 63, 0, 0},  //
-    {1, {2}, 1, 63, 0, 0},  //
-};
-static constexpr size_t kNumScans1 = ARRAY_SIZE(kScanScript1);
+    {1, {2}, 1, 63, 0, 0}   //
+});
+constexpr size_t kNumScans1 = kScanScript1.size();
 
-static constexpr jpeg_scan_info kScanScript2[] = {
+constexpr auto kScanScript2 = to_array<jpeg_scan_info>({
     {1, {0}, 0, 0, 0, 0},   //
     {1, {1}, 0, 0, 0, 0},   //
     {1, {2}, 0, 0, 0, 0},   //
@@ -74,11 +73,11 @@ static constexpr jpeg_scan_info kScanScript2[] = {
     {1, {0}, 3, 63, 0, 1},  //
     {1, {0}, 1, 63, 1, 0},  //
     {1, {1}, 1, 63, 0, 0},  //
-    {1, {2}, 1, 63, 0, 0},  //
-};
-static constexpr size_t kNumScans2 = ARRAY_SIZE(kScanScript2);
+    {1, {2}, 1, 63, 0, 0}   //
+});
+constexpr size_t kNumScans2 = kScanScript2.size();
 
-static constexpr jpeg_scan_info kScanScript3[] = {
+constexpr auto kScanScript3 = to_array<jpeg_scan_info>({
     {1, {0}, 0, 0, 0, 0},   //
     {1, {1}, 0, 0, 0, 0},   //
     {1, {2}, 0, 0, 0, 0},   //
@@ -86,11 +85,11 @@ static constexpr jpeg_scan_info kScanScript3[] = {
     {1, {0}, 1, 63, 2, 1},  //
     {1, {0}, 1, 63, 1, 0},  //
     {1, {1}, 1, 63, 0, 0},  //
-    {1, {2}, 1, 63, 0, 0},  //
-};
-static constexpr size_t kNumScans3 = ARRAY_SIZE(kScanScript3);
+    {1, {2}, 1, 63, 0, 0}   //
+});
+constexpr size_t kNumScans3 = kScanScript3.size();
 
-static constexpr jpeg_scan_info kScanScript4[] = {
+constexpr auto kScanScript4 = to_array<jpeg_scan_info>({
     {3, {0, 1, 2}, 0, 0, 0, 1},  //
     {1, {0}, 1, 5, 0, 2},        //
     {1, {2}, 1, 63, 0, 1},       //
@@ -100,11 +99,11 @@ static constexpr jpeg_scan_info kScanScript4[] = {
     {3, {0, 1, 2}, 0, 0, 1, 0},  //
     {1, {2}, 1, 63, 1, 0},       //
     {1, {1}, 1, 63, 1, 0},       //
-    {1, {0}, 1, 63, 1, 0},       //
-};
-static constexpr size_t kNumScans4 = ARRAY_SIZE(kScanScript4);
+    {1, {0}, 1, 63, 1, 0}        //
+});
+constexpr size_t kNumScans4 = kScanScript4.size();
 
-static constexpr jpeg_scan_info kScanScript5[] = {
+constexpr auto kScanScript5 = to_array<jpeg_scan_info>({
     {3, {0, 1, 2}, 0, 0, 0, 1},  //
     {1, {0}, 1, 5, 0, 2},        //
     {1, {1}, 1, 5, 0, 2},        //
@@ -118,12 +117,12 @@ static constexpr jpeg_scan_info kScanScript5[] = {
     {3, {0, 1, 2}, 0, 0, 1, 0},  //
     {1, {0}, 1, 63, 1, 0},       //
     {1, {1}, 1, 63, 1, 0},       //
-    {1, {2}, 1, 63, 1, 0},       //
-};
-static constexpr size_t kNumScans5 = ARRAY_SIZE(kScanScript5);
+    {1, {2}, 1, 63, 1, 0}        //
+});
+constexpr size_t kNumScans5 = kScanScript5.size();
 
 // default progressive mode of jpegli
-static constexpr jpeg_scan_info kScanScript6[] = {
+constexpr auto kScanScript6 = to_array<jpeg_scan_info>({
     {3, {0, 1, 2}, 0, 0, 0, 0},  //
     {1, {0}, 1, 2, 0, 0},        //
     {1, {1}, 1, 2, 0, 0},        //
@@ -137,8 +136,8 @@ static constexpr jpeg_scan_info kScanScript6[] = {
     {1, {0}, 3, 63, 1, 0},       //
     {1, {1}, 3, 63, 1, 0},       //
     {1, {2}, 3, 63, 1, 0},       //
-};
-static constexpr size_t kNumScans6 = ARRAY_SIZE(kScanScript6);
+});
+constexpr size_t kNumScans6 = kScanScript6.size();
 
 // Adapt RGB scan info to grayscale jpegs.
 void FilterScanComponents(const jpeg_compress_struct* cinfo,
@@ -163,12 +162,12 @@ Status SetJpegProgression(int progressive_id,
     jpeg_simple_progression(cinfo);
     return true;
   }
-  constexpr const jpeg_scan_info* kScanScripts[] = {kScanScript1, kScanScript2,
-                                                    kScanScript3, kScanScript4,
-                                                    kScanScript5, kScanScript6};
-  constexpr size_t kNumScans[] = {kNumScans1, kNumScans2, kNumScans3,
-                                  kNumScans4, kNumScans5, kNumScans6};
-  if (progressive_id > static_cast<int>(ARRAY_SIZE(kNumScans))) {
+  const jpeg_scan_info* kScanScripts[] = {
+      kScanScript1.data(), kScanScript2.data(), kScanScript3.data(),
+      kScanScript4.data(), kScanScript5.data(), kScanScript6.data()};
+  constexpr auto kNumScans = to_array<size_t>(
+      {kNumScans1, kNumScans2, kNumScans3, kNumScans4, kNumScans5, kNumScans6});
+  if (progressive_id > static_cast<int>(kNumScans.size())) {
     return JXL_FAILURE("Unknown jpeg scan script id %d", progressive_id);
   }
   const jpeg_scan_info* scan_script = kScanScripts[progressive_id - 1];
@@ -178,7 +177,7 @@ Status SetJpegProgression(int progressive_id,
     jpeg_scan_info scan_info = scan_script[i];
     FilterScanComponents(cinfo, &scan_info);
     if (scan_info.comps_in_scan > 0) {
-      scan_infos->emplace_back(std::move(scan_info));
+      scan_infos->emplace_back(scan_info);
     }
   }
   cinfo->scan_info = scan_infos->data();
@@ -217,8 +216,8 @@ void WriteExif(jpeg_compress_struct* const cinfo,
   for (const unsigned char c : kExifSignature) {
     jpeg_write_m_byte(cinfo, c);
   }
-  for (size_t i = 0; i < exif.size(); ++i) {
-    jpeg_write_m_byte(cinfo, exif[i]);
+  for (uint8_t c : exif) {
+    jpeg_write_m_byte(cinfo, c);
   }
 }
 
@@ -284,7 +283,7 @@ Status EncodeWithLibJpeg(const PackedImage& image, const JxlBasicInfo& info,
   cinfo.input_components = info.num_color_channels;
   cinfo.in_color_space = info.num_color_channels == 1 ? JCS_GRAYSCALE : JCS_RGB;
   jpeg_set_defaults(&cinfo);
-  cinfo.optimize_coding = params.optimize_coding;
+  cinfo.optimize_coding = static_cast<boolean>(params.optimize_coding);
   if (cinfo.input_components == 3) {
     JXL_RETURN_IF_ERROR(
         SetChromaSubsampling(params.chroma_subsampling, &cinfo));
@@ -310,10 +309,10 @@ Status EncodeWithLibJpeg(const PackedImage& image, const JxlBasicInfo& info,
 
   std::vector<uint8_t> row_bytes(image.stride);
   const uint8_t* pixels = reinterpret_cast<const uint8_t*>(image.pixels());
-  if (cinfo.num_components == (int)image.format.num_channels &&
+  if (cinfo.num_components == static_cast<int>(image.format.num_channels) &&
       image.format.data_type == JXL_TYPE_UINT8) {
     for (size_t y = 0; y < info.ysize; ++y) {
-      memcpy(&row_bytes[0], pixels + y * image.stride, image.stride);
+      memcpy(row_bytes.data(), pixels + y * image.stride, image.stride);
       JSAMPROW row[] = {row_bytes.data()};
       jpeg_write_scanlines(&cinfo, row, 1);
     }
@@ -401,7 +400,7 @@ struct MySearchHook : public sjpeg::SearchHook {
   }
   bool Update(float result) override {
     value = result;
-    if (fabs(value - target) < tolerance * target) {
+    if (std::fabs(value - target) < tolerance * target) {
       return true;
     }
     if (value > target) {
@@ -420,9 +419,9 @@ struct MySearchHook : public sjpeg::SearchHook {
     } else {
       q = (qmin + qmax) / 2.;
     }
-    return (pass > 0 && fabs(q - last_q) < q_precision);
+    return (pass > 0 && std::fabs(q - last_q) < q_precision);
   }
-  ~MySearchHook() override {}
+  ~MySearchHook() override = default;
 };
 #endif
 
@@ -539,7 +538,7 @@ class JPEGEncoder : public Encoder {
     return formats;
   }
   Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image,
-                ThreadPool* pool = nullptr) const override {
+                ThreadPool* pool) const override {
     JXL_RETURN_IF_ERROR(VerifyBasicInfo(ppf.info));
     JpegEncoder jpeg_encoder = JpegEncoder::kLibJpeg;
     JpegParams params;
diff --git a/third_party/jpeg-xl/lib/extras/enc/jxl.cc b/third_party/jpeg-xl/lib/extras/enc/jxl.cc
index 00adbb7dda..d563f298e6 100644
--- a/third_party/jpeg-xl/lib/extras/enc/jxl.cc
+++ b/third_party/jpeg-xl/lib/extras/enc/jxl.cc
@@ -7,6 +7,7 @@
 
 #include <jxl/encode.h>
 #include <jxl/encode_cxx.h>
+#include <jxl/types.h>
 
 #include "lib/jxl/base/exif.h"
 
@@ -132,7 +133,7 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
     return false;
   }
 
-  auto settings = JxlEncoderFrameSettingsCreate(enc, nullptr);
+  auto* settings = JxlEncoderFrameSettingsCreate(enc, nullptr);
   size_t option_idx = 0;
   if (!SetFrameOptions(params.options, 0, &option_idx, settings)) {
     return false;
@@ -150,10 +151,11 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
     JxlEncoderCollectStats(settings, params.stats);
   }
 
+  bool has_jpeg_bytes = (jpeg_bytes != nullptr);
   bool use_boxes = !ppf.metadata.exif.empty() || !ppf.metadata.xmp.empty() ||
                    !ppf.metadata.jumbf.empty() || !ppf.metadata.iptc.empty();
   bool use_container = params.use_container || use_boxes ||
-                       (jpeg_bytes && params.jpeg_store_metadata);
+                       (has_jpeg_bytes && params.jpeg_store_metadata);
 
   if (JXL_ENC_SUCCESS !=
       JxlEncoderUseContainer(enc, static_cast<int>(use_container))) {
@@ -161,12 +163,22 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
     return false;
   }
 
-  if (jpeg_bytes) {
+  if (has_jpeg_bytes) {
     if (params.jpeg_store_metadata &&
         JXL_ENC_SUCCESS != JxlEncoderStoreJPEGMetadata(enc, JXL_TRUE)) {
       fprintf(stderr, "Storing JPEG metadata failed.\n");
       return false;
     }
+    if (params.jpeg_store_metadata && params.jpeg_strip_exif) {
+      fprintf(stderr,
+              "Cannot store metadata and strip exif at the same time.\n");
+      return false;
+    }
+    if (params.jpeg_store_metadata && params.jpeg_strip_xmp) {
+      fprintf(stderr,
+              "Cannot store metadata and strip xmp at the same time.\n");
+      return false;
+    }
     if (!params.jpeg_store_metadata && params.jpeg_strip_exif) {
       JxlEncoderFrameSettingsSetOption(settings,
                                        JXL_ENC_FRAME_SETTING_JPEG_KEEP_EXIF, 0);
@@ -210,8 +222,8 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
     basic_info.num_extra_channels =
         std::max<uint32_t>(num_alpha_channels, ppf.info.num_extra_channels);
     basic_info.num_color_channels = ppf.info.num_color_channels;
-    const bool lossless = params.distance == 0;
-    basic_info.uses_original_profile = lossless;
+    const bool lossless = (params.distance == 0);
+    basic_info.uses_original_profile = TO_JXL_BOOL(lossless);
     if (params.override_bitdepth != 0) {
       basic_info.bits_per_sample = params.override_bitdepth;
       basic_info.exponent_bits_per_sample =
@@ -233,7 +245,7 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
       return false;
     }
     if (JXL_ENC_SUCCESS !=
-        JxlEncoderSetFrameBitDepth(settings, &params.input_bitdepth)) {
+        JxlEncoderSetFrameBitDepth(settings, &ppf.input_bitdepth)) {
       fprintf(stderr, "JxlEncoderSetFrameBitDepth() failed.\n");
       return false;
     }
@@ -248,7 +260,7 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
       fprintf(stderr, "JxlEncoderSetFrameLossless() failed.\n");
       return false;
     }
-    if (!ppf.icc.empty()) {
+    if (ppf.primary_color_representation == PackedPixelFile::kIccIsPrimary) {
       if (JXL_ENC_SUCCESS !=
           JxlEncoderSetICCProfile(enc, ppf.icc.data(), ppf.icc.size())) {
         fprintf(stderr, "JxlEncoderSetICCProfile() failed.\n");
@@ -284,14 +296,15 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
           {"jumb", ppf.metadata.jumbf},
           {"xml ", ppf.metadata.iptc},
       };
-      for (size_t i = 0; i < sizeof boxes / sizeof *boxes; ++i) {
-        const BoxInfo& box = boxes[i];
-        if (!box.bytes.empty() &&
-            JXL_ENC_SUCCESS != JxlEncoderAddBox(enc, box.type, box.bytes.data(),
-                                                box.bytes.size(),
-                                                params.compress_boxes)) {
-          fprintf(stderr, "JxlEncoderAddBox() failed (%s).\n", box.type);
-          return false;
+      for (auto box : boxes) {
+        if (!box.bytes.empty()) {
+          if (JXL_ENC_SUCCESS !=
+              JxlEncoderAddBox(enc, box.type, box.bytes.data(),
+                               box.bytes.size(),
+                               TO_JXL_BOOL(params.compress_boxes))) {
+            fprintf(stderr, "JxlEncoderAddBox() failed (%s).\n", box.type);
+            return false;
+          }
         }
       }
       JxlEncoderCloseBoxes(enc);
@@ -336,7 +349,7 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
       }
       const bool last_frame = fi + 1 == ppf.chunked_frames.size();
       if (JXL_ENC_SUCCESS !=
-          JxlEncoderAddChunkedFrame(settings, last_frame,
+          JxlEncoderAddChunkedFrame(settings, TO_JXL_BOOL(last_frame),
                                     chunked_frame.GetInputSource())) {
         fprintf(stderr, "JxlEncoderAddChunkedFrame() failed.\n");
         return false;
diff --git a/third_party/jpeg-xl/lib/extras/enc/jxl.h b/third_party/jpeg-xl/lib/extras/enc/jxl.h
index b8ca5bda2f..2b3793c0c4 100644
--- a/third_party/jpeg-xl/lib/extras/enc/jxl.h
+++ b/third_party/jpeg-xl/lib/extras/enc/jxl.h
@@ -38,7 +38,7 @@ struct JXLCompressParams {
   std::vector<JXLOption> options;
   // Target butteraugli distance, 0.0 means lossless.
   float distance = 1.0f;
-  float alpha_distance = 1.0f;
+  float alpha_distance = 0.0f;
   // If set to true, forces container mode.
   bool use_container = false;
   // Whether to enable/disable byte-exact jpeg reconstruction for jpeg inputs.
@@ -57,8 +57,6 @@ struct JXLCompressParams {
   size_t override_bitdepth = 0;
   int32_t codestream_level = -1;
   int32_t premultiply = -1;
-  // Override input buffer interpretation.
-  JxlBitDepth input_bitdepth = {JXL_BIT_DEPTH_FROM_PIXEL_FORMAT, 0, 0};
   // If runner_opaque is set, the decoder uses this parallel runner.
   JxlParallelRunner runner = JxlThreadParallelRunner;
   void* runner_opaque = nullptr;
@@ -69,10 +67,10 @@ struct JXLCompressParams {
   bool allow_expert_options = false;
 
   void AddOption(JxlEncoderFrameSettingId id, int64_t val) {
-    options.emplace_back(JXLOption(id, val, 0));
+    options.emplace_back(id, val, 0);
   }
   void AddFloatOption(JxlEncoderFrameSettingId id, float val) {
-    options.emplace_back(JXLOption(id, val, 0));
+    options.emplace_back(id, val, 0);
   }
   bool HasOutputProcessor() const {
     return (output_processor.get_buffer != nullptr &&
diff --git a/third_party/jpeg-xl/lib/extras/enc/npy.cc b/third_party/jpeg-xl/lib/extras/enc/npy.cc
index ae8cf13cc4..8d9954ef31 100644
--- a/third_party/jpeg-xl/lib/extras/enc/npy.cc
+++ b/third_party/jpeg-xl/lib/extras/enc/npy.cc
@@ -7,11 +7,13 @@
 
 #include <jxl/types.h>
 
+#include <memory>
 #include <sstream>
 #include <string>
 #include <vector>
 
 #include "lib/extras/packed_image.h"
+#include "lib/jxl/base/common.h"
 
 namespace jxl {
 namespace extras {
@@ -52,14 +54,17 @@ class JSONDict : public JSONField {
     static_assert(std::is_convertible<T*, JSONField*>::value,
                   "T must be a JSONField");
     T* ret = new T();
-    values_.emplace_back(
-        key, std::unique_ptr<JSONField>(static_cast<JSONField*>(ret)));
+    JSONField* field = static_cast<JSONField*>(ret);
+    auto handle = std::unique_ptr<JSONField>(field);
+    values_.emplace_back(key, std::move(handle));
     return ret;
   }
 
   template <typename T>
   void Add(const std::string& key, const T& value) {
-    values_.emplace_back(key, std::unique_ptr<JSONField>(new JSONValue(value)));
+    JSONField* field = static_cast<JSONField*>(new JSONValue(value));
+    auto handle = std::unique_ptr<JSONField>(field);
+    values_.emplace_back(key, std::move(handle));
   }
 
   void Write(std::ostream& o, uint32_t indent) const override {
@@ -71,11 +76,11 @@ class JSONDict : public JSONField {
         o << ",";
       }
       is_first = false;
-      o << std::endl << indent_str << "  \"" << key_value.first << "\": ";
+      o << "\n" << indent_str << "  \"" << key_value.first << "\": ";
       key_value.second->Write(o, indent + 2);
     }
     if (!values_.empty()) {
-      o << std::endl << indent_str;
+      o << "\n" << indent_str;
     }
     o << "}";
   }
@@ -112,11 +117,11 @@ class JSONArray : public JSONField {
         o << ",";
       }
       is_first = false;
-      o << std::endl << indent_str << "  ";
+      o << "\n" << indent_str << "  ";
       value->Write(o, indent + 2);
     }
     if (!values_.empty()) {
-      o << std::endl << indent_str;
+      o << "\n" << indent_str;
     }
     o << "]";
   }
@@ -160,13 +165,13 @@ void GenerateMetadata(const PackedPixelFile& ppf, std::vector<uint8_t>* out) {
   }
 
   {
-    auto ectype = meta.AddEmpty<JSONArray>("extra_channel_type");
-    auto bps = meta.AddEmpty<JSONArray>("bits_per_sample");
-    auto ebps = meta.AddEmpty<JSONArray>("exp_bits_per_sample");
+    auto* ectype = meta.AddEmpty<JSONArray>("extra_channel_type");
+    auto* bps = meta.AddEmpty<JSONArray>("bits_per_sample");
+    auto* ebps = meta.AddEmpty<JSONArray>("exp_bits_per_sample");
     bps->Add(ppf.info.bits_per_sample);
     ebps->Add(ppf.info.exponent_bits_per_sample);
-    for (size_t i = 0; i < ppf.extra_channels_info.size(); i++) {
-      switch (ppf.extra_channels_info[i].ec_info.type) {
+    for (const auto& eci : ppf.extra_channels_info) {
+      switch (eci.ec_info.type) {
         case JXL_CHANNEL_ALPHA: {
           ectype->Add(std::string("Alpha"));
           break;
@@ -200,8 +205,8 @@ void GenerateMetadata(const PackedPixelFile& ppf, std::vector<uint8_t>* out) {
           break;
         }
       }
-      bps->Add(ppf.extra_channels_info[i].ec_info.bits_per_sample);
-      ebps->Add(ppf.extra_channels_info[i].ec_info.exponent_bits_per_sample);
+      bps->Add(eci.ec_info.bits_per_sample);
+      ebps->Add(eci.ec_info.exponent_bits_per_sample);
     }
   }
 
@@ -282,7 +287,7 @@ bool WriteNPYArray(const PackedPixelFile& ppf, std::vector<uint8_t>* out) {
 class NumPyEncoder : public Encoder {
  public:
   Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image,
-                ThreadPool* pool = nullptr) const override {
+                ThreadPool* pool) const override {
     JXL_RETURN_IF_ERROR(VerifyBasicInfo(ppf.info));
     GenerateMetadata(ppf, &encoded_image->metadata);
     encoded_image->bitstreams.emplace_back();
diff --git a/third_party/jpeg-xl/lib/extras/enc/pgx.cc b/third_party/jpeg-xl/lib/extras/enc/pgx.cc
index d4809e38b6..eb8eab4271 100644
--- a/third_party/jpeg-xl/lib/extras/enc/pgx.cc
+++ b/third_party/jpeg-xl/lib/extras/enc/pgx.cc
@@ -60,7 +60,7 @@ Status EncodeImagePGX(const PackedFrame& frame, const JxlBasicInfo& info,
   std::vector<uint8_t> pixels(num_samples * bytes_per_sample);
 
   if (format.data_type == JXL_TYPE_UINT8) {
-    memcpy(&pixels[0], in, num_samples * bytes_per_sample);
+    memcpy(pixels.data(), in, num_samples * bytes_per_sample);
   } else if (format.data_type == JXL_TYPE_UINT16) {
     if (format.endianness != JXL_BIG_ENDIAN) {
       const uint8_t* p_in = in;
@@ -69,7 +69,7 @@ Status EncodeImagePGX(const PackedFrame& frame, const JxlBasicInfo& info,
         StoreBE16(LoadLE16(p_in), p_out);
       }
     } else {
-      memcpy(&pixels[0], in, num_samples * bytes_per_sample);
+      memcpy(pixels.data(), in, num_samples * bytes_per_sample);
     }
   } else {
     return JXL_FAILURE("Unsupported pixel data type");
diff --git a/third_party/jpeg-xl/lib/extras/enc/pnm.cc b/third_party/jpeg-xl/lib/extras/enc/pnm.cc
index 4183900198..966611cfca 100644
--- a/third_party/jpeg-xl/lib/extras/enc/pnm.cc
+++ b/third_party/jpeg-xl/lib/extras/enc/pnm.cc
@@ -31,7 +31,7 @@ constexpr size_t kMaxHeaderSize = 200;
 class BasePNMEncoder : public Encoder {
  public:
   Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image,
-                ThreadPool* pool = nullptr) const override {
+                ThreadPool* pool) const override {
     JXL_RETURN_IF_ERROR(VerifyBasicInfo(ppf.info));
     if (!ppf.metadata.exif.empty() || !ppf.metadata.iptc.empty() ||
         !ppf.metadata.jumbf.empty() || !ppf.metadata.xmp.empty()) {
-- 
cgit v1.2.3