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