toc_test.cc (3485B)
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/toc.h" 7 8 #include <jxl/memory_manager.h> 9 10 #include <cstddef> 11 #include <cstdint> 12 #include <memory> 13 #include <vector> 14 15 #include "lib/jxl/base/common.h" 16 #include "lib/jxl/base/random.h" 17 #include "lib/jxl/coeff_order_fwd.h" 18 #include "lib/jxl/dec_bit_reader.h" 19 #include "lib/jxl/enc_aux_out.h" 20 #include "lib/jxl/enc_bit_writer.h" 21 #include "lib/jxl/enc_toc.h" 22 #include "lib/jxl/test_memory_manager.h" 23 #include "lib/jxl/test_utils.h" 24 #include "lib/jxl/testing.h" 25 26 namespace jxl { 27 namespace { 28 29 void Roundtrip(size_t num_entries, bool permute, Rng* rng) { 30 JxlMemoryManager* memory_manager = jxl::test::MemoryManager(); 31 // Generate a random permutation. 32 std::vector<coeff_order_t> permutation; 33 std::vector<coeff_order_t> inv_permutation(num_entries); 34 for (size_t i = 0; i < num_entries; i++) { 35 inv_permutation[i] = i; 36 } 37 if (permute) { 38 permutation.resize(num_entries); 39 for (size_t i = 0; i < num_entries; i++) { 40 permutation[i] = i; 41 } 42 rng->Shuffle(permutation.data(), permutation.size()); 43 for (size_t i = 0; i < num_entries; i++) { 44 inv_permutation[permutation[i]] = i; 45 } 46 } 47 48 // Generate num_entries groups of random (byte-aligned) length 49 std::vector<std::unique_ptr<BitWriter>> group_codes; 50 group_codes.reserve(num_entries); 51 for (size_t i = 0; i < num_entries; ++i) { 52 group_codes.emplace_back(jxl::make_unique<BitWriter>(memory_manager)); 53 } 54 for (std::unique_ptr<BitWriter>& writer : group_codes) { 55 const size_t max_bits = (*rng)() & 0xFFF; 56 AuxOut aux_out; 57 ASSERT_TRUE(writer->WithMaxBits( 58 max_bits + kBitsPerByte, LayerType::Header, &aux_out, [&] { 59 size_t i = 0; 60 for (; i + BitWriter::kMaxBitsPerCall < max_bits; 61 i += BitWriter::kMaxBitsPerCall) { 62 writer->Write(BitWriter::kMaxBitsPerCall, 0); 63 } 64 for (; i < max_bits; i += 1) { 65 writer->Write(/*n_bits=*/1, 0); 66 } 67 writer->ZeroPadToByte(); 68 return true; 69 })); 70 } 71 72 BitWriter writer{memory_manager}; 73 AuxOut aux_out; 74 ASSERT_TRUE(WriteGroupOffsets(group_codes, permutation, &writer, &aux_out)); 75 76 BitReader reader(writer.GetSpan()); 77 std::vector<uint64_t> group_offsets; 78 std::vector<uint32_t> group_sizes; 79 uint64_t total_size; 80 ASSERT_TRUE(ReadGroupOffsets(memory_manager, num_entries, &reader, 81 &group_offsets, &group_sizes, &total_size)); 82 ASSERT_EQ(num_entries, group_offsets.size()); 83 ASSERT_EQ(num_entries, group_sizes.size()); 84 EXPECT_TRUE(reader.Close()); 85 86 uint64_t prefix_sum = 0; 87 for (size_t i = 0; i < num_entries; ++i) { 88 EXPECT_EQ(prefix_sum, group_offsets[inv_permutation[i]]); 89 90 EXPECT_EQ(0u, group_codes[i]->BitsWritten() % kBitsPerByte); 91 prefix_sum += group_codes[i]->BitsWritten() / kBitsPerByte; 92 93 if (i + 1 < num_entries) { 94 EXPECT_EQ( 95 group_offsets[inv_permutation[i]] + group_sizes[inv_permutation[i]], 96 group_offsets[inv_permutation[i + 1]]); 97 } 98 } 99 EXPECT_EQ(prefix_sum, total_size); 100 } 101 102 TEST(TocTest, Test) { 103 Rng rng(0); 104 for (size_t num_entries = 1; num_entries < 10; ++num_entries) { 105 for (bool permute : std::vector<bool>{false, true}) { 106 Roundtrip(num_entries, permute, &rng); 107 } 108 } 109 } 110 111 } // namespace 112 } // namespace jxl