Imported Upstream version 0.9.0
[platform/upstream/libjxl.git] / lib / jxl / roundtrip_test.cc
index d057172..0eb4393 100644 (file)
@@ -3,28 +3,32 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+#include <jxl/cms.h>
+#include <jxl/codestream_header.h>
+#include <jxl/decode.h>
+#include <jxl/decode_cxx.h>
+#include <jxl/encode.h>
+#include <jxl/encode_cxx.h>
+#include <jxl/types.h>
+
 #include <cmath>  // std::abs
 #include <cstddef>
 #include <cstdint>
 #include <cstdio>
 #include <vector>
 
-#include "gtest/gtest.h"
-#include "jxl/codestream_header.h"
-#include "jxl/decode.h"
-#include "jxl/decode_cxx.h"
-#include "jxl/encode.h"
-#include "jxl/encode_cxx.h"
-#include "jxl/types.h"
 #include "lib/extras/codec.h"
+#include "lib/jxl/base/span.h"
+#include "lib/jxl/dec_bit_reader.h"
 #include "lib/jxl/dec_external_image.h"
 #include "lib/jxl/enc_butteraugli_comparator.h"
 #include "lib/jxl/enc_comparator.h"
 #include "lib/jxl/enc_external_image.h"
 #include "lib/jxl/encode_internal.h"
 #include "lib/jxl/icc_codec.h"
+#include "lib/jxl/image_test_utils.h"
 #include "lib/jxl/test_utils.h"
