image_ops_test.cc (3480B)
1 // Copyright (c) the JPEG XL Project Authors. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 #include "lib/jxl/image_ops.h" 7 8 #include <cstdint> 9 #include <cstdlib> 10 #include <cstring> 11 12 #include "lib/jxl/base/compiler_specific.h" 13 #include "lib/jxl/base/printf_macros.h" 14 #include "lib/jxl/base/rect.h" 15 #include "lib/jxl/image.h" 16 #include "lib/jxl/test_memory_manager.h" 17 #include "lib/jxl/test_utils.h" 18 #include "lib/jxl/testing.h" 19 20 namespace jxl { 21 namespace { 22 23 template <typename T> 24 void TestFillImpl(Image3<T>* img, const char* layout) { 25 FillImage(static_cast<T>(1), img); 26 for (size_t y = 0; y < img->ysize(); ++y) { 27 for (size_t c = 0; c < 3; ++c) { 28 T* JXL_RESTRICT row = img->PlaneRow(c, y); 29 for (size_t x = 0; x < img->xsize(); ++x) { 30 if (row[x] != static_cast<T>(1)) { 31 printf("Not 1 at c=%" PRIuS " %" PRIuS ", %" PRIuS " (%" PRIuS 32 " x %" PRIuS ") (%s)\n", 33 c, x, y, img->xsize(), img->ysize(), layout); 34 abort(); 35 } 36 row[x] = static_cast<T>(2); 37 } 38 } 39 } 40 41 // Same for ZeroFillImage and swapped c/y loop ordering. 42 ZeroFillImage(img); 43 for (size_t c = 0; c < 3; ++c) { 44 for (size_t y = 0; y < img->ysize(); ++y) { 45 T* JXL_RESTRICT row = img->PlaneRow(c, y); 46 for (size_t x = 0; x < img->xsize(); ++x) { 47 if (row[x] != static_cast<T>(0)) { 48 printf("Not 0 at c=%" PRIuS " %" PRIuS ", %" PRIuS " (%" PRIuS 49 " x %" PRIuS ") (%s)\n", 50 c, x, y, img->xsize(), img->ysize(), layout); 51 abort(); 52 } 53 row[x] = static_cast<T>(3); 54 } 55 } 56 } 57 } 58 59 template <typename T> 60 void TestFillT() { 61 for (uint32_t xsize : {0, 1, 15, 16, 31, 32}) { 62 for (uint32_t ysize : {0, 1, 15, 16, 31, 32}) { 63 JXL_TEST_ASSIGN_OR_DIE( 64 Image3<T> image, 65 Image3<T>::Create(jxl::test::MemoryManager(), xsize, ysize)); 66 TestFillImpl(&image, "size ctor"); 67 } 68 } 69 } 70 71 // Ensure y/c/x and c/y/x loops visit pixels no more than once. 72 TEST(ImageTest, TestFill) { 73 TestFillT<uint8_t>(); 74 TestFillT<int16_t>(); 75 TestFillT<float>(); 76 TestFillT<double>(); 77 } 78 79 TEST(ImageTest, CopyImageToWithPaddingTest) { 80 JXL_TEST_ASSIGN_OR_DIE( 81 Plane<uint32_t> src, 82 Plane<uint32_t>::Create(jxl::test::MemoryManager(), 100, 61)); 83 for (size_t y = 0; y < src.ysize(); y++) { 84 for (size_t x = 0; x < src.xsize(); x++) { 85 src.Row(y)[x] = x * 1000 + y; 86 } 87 } 88 Rect src_rect(10, 20, 30, 40); 89 EXPECT_TRUE(src_rect.IsInside(src)); 90 91 JXL_TEST_ASSIGN_OR_DIE( 92 Plane<uint32_t> dst, 93 Plane<uint32_t>::Create(jxl::test::MemoryManager(), 60, 50)); 94 FillImage(0u, &dst); 95 Rect dst_rect(20, 5, 30, 40); 96 EXPECT_TRUE(dst_rect.IsInside(dst)); 97 98 ASSERT_TRUE( 99 CopyImageToWithPadding(src_rect, src, /*padding=*/2, dst_rect, &dst)); 100 101 // ysize is + 3 instead of + 4 because we are at the y image boundary on the 102 // source image. 103 Rect padded_dst_rect(20 - 2, 5 - 2, 30 + 4, 40 + 3); 104 for (size_t y = 0; y < dst.ysize(); y++) { 105 for (size_t x = 0; x < dst.xsize(); x++) { 106 if (Rect(x, y, 1, 1).IsInside(padded_dst_rect)) { 107 EXPECT_EQ((x - dst_rect.x0() + src_rect.x0()) * 1000 + 108 (y - dst_rect.y0() + src_rect.y0()), 109 dst.Row(y)[x]); 110 } else { 111 EXPECT_EQ(0u, dst.Row(y)[x]); 112 } 113 } 114 } 115 } 116 117 } // namespace 118 } // namespace jxl