summaryrefslogtreecommitdiffstats
path: root/third_party/jpeg-xl/lib/jxl/gradient_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/jpeg-xl/lib/jxl/gradient_test.cc')
-rw-r--r--third_party/jpeg-xl/lib/jxl/gradient_test.cc116
1 files changed, 57 insertions, 59 deletions
diff --git a/third_party/jpeg-xl/lib/jxl/gradient_test.cc b/third_party/jpeg-xl/lib/jxl/gradient_test.cc
index 055a419f5b..d2c83619fc 100644
--- a/third_party/jpeg-xl/lib/jxl/gradient_test.cc
+++ b/third_party/jpeg-xl/lib/jxl/gradient_test.cc
@@ -9,7 +9,6 @@
#include <stdint.h>
#include <algorithm>
-#include <array>
#include <cmath>
#include <utility>
#include <vector>
@@ -45,10 +44,10 @@ double PointLineDist(double x0, double y0, double x1, double y1, double x,
// angle in which the change direction happens.
Image3F GenerateTestGradient(uint32_t color0, uint32_t color1, double angle,
size_t xsize, size_t ysize) {
- Image3F image(xsize, ysize);
+ JXL_ASSIGN_OR_DIE(Image3F image, Image3F::Create(xsize, ysize));
- double x0 = xsize / 2;
- double y0 = ysize / 2;
+ double x0 = xsize / 2.0;
+ double y0 = ysize / 2.0;
double x1 = x0 + std::sin(angle / 360.0 * 2.0 * kPi);
double y1 = y0 + std::cos(angle / 360.0 * 2.0 * kPi);
@@ -78,63 +77,60 @@ Image3F GenerateTestGradient(uint32_t color0, uint32_t color1, double angle,
// delta and right delta (top/bottom for vertical direction).
// The radius over which the derivative is computed is only 1 pixel and it only
// checks two angles (hor and ver), but this approximation works well enough.
-static ImageF Gradient2(const ImageF& image) {
+Image3F Gradient2(const Image3F& image) {
size_t xsize = image.xsize();
size_t ysize = image.ysize();
- ImageF image2(image.xsize(), image.ysize());
- for (size_t y = 1; y + 1 < ysize; y++) {
- const auto* JXL_RESTRICT row0 = image.Row(y - 1);
- const auto* JXL_RESTRICT row1 = image.Row(y);
- const auto* JXL_RESTRICT row2 = image.Row(y + 1);
- auto* row_out = image2.Row(y);
- for (size_t x = 1; x + 1 < xsize; x++) {
- float ddx = (row1[x] - row1[x - 1]) - (row1[x + 1] - row1[x]);
- float ddy = (row1[x] - row0[x]) - (row2[x] - row1[x]);
- row_out[x] = std::max(fabsf(ddx), fabsf(ddy));
- }
- }
- // Copy to the borders
- if (ysize > 2) {
- auto* JXL_RESTRICT row0 = image2.Row(0);
- const auto* JXL_RESTRICT row1 = image2.Row(1);
- const auto* JXL_RESTRICT row2 = image2.Row(ysize - 2);
- auto* JXL_RESTRICT row3 = image2.Row(ysize - 1);
- for (size_t x = 1; x + 1 < xsize; x++) {
- row0[x] = row1[x];
- row3[x] = row2[x];
- }
- } else {
- const auto* row0_in = image.Row(0);
- const auto* row1_in = image.Row(ysize - 1);
- auto* row0_out = image2.Row(0);
- auto* row1_out = image2.Row(ysize - 1);
- for (size_t x = 1; x + 1 < xsize; x++) {
- // Image too narrow, take first derivative instead
- row0_out[x] = row1_out[x] = fabsf(row0_in[x] - row1_in[x]);
+ JXL_ASSIGN_OR_DIE(Image3F image2, Image3F::Create(xsize, ysize));
+ for (size_t c = 0; c < 3; ++c) {
+ for (size_t y = 1; y + 1 < ysize; y++) {
+ const auto* JXL_RESTRICT row0 = image.ConstPlaneRow(c, y - 1);
+ const auto* JXL_RESTRICT row1 = image.ConstPlaneRow(c, y);
+ const auto* JXL_RESTRICT row2 = image.ConstPlaneRow(c, y + 1);
+ auto* row_out = image2.PlaneRow(c, y);
+ for (size_t x = 1; x + 1 < xsize; x++) {
+ float ddx = (row1[x] - row1[x - 1]) - (row1[x + 1] - row1[x]);
+ float ddy = (row1[x] - row0[x]) - (row2[x] - row1[x]);
+ row_out[x] = std::max(fabsf(ddx), fabsf(ddy));
+ }
}
- }
- if (xsize > 2) {
- for (size_t y = 0; y < ysize; y++) {
- auto* row = image2.Row(y);
- row[0] = row[1];
- row[xsize - 1] = row[xsize - 2];
+ // Copy to the borders
+ if (ysize > 2) {
+ auto* JXL_RESTRICT row0 = image2.PlaneRow(c, 0);
+ const auto* JXL_RESTRICT row1 = image2.PlaneRow(c, 1);
+ const auto* JXL_RESTRICT row2 = image2.PlaneRow(c, ysize - 2);
+ auto* JXL_RESTRICT row3 = image2.PlaneRow(c, ysize - 1);
+ for (size_t x = 1; x + 1 < xsize; x++) {
+ row0[x] = row1[x];
+ row3[x] = row2[x];
+ }
+ } else {
+ const auto* row0_in = image.ConstPlaneRow(c, 0);
+ const auto* row1_in = image.ConstPlaneRow(c, ysize - 1);
+ auto* row0_out = image2.PlaneRow(c, 0);
+ auto* row1_out = image2.PlaneRow(c, ysize - 1);
+ for (size_t x = 1; x + 1 < xsize; x++) {
+ // Image too narrow, take first derivative instead
+ row0_out[x] = row1_out[x] = fabsf(row0_in[x] - row1_in[x]);
+ }
}
- } else {
- for (size_t y = 0; y < ysize; y++) {
- const auto* JXL_RESTRICT row_in = image.Row(y);
- auto* row_out = image2.Row(y);
- // Image too narrow, take first derivative instead
- row_out[0] = row_out[xsize - 1] = fabsf(row_in[0] - row_in[xsize - 1]);
+ if (xsize > 2) {
+ for (size_t y = 0; y < ysize; y++) {
+ auto* row = image2.PlaneRow(c, y);
+ row[0] = row[1];
+ row[xsize - 1] = row[xsize - 2];
+ }
+ } else {
+ for (size_t y = 0; y < ysize; y++) {
+ const auto* JXL_RESTRICT row_in = image.ConstPlaneRow(c, y);
+ auto* row_out = image2.PlaneRow(c, y);
+ // Image too narrow, take first derivative instead
+ row_out[0] = row_out[xsize - 1] = fabsf(row_in[0] - row_in[xsize - 1]);
+ }
}
}
return image2;
}
-static Image3F Gradient2(const Image3F& image) {
- return Image3F(Gradient2(image.Plane(0)), Gradient2(image.Plane(1)),
- Gradient2(image.Plane(2)));
-}
-
/*
Tests if roundtrip with jxl on a gradient image doesn't cause banding.
Only tests if use_gradient is true. Set to false for debugging to see the
@@ -173,17 +169,19 @@ void TestGradient(ThreadPool* pool, uint32_t color0, uint32_t color1,
// butteraugli_distance).
Image3F gradient2 = Gradient2(*io2.Main().color());
- std::array<float, 3> image_max;
- Image3Max(gradient2, &image_max);
-
// TODO(jyrki): These values used to work with 0.2, 0.2, 0.2.
- EXPECT_LE(image_max[0], 3.15);
- EXPECT_LE(image_max[1], 1.72);
- EXPECT_LE(image_max[2], 5.05);
+ float image_min;
+ float image_max;
+ ImageMinMax(gradient2.Plane(0), &image_min, &image_max);
+ EXPECT_LE(image_max, 3.15);
+ ImageMinMax(gradient2.Plane(1), &image_min, &image_max);
+ EXPECT_LE(image_max, 1.72);
+ ImageMinMax(gradient2.Plane(2), &image_min, &image_max);
+ EXPECT_LE(image_max, 5.05);
}
}
-static constexpr bool fast_mode = true;
+constexpr bool fast_mode = true;
TEST(GradientTest, SteepGradient) {
test::ThreadPoolForTests pool(8);