-#include "lib/jxl/testdata.h"
+#include "lib/jxl/testing.h"
 
 namespace {
 
@@ -34,7 +38,7 @@ namespace {
 jxl::CodecInOut ConvertTestImage(const std::vector<uint8_t>& buf,
                                  const size_t xsize, const size_t ysize,
                                  const JxlPixelFormat& pixel_format,
-                                 const jxl::PaddedBytes& icc_profile) {
+                                 const jxl::Bytes& icc_profile) {
   jxl::CodecInOut io;
   io.SetSize(xsize, ysize);
 
@@ -56,58 +60,52 @@ jxl::CodecInOut ConvertTestImage(const std::vector<uint8_t>& buf,
         io.metadata.m.SetAlphaBits(16);
         break;
       default:
-        EXPECT_TRUE(false) << "Roundtrip tests for data type "
-                           << pixel_format.data_type << " not yet implemented.";
+        ADD_FAILURE() << "Roundtrip tests for data type "
+                      << pixel_format.data_type << " not yet implemented.";
     }
   }
   size_t bitdepth = 0;
-  bool float_in = false;
   switch (pixel_format.data_type) {
     case JXL_TYPE_FLOAT:
       bitdepth = 32;
-      float_in = true;
       io.metadata.m.SetFloat32Samples();
       break;
     case JXL_TYPE_FLOAT16:
       bitdepth = 16;
-      float_in = true;
       io.metadata.m.SetFloat16Samples();
       break;
     case JXL_TYPE_UINT8:
       bitdepth = 8;
-      float_in = false;
       io.metadata.m.SetUintSamples(8);
       break;
     case JXL_TYPE_UINT16:
       bitdepth = 16;
-      float_in = false;
       io.metadata.m.SetUintSamples(16);
       break;
     default:
-      EXPECT_TRUE(false) << "Roundtrip tests for data type "
-                         << pixel_format.data_type << " not yet implemented.";
+      ADD_FAILURE() << "Roundtrip tests for data type "
+                    << pixel_format.data_type << " not yet implemented.";
   }
   jxl::ColorEncoding color_encoding;
   if (!icc_profile.empty()) {
-    jxl::PaddedBytes icc_profile_copy(icc_profile);
-    EXPECT_TRUE(color_encoding.SetICC(std::move(icc_profile_copy)));
+    jxl::IccBytes icc_profile_copy;
+    icc_profile.AppendTo(&icc_profile_copy);
+    EXPECT_TRUE(
+        color_encoding.SetICC(std::move(icc_profile_copy), JxlGetDefaultCms()));
   } else if (pixel_format.data_type == JXL_TYPE_FLOAT) {
     color_encoding = jxl::ColorEncoding::LinearSRGB(is_gray);
   } else {
     color_encoding = jxl::ColorEncoding::SRGB(is_gray);
   }
-  EXPECT_TRUE(ConvertFromExternal(
-      jxl::Span<const uint8_t>(buf.data(), buf.size()), xsize, ysize,
-      color_encoding, pixel_format.num_channels,
-      /*alpha_is_premultiplied=*/false,
-      /*bits_per_sample=*/bitdepth, pixel_format.endianness,
-      /*pool=*/nullptr, &io.Main(), float_in,
-      /*align=*/0));
+  EXPECT_TRUE(ConvertFromExternal(jxl::Bytes(buf.data(), buf.size()), xsize,
+                                  ysize, color_encoding,
+                                  /*bits_per_sample=*/bitdepth, pixel_format,
+                                  /*pool=*/nullptr, &io.Main()));
   return io;
 }
 
 template <typename T>
-T ConvertTestPixel(const float val);
+T ConvertTestPixel(float val);
 
 template <>
 float ConvertTestPixel<float>(const float val) {
@@ -175,7 +173,7 @@ void EncodeWithEncoder(JxlEncoder* enc, std::vector<uint8_t>* compressed) {
   EXPECT_EQ(JXL_ENC_SUCCESS, process_result);
 }
 
-// Generates some pixels using using some dimensions and pixel_format,
+// Generates some pixels using some dimensions and pixel_format,
 // compresses them, and verifies that the decoded version is similar to the
 // original pixels.
 // TODO(firsching): change this to be a parameterized test, like in
@@ -188,7 +186,8 @@ void VerifyRoundtripCompression(
     const bool use_container, const uint32_t resampling = 1,
     const bool already_downsampled = false,
     const std::vector<std::pair<JxlExtraChannelType, std::string>>&
-        extra_channels = {}) {
+        extra_channels = {},
+    const int upsampling_mode = -1) {
   size_t orig_xsize = xsize;
   size_t orig_ysize = ysize;
   if (already_downsampled) {
@@ -231,19 +230,13 @@ void VerifyRoundtripCompression(
   }
   if (alpha_in_extra_channels_vector && !has_interleaved_alpha) {
     jxl::ImageF alpha_channel(xsize, ysize);
-
-    EXPECT_EQ(
-        jxl::ConvertFromExternal(
-            jxl::Span<const uint8_t>(extra_channel_bytes.data(),
-                                     extra_channel_bytes.size()),
-            xsize, ysize, basic_info.bits_per_sample,
-            input_pixel_format.endianness, /*pool=*/nullptr, &alpha_channel,
-            /*float_in=*/input_pixel_format.data_type == JXL_TYPE_FLOAT,
-            /*align=*/0),
-        true);
+    EXPECT_TRUE(jxl::ConvertFromExternal(
+        jxl::Bytes(extra_channel_bytes.data(), extra_channel_bytes.size()),
+        xsize, ysize, basic_info.bits_per_sample, extra_channel_pixel_format, 0,
+        /*pool=*/nullptr, &alpha_channel));
 
     original_io.metadata.m.SetAlphaBits(basic_info.bits_per_sample);
-    original_io.Main().SetAlpha(std::move(alpha_channel), false);
+    original_io.Main().SetAlpha(std::move(alpha_channel));
     output_pixel_format_with_extra_channel_alpha.num_channels++;
   }
   // Those are the num_extra_channels including a potential alpha channel.
@@ -281,6 +274,13 @@ void VerifyRoundtripCompression(
                                             name.c_str(), name.length()));
   }
   EXPECT_EQ(JXL_ENC_SUCCESS, JxlEncoderSetColorEncoding(enc, &color_encoding));
+  if (resampling > 1) {
+    EXPECT_EQ(JXL_ENC_ERROR, JxlEncoderSetUpsamplingMode(enc, 3, 0));
+    EXPECT_EQ(JXL_ENC_ERROR, JxlEncoderSetUpsamplingMode(enc, resampling, -2));
+    EXPECT_EQ(JXL_ENC_ERROR, JxlEncoderSetUpsamplingMode(enc, resampling, 2));
+  }
+  EXPECT_EQ(JXL_ENC_SUCCESS,
+            JxlEncoderSetUpsamplingMode(enc, resampling, upsampling_mode));
   JxlEncoderFrameSettings* frame_settings =
       JxlEncoderFrameSettingsCreate(enc, nullptr);
   JxlEncoderSetFrameLossless(frame_settings, lossless);
@@ -306,7 +306,7 @@ void VerifyRoundtripCompression(
   for (size_t index = 0; index < channel_infos.size(); index++) {
     EXPECT_EQ(JXL_ENC_SUCCESS,
               JxlEncoderSetExtraChannelBuffer(
-                  frame_settings, &input_pixel_format,
+                  frame_settings, &extra_channel_pixel_format,
                   (void*)extra_channel_bytes.data(), extra_channel_bytes.size(),
                   index + has_interleaved_alpha));
   }
@@ -353,14 +353,12 @@ void VerifyRoundtripCompression(
 
   size_t icc_profile_size;
   EXPECT_EQ(JXL_DEC_SUCCESS,
-            JxlDecoderGetICCProfileSize(
-                dec, &output_pixel_format_with_extra_channel_alpha,
-                JXL_COLOR_PROFILE_TARGET_DATA, &icc_profile_size));
-  jxl::PaddedBytes icc_profile(icc_profile_size);
-  EXPECT_EQ(JXL_DEC_SUCCESS,
-            JxlDecoderGetColorAsICCProfile(
-                dec, &output_pixel_format, JXL_COLOR_PROFILE_TARGET_DATA,
-                icc_profile.data(), icc_profile.size()));
+            JxlDecoderGetICCProfileSize(dec, JXL_COLOR_PROFILE_TARGET_DATA,
+                                        &icc_profile_size));
+  std::vector<uint8_t> icc_profile(icc_profile_size);
+  EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderGetColorAsICCProfile(
+                                 dec, JXL_COLOR_PROFILE_TARGET_DATA,
+                                 icc_profile.data(), icc_profile.size()));
 
   std::vector<uint8_t> decoded_bytes(buffer_size);
 
@@ -414,7 +412,7 @@ void VerifyRoundtripCompression(
 
   jxl::CodecInOut decoded_io = ConvertTestImage(
       decoded_bytes, xsize, ysize, output_pixel_format_with_extra_channel_alpha,
-      icc_profile);
+      jxl::Bytes(icc_profile));
 
   if (already_downsampled) {
     jxl::Image3F* color = decoded_io.Main().color();
@@ -426,14 +424,20 @@ void VerifyRoundtripCompression(
     decoded_io.SetSize(color->xsize(), color->ysize());
   }
 
-  jxl::ButteraugliParams ba;
-  float butteraugli_score =
-      ButteraugliDistance(original_io, decoded_io, ba, jxl::GetJxlCms(),
-                          /*distmap=*/nullptr, nullptr);
   if (lossless && !already_downsampled) {
-    EXPECT_LE(butteraugli_score, 0.0f);
+    JXL_EXPECT_OK(jxl::SamePixels(*original_io.Main().color(),
+                                  *decoded_io.Main().color(), _));
   } else {
-    EXPECT_LE(butteraugli_score, 2.0f);
+    jxl::ButteraugliParams ba;
+    float butteraugli_score = ButteraugliDistance(
+        original_io.frames, decoded_io.frames, ba, *JxlGetDefaultCms(),
+        /*distmap=*/nullptr, nullptr);
+    float target_score = 1.3f;
+    // upsampling mode 1 (unlike default and NN) does not downscale back to the
+    // already downsampled image
+    if (upsampling_mode == 1 && resampling >= 4 && already_downsampled)
+      target_score = 15.f;
+    EXPECT_LE(butteraugli_score, target_score);
   }
   JxlPixelFormat extra_channel_output_pixel_format = output_pixel_format;
   extra_channel_output_pixel_format.num_channels = 1;
@@ -540,7 +544,7 @@ TEST(RoundtripTest, TestNonlinearSrgbAsXybEncoded) {
           JxlPixelFormat{num_channels, JXL_TYPE_FLOAT, JXL_NATIVE_ENDIAN, 0};
       VerifyRoundtripCompression<uint8_t>(
           63, 129, pixel_format_in, pixel_format_out,
-          /*lossless=*/false, (bool)use_container, {});
+          /*lossless=*/false, (bool)use_container, 1, false, {});
     }
   }
 }
