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