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