coeff_order_test.cc (3471B)
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/coeff_order.h" 7 8 #include <jxl/memory_manager.h> 9 10 #include <algorithm> 11 #include <cstddef> 12 #include <cstdio> 13 #include <numeric> // iota 14 #include <utility> 15 #include <vector> 16 17 #include "lib/jxl/base/printf_macros.h" 18 #include "lib/jxl/base/random.h" 19 #include "lib/jxl/base/span.h" 20 #include "lib/jxl/base/status.h" 21 #include "lib/jxl/coeff_order_fwd.h" 22 #include "lib/jxl/dec_bit_reader.h" 23 #include "lib/jxl/enc_aux_out.h" 24 #include "lib/jxl/enc_bit_writer.h" 25 #include "lib/jxl/enc_coeff_order.h" 26 #include "lib/jxl/test_memory_manager.h" 27 #include "lib/jxl/testing.h" 28 29 namespace jxl { 30 namespace { 31 32 void RoundtripPermutation(coeff_order_t* perm, coeff_order_t* out, size_t len, 33 size_t* size) { 34 JxlMemoryManager* memory_manager = jxl::test::MemoryManager(); 35 BitWriter writer{memory_manager}; 36 ASSERT_TRUE( 37 EncodePermutation(perm, 0, len, &writer, LayerType::Header, nullptr)); 38 writer.ZeroPadToByte(); 39 Status status = true; 40 Bytes bytes = writer.GetSpan(); 41 { 42 BitReader reader(bytes); 43 BitReaderScopedCloser closer(reader, status); 44 ASSERT_TRUE(DecodePermutation(memory_manager, 0, len, out, &reader)); 45 } 46 ASSERT_TRUE(status); 47 *size = bytes.size(); 48 } 49 50 enum Permutation { kIdentity, kFewSwaps, kFewSlides, kRandom }; 51 52 constexpr size_t kSwaps = 32; 53 54 void TestPermutation(Permutation kind, size_t len) { 55 std::vector<coeff_order_t> perm(len); 56 std::iota(perm.begin(), perm.end(), 0); 57 Rng rng(0); 58 if (kind == kFewSwaps) { 59 for (size_t i = 0; i < kSwaps; i++) { 60 size_t a = rng.UniformU(0, len - 1); 61 size_t b = rng.UniformU(0, len - 1); 62 std::swap(perm[a], perm[b]); 63 } 64 } 65 if (kind == kFewSlides) { 66 for (size_t i = 0; i < kSwaps; i++) { 67 size_t a = rng.UniformU(0, len - 1); 68 size_t b = rng.UniformU(0, len - 1); 69 size_t from = std::min(a, b); 70 size_t to = std::max(a, b); 71 size_t start = perm[from]; 72 for (size_t j = from; j < to; j++) { 73 perm[j] = perm[j + 1]; 74 } 75 perm[to] = start; 76 } 77 } 78 if (kind == kRandom) { 79 rng.Shuffle(perm.data(), perm.size()); 80 } 81 std::vector<coeff_order_t> out(len); 82 size_t size = 0; 83 RoundtripPermutation(perm.data(), out.data(), len, &size); 84 for (size_t idx = 0; idx < len; idx++) { 85 EXPECT_EQ(perm[idx], out[idx]); 86 } 87 printf("Encoded size: %" PRIuS "\n", size); 88 } 89 90 TEST(CoeffOrderTest, IdentitySmall) { TestPermutation(kIdentity, 256); } 91 TEST(CoeffOrderTest, FewSlidesSmall) { TestPermutation(kFewSlides, 256); } 92 TEST(CoeffOrderTest, FewSwapsSmall) { TestPermutation(kFewSwaps, 256); } 93 TEST(CoeffOrderTest, RandomSmall) { TestPermutation(kRandom, 256); } 94 95 TEST(CoeffOrderTest, IdentityMedium) { TestPermutation(kIdentity, 1 << 12); } 96 TEST(CoeffOrderTest, FewSlidesMedium) { TestPermutation(kFewSlides, 1 << 12); } 97 TEST(CoeffOrderTest, FewSwapsMedium) { TestPermutation(kFewSwaps, 1 << 12); } 98 TEST(CoeffOrderTest, RandomMedium) { TestPermutation(kRandom, 1 << 12); } 99 100 TEST(CoeffOrderTest, IdentityBig) { TestPermutation(kIdentity, 1 << 16); } 101 TEST(CoeffOrderTest, FewSlidesBig) { TestPermutation(kFewSlides, 1 << 16); } 102 TEST(CoeffOrderTest, FewSwapsBig) { TestPermutation(kFewSwaps, 1 << 16); } 103 TEST(CoeffOrderTest, RandomBig) { TestPermutation(kRandom, 1 << 16); } 104 105 } // namespace 106 } // namespace jxl