summaryrefslogtreecommitdiffstats
path: root/third_party/jpeg-xl/lib/jxl/jxl_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/jpeg-xl/lib/jxl/jxl_test.cc')
-rw-r--r--third_party/jpeg-xl/lib/jxl/jxl_test.cc326
1 files changed, 223 insertions, 103 deletions
diff --git a/third_party/jpeg-xl/lib/jxl/jxl_test.cc b/third_party/jpeg-xl/lib/jxl/jxl_test.cc
index a91dbd0672..b0933d5d50 100644
--- a/third_party/jpeg-xl/lib/jxl/jxl_test.cc
+++ b/third_party/jpeg-xl/lib/jxl/jxl_test.cc
@@ -33,7 +33,6 @@
#include "lib/jxl/codec_in_out.h"
#include "lib/jxl/color_encoding_internal.h"
#include "lib/jxl/common.h" // JXL_HIGH_PRECISION
-#include "lib/jxl/enc_butteraugli_comparator.h"
#include "lib/jxl/enc_params.h"
#include "lib/jxl/fake_parallel_runner_testonly.h"
#include "lib/jxl/image.h"
@@ -72,7 +71,7 @@ TEST(JxlTest, RoundtripSinglePixelWithAlpha) {
TestImage t;
t.SetDimensions(1, 1).SetChannels(4).AddFrame().ZeroFill();
PackedPixelFile ppf_out;
- EXPECT_EQ(Roundtrip(t.ppf(), {}, {}, nullptr, &ppf_out), 59);
+ EXPECT_EQ(Roundtrip(t.ppf(), {}, {}, nullptr, &ppf_out), 58);
}
// Changing serialized signature causes Decode to fail.
@@ -87,7 +86,7 @@ TEST(JxlTest, RoundtripMarker) {
compressed[i] ^= 0xFF;
PackedPixelFile ppf_out;
EXPECT_FALSE(extras::DecodeImageJXL(compressed.data(), compressed.size(),
- {}, /*decodec_bytes=*/nullptr,
+ {}, /* decoded_bytes */ nullptr,
&ppf_out));
}
}
@@ -121,7 +120,7 @@ TEST(JxlTest, RoundtripSmallD1) {
{
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), {}, {}, pool, &ppf_out), 916, 40);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(0.888));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.888);
}
// With a lower intensity target than the default, the bitrate should be
@@ -131,7 +130,7 @@ TEST(JxlTest, RoundtripSmallD1) {
{
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), {}, {}, pool, &ppf_out), 745, 20);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(1.3));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.3);
EXPECT_EQ(ppf_out.info.intensity_target, t.ppf().info.intensity_target);
}
}
@@ -147,8 +146,8 @@ TEST(JxlTest, RoundtripResample2) {
cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 3); // kFalcon
PackedPixelFile ppf_out;
- EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 18500, 200);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out), IsSlightlyBelow(90));
+ EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 17300, 500);
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 90);
}
TEST(JxlTest, RoundtripResample2Slow) {
@@ -165,7 +164,7 @@ TEST(JxlTest, RoundtripResample2Slow) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 3888, 200);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out), IsSlightlyBelow(250));
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 250);
}
TEST(JxlTest, RoundtripResample2MT) {
@@ -180,8 +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), 223310, 2000);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out), IsSlightlyBelow(340));
+ EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 203300, 2000);
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 340);
}
// Roundtrip the image using a parallel runner that executes single-threaded but
@@ -237,7 +236,7 @@ TEST(JxlTest, RoundtripResample4) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 5758, 100);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(22));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 22);
}
TEST(JxlTest, RoundtripResample8) {
@@ -252,7 +251,7 @@ TEST(JxlTest, RoundtripResample8) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 2036, 50);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(50));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 50);
}
TEST(JxlTest, RoundtripUnalignedD2) {
@@ -270,7 +269,7 @@ TEST(JxlTest, RoundtripUnalignedD2) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 506, 30);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(1.72));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.72);
}
TEST(JxlTest, RoundtripMultiGroup) {
@@ -289,8 +288,8 @@ TEST(JxlTest, RoundtripMultiGroup) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), expected_size,
700);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out),
- IsSlightlyBelow(expected_distance));
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out),
+ expected_distance);
};
auto run_kitten = std::async(std::launch::async, test, SpeedTier::kKitten,
@@ -339,10 +338,11 @@ TEST(JxlTest, RoundtripRGBToGrayscale) {
ASSERT_TRUE(io.frames[0].TransformTo(srgb_gamma, *JxlGetDefaultCms()));
io.metadata.m.color_encoding = io2.Main().c_current();
io.Main().OverrideProfile(io2.Main().c_current());
- EXPECT_THAT(ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(),
- *JxlGetDefaultCms(),
- /*distmap=*/nullptr, &pool),
- IsSlightlyBelow(1.36));
+ EXPECT_SLIGHTLY_BELOW(
+ ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(),
+ *JxlGetDefaultCms(),
+ /*distmap=*/nullptr, &pool),
+ 1.4);
}
TEST(JxlTest, RoundtripLargeFast) {
@@ -355,8 +355,57 @@ TEST(JxlTest, RoundtripLargeFast) {
cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 7); // kSquirrel
PackedPixelFile ppf_out;
- EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 492867, 5000);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out), IsSlightlyBelow(78));
+ EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 503000, 12000);
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 78);
+}
+
+TEST(JxlTest, JXL_X86_64_TEST(RoundtripLargeEmptyModular)) {
+ ThreadPoolForTests pool(8);
+ TestImage t;
+ t.SetDimensions(4096, 4096).SetDataType(JXL_TYPE_UINT8).SetChannels(4);
+ TestImage::Frame frame = t.AddFrame();
+ frame.ZeroFill();
+ for (size_t c = 0; c < 4; ++c) {
+ for (size_t y = 0; y < 1024; y += (c + 1)) {
+ for (size_t x = 0; x < 1024; x += ((y % 4) + 3)) {
+ frame.SetValue(y, x, c, 0.88);
+ }
+ }
+ }
+
+ JXLCompressParams cparams;
+ cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 1);
+ cparams.AddOption(JXL_ENC_FRAME_SETTING_MODULAR, 1);
+ cparams.AddOption(JXL_ENC_FRAME_SETTING_RESPONSIVE, 1);
+ cparams.AddOption(JXL_ENC_FRAME_SETTING_DECODING_SPEED, 2);
+
+ PackedPixelFile ppf_out;
+ EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 3474795,
+ 100000);
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out),
+#if JXL_HIGH_PRECISION
+ 2050
+#else
+ 12100
+#endif
+ );
+}
+
+TEST(JxlTest, RoundtripOutputColorSpace) {
+ ThreadPoolForTests pool(8);
+ const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png");
+ TestImage t;
+ t.DecodeFromBytes(orig).ClearMetadata();
+
+ JXLCompressParams cparams;
+ cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 7); // kSquirrel
+
+ 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_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 78);
}
TEST(JxlTest, RoundtripDotsForceEpf) {
@@ -373,7 +422,7 @@ TEST(JxlTest, RoundtripDotsForceEpf) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 41355, 300);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out), IsSlightlyBelow(18));
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 18);
}
// Checks for differing size/distance in two consecutive runs of distance 2,
@@ -453,7 +502,7 @@ TEST(JxlTest, RoundtripSmallNL) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), {}, {}, pool, &ppf_out), 916, 45);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(0.82));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.82);
}
TEST(JxlTest, RoundtripNoGaborishNoAR) {
@@ -469,7 +518,7 @@ TEST(JxlTest, RoundtripNoGaborishNoAR) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 41142, 400);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(1.8));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.8);
}
TEST(JxlTest, RoundtripSmallNoGaborish) {
@@ -487,7 +536,7 @@ TEST(JxlTest, RoundtripSmallNoGaborish) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 1006, 20);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(1.1));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.1);
}
TEST(JxlTest, RoundtripSmallPatchesAlpha) {
@@ -513,7 +562,7 @@ TEST(JxlTest, RoundtripSmallPatchesAlpha) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 597, 100);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(0.018f));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.018f);
}
TEST(JxlTest, RoundtripSmallPatches) {
@@ -538,17 +587,17 @@ TEST(JxlTest, RoundtripSmallPatches) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 486, 100);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(0.018f));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.018f);
}
// TODO(szabadka) Add encoder and decoder API functions that accept frame
// buffers in arbitrary unsigned and floating point formats, and then roundtrip
// test the lossless codepath to make sure the exact binary representations
// are preserved.
-#if 0
+#if JXL_FALSE
TEST(JxlTest, RoundtripImageBundleOriginalBits) {
// Image does not matter, only io.metadata.m and io2.metadata.m are tested.
- Image3F image(1, 1);
+ JXL_ASSIGN_OR_DIE(Image3F image, Image3F::Create(1, 1));
ZeroFillImage(&image);
CodecInOut io;
io.metadata.m.color_encoding = ColorEncoding::LinearSRGB();
@@ -639,10 +688,11 @@ TEST(JxlTest, RoundtripGrayscale) {
EXPECT_TRUE(io2.Main().IsGray());
EXPECT_LE(compressed.size(), 7000u);
- EXPECT_THAT(ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(),
- *JxlGetDefaultCms(),
- /*distmap=*/nullptr),
- IsSlightlyBelow(1.6));
+ EXPECT_SLIGHTLY_BELOW(
+ ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(),
+ *JxlGetDefaultCms(),
+ /*distmap=*/nullptr),
+ 1.6);
}
// Test with larger butteraugli distance and other settings enabled so
@@ -658,10 +708,11 @@ TEST(JxlTest, RoundtripGrayscale) {
EXPECT_TRUE(io2.Main().IsGray());
EXPECT_LE(compressed.size(), 1300u);
- EXPECT_THAT(ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(),
- *JxlGetDefaultCms(),
- /*distmap=*/nullptr),
- IsSlightlyBelow(6.7));
+ EXPECT_SLIGHTLY_BELOW(
+ ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(),
+ *JxlGetDefaultCms(),
+ /*distmap=*/nullptr),
+ 6.7);
}
{
@@ -678,10 +729,11 @@ TEST(JxlTest, RoundtripGrayscale) {
EXPECT_FALSE(io2.Main().IsGray());
EXPECT_LE(compressed.size(), 7000u);
- EXPECT_THAT(ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(),
- *JxlGetDefaultCms(),
- /*distmap=*/nullptr),
- IsSlightlyBelow(1.6));
+ EXPECT_SLIGHTLY_BELOW(
+ ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(),
+ *JxlGetDefaultCms(),
+ /*distmap=*/nullptr),
+ 1.6);
}
}
@@ -706,7 +758,7 @@ TEST(JxlTest, RoundtripAlpha) {
std::vector<uint8_t> compressed;
EXPECT_TRUE(test::EncodeFile(cparams, &io, &compressed));
- EXPECT_LE(compressed.size(), 10077u);
+ EXPECT_LE(compressed.size(), 20000u);
for (bool use_image_callback : {false, true}) {
for (bool unpremul_alpha : {false, true}) {
@@ -715,10 +767,11 @@ TEST(JxlTest, RoundtripAlpha) {
dparams.use_image_callback = use_image_callback;
dparams.unpremultiply_alpha = unpremul_alpha;
EXPECT_TRUE(test::DecodeFile(dparams, Bytes(compressed), &io2));
- EXPECT_THAT(ButteraugliDistance(io.frames, io2.frames,
- ButteraugliParams(), *JxlGetDefaultCms(),
- /*distmap=*/nullptr),
- IsSlightlyBelow(1.15));
+ EXPECT_SLIGHTLY_BELOW(
+ ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(),
+ *JxlGetDefaultCms(),
+ /*distmap=*/nullptr),
+ 1.15);
}
}
}
@@ -781,7 +834,8 @@ bool UnpremultiplyAlpha(CodecInOut& io) {
TEST(JxlTest, RoundtripAlphaPremultiplied) {
const std::vector<uint8_t> orig =
ReadTestData("external/wesaturate/500px/tmshre_riaphotographs_alpha.png");
- CodecInOut io, io_nopremul;
+ CodecInOut io;
+ CodecInOut io_nopremul;
ASSERT_TRUE(SetFromBytes(Bytes(orig), &io));
ASSERT_TRUE(SetFromBytes(Bytes(orig), &io_nopremul));
@@ -803,7 +857,7 @@ TEST(JxlTest, RoundtripAlphaPremultiplied) {
std::vector<uint8_t> compressed;
EXPECT_TRUE(test::EncodeFile(cparams, &io, &compressed));
- EXPECT_LE(compressed.size(), 10000u);
+ EXPECT_LE(compressed.size(), 18000u);
for (bool use_image_callback : {false, true}) {
for (bool unpremul_alpha : {false, true}) {
@@ -826,19 +880,19 @@ TEST(JxlTest, RoundtripAlphaPremultiplied) {
EXPECT_EQ(unpremul_alpha, !io2.Main().AlphaIsPremultiplied());
if (!unpremul_alpha) {
- EXPECT_THAT(
+ EXPECT_SLIGHTLY_BELOW(
ButteraugliDistance(io.frames, io2.frames, ButteraugliParams(),
*JxlGetDefaultCms(),
/*distmap=*/nullptr),
- IsSlightlyBelow(1.111));
+ 1.111);
EXPECT_TRUE(UnpremultiplyAlpha(io2));
EXPECT_FALSE(io2.Main().AlphaIsPremultiplied());
}
- EXPECT_THAT(
+ EXPECT_SLIGHTLY_BELOW(
ButteraugliDistance(io_nopremul.frames, io2.frames,
ButteraugliParams(), *JxlGetDefaultCms(),
/*distmap=*/nullptr),
- IsSlightlyBelow(1.55));
+ 1.0);
}
}
}
@@ -854,13 +908,14 @@ TEST(JxlTest, RoundtripAlphaResampling) {
ASSERT_TRUE(t.ppf().info.alpha_bits > 0);
JXLCompressParams cparams;
+ cparams.alpha_distance = 1.0;
cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 5); // kHare
cparams.AddOption(JXL_ENC_FRAME_SETTING_RESAMPLING, 2);
cparams.AddOption(JXL_ENC_FRAME_SETTING_EXTRA_CHANNEL_RESAMPLING, 2);
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 13507, 130);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(5.2));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 5.2);
}
TEST(JxlTest, RoundtripAlphaResamplingOnlyAlpha) {
@@ -873,12 +928,13 @@ TEST(JxlTest, RoundtripAlphaResamplingOnlyAlpha) {
ASSERT_TRUE(t.ppf().info.alpha_bits > 0);
JXLCompressParams cparams;
+ cparams.alpha_distance = 1.0;
cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 3); // kFalcon
cparams.AddOption(JXL_ENC_FRAME_SETTING_EXTRA_CHANNEL_RESAMPLING, 2);
PackedPixelFile ppf_out;
- EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 33571, 400);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(1.49));
+ EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 32000, 1000);
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.52);
}
TEST(JxlTest, RoundtripAlphaNonMultipleOf8) {
@@ -893,13 +949,14 @@ TEST(JxlTest, RoundtripAlphaNonMultipleOf8) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), {}, {}, pool, &ppf_out), 107, 10);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(0.95));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.006);
}
TEST(JxlTest, RoundtripAlpha16) {
ThreadPoolForTests pool(4);
// The image is wider than 512 pixels to ensure multiple groups are tested.
- size_t xsize = 1200, ysize = 160;
+ size_t xsize = 1200;
+ size_t ysize = 160;
TestImage t;
t.SetDimensions(xsize, ysize).SetChannels(4).SetAllBitDepths(16);
TestImage::Frame frame = t.AddFrame();
@@ -923,12 +980,13 @@ TEST(JxlTest, RoundtripAlpha16) {
JXLCompressParams cparams;
cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 6); // kWombat
cparams.distance = 0.5;
+ cparams.alpha_distance = 0.5;
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_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(0.65));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.65);
}
namespace {
@@ -990,8 +1048,8 @@ TEST(JxlTest, JXL_SLOW_TEST(RoundtripLossless8LightningGradient)) {
PackedPixelFile ppf_out;
// Lax comparison because different SIMD will cause different compression.
- EXPECT_THAT(Roundtrip(t.ppf(), cparams, dparams, &pool, &ppf_out),
- IsSlightlyBelow(286848u));
+ EXPECT_SLIGHTLY_BELOW(Roundtrip(t.ppf(), cparams, dparams, &pool, &ppf_out),
+ 286848u);
EXPECT_EQ(ComputeDistance2(t.ppf(), ppf_out), 0.0);
}
@@ -1035,7 +1093,8 @@ TEST(JxlTest, RoundtripLossless8Alpha) {
TEST(JxlTest, RoundtripLossless16Alpha) {
ThreadPool* pool = nullptr;
- size_t xsize = 1200, ysize = 160;
+ size_t xsize = 1200;
+ size_t ysize = 160;
TestImage t;
t.SetDimensions(xsize, ysize).SetChannels(4).SetAllBitDepths(16);
TestImage::Frame frame = t.AddFrame();
@@ -1062,7 +1121,7 @@ TEST(JxlTest, RoundtripLossless16Alpha) {
PackedPixelFile ppf_out;
// TODO(szabadka) Investigate big size difference on i686
- EXPECT_NEAR(Roundtrip(t.ppf(), cparams, dparams, pool, &ppf_out), 4884, 100);
+ EXPECT_NEAR(Roundtrip(t.ppf(), cparams, dparams, pool, &ppf_out), 4665, 100);
EXPECT_EQ(ComputeDistance2(t.ppf(), ppf_out), 0.0);
EXPECT_EQ(ppf_out.info.alpha_bits, 16);
EXPECT_TRUE(test::SameAlpha(t.ppf(), ppf_out));
@@ -1070,7 +1129,8 @@ TEST(JxlTest, RoundtripLossless16Alpha) {
TEST(JxlTest, RoundtripLossless16AlphaNotMisdetectedAs8Bit) {
ThreadPool* pool = nullptr;
- size_t xsize = 128, ysize = 128;
+ size_t xsize = 128;
+ size_t ysize = 128;
TestImage t;
t.SetDimensions(xsize, ysize).SetChannels(4).SetAllBitDepths(16);
TestImage::Frame frame = t.AddFrame();
@@ -1098,7 +1158,7 @@ TEST(JxlTest, RoundtripLossless16AlphaNotMisdetectedAs8Bit) {
dparams.accepted_formats.push_back(t.ppf().frames[0].color.format);
PackedPixelFile ppf_out;
- EXPECT_NEAR(Roundtrip(t.ppf(), cparams, dparams, pool, &ppf_out), 591, 50);
+ EXPECT_NEAR(Roundtrip(t.ppf(), cparams, dparams, pool, &ppf_out), 280, 50);
EXPECT_EQ(ComputeDistance2(t.ppf(), ppf_out), 0.0);
EXPECT_EQ(ppf_out.info.bits_per_sample, 16);
EXPECT_EQ(ppf_out.info.alpha_bits, 16);
@@ -1123,7 +1183,7 @@ TEST(JxlTest, RoundtripDots) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 280333, 4000);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(0.35));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 0.35);
}
TEST(JxlTest, RoundtripNoise) {
@@ -1143,7 +1203,7 @@ TEST(JxlTest, RoundtripNoise) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, pool, &ppf_out), 41009, 750);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(1.42));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.42);
}
TEST(JxlTest, RoundtripLossless8Gray) {
@@ -1182,17 +1242,17 @@ TEST(JxlTest, RoundtripAnimation) {
dparams.accepted_formats.push_back(t.ppf().frames[0].color.format);
PackedPixelFile ppf_out;
- EXPECT_THAT(Roundtrip(t.ppf(), {}, dparams, pool, &ppf_out),
- IsSlightlyBelow(2888));
+ EXPECT_SLIGHTLY_BELOW(Roundtrip(t.ppf(), {}, dparams, pool, &ppf_out), 3350);
t.CoalesceGIFAnimationWithAlpha();
ASSERT_EQ(ppf_out.frames.size(), t.ppf().frames.size());
- EXPECT_LE(ButteraugliDistance(t.ppf(), ppf_out),
+ static constexpr double kMaxButteraugli =
#if JXL_HIGH_PRECISION
- 1.55);
+ 1.55;
#else
- 1.75);
+ 1.75;
#endif
+ EXPECT_LE(ButteraugliDistance(t.ppf(), ppf_out), kMaxButteraugli);
}
TEST(JxlTest, RoundtripLosslessAnimation) {
@@ -1212,8 +1272,8 @@ TEST(JxlTest, RoundtripLosslessAnimation) {
dparams.accepted_formats.push_back(t.ppf().frames[0].color.format);
PackedPixelFile ppf_out;
- EXPECT_THAT(Roundtrip(t.ppf(), cparams, dparams, pool, &ppf_out),
- IsSlightlyBelow(958));
+ EXPECT_SLIGHTLY_BELOW(Roundtrip(t.ppf(), cparams, dparams, pool, &ppf_out),
+ 958);
t.CoalesceGIFAnimationWithAlpha();
ASSERT_EQ(ppf_out.frames.size(), t.ppf().frames.size());
@@ -1240,11 +1300,11 @@ TEST(JxlTest, RoundtripAnimationPatches) {
PackedPixelFile ppf_out;
// 40k with no patches, 27k with patch frames encoded multiple times.
- EXPECT_THAT(Roundtrip(t.ppf(), cparams, dparams, pool, &ppf_out),
- IsSlightlyBelow(19300));
+ EXPECT_SLIGHTLY_BELOW(Roundtrip(t.ppf(), cparams, dparams, pool, &ppf_out),
+ 19300);
EXPECT_EQ(ppf_out.frames.size(), t.ppf().frames.size());
// >10 with broken patches; not all patches are detected on borders.
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(1.9));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.9);
}
size_t RoundtripJpeg(const std::vector<uint8_t>& jpeg_in, ThreadPool* pool) {
@@ -1293,7 +1353,7 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression444)) {
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), 568940u, 20);
+ EXPECT_NEAR(RoundtripJpeg(orig, &pool), 568891u, 20);
}
TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels)) {
@@ -1306,7 +1366,7 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels)) {
PackedPixelFile ppf_out;
RoundtripJpegToPixels(orig, {}, &pool, &ppf_out);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out), IsSlightlyBelow(12));
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 12);
}
TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels420)) {
@@ -1319,7 +1379,7 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionToPixels420)) {
PackedPixelFile ppf_out;
RoundtripJpegToPixels(orig, {}, &pool, &ppf_out);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out), IsSlightlyBelow(11));
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 11);
}
TEST(JxlTest,
@@ -1336,7 +1396,7 @@ TEST(JxlTest,
PackedPixelFile ppf_out;
RoundtripJpegToPixels(orig, dparams, &pool, &ppf_out);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out), IsSlightlyBelow(4410));
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 4410);
}
TEST(JxlTest,
@@ -1350,7 +1410,7 @@ TEST(JxlTest,
PackedPixelFile ppf_out;
RoundtripJpegToPixels(orig, {}, &pool, &ppf_out);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out), IsSlightlyBelow(4));
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 4);
}
TEST(JxlTest,
@@ -1364,7 +1424,7 @@ TEST(JxlTest,
PackedPixelFile ppf_out;
RoundtripJpegToPixels(orig, {}, &pool, &ppf_out);
- EXPECT_THAT(ComputeDistance2(t.ppf(), ppf_out), IsSlightlyBelow(10));
+ EXPECT_SLIGHTLY_BELOW(ComputeDistance2(t.ppf(), ppf_out), 10);
}
TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionGray)) {
@@ -1380,7 +1440,7 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression420)) {
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), 455560u, 10);
+ EXPECT_NEAR(RoundtripJpeg(orig, &pool), 455510u, 20);
}
TEST(JxlTest,
@@ -1389,7 +1449,7 @@ TEST(JxlTest,
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), 325354u, 15);
+ EXPECT_NEAR(RoundtripJpeg(orig, &pool), 325310u, 20);
}
TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression444_12)) {
@@ -1398,7 +1458,7 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression444_12)) {
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), 569679u, 10);
+ EXPECT_NEAR(RoundtripJpeg(orig, &pool), 569630u, 20);
}
TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression422)) {
@@ -1406,7 +1466,7 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression422)) {
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), 499282u, 10);
+ EXPECT_NEAR(RoundtripJpeg(orig, &pool), 499236u, 20);
}
TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression440)) {
@@ -1414,7 +1474,7 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression440)) {
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), 501151u, 10);
+ EXPECT_NEAR(RoundtripJpeg(orig, &pool), 501101u, 20);
}
TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression_asymmetric)) {
@@ -1424,7 +1484,7 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression_asymmetric)) {
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), 500602u, 10);
+ EXPECT_NEAR(RoundtripJpeg(orig, &pool), 500548u, 20);
}
TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression420Progr)) {
@@ -1432,7 +1492,7 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompression420Progr)) {
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), 455499u, 10);
+ EXPECT_NEAR(RoundtripJpeg(orig, &pool), 455454u, 20);
}
TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionMetadata)) {
@@ -1440,7 +1500,8 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionMetadata)) {
const std::vector<uint8_t> orig =
ReadTestData("jxl/jpeg_reconstruction/1x1_exif_xmp.jpg");
// JPEG size is 4290 bytes
- EXPECT_NEAR(RoundtripJpeg(orig, &pool), 1400u, 30);
+ // 1370 on 386, so higher margin.
+ EXPECT_NEAR(RoundtripJpeg(orig, &pool), 1334u, 100);
}
TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionRestarts)) {
@@ -1448,7 +1509,7 @@ TEST(JxlTest, JXL_TRANSCODE_JPEG_TEST(RoundtripJpegRecompressionRestarts)) {
const std::vector<uint8_t> orig =
ReadTestData("jxl/jpeg_reconstruction/bicycles_restarts.jpg");
// JPEG size is 87478 bytes
- EXPECT_NEAR(RoundtripJpeg(orig, &pool), 76125u, 30);
+ EXPECT_NEAR(RoundtripJpeg(orig, &pool), 76054u, 30);
}
TEST(JxlTest,
@@ -1475,7 +1536,7 @@ TEST(JxlTest, RoundtripProgressive) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 70544, 750);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(1.4));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.4);
}
TEST(JxlTest, RoundtripProgressiveLevel2Slow) {
@@ -1492,7 +1553,7 @@ TEST(JxlTest, RoundtripProgressiveLevel2Slow) {
PackedPixelFile ppf_out;
EXPECT_NEAR(Roundtrip(t.ppf(), cparams, {}, &pool, &ppf_out), 76666, 1000);
- EXPECT_THAT(ButteraugliDistance(t.ppf(), ppf_out), IsSlightlyBelow(1.17));
+ EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(t.ppf(), ppf_out), 1.17);
}
TEST(JxlTest, RoundtripUnsignedCustomBitdepthLossless) {
@@ -1509,9 +1570,9 @@ TEST(JxlTest, RoundtripUnsignedCustomBitdepthLossless) {
t.SetAllBitDepths(bitdepth).SetEndianness(endianness);
TestImage::Frame frame = t.AddFrame();
frame.RandomFill();
+ t.ppf().input_bitdepth.type = JXL_BIT_DEPTH_FROM_CODESTREAM;
JXLCompressParams cparams = CompressParamsForLossless();
- cparams.input_bitdepth.type = JXL_BIT_DEPTH_FROM_CODESTREAM;
JXLDecompressParams dparams;
dparams.accepted_formats.push_back(t.ppf().frames[0].color.format);
@@ -1543,7 +1604,6 @@ TEST(JxlTest, LosslessPNMRoundtrip) {
JXLCompressParams cparams = CompressParamsForLossless();
cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 1); // kLightning
- cparams.input_bitdepth.type = JXL_BIT_DEPTH_FROM_CODESTREAM;
JXLDecompressParams dparams;
dparams.accepted_formats.push_back(t.ppf().frames[0].color.format);
@@ -1592,10 +1652,13 @@ struct StreamingTestParam {
size_t xsize;
size_t ysize;
bool is_grey;
+ bool has_alpha;
int effort;
bool progressive;
- size_t num_channels() const { return is_grey ? 1 : 3; }
+ size_t num_channels() const {
+ return (is_grey ? 1 : 3) + (has_alpha ? 1 : 0);
+ }
float max_psnr() const { return is_grey ? 90 : 50; }
@@ -1603,11 +1666,13 @@ struct StreamingTestParam {
std::vector<StreamingTestParam> params;
for (int e : {1, 3, 4, 7}) {
for (bool g : {false, true}) {
- params.push_back(StreamingTestParam{357, 517, g, e, false});
- params.push_back(StreamingTestParam{2247, 2357, g, e, false});
+ params.push_back(StreamingTestParam{357, 517, g, false, e, false});
+ params.push_back(StreamingTestParam{2247, 2357, g, false, e, false});
}
}
- params.push_back(StreamingTestParam{2247, 2357, false, 1, true});
+ params.push_back(StreamingTestParam{2247, 2357, false, false, 1, true});
+ params.push_back(StreamingTestParam{2247, 2157, false, false, 5, false});
+ params.push_back(StreamingTestParam{2247, 2157, false, true, 5, false});
return params;
}
};
@@ -1651,15 +1716,66 @@ JXL_GTEST_INSTANTIATE_TEST_SUITE_P(
JxlStreamingTest, JxlStreamingTest,
testing::ValuesIn(StreamingTestParam::All()));
+struct StreamingEncodingTestParam {
+ std::string file;
+ int effort;
+ float distance;
+ int group_size;
+ float palette_percent;
+
+ static std::vector<StreamingEncodingTestParam> All() {
+ std::vector<StreamingEncodingTestParam> params;
+ for (const auto* file :
+ {"jxl/flower/flower.png", "jxl/flower/flower_alpha.png"}) {
+ for (int effort : {1, 3, 5, 6}) {
+ if (effort != 1) {
+ params.push_back(
+ StreamingEncodingTestParam{file, effort, 1.0, 1, -1});
+ params.push_back(
+ StreamingEncodingTestParam{file, effort, 4.0, 1, -1});
+ }
+ for (auto group_size : {-1, 0}) {
+ for (float palette_percent : {-1, 50, 100}) {
+ params.push_back(StreamingEncodingTestParam{
+ file, effort, 0.0, group_size, palette_percent});
+ }
+ }
+ }
+ }
+ return params;
+ }
+};
+
+std::ostream& operator<<(std::ostream& out,
+ const StreamingEncodingTestParam& p) {
+ out << p.file << "-";
+ out << "e" << p.effort;
+ if (p.distance == 0) {
+ out << "Lossless";
+ out << "G" << p.group_size << "P" << p.palette_percent;
+ } else {
+ out << "D" << p.distance;
+ }
+ return out;
+}
+
+class JxlStreamingEncodingTest
+ : public ::testing::TestWithParam<StreamingEncodingTestParam> {};
+
// This is broken on mingw32, so we only enable it for x86_64 now.
-TEST(JxlTest, JXL_X86_64_TEST(StreamingSamePixels)) {
- const std::vector<uint8_t> orig = ReadTestData("jxl/flower/flower.png");
+TEST_P(JxlStreamingEncodingTest, JXL_X86_64_TEST(StreamingSamePixels)) {
+ const auto param = GetParam();
+ const std::vector<uint8_t> orig = ReadTestData(param.file);
jxl::test::TestImage image;
image.DecodeFromBytes(orig);
+
JXLCompressParams cparams;
- cparams.distance = 1.0;
- cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, 6);
+ cparams.distance = param.distance;
+ cparams.AddOption(JXL_ENC_FRAME_SETTING_EFFORT, param.effort);
+ cparams.AddOption(JXL_ENC_FRAME_SETTING_MODULAR_GROUP_SIZE, param.group_size);
+ cparams.AddFloatOption(JXL_ENC_FRAME_SETTING_CHANNEL_COLORS_GROUP_PERCENT,
+ param.palette_percent);
cparams.AddOption(JXL_ENC_FRAME_SETTING_USE_FULL_IMAGE_HEURISTICS, 0);
ThreadPoolForTests pool(8);
@@ -1673,5 +1789,9 @@ TEST(JxlTest, JXL_X86_64_TEST(StreamingSamePixels)) {
EXPECT_TRUE(jxl::test::SamePixels(ppf_out, ppf_out_streaming));
}
+JXL_GTEST_INSTANTIATE_TEST_SUITE_P(
+ JxlStreamingTest, JxlStreamingEncodingTest,
+ testing::ValuesIn(StreamingEncodingTestParam::All()));
+
} // namespace
} // namespace jxl