enc_jpeg_data_reader.cc (35782B)
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/jpeg/enc_jpeg_data_reader.h" 7 8 #include <inttypes.h> 9 #include <string.h> 10 11 #include <algorithm> 12 #include <string> 13 #include <vector> 14 15 #include "lib/jxl/base/common.h" 16 #include "lib/jxl/base/printf_macros.h" 17 #include "lib/jxl/base/status.h" 18 #include "lib/jxl/frame_dimensions.h" 19 #include "lib/jxl/jpeg/enc_jpeg_huffman_decode.h" 20 #include "lib/jxl/jpeg/jpeg_data.h" 21 22 namespace jxl { 23 namespace jpeg { 24 25 namespace { 26 const int kBrunsliMaxSampling = 15; 27 28 // Macros for commonly used error conditions. 29 30 #define JXL_JPEG_VERIFY_LEN(n) \ 31 if (*pos + (n) > len) { \ 32 return JXL_FAILURE("Unexpected end of input: pos=%" PRIuS \ 33 " need=%d len=%" PRIuS, \ 34 *pos, static_cast<int>(n), len); \ 35 } 36 37 #define JXL_JPEG_VERIFY_INPUT(var, low, high, code) \ 38 if ((var) < (low) || (var) > (high)) { \ 39 return JXL_FAILURE("Invalid " #var ": %d", static_cast<int>(var)); \ 40 } 41 42 #define JXL_JPEG_VERIFY_MARKER_END() \ 43 if (start_pos + marker_len != *pos) { \ 44 return JXL_FAILURE("Invalid marker length: declared=%" PRIuS \ 45 " actual=%" PRIuS, \ 46 marker_len, (*pos - start_pos)); \ 47 } 48 49 #define JXL_JPEG_EXPECT_MARKER() \ 50 if (pos + 2 > len || data[pos] != 0xff) { \ 51 return JXL_FAILURE( \ 52 "Marker byte (0xff) expected, found: 0x%.2x pos=%" PRIuS \ 53 " len=%" PRIuS, \ 54 (pos < len ? data[pos] : 0), pos, len); \ 55 } 56 57 inline int ReadUint8(const uint8_t* data, size_t* pos) { 58 return data[(*pos)++]; 59 } 60 61 inline int ReadUint16(const uint8_t* data, size_t* pos) { 62 int v = (data[*pos] << 8) + data[*pos + 1]; 63 *pos += 2; 64 return v; 65 } 66 67 // Reads the Start of Frame (SOF) marker segment and fills in *jpg with the 68 // parsed data. 69 bool ProcessSOF(const uint8_t* data, const size_t len, JpegReadMode mode, 70 size_t* pos, JPEGData* jpg) { 71 if (jpg->width != 0) { 72 return JXL_FAILURE("Duplicate SOF marker."); 73 } 74 const size_t start_pos = *pos; 75 JXL_JPEG_VERIFY_LEN(8); 76 size_t marker_len = ReadUint16(data, pos); 77 int precision = ReadUint8(data, pos); 78 int height = ReadUint16(data, pos); 79 int width = ReadUint16(data, pos); 80 int num_components = ReadUint8(data, pos); 81 // 'jbrd' is hardcoded for 8bits: 82 JXL_JPEG_VERIFY_INPUT(precision, 8, 8, PRECISION); 83 JXL_JPEG_VERIFY_INPUT(height, 1, kMaxDimPixels, HEIGHT); 84 JXL_JPEG_VERIFY_INPUT(width, 1, kMaxDimPixels, WIDTH); 85 JXL_JPEG_VERIFY_INPUT(num_components, 1, kMaxComponents, NUMCOMP); 86 JXL_JPEG_VERIFY_LEN(3 * num_components); 87 jpg->height = height; 88 jpg->width = width; 89 jpg->components.resize(num_components); 90 91 // Read sampling factors and quant table index for each component. 92 std::vector<bool> ids_seen(256, false); 93 int max_h_samp_factor = 1; 94 int max_v_samp_factor = 1; 95 for (size_t i = 0; i < jpg->components.size(); ++i) { 96 const int id = ReadUint8(data, pos); 97 if (ids_seen[id]) { // (cf. section B.2.2, syntax of Ci) 98 return JXL_FAILURE("Duplicate ID %d in SOF.", id); 99 } 100 ids_seen[id] = true; 101 jpg->components[i].id = id; 102 int factor = ReadUint8(data, pos); 103 int h_samp_factor = factor >> 4; 104 int v_samp_factor = factor & 0xf; 105 JXL_JPEG_VERIFY_INPUT(h_samp_factor, 1, kBrunsliMaxSampling, SAMP_FACTOR); 106 JXL_JPEG_VERIFY_INPUT(v_samp_factor, 1, kBrunsliMaxSampling, SAMP_FACTOR); 107 jpg->components[i].h_samp_factor = h_samp_factor; 108 jpg->components[i].v_samp_factor = v_samp_factor; 109 jpg->components[i].quant_idx = ReadUint8(data, pos); 110 max_h_samp_factor = std::max(max_h_samp_factor, h_samp_factor); 111 max_v_samp_factor = std::max(max_v_samp_factor, v_samp_factor); 112 } 113 114 // We have checked above that none of the sampling factors are 0, so the max 115 // sampling factors can not be 0. 116 int MCU_rows = DivCeil(jpg->height, max_v_samp_factor * 8); 117 int MCU_cols = DivCeil(jpg->width, max_h_samp_factor * 8); 118 // Compute the block dimensions for each component. 119 for (size_t i = 0; i < jpg->components.size(); ++i) { 120 JPEGComponent* c = &jpg->components[i]; 121 if (max_h_samp_factor % c->h_samp_factor != 0 || 122 max_v_samp_factor % c->v_samp_factor != 0) { 123 return JXL_FAILURE("Non-integral subsampling ratios."); 124 } 125 c->width_in_blocks = MCU_cols * c->h_samp_factor; 126 c->height_in_blocks = MCU_rows * c->v_samp_factor; 127 const uint64_t num_blocks = 128 static_cast<uint64_t>(c->width_in_blocks) * c->height_in_blocks; 129 if (mode == JpegReadMode::kReadAll) { 130 c->coeffs.resize(num_blocks * kDCTBlockSize); 131 } 132 } 133 JXL_JPEG_VERIFY_MARKER_END(); 134 return true; 135 } 136 137 // Reads the Start of Scan (SOS) marker segment and fills in *scan_info with the 138 // parsed data. 139 bool ProcessSOS(const uint8_t* data, const size_t len, size_t* pos, 140 JPEGData* jpg) { 141 const size_t start_pos = *pos; 142 JXL_JPEG_VERIFY_LEN(3); 143 size_t marker_len = ReadUint16(data, pos); 144 size_t comps_in_scan = ReadUint8(data, pos); 145 JXL_JPEG_VERIFY_INPUT(comps_in_scan, 1, jpg->components.size(), 146 COMPS_IN_SCAN); 147 148 JPEGScanInfo scan_info; 149 scan_info.num_components = comps_in_scan; 150 JXL_JPEG_VERIFY_LEN(2 * comps_in_scan); 151 std::vector<bool> ids_seen(256, false); 152 for (size_t i = 0; i < comps_in_scan; ++i) { 153 uint32_t id = ReadUint8(data, pos); 154 if (ids_seen[id]) { // (cf. section B.2.3, regarding CSj) 155 return JXL_FAILURE("Duplicate ID %d in SOS.", id); 156 } 157 ids_seen[id] = true; 158 bool found_index = false; 159 for (size_t j = 0; j < jpg->components.size(); ++j) { 160 if (jpg->components[j].id == id) { 161 scan_info.components[i].comp_idx = j; 162 found_index = true; 163 } 164 } 165 if (!found_index) { 166 return JXL_FAILURE("SOS marker: Could not find component with id %d", id); 167 } 168 int c = ReadUint8(data, pos); 169 int dc_tbl_idx = c >> 4; 170 int ac_tbl_idx = c & 0xf; 171 JXL_JPEG_VERIFY_INPUT(dc_tbl_idx, 0, 3, HUFFMAN_INDEX); 172 JXL_JPEG_VERIFY_INPUT(ac_tbl_idx, 0, 3, HUFFMAN_INDEX); 173 scan_info.components[i].dc_tbl_idx = dc_tbl_idx; 174 scan_info.components[i].ac_tbl_idx = ac_tbl_idx; 175 } 176 JXL_JPEG_VERIFY_LEN(3); 177 scan_info.Ss = ReadUint8(data, pos); 178 scan_info.Se = ReadUint8(data, pos); 179 JXL_JPEG_VERIFY_INPUT(static_cast<int>(scan_info.Ss), 0, 63, START_OF_SCAN); 180 JXL_JPEG_VERIFY_INPUT(scan_info.Se, scan_info.Ss, 63, END_OF_SCAN); 181 int c = ReadUint8(data, pos); 182 scan_info.Ah = c >> 4; 183 scan_info.Al = c & 0xf; 184 if (scan_info.Ah != 0 && scan_info.Al != scan_info.Ah - 1) { 185 // section G.1.1.1.2 : Successive approximation control only improves 186 // by one bit at a time. But it's not always respected, so we just issue 187 // a warning. 188 JXL_WARNING("Invalid progressive parameters: Al=%d Ah=%d", scan_info.Al, 189 scan_info.Ah); 190 } 191 // Check that all the Huffman tables needed for this scan are defined. 192 for (size_t i = 0; i < comps_in_scan; ++i) { 193 bool found_dc_table = false; 194 bool found_ac_table = false; 195 for (size_t j = 0; j < jpg->huffman_code.size(); ++j) { 196 uint32_t slot_id = jpg->huffman_code[j].slot_id; 197 if (slot_id == scan_info.components[i].dc_tbl_idx) { 198 found_dc_table = true; 199 } else if (slot_id == scan_info.components[i].ac_tbl_idx + 16) { 200 found_ac_table = true; 201 } 202 } 203 if (scan_info.Ss == 0 && !found_dc_table) { 204 return JXL_FAILURE( 205 "SOS marker: Could not find DC Huffman table with index %d", 206 scan_info.components[i].dc_tbl_idx); 207 } 208 if (scan_info.Se > 0 && !found_ac_table) { 209 return JXL_FAILURE( 210 "SOS marker: Could not find AC Huffman table with index %d", 211 scan_info.components[i].ac_tbl_idx); 212 } 213 } 214 jpg->scan_info.push_back(scan_info); 215 JXL_JPEG_VERIFY_MARKER_END(); 216 return true; 217 } 218 219 // Reads the Define Huffman Table (DHT) marker segment and fills in *jpg with 220 // the parsed data. Builds the Huffman decoding table in either dc_huff_lut or 221 // ac_huff_lut, depending on the type and solt_id of Huffman code being read. 222 bool ProcessDHT(const uint8_t* data, const size_t len, JpegReadMode mode, 223 std::vector<HuffmanTableEntry>* dc_huff_lut, 224 std::vector<HuffmanTableEntry>* ac_huff_lut, size_t* pos, 225 JPEGData* jpg) { 226 const size_t start_pos = *pos; 227 JXL_JPEG_VERIFY_LEN(2); 228 size_t marker_len = ReadUint16(data, pos); 229 if (marker_len == 2) { 230 return JXL_FAILURE("DHT marker: no Huffman table found"); 231 } 232 while (*pos < start_pos + marker_len) { 233 JXL_JPEG_VERIFY_LEN(1 + kJpegHuffmanMaxBitLength); 234 JPEGHuffmanCode huff; 235 huff.slot_id = ReadUint8(data, pos); 236 int huffman_index = huff.slot_id; 237 bool is_ac_table = ((huff.slot_id & 0x10) != 0); 238 HuffmanTableEntry* huff_lut; 239 if (is_ac_table) { 240 huffman_index -= 0x10; 241 JXL_JPEG_VERIFY_INPUT(huffman_index, 0, 3, HUFFMAN_INDEX); 242 huff_lut = &(*ac_huff_lut)[huffman_index * kJpegHuffmanLutSize]; 243 } else { 244 JXL_JPEG_VERIFY_INPUT(huffman_index, 0, 3, HUFFMAN_INDEX); 245 huff_lut = &(*dc_huff_lut)[huffman_index * kJpegHuffmanLutSize]; 246 } 247 huff.counts[0] = 0; 248 int total_count = 0; 249 int space = 1 << kJpegHuffmanMaxBitLength; 250 int max_depth = 1; 251 for (size_t i = 1; i <= kJpegHuffmanMaxBitLength; ++i) { 252 int count = ReadUint8(data, pos); 253 if (count != 0) { 254 max_depth = i; 255 } 256 huff.counts[i] = count; 257 total_count += count; 258 space -= count * (1 << (kJpegHuffmanMaxBitLength - i)); 259 } 260 if (is_ac_table) { 261 JXL_JPEG_VERIFY_INPUT(total_count, 0, kJpegHuffmanAlphabetSize, 262 HUFFMAN_CODE); 263 } else { 264 JXL_JPEG_VERIFY_INPUT(total_count, 0, kJpegDCAlphabetSize, HUFFMAN_CODE); 265 } 266 JXL_JPEG_VERIFY_LEN(total_count); 267 std::vector<bool> values_seen(256, false); 268 for (int i = 0; i < total_count; ++i) { 269 int value = ReadUint8(data, pos); 270 if (!is_ac_table) { 271 JXL_JPEG_VERIFY_INPUT(value, 0, kJpegDCAlphabetSize - 1, HUFFMAN_CODE); 272 } 273 if (values_seen[value]) { 274 return JXL_FAILURE("Duplicate Huffman code value %d", value); 275 } 276 values_seen[value] = true; 277 huff.values[i] = value; 278 } 279 // Add an invalid symbol that will have the all 1 code. 280 ++huff.counts[max_depth]; 281 huff.values[total_count] = kJpegHuffmanAlphabetSize; 282 space -= (1 << (kJpegHuffmanMaxBitLength - max_depth)); 283 if (space < 0) { 284 return JXL_FAILURE("Invalid Huffman code lengths."); 285 } else if (space > 0 && huff_lut[0].value != 0xffff) { 286 // Re-initialize the values to an invalid symbol so that we can recognize 287 // it when reading the bit stream using a Huffman code with space > 0. 288 for (int i = 0; i < kJpegHuffmanLutSize; ++i) { 289 huff_lut[i].bits = 0; 290 huff_lut[i].value = 0xffff; 291 } 292 } 293 huff.is_last = (*pos == start_pos + marker_len); 294 if (mode == JpegReadMode::kReadAll) { 295 BuildJpegHuffmanTable(huff.counts.data(), huff.values.data(), huff_lut); 296 } 297 jpg->huffman_code.push_back(huff); 298 } 299 JXL_JPEG_VERIFY_MARKER_END(); 300 return true; 301 } 302 303 // Reads the Define Quantization Table (DQT) marker segment and fills in *jpg 304 // with the parsed data. 305 bool ProcessDQT(const uint8_t* data, const size_t len, size_t* pos, 306 JPEGData* jpg) { 307 const size_t start_pos = *pos; 308 JXL_JPEG_VERIFY_LEN(2); 309 size_t marker_len = ReadUint16(data, pos); 310 if (marker_len == 2) { 311 return JXL_FAILURE("DQT marker: no quantization table found"); 312 } 313 while (*pos < start_pos + marker_len && jpg->quant.size() < kMaxQuantTables) { 314 JXL_JPEG_VERIFY_LEN(1); 315 int quant_table_index = ReadUint8(data, pos); 316 int quant_table_precision = quant_table_index >> 4; 317 JXL_JPEG_VERIFY_INPUT(quant_table_precision, 0, 1, QUANT_TBL_PRECISION); 318 quant_table_index &= 0xf; 319 JXL_JPEG_VERIFY_INPUT(quant_table_index, 0, 3, QUANT_TBL_INDEX); 320 JXL_JPEG_VERIFY_LEN((quant_table_precision + 1) * kDCTBlockSize); 321 JPEGQuantTable table; 322 table.index = quant_table_index; 323 table.precision = quant_table_precision; 324 for (size_t i = 0; i < kDCTBlockSize; ++i) { 325 int quant_val = 326 quant_table_precision ? ReadUint16(data, pos) : ReadUint8(data, pos); 327 JXL_JPEG_VERIFY_INPUT(quant_val, 1, 65535, QUANT_VAL); 328 table.values[kJPEGNaturalOrder[i]] = quant_val; 329 } 330 table.is_last = (*pos == start_pos + marker_len); 331 jpg->quant.push_back(table); 332 } 333 JXL_JPEG_VERIFY_MARKER_END(); 334 return true; 335 } 336 337 // Reads the DRI marker and saves the restart interval into *jpg. 338 bool ProcessDRI(const uint8_t* data, const size_t len, size_t* pos, 339 bool* found_dri, JPEGData* jpg) { 340 if (*found_dri) { 341 return JXL_FAILURE("Duplicate DRI marker."); 342 } 343 *found_dri = true; 344 const size_t start_pos = *pos; 345 JXL_JPEG_VERIFY_LEN(4); 346 size_t marker_len = ReadUint16(data, pos); 347 int restart_interval = ReadUint16(data, pos); 348 jpg->restart_interval = restart_interval; 349 JXL_JPEG_VERIFY_MARKER_END(); 350 return true; 351 } 352 353 // Saves the APP marker segment as a string to *jpg. 354 bool ProcessAPP(const uint8_t* data, const size_t len, size_t* pos, 355 JPEGData* jpg) { 356 JXL_JPEG_VERIFY_LEN(2); 357 size_t marker_len = ReadUint16(data, pos); 358 JXL_JPEG_VERIFY_INPUT(marker_len, 2, 65535, MARKER_LEN); 359 JXL_JPEG_VERIFY_LEN(marker_len - 2); 360 JXL_DASSERT(*pos >= 3); 361 // Save the marker type together with the app data. 362 const uint8_t* app_str_start = data + *pos - 3; 363 std::vector<uint8_t> app_str(app_str_start, app_str_start + marker_len + 1); 364 *pos += marker_len - 2; 365 jpg->app_data.push_back(app_str); 366 return true; 367 } 368 369 // Saves the COM marker segment as a string to *jpg. 370 bool ProcessCOM(const uint8_t* data, const size_t len, size_t* pos, 371 JPEGData* jpg) { 372 JXL_JPEG_VERIFY_LEN(2); 373 size_t marker_len = ReadUint16(data, pos); 374 JXL_JPEG_VERIFY_INPUT(marker_len, 2, 65535, MARKER_LEN); 375 JXL_JPEG_VERIFY_LEN(marker_len - 2); 376 const uint8_t* com_str_start = data + *pos - 3; 377 std::vector<uint8_t> com_str(com_str_start, com_str_start + marker_len + 1); 378 *pos += marker_len - 2; 379 jpg->com_data.push_back(com_str); 380 return true; 381 } 382 383 // Helper structure to read bits from the entropy coded data segment. 384 struct BitReaderState { 385 BitReaderState(const uint8_t* data, const size_t len, size_t pos) 386 : data_(data), len_(len) { 387 Reset(pos); 388 } 389 390 void Reset(size_t pos) { 391 pos_ = pos; 392 val_ = 0; 393 bits_left_ = 0; 394 next_marker_pos_ = len_ - 2; 395 FillBitWindow(); 396 } 397 398 // Returns the next byte and skips the 0xff/0x00 escape sequences. 399 uint8_t GetNextByte() { 400 if (pos_ >= next_marker_pos_) { 401 ++pos_; 402 return 0; 403 } 404 uint8_t c = data_[pos_++]; 405 if (c == 0xff) { 406 uint8_t escape = data_[pos_]; 407 if (escape == 0) { 408 ++pos_; 409 } else { 410 // 0xff was followed by a non-zero byte, which means that we found the 411 // start of the next marker segment. 412 next_marker_pos_ = pos_ - 1; 413 } 414 } 415 return c; 416 } 417 418 void FillBitWindow() { 419 if (bits_left_ <= 16) { 420 while (bits_left_ <= 56) { 421 val_ <<= 8; 422 val_ |= static_cast<uint64_t>(GetNextByte()); 423 bits_left_ += 8; 424 } 425 } 426 } 427 428 int ReadBits(int nbits) { 429 FillBitWindow(); 430 uint64_t val = (val_ >> (bits_left_ - nbits)) & ((1ULL << nbits) - 1); 431 bits_left_ -= nbits; 432 return val; 433 } 434 435 // Sets *pos to the next stream position where parsing should continue. 436 // Enqueue the padding bits seen (0 or 1). 437 // Returns false if there is inconsistent or invalid padding or the stream 438 // ended too early. 439 bool FinishStream(JPEGData* jpg, size_t* pos) { 440 int npadbits = bits_left_ & 7; 441 if (npadbits > 0) { 442 uint64_t padmask = (1ULL << npadbits) - 1; 443 uint64_t padbits = (val_ >> (bits_left_ - npadbits)) & padmask; 444 if (padbits != padmask) { 445 jpg->has_zero_padding_bit = true; 446 } 447 for (int i = npadbits - 1; i >= 0; --i) { 448 jpg->padding_bits.push_back((padbits >> i) & 1); 449 } 450 } 451 // Give back some bytes that we did not use. 452 int unused_bytes_left = bits_left_ >> 3; 453 while (unused_bytes_left-- > 0) { 454 --pos_; 455 // If we give back a 0 byte, we need to check if it was a 0xff/0x00 escape 456 // sequence, and if yes, we need to give back one more byte. 457 if (pos_ < next_marker_pos_ && data_[pos_] == 0 && 458 data_[pos_ - 1] == 0xff) { 459 --pos_; 460 } 461 } 462 if (pos_ > next_marker_pos_) { 463 // Data ran out before the scan was complete. 464 return JXL_FAILURE("Unexpected end of scan."); 465 } 466 *pos = pos_; 467 return true; 468 } 469 470 const uint8_t* data_; 471 const size_t len_; 472 size_t pos_; 473 uint64_t val_; 474 int bits_left_; 475 size_t next_marker_pos_; 476 }; 477 478 // Returns the next Huffman-coded symbol. 479 int ReadSymbol(const HuffmanTableEntry* table, BitReaderState* br) { 480 int nbits; 481 br->FillBitWindow(); 482 int val = (br->val_ >> (br->bits_left_ - 8)) & 0xff; 483 table += val; 484 nbits = table->bits - 8; 485 if (nbits > 0) { 486 br->bits_left_ -= 8; 487 table += table->value; 488 val = (br->val_ >> (br->bits_left_ - nbits)) & ((1 << nbits) - 1); 489 table += val; 490 } 491 br->bits_left_ -= table->bits; 492 return table->value; 493 } 494 495 /** 496 * Returns the DC diff or AC value for extra bits value x and prefix code s. 497 * 498 * CCITT Rec. T.81 (1992 E) 499 * Table F.1 – Difference magnitude categories for DC coding 500 * SSSS | DIFF values 501 * ------+-------------------------- 502 * 0 | 0 503 * 1 | –1, 1 504 * 2 | –3, –2, 2, 3 505 * 3 | –7..–4, 4..7 506 * ......|.......................... 507 * 11 | –2047..–1024, 1024..2047 508 * 509 * CCITT Rec. T.81 (1992 E) 510 * Table F.2 – Categories assigned to coefficient values 511 * [ Same as Table F.1, but does not include SSSS equal to 0 and 11] 512 * 513 * 514 * CCITT Rec. T.81 (1992 E) 515 * F.1.2.1.1 Structure of DC code table 516 * For each category,... additional bits... appended... to uniquely identify 517 * which difference... occurred... When DIFF is positive... SSSS... bits of DIFF 518 * are appended. When DIFF is negative... SSSS... bits of (DIFF – 1) are 519 * appended... Most significant bit... is 0 for negative differences and 1 for 520 * positive differences. 521 * 522 * In other words the upper half of extra bits range represents DIFF as is. 523 * The lower half represents the negative DIFFs with an offset. 524 */ 525 int HuffExtend(int x, int s) { 526 JXL_DASSERT(s >= 1); 527 int half = 1 << (s - 1); 528 if (x >= half) { 529 JXL_DASSERT(x < (1 << s)); 530 return x; 531 } else { 532 return x - (1 << s) + 1; 533 } 534 } 535 536 // Decodes one 8x8 block of DCT coefficients from the bit stream. 537 bool DecodeDCTBlock(const HuffmanTableEntry* dc_huff, 538 const HuffmanTableEntry* ac_huff, int Ss, int Se, int Al, 539 int* eobrun, bool* reset_state, int* num_zero_runs, 540 BitReaderState* br, JPEGData* jpg, coeff_t* last_dc_coeff, 541 coeff_t* coeffs) { 542 // Nowadays multiplication is even faster than variable shift. 543 int Am = 1 << Al; 544 bool eobrun_allowed = Ss > 0; 545 if (Ss == 0) { 546 int s = ReadSymbol(dc_huff, br); 547 if (s >= kJpegDCAlphabetSize) { 548 return JXL_FAILURE("Invalid Huffman symbol %d for DC coefficient.", s); 549 } 550 int diff = 0; 551 if (s > 0) { 552 int bits = br->ReadBits(s); 553 diff = HuffExtend(bits, s); 554 } 555 int coeff = diff + *last_dc_coeff; 556 const int dc_coeff = coeff * Am; 557 coeffs[0] = dc_coeff; 558 // TODO(eustas): is there a more elegant / explicit way to check this? 559 if (dc_coeff != coeffs[0]) { 560 return JXL_FAILURE("Invalid DC coefficient %d", dc_coeff); 561 } 562 *last_dc_coeff = coeff; 563 ++Ss; 564 } 565 if (Ss > Se) { 566 return true; 567 } 568 if (*eobrun > 0) { 569 --(*eobrun); 570 return true; 571 } 572 *num_zero_runs = 0; 573 for (int k = Ss; k <= Se; k++) { 574 int sr = ReadSymbol(ac_huff, br); 575 if (sr >= kJpegHuffmanAlphabetSize) { 576 return JXL_FAILURE("Invalid Huffman symbol %d for AC coefficient %d", sr, 577 k); 578 } 579 int r = sr >> 4; 580 int s = sr & 15; 581 if (s > 0) { 582 k += r; 583 if (k > Se) { 584 return JXL_FAILURE("Out-of-band coefficient %d band was %d-%d", k, Ss, 585 Se); 586 } 587 if (s + Al >= kJpegDCAlphabetSize) { 588 return JXL_FAILURE( 589 "Out of range AC coefficient value: s = %d Al = %d k = %d", s, Al, 590 k); 591 } 592 int bits = br->ReadBits(s); 593 int coeff = HuffExtend(bits, s); 594 coeffs[kJPEGNaturalOrder[k]] = coeff * Am; 595 *num_zero_runs = 0; 596 } else if (r == 15) { 597 k += 15; 598 ++(*num_zero_runs); 599 } else { 600 if (eobrun_allowed && k == Ss && *eobrun == 0) { 601 // We have two end-of-block runs right after each other, so we signal 602 // the jpeg encoder to force a state reset at this point. 603 *reset_state = true; 604 } 605 *eobrun = 1 << r; 606 if (r > 0) { 607 if (!eobrun_allowed) { 608 return JXL_FAILURE("End-of-block run crossing DC coeff."); 609 } 610 *eobrun += br->ReadBits(r); 611 } 612 break; 613 } 614 } 615 --(*eobrun); 616 return true; 617 } 618 619 bool RefineDCTBlock(const HuffmanTableEntry* ac_huff, int Ss, int Se, int Al, 620 int* eobrun, bool* reset_state, BitReaderState* br, 621 JPEGData* jpg, coeff_t* coeffs) { 622 // Nowadays multiplication is even faster than variable shift. 623 int Am = 1 << Al; 624 bool eobrun_allowed = Ss > 0; 625 if (Ss == 0) { 626 int s = br->ReadBits(1); 627 coeff_t dc_coeff = coeffs[0]; 628 dc_coeff |= s * Am; 629 coeffs[0] = dc_coeff; 630 ++Ss; 631 } 632 if (Ss > Se) { 633 return true; 634 } 635 int p1 = Am; 636 int m1 = -Am; 637 int k = Ss; 638 int r; 639 int s; 640 bool in_zero_run = false; 641 if (*eobrun <= 0) { 642 for (; k <= Se; k++) { 643 s = ReadSymbol(ac_huff, br); 644 if (s >= kJpegHuffmanAlphabetSize) { 645 return JXL_FAILURE("Invalid Huffman symbol %d for AC coefficient %d", s, 646 k); 647 } 648 r = s >> 4; 649 s &= 15; 650 if (s) { 651 if (s != 1) { 652 return JXL_FAILURE("Invalid Huffman symbol %d for AC coefficient %d", 653 s, k); 654 } 655 s = br->ReadBits(1) ? p1 : m1; 656 in_zero_run = false; 657 } else { 658 if (r != 15) { 659 if (eobrun_allowed && k == Ss && *eobrun == 0) { 660 // We have two end-of-block runs right after each other, so we 661 // signal the jpeg encoder to force a state reset at this point. 662 *reset_state = true; 663 } 664 *eobrun = 1 << r; 665 if (r > 0) { 666 if (!eobrun_allowed) { 667 return JXL_FAILURE("End-of-block run crossing DC coeff."); 668 } 669 *eobrun += br->ReadBits(r); 670 } 671 break; 672 } 673 in_zero_run = true; 674 } 675 do { 676 coeff_t thiscoef = coeffs[kJPEGNaturalOrder[k]]; 677 if (thiscoef != 0) { 678 if (br->ReadBits(1)) { 679 if ((thiscoef & p1) == 0) { 680 if (thiscoef >= 0) { 681 thiscoef += p1; 682 } else { 683 thiscoef += m1; 684 } 685 } 686 } 687 coeffs[kJPEGNaturalOrder[k]] = thiscoef; 688 } else { 689 if (--r < 0) { 690 break; 691 } 692 } 693 k++; 694 } while (k <= Se); 695 if (s) { 696 if (k > Se) { 697 return JXL_FAILURE("Out-of-band coefficient %d band was %d-%d", k, Ss, 698 Se); 699 } 700 coeffs[kJPEGNaturalOrder[k]] = s; 701 } 702 } 703 } 704 if (in_zero_run) { 705 return JXL_FAILURE("Extra zero run before end-of-block."); 706 } 707 if (*eobrun > 0) { 708 for (; k <= Se; k++) { 709 coeff_t thiscoef = coeffs[kJPEGNaturalOrder[k]]; 710 if (thiscoef != 0) { 711 if (br->ReadBits(1)) { 712 if ((thiscoef & p1) == 0) { 713 if (thiscoef >= 0) { 714 thiscoef += p1; 715 } else { 716 thiscoef += m1; 717 } 718 } 719 } 720 coeffs[kJPEGNaturalOrder[k]] = thiscoef; 721 } 722 } 723 } 724 --(*eobrun); 725 return true; 726 } 727 728 bool ProcessRestart(const uint8_t* data, const size_t len, 729 int* next_restart_marker, BitReaderState* br, 730 JPEGData* jpg) { 731 size_t pos = 0; 732 if (!br->FinishStream(jpg, &pos)) { 733 return JXL_FAILURE("Invalid scan"); 734 } 735 int expected_marker = 0xd0 + *next_restart_marker; 736 JXL_JPEG_EXPECT_MARKER(); 737 int marker = data[pos + 1]; 738 if (marker != expected_marker) { 739 return JXL_FAILURE("Did not find expected restart marker %d actual %d", 740 expected_marker, marker); 741 } 742 br->Reset(pos + 2); 743 *next_restart_marker += 1; 744 *next_restart_marker &= 0x7; 745 return true; 746 } 747 748 bool ProcessScan(const uint8_t* data, const size_t len, 749 const std::vector<HuffmanTableEntry>& dc_huff_lut, 750 const std::vector<HuffmanTableEntry>& ac_huff_lut, 751 uint16_t scan_progression[kMaxComponents][kDCTBlockSize], 752 bool is_progressive, size_t* pos, JPEGData* jpg) { 753 if (!ProcessSOS(data, len, pos, jpg)) { 754 return false; 755 } 756 JPEGScanInfo* scan_info = &jpg->scan_info.back(); 757 bool is_interleaved = (scan_info->num_components > 1); 758 int max_h_samp_factor = 1; 759 int max_v_samp_factor = 1; 760 for (size_t i = 0; i < jpg->components.size(); ++i) { 761 max_h_samp_factor = 762 std::max(max_h_samp_factor, jpg->components[i].h_samp_factor); 763 max_v_samp_factor = 764 std::max(max_v_samp_factor, jpg->components[i].v_samp_factor); 765 } 766 767 int MCU_rows = DivCeil(jpg->height, max_v_samp_factor * 8); 768 int MCUs_per_row = DivCeil(jpg->width, max_h_samp_factor * 8); 769 if (!is_interleaved) { 770 const JPEGComponent& c = jpg->components[scan_info->components[0].comp_idx]; 771 MCUs_per_row = DivCeil(jpg->width * c.h_samp_factor, 8 * max_h_samp_factor); 772 MCU_rows = DivCeil(jpg->height * c.v_samp_factor, 8 * max_v_samp_factor); 773 } 774 coeff_t last_dc_coeff[kMaxComponents] = {0}; 775 BitReaderState br(data, len, *pos); 776 int restarts_to_go = jpg->restart_interval; 777 int next_restart_marker = 0; 778 int eobrun = -1; 779 int block_scan_index = 0; 780 const int Al = is_progressive ? scan_info->Al : 0; 781 const int Ah = is_progressive ? scan_info->Ah : 0; 782 const int Ss = is_progressive ? scan_info->Ss : 0; 783 const int Se = is_progressive ? scan_info->Se : 63; 784 const uint16_t scan_bitmask = Ah == 0 ? (0xffff << Al) : (1u << Al); 785 const uint16_t refinement_bitmask = (1 << Al) - 1; 786 for (size_t i = 0; i < scan_info->num_components; ++i) { 787 int comp_idx = scan_info->components[i].comp_idx; 788 for (int k = Ss; k <= Se; ++k) { 789 if (scan_progression[comp_idx][k] & scan_bitmask) { 790 return JXL_FAILURE( 791 "Overlapping scans: component=%d k=%d prev_mask: %u cur_mask %u", 792 comp_idx, k, scan_progression[i][k], scan_bitmask); 793 } 794 if (scan_progression[comp_idx][k] & refinement_bitmask) { 795 return JXL_FAILURE( 796 "Invalid scan order, a more refined scan was already done: " 797 "component=%d k=%d prev_mask=%u cur_mask=%u", 798 comp_idx, k, scan_progression[i][k], scan_bitmask); 799 } 800 scan_progression[comp_idx][k] |= scan_bitmask; 801 } 802 } 803 if (Al > 10) { 804 return JXL_FAILURE("Scan parameter Al=%d is not supported.", Al); 805 } 806 for (int mcu_y = 0; mcu_y < MCU_rows; ++mcu_y) { 807 for (int mcu_x = 0; mcu_x < MCUs_per_row; ++mcu_x) { 808 // Handle the restart intervals. 809 if (jpg->restart_interval > 0) { 810 if (restarts_to_go == 0) { 811 if (ProcessRestart(data, len, &next_restart_marker, &br, jpg)) { 812 restarts_to_go = jpg->restart_interval; 813 memset(static_cast<void*>(last_dc_coeff), 0, sizeof(last_dc_coeff)); 814 if (eobrun > 0) { 815 return JXL_FAILURE("End-of-block run too long."); 816 } 817 eobrun = -1; // fresh start 818 } else { 819 return JXL_FAILURE("Could not process restart."); 820 } 821 } 822 --restarts_to_go; 823 } 824 // Decode one MCU. 825 for (size_t i = 0; i < scan_info->num_components; ++i) { 826 JPEGComponentScanInfo* si = &scan_info->components[i]; 827 JPEGComponent* c = &jpg->components[si->comp_idx]; 828 const HuffmanTableEntry* dc_lut = 829 &dc_huff_lut[si->dc_tbl_idx * kJpegHuffmanLutSize]; 830 const HuffmanTableEntry* ac_lut = 831 &ac_huff_lut[si->ac_tbl_idx * kJpegHuffmanLutSize]; 832 int nblocks_y = is_interleaved ? c->v_samp_factor : 1; 833 int nblocks_x = is_interleaved ? c->h_samp_factor : 1; 834 for (int iy = 0; iy < nblocks_y; ++iy) { 835 for (int ix = 0; ix < nblocks_x; ++ix) { 836 int block_y = mcu_y * nblocks_y + iy; 837 int block_x = mcu_x * nblocks_x + ix; 838 int block_idx = block_y * c->width_in_blocks + block_x; 839 bool reset_state = false; 840 int num_zero_runs = 0; 841 coeff_t* coeffs = &c->coeffs[block_idx * kDCTBlockSize]; 842 if (Ah == 0) { 843 if (!DecodeDCTBlock(dc_lut, ac_lut, Ss, Se, Al, &eobrun, 844 &reset_state, &num_zero_runs, &br, jpg, 845 &last_dc_coeff[si->comp_idx], coeffs)) { 846 return false; 847 } 848 } else { 849 if (!RefineDCTBlock(ac_lut, Ss, Se, Al, &eobrun, &reset_state, 850 &br, jpg, coeffs)) { 851 return false; 852 } 853 } 854 if (reset_state) { 855 scan_info->reset_points.emplace_back(block_scan_index); 856 } 857 if (num_zero_runs > 0) { 858 JPEGScanInfo::ExtraZeroRunInfo info; 859 info.block_idx = block_scan_index; 860 info.num_extra_zero_runs = num_zero_runs; 861 scan_info->extra_zero_runs.push_back(info); 862 } 863 ++block_scan_index; 864 } 865 } 866 } 867 } 868 } 869 if (eobrun > 0) { 870 return JXL_FAILURE("End-of-block run too long."); 871 } 872 if (!br.FinishStream(jpg, pos)) { 873 return JXL_FAILURE("Invalid scan."); 874 } 875 if (*pos > len) { 876 return JXL_FAILURE("Unexpected end of file during scan. pos=%" PRIuS 877 " len=%" PRIuS, 878 *pos, len); 879 } 880 return true; 881 } 882 883 // Changes the quant_idx field of the components to refer to the index of the 884 // quant table in the jpg->quant array. 885 bool FixupIndexes(JPEGData* jpg) { 886 for (size_t i = 0; i < jpg->components.size(); ++i) { 887 JPEGComponent* c = &jpg->components[i]; 888 bool found_index = false; 889 for (size_t j = 0; j < jpg->quant.size(); ++j) { 890 if (jpg->quant[j].index == c->quant_idx) { 891 c->quant_idx = j; 892 found_index = true; 893 break; 894 } 895 } 896 if (!found_index) { 897 return JXL_FAILURE("Quantization table with index %u not found", 898 c->quant_idx); 899 } 900 } 901 return true; 902 } 903 904 size_t FindNextMarker(const uint8_t* data, const size_t len, size_t pos) { 905 // kIsValidMarker[i] == 1 means (0xc0 + i) is a valid marker. 906 static const uint8_t kIsValidMarker[] = { 907 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 908 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 909 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 910 }; 911 size_t num_skipped = 0; 912 while (pos + 1 < len && (data[pos] != 0xff || data[pos + 1] < 0xc0 || 913 !kIsValidMarker[data[pos + 1] - 0xc0])) { 914 ++pos; 915 ++num_skipped; 916 } 917 return num_skipped; 918 } 919 920 } // namespace 921 922 bool ReadJpeg(const uint8_t* data, const size_t len, JpegReadMode mode, 923 JPEGData* jpg) { 924 size_t pos = 0; 925 // Check SOI marker. 926 JXL_JPEG_EXPECT_MARKER(); 927 int marker = data[pos + 1]; 928 pos += 2; 929 if (marker != 0xd8) { 930 return JXL_FAILURE("Did not find expected SOI marker, actual=%d", marker); 931 } 932 int lut_size = kMaxHuffmanTables * kJpegHuffmanLutSize; 933 std::vector<HuffmanTableEntry> dc_huff_lut(lut_size); 934 std::vector<HuffmanTableEntry> ac_huff_lut(lut_size); 935 bool found_sof = false; 936 bool found_dri = false; 937 uint16_t scan_progression[kMaxComponents][kDCTBlockSize] = {{0}}; 938 939 jpg->padding_bits.resize(0); 940 bool is_progressive = false; // default 941 do { 942 // Read next marker. 943 size_t num_skipped = FindNextMarker(data, len, pos); 944 if (num_skipped > 0) { 945 // Add a fake marker to indicate arbitrary in-between-markers data. 946 jpg->marker_order.push_back(0xff); 947 jpg->inter_marker_data.emplace_back(data + pos, data + pos + num_skipped); 948 pos += num_skipped; 949 } 950 JXL_JPEG_EXPECT_MARKER(); 951 marker = data[pos + 1]; 952 pos += 2; 953 bool ok = true; 954 switch (marker) { 955 case 0xc0: 956 case 0xc1: 957 case 0xc2: 958 is_progressive = (marker == 0xc2); 959 ok = ProcessSOF(data, len, mode, &pos, jpg); 960 found_sof = true; 961 break; 962 case 0xc4: 963 ok = ProcessDHT(data, len, mode, &dc_huff_lut, &ac_huff_lut, &pos, jpg); 964 break; 965 case 0xd0: 966 case 0xd1: 967 case 0xd2: 968 case 0xd3: 969 case 0xd4: 970 case 0xd5: 971 case 0xd6: 972 case 0xd7: 973 // RST markers do not have any data. 974 break; 975 case 0xd9: 976 // Found end marker. 977 break; 978 case 0xda: 979 if (mode == JpegReadMode::kReadAll) { 980 ok = ProcessScan(data, len, dc_huff_lut, ac_huff_lut, 981 scan_progression, is_progressive, &pos, jpg); 982 } 983 break; 984 case 0xdb: 985 ok = ProcessDQT(data, len, &pos, jpg); 986 break; 987 case 0xdd: 988 ok = ProcessDRI(data, len, &pos, &found_dri, jpg); 989 break; 990 case 0xe0: 991 case 0xe1: 992 case 0xe2: 993 case 0xe3: 994 case 0xe4: 995 case 0xe5: 996 case 0xe6: 997 case 0xe7: 998 case 0xe8: 999 case 0xe9: 1000 case 0xea: 1001 case 0xeb: 1002 case 0xec: 1003 case 0xed: 1004 case 0xee: 1005 case 0xef: 1006 if (mode != JpegReadMode::kReadTables) { 1007 ok = ProcessAPP(data, len, &pos, jpg); 1008 } 1009 break; 1010 case 0xfe: 1011 if (mode != JpegReadMode::kReadTables) { 1012 ok = ProcessCOM(data, len, &pos, jpg); 1013 } 1014 break; 1015 default: 1016 return JXL_FAILURE("Unsupported marker: %d pos=%" PRIuS " len=%" PRIuS, 1017 marker, pos, len); 1018 } 1019 if (!ok) { 1020 return false; 1021 } 1022 jpg->marker_order.push_back(marker); 1023 if (mode == JpegReadMode::kReadHeader && found_sof) { 1024 break; 1025 } 1026 } while (marker != 0xd9); 1027 1028 if (!found_sof) { 1029 return JXL_FAILURE("Missing SOF marker."); 1030 } 1031 1032 // Supplemental checks. 1033 if (mode == JpegReadMode::kReadAll) { 1034 if (pos < len) { 1035 jpg->tail_data = std::vector<uint8_t>(data + pos, data + len); 1036 } 1037 if (!FixupIndexes(jpg)) { 1038 return false; 1039 } 1040 if (jpg->huffman_code.empty()) { 1041 // Section B.2.4.2: "If a table has never been defined for a particular 1042 // destination, then when this destination is specified in a scan header, 1043 // the results are unpredictable." 1044 return JXL_FAILURE("Need at least one Huffman code table."); 1045 } 1046 if (jpg->huffman_code.size() >= kMaxDHTMarkers) { 1047 return JXL_FAILURE("Too many Huffman tables."); 1048 } 1049 } 1050 return true; 1051 } 1052 1053 } // namespace jpeg 1054 } // namespace jxl