libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

fields_test.cc (14094B)


      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/fields.h"
      7 
      8 #include <stddef.h>
      9 #include <stdint.h>
     10 
     11 #include <array>
     12 #include <utility>
     13 
     14 #include "lib/jxl/base/common.h"
     15 #include "lib/jxl/base/span.h"
     16 #include "lib/jxl/enc_aux_out.h"
     17 #include "lib/jxl/enc_fields.h"
     18 #include "lib/jxl/frame_header.h"
     19 #include "lib/jxl/headers.h"
     20 #include "lib/jxl/testing.h"
     21 
     22 namespace jxl {
     23 namespace {
     24 
     25 // Ensures `value` round-trips and in exactly `expected_bits_written`.
     26 void TestU32Coder(const uint32_t value, const size_t expected_bits_written) {
     27   const U32Enc enc(Val(0), Bits(4), Val(0x7FFFFFFF), Bits(32));
     28 
     29   BitWriter writer;
     30   BitWriter::Allotment allotment(
     31       &writer, RoundUpBitsToByteMultiple(U32Coder::MaxEncodedBits(enc)));
     32 
     33   size_t precheck_pos;
     34   EXPECT_TRUE(U32Coder::CanEncode(enc, value, &precheck_pos));
     35   EXPECT_EQ(expected_bits_written, precheck_pos);
     36 
     37   EXPECT_TRUE(U32Coder::Write(enc, value, &writer));
     38   EXPECT_EQ(expected_bits_written, writer.BitsWritten());
     39   writer.ZeroPadToByte();
     40   allotment.ReclaimAndCharge(&writer, 0, nullptr);
     41 
     42   BitReader reader(writer.GetSpan());
     43   const uint32_t decoded_value = U32Coder::Read(enc, &reader);
     44   EXPECT_EQ(value, decoded_value);
     45   EXPECT_TRUE(reader.Close());
     46 }
     47 
     48 TEST(FieldsTest, U32CoderTest) {
     49   TestU32Coder(0, 2);
     50   TestU32Coder(1, 6);
     51   TestU32Coder(15, 6);
     52   TestU32Coder(0x7FFFFFFF, 2);
     53   TestU32Coder(128, 34);
     54   TestU32Coder(0x7FFFFFFEu, 34);
     55   TestU32Coder(0x80000000u, 34);
     56   TestU32Coder(0xFFFFFFFFu, 34);
     57 }
     58 
     59 void TestU64Coder(const uint64_t value, const size_t expected_bits_written) {
     60   BitWriter writer;
     61   BitWriter::Allotment allotment(
     62       &writer, RoundUpBitsToByteMultiple(U64Coder::MaxEncodedBits()));
     63 
     64   size_t precheck_pos;
     65   EXPECT_TRUE(U64Coder::CanEncode(value, &precheck_pos));
     66   EXPECT_EQ(expected_bits_written, precheck_pos);
     67 
     68   EXPECT_TRUE(U64Coder::Write(value, &writer));
     69   EXPECT_EQ(expected_bits_written, writer.BitsWritten());
     70 
     71   writer.ZeroPadToByte();
     72   allotment.ReclaimAndCharge(&writer, 0, nullptr);
     73 
     74   BitReader reader(writer.GetSpan());
     75   const uint64_t decoded_value = U64Coder::Read(&reader);
     76   EXPECT_EQ(value, decoded_value);
     77   EXPECT_TRUE(reader.Close());
     78 }
     79 
     80 TEST(FieldsTest, U64CoderTest) {
     81   // Values that should take 2 bits (selector 00): 0
     82   TestU64Coder(0, 2);
     83 
     84   // Values that should take 6 bits (2 for selector, 4 for value): 1..16
     85   TestU64Coder(1, 6);
     86   TestU64Coder(2, 6);
     87   TestU64Coder(8, 6);
     88   TestU64Coder(15, 6);
     89   TestU64Coder(16, 6);
     90 
     91   // Values that should take 10 bits (2 for selector, 8 for value): 17..272
     92   TestU64Coder(17, 10);
     93   TestU64Coder(18, 10);
     94   TestU64Coder(100, 10);
     95   TestU64Coder(271, 10);
     96   TestU64Coder(272, 10);
     97 
     98   // Values that should take 15 bits (2 for selector, 12 for value, 1 for varint
     99   // end): (0)..273..4095
    100   TestU64Coder(273, 15);
    101   TestU64Coder(274, 15);
    102   TestU64Coder(1000, 15);
    103   TestU64Coder(4094, 15);
    104   TestU64Coder(4095, 15);
    105 
    106   // Take 24 bits (of which 20 actual value): (0)..4096..1048575
    107   TestU64Coder(4096, 24);
    108   TestU64Coder(4097, 24);
    109   TestU64Coder(10000, 24);
    110   TestU64Coder(1048574, 24);
    111   TestU64Coder(1048575, 24);
    112 
    113   // Take 33 bits (of which 28 actual value): (0)..1048576..268435455
    114   TestU64Coder(1048576, 33);
    115   TestU64Coder(1048577, 33);
    116   TestU64Coder(10000000, 33);
    117   TestU64Coder(268435454, 33);
    118   TestU64Coder(268435455, 33);
    119 
    120   // Take 42 bits (of which 36 actual value): (0)..268435456..68719476735
    121   TestU64Coder(268435456ull, 42);
    122   TestU64Coder(268435457ull, 42);
    123   TestU64Coder(1000000000ull, 42);
    124   TestU64Coder(68719476734ull, 42);
    125   TestU64Coder(68719476735ull, 42);
    126 
    127   // Take 51 bits (of which 44 actual value): (0)..68719476736..17592186044415
    128   TestU64Coder(68719476736ull, 51);
    129   TestU64Coder(68719476737ull, 51);
    130   TestU64Coder(1000000000000ull, 51);
    131   TestU64Coder(17592186044414ull, 51);
    132   TestU64Coder(17592186044415ull, 51);
    133 
    134   // Take 60 bits (of which 52 actual value):
    135   // (0)..17592186044416..4503599627370495
    136   TestU64Coder(17592186044416ull, 60);
    137   TestU64Coder(17592186044417ull, 60);
    138   TestU64Coder(100000000000000ull, 60);
    139   TestU64Coder(4503599627370494ull, 60);
    140   TestU64Coder(4503599627370495ull, 60);
    141 
    142   // Take 69 bits (of which 60 actual value):
    143   // (0)..4503599627370496..1152921504606846975
    144   TestU64Coder(4503599627370496ull, 69);
    145   TestU64Coder(4503599627370497ull, 69);
    146   TestU64Coder(10000000000000000ull, 69);
    147   TestU64Coder(1152921504606846974ull, 69);
    148   TestU64Coder(1152921504606846975ull, 69);
    149 
    150   // Take 73 bits (of which 64 actual value):
    151   // (0)..1152921504606846976..18446744073709551615
    152   TestU64Coder(1152921504606846976ull, 73);
    153   TestU64Coder(1152921504606846977ull, 73);
    154   TestU64Coder(10000000000000000000ull, 73);
    155   TestU64Coder(18446744073709551614ull, 73);
    156   TestU64Coder(18446744073709551615ull, 73);
    157 }
    158 
    159 Status TestF16Coder(const float value) {
    160   size_t max_encoded_bits;
    161   // It is not a fatal error if it can't be encoded.
    162   if (!F16Coder::CanEncode(value, &max_encoded_bits)) return false;
    163   EXPECT_EQ(F16Coder::MaxEncodedBits(), max_encoded_bits);
    164 
    165   BitWriter writer;
    166   BitWriter::Allotment allotment(&writer,
    167                                  RoundUpBitsToByteMultiple(max_encoded_bits));
    168 
    169   EXPECT_TRUE(F16Coder::Write(value, &writer));
    170   EXPECT_EQ(F16Coder::MaxEncodedBits(), writer.BitsWritten());
    171   writer.ZeroPadToByte();
    172   allotment.ReclaimAndCharge(&writer, 0, nullptr);
    173 
    174   BitReader reader(writer.GetSpan());
    175   float decoded_value;
    176   EXPECT_TRUE(F16Coder::Read(&reader, &decoded_value));
    177   // All values we test can be represented exactly.
    178   EXPECT_EQ(value, decoded_value);
    179   EXPECT_TRUE(reader.Close());
    180   return true;
    181 }
    182 
    183 TEST(FieldsTest, F16CoderTest) {
    184   for (float sign : {-1.0f, 1.0f}) {
    185     // (anything less than 1E-3 are subnormals)
    186     for (float mag : {0.0f, 0.5f, 1.0f, 2.0f, 2.5f, 16.015625f, 1.0f / 4096,
    187                       1.0f / 16384, 65504.0f}) {
    188       EXPECT_TRUE(TestF16Coder(sign * mag));
    189     }
    190   }
    191 
    192   // Out of range
    193   EXPECT_FALSE(TestF16Coder(65504.01f));
    194   EXPECT_FALSE(TestF16Coder(-65505.0f));
    195 }
    196 
    197 // Ensures Read(Write()) returns the same fields.
    198 TEST(FieldsTest, TestRoundtripSize) {
    199   for (int i = 0; i < 8; i++) {
    200     SizeHeader size;
    201     ASSERT_TRUE(size.Set(123 + 77 * i, 7 + i));
    202 
    203     size_t extension_bits = 999;
    204     size_t total_bits = 999;  // Initialize as garbage.
    205     ASSERT_TRUE(Bundle::CanEncode(size, &extension_bits, &total_bits));
    206     EXPECT_EQ(0u, extension_bits);
    207 
    208     BitWriter writer;
    209     ASSERT_TRUE(WriteSizeHeader(size, &writer, 0, nullptr));
    210     EXPECT_EQ(total_bits, writer.BitsWritten());
    211     writer.ZeroPadToByte();
    212 
    213     SizeHeader size2;
    214     BitReader reader(writer.GetSpan());
    215     ASSERT_TRUE(ReadSizeHeader(&reader, &size2));
    216     EXPECT_EQ(total_bits, reader.TotalBitsConsumed());
    217     EXPECT_TRUE(reader.Close());
    218 
    219     EXPECT_EQ(size.xsize(), size2.xsize());
    220     EXPECT_EQ(size.ysize(), size2.ysize());
    221   }
    222 }
    223 
    224 // Ensure all values can be reached by the encoding.
    225 TEST(FieldsTest, TestCropRect) {
    226   CodecMetadata metadata;
    227   for (int32_t i = -999; i < 19000; ++i) {
    228     FrameHeader f(&metadata);
    229     f.custom_size_or_origin = true;
    230     f.frame_origin.x0 = i;
    231     f.frame_origin.y0 = i;
    232     f.frame_size.xsize = 1000 + i;
    233     f.frame_size.ysize = 1000 + i;
    234     size_t extension_bits = 0;
    235     size_t total_bits = 0;
    236     ASSERT_TRUE(Bundle::CanEncode(f, &extension_bits, &total_bits));
    237     EXPECT_EQ(0u, extension_bits);
    238     EXPECT_GE(total_bits, 9u);
    239   }
    240 }
    241 TEST(FieldsTest, TestPreview) {
    242   // (div8 cannot represent 4360, but !div8 can go a little higher)
    243   for (uint32_t i = 1; i < 4360; ++i) {
    244     PreviewHeader p;
    245     ASSERT_TRUE(p.Set(i, i));
    246     size_t extension_bits = 0;
    247     size_t total_bits = 0;
    248     ASSERT_TRUE(Bundle::CanEncode(p, &extension_bits, &total_bits));
    249     EXPECT_EQ(0u, extension_bits);
    250     EXPECT_GE(total_bits, 6u);
    251   }
    252 }
    253 
    254 // Ensures Read(Write()) returns the same fields.
    255 TEST(FieldsTest, TestRoundtripFrame) {
    256   CodecMetadata metadata;
    257   FrameHeader h(&metadata);
    258   h.extensions = 0x800;
    259 
    260   size_t extension_bits = 999;
    261   size_t total_bits = 999;  // Initialize as garbage.
    262   ASSERT_TRUE(Bundle::CanEncode(h, &extension_bits, &total_bits));
    263   EXPECT_EQ(0u, extension_bits);
    264   BitWriter writer;
    265   ASSERT_TRUE(WriteFrameHeader(h, &writer, nullptr));
    266   EXPECT_EQ(total_bits, writer.BitsWritten());
    267   writer.ZeroPadToByte();
    268 
    269   FrameHeader h2(&metadata);
    270   BitReader reader(writer.GetSpan());
    271   ASSERT_TRUE(ReadFrameHeader(&reader, &h2));
    272   EXPECT_EQ(total_bits, reader.TotalBitsConsumed());
    273   EXPECT_TRUE(reader.Close());
    274 
    275   EXPECT_EQ(h.extensions, h2.extensions);
    276   EXPECT_EQ(h.flags, h2.flags);
    277 }
    278 
    279 #ifndef JXL_CRASH_ON_ERROR
    280 // Ensure out-of-bounds values cause an error.
    281 TEST(FieldsTest, TestOutOfRange) {
    282   SizeHeader h;
    283   ASSERT_TRUE(h.Set(0xFFFFFFFFull, 0xFFFFFFFFull));
    284   size_t extension_bits = 999;
    285   size_t total_bits = 999;  // Initialize as garbage.
    286   ASSERT_FALSE(Bundle::CanEncode(h, &extension_bits, &total_bits));
    287 }
    288 #endif
    289 
    290 struct OldBundle : public Fields {
    291   OldBundle() { Bundle::Init(this); }
    292   JXL_FIELDS_NAME(OldBundle)
    293 
    294   Status VisitFields(Visitor* JXL_RESTRICT visitor) override {
    295     JXL_QUIET_RETURN_IF_ERROR(
    296         visitor->U32(Val(1), Bits(2), Bits(3), Bits(4), 1, &old_small));
    297     JXL_QUIET_RETURN_IF_ERROR(visitor->F16(1.125f, &old_f));
    298     JXL_QUIET_RETURN_IF_ERROR(
    299         visitor->U32(Bits(7), Bits(12), Bits(16), Bits(32), 0, &old_large));
    300 
    301     JXL_QUIET_RETURN_IF_ERROR(visitor->BeginExtensions(&extensions));
    302     return visitor->EndExtensions();
    303   }
    304 
    305   uint32_t old_small;
    306   float old_f;
    307   uint32_t old_large;
    308   uint64_t extensions;
    309 };
    310 
    311 struct NewBundle : public Fields {
    312   NewBundle() { Bundle::Init(this); }
    313   JXL_FIELDS_NAME(NewBundle)
    314 
    315   Status VisitFields(Visitor* JXL_RESTRICT visitor) override {
    316     JXL_QUIET_RETURN_IF_ERROR(
    317         visitor->U32(Val(1), Bits(2), Bits(3), Bits(4), 1, &old_small));
    318     JXL_QUIET_RETURN_IF_ERROR(visitor->F16(1.125f, &old_f));
    319     JXL_QUIET_RETURN_IF_ERROR(
    320         visitor->U32(Bits(7), Bits(12), Bits(16), Bits(32), 0, &old_large));
    321 
    322     JXL_QUIET_RETURN_IF_ERROR(visitor->BeginExtensions(&extensions));
    323     if (visitor->Conditional((extensions & 1) != 0)) {
    324       JXL_QUIET_RETURN_IF_ERROR(
    325           visitor->U32(Val(2), Bits(2), Bits(3), Bits(4), 2, &new_small));
    326       JXL_QUIET_RETURN_IF_ERROR(visitor->F16(-2.0f, &new_f));
    327     }
    328     if (visitor->Conditional((extensions & 2) != 0)) {
    329       JXL_QUIET_RETURN_IF_ERROR(
    330           visitor->U32(Bits(9), Bits(12), Bits(16), Bits(32), 0, &new_large));
    331     }
    332     return visitor->EndExtensions();
    333   }
    334 
    335   uint32_t old_small;
    336   float old_f;
    337   uint32_t old_large;
    338   uint64_t extensions;
    339 
    340   // If extensions & 1
    341   uint32_t new_small = 2;
    342   float new_f = -2.0f;
    343   // If extensions & 2
    344   uint32_t new_large = 0;
    345 };
    346 
    347 TEST(FieldsTest, TestNewDecoderOldData) {
    348   OldBundle old_bundle;
    349   old_bundle.old_large = 123;
    350   old_bundle.old_f = 3.75f;
    351   old_bundle.extensions = 0;
    352 
    353   // Write to bit stream
    354   const size_t kMaxOutBytes = 999;
    355   BitWriter writer;
    356   // Make sure values are initialized by code under test.
    357   size_t extension_bits = 12345;
    358   size_t total_bits = 12345;
    359   ASSERT_TRUE(Bundle::CanEncode(old_bundle, &extension_bits, &total_bits));
    360   ASSERT_LE(total_bits, kMaxOutBytes * kBitsPerByte);
    361   EXPECT_EQ(0u, extension_bits);
    362   AuxOut aux_out;
    363   ASSERT_TRUE(Bundle::Write(old_bundle, &writer, kLayerHeader, &aux_out));
    364 
    365   BitWriter::Allotment allotment(&writer,
    366                                  kMaxOutBytes * kBitsPerByte - total_bits);
    367   writer.Write(20, 0xA55A);  // sentinel
    368   writer.ZeroPadToByte();
    369   allotment.ReclaimAndCharge(&writer, kLayerHeader, nullptr);
    370 
    371   ASSERT_LE(writer.GetSpan().size(), kMaxOutBytes);
    372   BitReader reader(writer.GetSpan());
    373   NewBundle new_bundle;
    374   ASSERT_TRUE(Bundle::Read(&reader, &new_bundle));
    375   EXPECT_EQ(reader.TotalBitsConsumed(),
    376             aux_out.layers[kLayerHeader].total_bits);
    377   EXPECT_EQ(reader.ReadBits(20), 0xA55Au);
    378   EXPECT_TRUE(reader.Close());
    379 
    380   // Old fields are the same in both
    381   EXPECT_EQ(old_bundle.extensions, new_bundle.extensions);
    382   EXPECT_EQ(old_bundle.old_small, new_bundle.old_small);
    383   EXPECT_EQ(old_bundle.old_f, new_bundle.old_f);
    384   EXPECT_EQ(old_bundle.old_large, new_bundle.old_large);
    385   // New fields match their defaults
    386   EXPECT_EQ(2u, new_bundle.new_small);
    387   EXPECT_EQ(-2.0f, new_bundle.new_f);
    388   EXPECT_EQ(0u, new_bundle.new_large);
    389 }
    390 
    391 TEST(FieldsTest, TestOldDecoderNewData) {
    392   NewBundle new_bundle;
    393   new_bundle.old_large = 123;
    394   new_bundle.extensions = 3;
    395   new_bundle.new_f = 999.0f;
    396   new_bundle.new_large = 456;
    397 
    398   // Write to bit stream
    399   constexpr size_t kMaxOutBytes = 999;
    400   BitWriter writer;
    401   // Make sure values are initialized by code under test.
    402   size_t extension_bits = 12345;
    403   size_t total_bits = 12345;
    404   ASSERT_TRUE(Bundle::CanEncode(new_bundle, &extension_bits, &total_bits));
    405   EXPECT_NE(0u, extension_bits);
    406   AuxOut aux_out;
    407   ASSERT_TRUE(Bundle::Write(new_bundle, &writer, kLayerHeader, &aux_out));
    408   ASSERT_LE(aux_out.layers[kLayerHeader].total_bits,
    409             kMaxOutBytes * kBitsPerByte);
    410 
    411   BitWriter::Allotment allotment(
    412       &writer,
    413       kMaxOutBytes * kBitsPerByte - aux_out.layers[kLayerHeader].total_bits);
    414   // Ensure Read skips the additional fields
    415   writer.Write(20, 0xA55A);  // sentinel
    416   writer.ZeroPadToByte();
    417   allotment.ReclaimAndCharge(&writer, kLayerHeader, nullptr);
    418 
    419   BitReader reader(writer.GetSpan());
    420   OldBundle old_bundle;
    421   ASSERT_TRUE(Bundle::Read(&reader, &old_bundle));
    422   EXPECT_EQ(reader.TotalBitsConsumed(),
    423             aux_out.layers[kLayerHeader].total_bits);
    424   EXPECT_EQ(reader.ReadBits(20), 0xA55Au);
    425   EXPECT_TRUE(reader.Close());
    426 
    427   // Old fields are the same in both
    428   EXPECT_EQ(new_bundle.extensions, old_bundle.extensions);
    429   EXPECT_EQ(new_bundle.old_small, old_bundle.old_small);
    430   EXPECT_EQ(new_bundle.old_f, old_bundle.old_f);
    431   EXPECT_EQ(new_bundle.old_large, old_bundle.old_large);
    432   // (Can't check new fields because old decoder doesn't know about them)
    433 }
    434 
    435 }  // namespace
    436 }  // namespace jxl