@@ -556,10 +560,15 @@ TEST(RoundtripTest, Resampling) {
   // TODO(lode): also make this work for odd sizes. This requires a fix in
   // enc_frame.cc to not set custom_size_or_origin to true due to even/odd
   // mismatch.
-  VerifyRoundtripCompression<uint8_t>(64, 128, pixel_format, pixel_format,
-                                      /*lossless=*/true,
-                                      /*use_container=*/false, 2,
-                                      /*already_downsampled=*/true);
+  for (int factor : {2, 4, 8}) {
+    for (int upsampling_mode : {-1, 0, 1}) {
+      VerifyRoundtripCompression<uint8_t>(
+          64, 128, pixel_format, pixel_format,
+          /*lossless=*/true,
+          /*use_container=*/false, factor,
+          /*already_downsampled=*/true, /*extra_channels=*/{}, upsampling_mode);
+    }
+  }
 }
 
 TEST(RoundtripTest, ExtraBoxesTest) {
@@ -638,14 +647,12 @@ TEST(RoundtripTest, ExtraBoxesTest) {
 
   size_t icc_profile_size;
   EXPECT_EQ(JXL_DEC_SUCCESS,
-            JxlDecoderGetICCProfileSize(dec, &pixel_format,
-                                        JXL_COLOR_PROFILE_TARGET_DATA,
+            JxlDecoderGetICCProfileSize(dec, JXL_COLOR_PROFILE_TARGET_DATA,
                                         &icc_profile_size));
-  jxl::PaddedBytes icc_profile(icc_profile_size);
-  EXPECT_EQ(JXL_DEC_SUCCESS,
-            JxlDecoderGetColorAsICCProfile(
-                dec, &pixel_format, JXL_COLOR_PROFILE_TARGET_DATA,
-                icc_profile.data(), icc_profile.size()));
+  std::vector<uint8_t> icc_profile(icc_profile_size);
+  EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderGetColorAsICCProfile(
+                                 dec, JXL_COLOR_PROFILE_TARGET_DATA,
+                                 icc_profile.data(), icc_profile.size()));
 
   std::vector<uint8_t> decoded_bytes(buffer_size);
 
@@ -659,14 +666,152 @@ TEST(RoundtripTest, ExtraBoxesTest) {
 
   JxlDecoderDestroy(dec);
 
-  jxl::CodecInOut decoded_io =
-      ConvertTestImage(decoded_bytes, xsize, ysize, pixel_format, icc_profile);
+  jxl::CodecInOut decoded_io = ConvertTestImage(
+      decoded_bytes, xsize, ysize, pixel_format, jxl::Bytes(icc_profile));
 
   jxl::ButteraugliParams ba;
-  float butteraugli_score =
-      ButteraugliDistance(original_io, decoded_io, ba, jxl::GetJxlCms(),
-                          /*distmap=*/nullptr, nullptr);
-  EXPECT_LE(butteraugli_score, 2.0f);
+  float butteraugli_score = ButteraugliDistance(
+      original_io.frames, decoded_io.frames, ba, *JxlGetDefaultCms(),
+      /*distmap=*/nullptr, nullptr);
+  EXPECT_LE(butteraugli_score, 1.0f);
+}
+
+TEST(RoundtripTest, MultiFrameTest) {
+  JxlPixelFormat pixel_format =
+      JxlPixelFormat{4, JXL_TYPE_FLOAT, JXL_NATIVE_ENDIAN, 0};
+  const size_t xsize = 61;
+  const size_t ysize = 71;
+  const size_t nb_frames = 4;
+  size_t compressed_size = 0;
+
+  for (int index_frames : {0, 1}) {
+    // use a vertical filmstrip of nb_frames frames
+    const std::vector<uint8_t> original_bytes =
+        GetTestImage<float>(xsize, ysize * nb_frames, pixel_format);
+    jxl::CodecInOut original_io = ConvertTestImage(
+        original_bytes, xsize, ysize * nb_frames, pixel_format, {});
+
+    JxlEncoder* enc = JxlEncoderCreate(nullptr);
+    EXPECT_NE(nullptr, enc);
+
+    EXPECT_EQ(JXL_ENC_SUCCESS, JxlEncoderUseContainer(enc, true));
+    JxlBasicInfo basic_info;
+    jxl::test::JxlBasicInfoSetFromPixelFormat(&basic_info, &pixel_format);
+    basic_info.xsize = xsize;
+    basic_info.ysize = ysize;
+    basic_info.uses_original_profile = JXL_FALSE;
+    basic_info.have_animation = JXL_TRUE;
+    basic_info.animation.tps_numerator = 1;
+    basic_info.animation.tps_denominator = 1;
+    EXPECT_EQ(JXL_ENC_SUCCESS, JxlEncoderSetCodestreamLevel(enc, 10));
+
+    EXPECT_EQ(JXL_ENC_SUCCESS, JxlEncoderSetBasicInfo(enc, &basic_info));
+    JxlColorEncoding color_encoding;
+    if (pixel_format.data_type == JXL_TYPE_FLOAT) {
+      JxlColorEncodingSetToLinearSRGB(
+          &color_encoding,
+          /*is_gray=*/pixel_format.num_channels < 3);
+    } else {
+      JxlColorEncodingSetToSRGB(&color_encoding,
+                                /*is_gray=*/pixel_format.num_channels < 3);
+    }
+    EXPECT_EQ(JXL_ENC_SUCCESS,
+              JxlEncoderSetColorEncoding(enc, &color_encoding));
+    JxlEncoderFrameSettings* frame_settings =
+        JxlEncoderFrameSettingsCreate(enc, nullptr);
+    JxlEncoderSetFrameLossless(frame_settings, false);
+    if (index_frames == 1) {
+      EXPECT_EQ(JXL_ENC_SUCCESS,
+                JxlEncoderFrameSettingsSetOption(frame_settings,
+                                                 JXL_ENC_FRAME_INDEX_BOX, 1));
+    }
+
+    size_t oneframesize = original_bytes.size() / nb_frames;
+    JxlFrameHeader frame_header;
+    JxlEncoderInitFrameHeader(&frame_header);
+    frame_header.duration = 1;
+    frame_header.is_last = JXL_FALSE;
+
+    for (size_t i = 0; i < nb_frames; i++) {
+      if (i + 1 == nb_frames) frame_header.is_last = JXL_TRUE;
+      JxlEncoderSetFrameHeader(frame_settings, &frame_header);
+      EXPECT_EQ(
+          JXL_ENC_SUCCESS,
+          JxlEncoderAddImageFrame(
+              frame_settings, &pixel_format,
+              (void*)(original_bytes.data() + oneframesize * i), oneframesize));
+    }
+    JxlEncoderCloseInput(enc);
+
+    std::vector<uint8_t> compressed;
+    EncodeWithEncoder(enc, &compressed);
+    JxlEncoderDestroy(enc);
+
+    JxlDecoder* dec = JxlDecoderCreate(nullptr);
+    EXPECT_NE(nullptr, dec);
+
+    const uint8_t* next_in = compressed.data();
+    size_t avail_in = compressed.size();
+
+    if (index_frames == 0) {
+      compressed_size = avail_in;
+    } else {
+      // a non-empty jxli box should be added
+      EXPECT_LE(avail_in, compressed_size + 50);
+      EXPECT_GE(avail_in, compressed_size + 10);
+    }
+
+    EXPECT_EQ(JXL_DEC_SUCCESS,
+              JxlDecoderSubscribeEvents(dec, JXL_DEC_BASIC_INFO |
+                                                 JXL_DEC_COLOR_ENCODING |
+                                                 JXL_DEC_FULL_IMAGE));
+
+    JxlDecoderSetInput(dec, next_in, avail_in);
+    EXPECT_EQ(JXL_DEC_BASIC_INFO, JxlDecoderProcessInput(dec));
+    size_t buffer_size;
+    EXPECT_EQ(JXL_DEC_SUCCESS,
+              JxlDecoderImageOutBufferSize(dec, &pixel_format, &buffer_size));
+    EXPECT_EQ(buffer_size, oneframesize);
+
+    JxlBasicInfo info;
+    EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderGetBasicInfo(dec, &info));
+    EXPECT_EQ(xsize, info.xsize);
+    EXPECT_EQ(ysize, info.ysize);
+
+    EXPECT_EQ(JXL_DEC_COLOR_ENCODING, JxlDecoderProcessInput(dec));
+
+    size_t icc_profile_size;
+    EXPECT_EQ(JXL_DEC_SUCCESS,
+              JxlDecoderGetICCProfileSize(dec, JXL_COLOR_PROFILE_TARGET_DATA,
+                                          &icc_profile_size));
+    std::vector<uint8_t> icc_profile(icc_profile_size);
+    EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderGetColorAsICCProfile(
+                                   dec, JXL_COLOR_PROFILE_TARGET_DATA,
+                                   icc_profile.data(), icc_profile.size()));
+
+    std::vector<uint8_t> decoded_bytes(buffer_size * nb_frames);
+
+    EXPECT_EQ(JXL_DEC_NEED_IMAGE_OUT_BUFFER, JxlDecoderProcessInput(dec));
+
+    for (size_t i = 0; i < nb_frames; i++) {
+      EXPECT_EQ(JXL_DEC_SUCCESS,
+                JxlDecoderSetImageOutBuffer(
+                    dec, &pixel_format, decoded_bytes.data() + i * oneframesize,
+                    buffer_size));
+
+      EXPECT_EQ(JXL_DEC_FULL_IMAGE, JxlDecoderProcessInput(dec));
+    }
+    JxlDecoderDestroy(dec);
+    jxl::CodecInOut decoded_io =
+        ConvertTestImage(decoded_bytes, xsize, ysize * nb_frames, pixel_format,
+                         jxl::Bytes(icc_profile));
+
+    jxl::ButteraugliParams ba;
+    float butteraugli_score = ButteraugliDistance(
+        original_io.frames, decoded_io.frames, ba, *JxlGetDefaultCms(),
+        /*distmap=*/nullptr, nullptr);
+    EXPECT_LE(butteraugli_score, 1.0f);
+  }
 }
 
 static const unsigned char kEncodedTestProfile[] = {
@@ -708,10 +853,10 @@ static const unsigned char kEncodedTestProfile[] = {
 TEST(RoundtripTest, TestICCProfile) {
   // JxlEncoderSetICCProfile parses the ICC profile, so a valid profile is
   // needed. The profile should be passed correctly through the roundtrip.
-  jxl::BitReader reader(jxl::Span<const uint8_t>(kEncodedTestProfile,
-                                                 sizeof(kEncodedTestProfile)));
-  jxl::PaddedBytes icc;
-  ASSERT_TRUE(ReadICC(&reader, &icc));
+  jxl::BitReader reader(
+      jxl::Bytes(kEncodedTestProfile, sizeof(kEncodedTestProfile)));
+  std::vector<uint8_t> icc;
+  ASSERT_TRUE(jxl::test::ReadICC(&reader, &icc));
   ASSERT_TRUE(reader.Close());
 
   JxlPixelFormat format =
@@ -772,16 +917,14 @@ TEST(RoundtripTest, TestICCProfile) {
   EXPECT_EQ(JXL_DEC_COLOR_ENCODING, JxlDecoderProcessInput(dec));
 
   size_t dec_icc_size;
-  EXPECT_EQ(
-      JXL_DEC_SUCCESS,
-      JxlDecoderGetICCProfileSize(
-          dec, &format, JXL_COLOR_PROFILE_TARGET_ORIGINAL, &dec_icc_size));
-  EXPECT_EQ(icc.size(), dec_icc_size);
-  jxl::PaddedBytes dec_icc(dec_icc_size);
   EXPECT_EQ(JXL_DEC_SUCCESS,
-            JxlDecoderGetColorAsICCProfile(dec, &format,
-                                           JXL_COLOR_PROFILE_TARGET_ORIGINAL,
-                                           dec_icc.data(), dec_icc.size()));
+            JxlDecoderGetICCProfileSize(dec, JXL_COLOR_PROFILE_TARGET_ORIGINAL,
+                                        &dec_icc_size));
+  EXPECT_EQ(icc.size(), dec_icc_size);
+  std::vector<uint8_t> dec_icc(dec_icc_size);
+  EXPECT_EQ(JXL_DEC_SUCCESS, JxlDecoderGetColorAsICCProfile(
+                                 dec, JXL_COLOR_PROFILE_TARGET_ORIGINAL,
+                                 dec_icc.data(), dec_icc.size()));
 
   std::vector<uint8_t> decoded_bytes(buffer_size);
 
@@ -798,13 +941,12 @@ TEST(RoundtripTest, TestICCProfile) {
   JxlDecoderDestroy(dec);
 }
 
-#if JPEGXL_ENABLE_JPEG  // Loading .jpg files requires libjpeg support.
 TEST(RoundtripTest, JXL_TRANSCODE_JPEG_TEST(TestJPEGReconstruction)) {
+  TEST_LIBJPEG_SUPPORT();
   const std::string jpeg_path = "jxl/flower/flower.png.im_q85_420.jpg";
-  const jxl::PaddedBytes orig = jxl::ReadTestData(jpeg_path);
+  const std::vector<uint8_t> orig = jxl::test::ReadTestData(jpeg_path);
   jxl::CodecInOut orig_io;
-  ASSERT_TRUE(
-      SetFromBytes(jxl::Span<const uint8_t>(orig), &orig_io, /*pool=*/nullptr));
+  ASSERT_TRUE(SetFromBytes(jxl::Bytes(orig), &orig_io, /*pool=*/nullptr));
 
   JxlEncoderPtr enc = JxlEncoderMake(nullptr);
   JxlEncoderFrameSettings* frame_settings =
@@ -845,4 +987,3 @@ TEST(RoundtripTest, JXL_TRANSCODE_JPEG_TEST(TestJPEGReconstruction)) {
   ASSERT_EQ(used, orig.size());
   EXPECT_EQ(0, memcmp(reconstructed_buffer.data(), orig.data(), used));
 }
-#endif  // JPEGXL_ENABLE_JPEG