jpeg_data.cc (18312B)
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/jpeg_data.h" 7 8 #include <jxl/types.h> 9 10 #include "lib/jxl/base/printf_macros.h" 11 #include "lib/jxl/base/status.h" 12 #include "lib/jxl/common.h" // kMaxNumPasses, JPEGXL_ENABLE_TRANSCODE_JPEG 13 14 namespace jxl { 15 namespace jpeg { 16 17 #if JPEGXL_ENABLE_TRANSCODE_JPEG 18 19 namespace { 20 enum JPEGComponentType : uint32_t { 21 kGray = 0, 22 kYCbCr = 1, 23 kRGB = 2, 24 kCustom = 3, 25 }; 26 27 struct JPEGInfo { 28 size_t num_app_markers = 0; 29 size_t num_com_markers = 0; 30 size_t num_scans = 0; 31 size_t num_intermarker = 0; 32 bool has_dri = false; 33 }; 34 35 Status VisitMarker(uint8_t* marker, Visitor* visitor, JPEGInfo* info) { 36 uint32_t marker32 = *marker - 0xc0; 37 JXL_RETURN_IF_ERROR(visitor->Bits(6, 0x00, &marker32)); 38 *marker = marker32 + 0xc0; 39 if ((*marker & 0xf0) == 0xe0) { 40 info->num_app_markers++; 41 } 42 if (*marker == 0xfe) { 43 info->num_com_markers++; 44 } 45 if (*marker == 0xda) { 46 info->num_scans++; 47 } 48 // We use a fake 0xff marker to signal intermarker data. 49 if (*marker == 0xff) { 50 info->num_intermarker++; 51 } 52 if (*marker == 0xdd) { 53 info->has_dri = true; 54 } 55 return true; 56 } 57 58 } // namespace 59 60 Status JPEGData::VisitFields(Visitor* visitor) { 61 bool is_gray = components.size() == 1; 62 JXL_RETURN_IF_ERROR(visitor->Bool(false, &is_gray)); 63 if (visitor->IsReading()) { 64 components.resize(is_gray ? 1 : 3); 65 } 66 JPEGInfo info; 67 if (visitor->IsReading()) { 68 uint8_t marker = 0xc0; 69 do { 70 JXL_RETURN_IF_ERROR(VisitMarker(&marker, visitor, &info)); 71 marker_order.push_back(marker); 72 if (marker_order.size() > 16384) { 73 return JXL_FAILURE("Too many markers: %" PRIuS "\n", 74 marker_order.size()); 75 } 76 } while (marker != 0xd9); 77 } else { 78 if (marker_order.size() > 16384) { 79 return JXL_FAILURE("Too many markers: %" PRIuS "\n", marker_order.size()); 80 } 81 for (size_t i = 0; i < marker_order.size(); i++) { 82 JXL_RETURN_IF_ERROR(VisitMarker(&marker_order[i], visitor, &info)); 83 } 84 if (!marker_order.empty()) { 85 // Last marker should always be EOI marker. 86 JXL_CHECK(marker_order.back() == 0xd9); 87 } 88 } 89 90 // Size of the APP and COM markers. 91 if (visitor->IsReading()) { 92 app_data.resize(info.num_app_markers); 93 app_marker_type.resize(info.num_app_markers); 94 com_data.resize(info.num_com_markers); 95 scan_info.resize(info.num_scans); 96 } 97 JXL_ASSERT(app_data.size() == info.num_app_markers); 98 JXL_ASSERT(app_marker_type.size() == info.num_app_markers); 99 JXL_ASSERT(com_data.size() == info.num_com_markers); 100 JXL_ASSERT(scan_info.size() == info.num_scans); 101 for (size_t i = 0; i < app_data.size(); i++) { 102 auto& app = app_data[i]; 103 // Encodes up to 8 different values. 104 JXL_RETURN_IF_ERROR( 105 visitor->U32(Val(0), Val(1), BitsOffset(1, 2), BitsOffset(2, 4), 0, 106 reinterpret_cast<uint32_t*>(&app_marker_type[i]))); 107 if (app_marker_type[i] != AppMarkerType::kUnknown && 108 app_marker_type[i] != AppMarkerType::kICC && 109 app_marker_type[i] != AppMarkerType::kExif && 110 app_marker_type[i] != AppMarkerType::kXMP) { 111 return JXL_FAILURE("Unknown app marker type %u", 112 static_cast<uint32_t>(app_marker_type[i])); 113 } 114 uint32_t len = app.size() - 1; 115 JXL_RETURN_IF_ERROR(visitor->Bits(16, 0, &len)); 116 if (visitor->IsReading()) app.resize(len + 1); 117 if (app.size() < 3) { 118 return JXL_FAILURE("Invalid marker size: %" PRIuS "\n", app.size()); 119 } 120 } 121 for (auto& com : com_data) { 122 uint32_t len = com.size() - 1; 123 JXL_RETURN_IF_ERROR(visitor->Bits(16, 0, &len)); 124 if (visitor->IsReading()) com.resize(len + 1); 125 if (com.size() < 3) { 126 return JXL_FAILURE("Invalid marker size: %" PRIuS "\n", com.size()); 127 } 128 } 129 130 uint32_t num_quant_tables = quant.size(); 131 JXL_RETURN_IF_ERROR( 132 visitor->U32(Val(1), Val(2), Val(3), Val(4), 2, &num_quant_tables)); 133 if (num_quant_tables == 4) { 134 return JXL_FAILURE("Invalid number of quant tables"); 135 } 136 if (visitor->IsReading()) { 137 quant.resize(num_quant_tables); 138 } 139 for (size_t i = 0; i < num_quant_tables; i++) { 140 if (quant[i].precision > 1) { 141 return JXL_FAILURE( 142 "Quant tables with more than 16 bits are not supported"); 143 } 144 JXL_RETURN_IF_ERROR(visitor->Bits(1, 0, &quant[i].precision)); 145 JXL_RETURN_IF_ERROR(visitor->Bits(2, i, &quant[i].index)); 146 JXL_RETURN_IF_ERROR(visitor->Bool(true, &quant[i].is_last)); 147 } 148 149 JPEGComponentType component_type = 150 components.size() == 1 && components[0].id == 1 ? JPEGComponentType::kGray 151 : components.size() == 3 && components[0].id == 1 && 152 components[1].id == 2 && components[2].id == 3 153 ? JPEGComponentType::kYCbCr 154 : components.size() == 3 && components[0].id == 'R' && 155 components[1].id == 'G' && components[2].id == 'B' 156 ? JPEGComponentType::kRGB 157 : JPEGComponentType::kCustom; 158 JXL_RETURN_IF_ERROR( 159 visitor->Bits(2, JPEGComponentType::kYCbCr, 160 reinterpret_cast<uint32_t*>(&component_type))); 161 uint32_t num_components; 162 if (component_type == JPEGComponentType::kGray) { 163 num_components = 1; 164 } else if (component_type != JPEGComponentType::kCustom) { 165 num_components = 3; 166 } else { 167 num_components = components.size(); 168 JXL_RETURN_IF_ERROR( 169 visitor->U32(Val(1), Val(2), Val(3), Val(4), 3, &num_components)); 170 if (num_components != 1 && num_components != 3) { 171 return JXL_FAILURE("Invalid number of components: %u", num_components); 172 } 173 } 174 if (visitor->IsReading()) { 175 components.resize(num_components); 176 } 177 if (component_type == JPEGComponentType::kCustom) { 178 for (size_t i = 0; i < components.size(); i++) { 179 JXL_RETURN_IF_ERROR(visitor->Bits(8, 0, &components[i].id)); 180 } 181 } else if (component_type == JPEGComponentType::kGray) { 182 components[0].id = 1; 183 } else if (component_type == JPEGComponentType::kRGB) { 184 components[0].id = 'R'; 185 components[1].id = 'G'; 186 components[2].id = 'B'; 187 } else { 188 components[0].id = 1; 189 components[1].id = 2; 190 components[2].id = 3; 191 } 192 size_t used_tables = 0; 193 for (size_t i = 0; i < components.size(); i++) { 194 JXL_RETURN_IF_ERROR(visitor->Bits(2, 0, &components[i].quant_idx)); 195 if (components[i].quant_idx >= quant.size()) { 196 return JXL_FAILURE("Invalid quant table for component %" PRIuS ": %u\n", 197 i, components[i].quant_idx); 198 } 199 used_tables |= 1U << components[i].quant_idx; 200 } 201 for (size_t i = 0; i < quant.size(); i++) { 202 if (used_tables & (1 << i)) continue; 203 if (i == 0) return JXL_FAILURE("First quant table unused."); 204 // Unused quant table has to be set to copy of previous quant table 205 for (size_t j = 0; j < 64; j++) { 206 if (quant[i].values[j] != quant[i - 1].values[j]) { 207 return JXL_FAILURE("Non-trivial unused quant table"); 208 } 209 } 210 } 211 212 uint32_t num_huff = huffman_code.size(); 213 JXL_RETURN_IF_ERROR(visitor->U32(Val(4), BitsOffset(3, 2), BitsOffset(4, 10), 214 BitsOffset(6, 26), 4, &num_huff)); 215 if (visitor->IsReading()) { 216 huffman_code.resize(num_huff); 217 } 218 for (JPEGHuffmanCode& hc : huffman_code) { 219 bool is_ac = ((hc.slot_id >> 4) != 0); 220 uint32_t id = hc.slot_id & 0xF; 221 JXL_RETURN_IF_ERROR(visitor->Bool(false, &is_ac)); 222 JXL_RETURN_IF_ERROR(visitor->Bits(2, 0, &id)); 223 hc.slot_id = (static_cast<uint32_t>(is_ac) << 4) | id; 224 JXL_RETURN_IF_ERROR(visitor->Bool(true, &hc.is_last)); 225 size_t num_symbols = 0; 226 for (size_t i = 0; i <= 16; i++) { 227 JXL_RETURN_IF_ERROR(visitor->U32(Val(0), Val(1), BitsOffset(3, 2), 228 Bits(8), 0, &hc.counts[i])); 229 num_symbols += hc.counts[i]; 230 } 231 if (num_symbols < 1) { 232 // Actually, at least 2 symbols are required, since one of them is EOI. 233 return JXL_FAILURE("Empty Huffman table"); 234 } 235 if (num_symbols > hc.values.size()) { 236 return JXL_FAILURE("Huffman code too large (%" PRIuS ")", num_symbols); 237 } 238 // Presence flags for 4 * 64 + 1 values. 239 uint64_t value_slots[5] = {}; 240 for (size_t i = 0; i < num_symbols; i++) { 241 // Goes up to 256, included. Might have the same symbol appear twice... 242 JXL_RETURN_IF_ERROR(visitor->U32(Bits(2), BitsOffset(2, 4), 243 BitsOffset(4, 8), BitsOffset(8, 1), 0, 244 &hc.values[i])); 245 value_slots[hc.values[i] >> 6] |= static_cast<uint64_t>(1) 246 << (hc.values[i] & 0x3F); 247 } 248 if (hc.values[num_symbols - 1] != kJpegHuffmanAlphabetSize) { 249 return JXL_FAILURE("Missing EOI symbol"); 250 } 251 // Last element, denoting EOI, have to be 1 after the loop. 252 JXL_ASSERT(value_slots[4] == 1); 253 size_t num_values = 1; 254 for (size_t i = 0; i < 4; ++i) num_values += hwy::PopCount(value_slots[i]); 255 if (num_values != num_symbols) { 256 return JXL_FAILURE("Duplicate Huffman symbols"); 257 } 258 if (!is_ac) { 259 bool only_dc = ((value_slots[0] >> kJpegDCAlphabetSize) | value_slots[1] | 260 value_slots[2] | value_slots[3]) == 0; 261 if (!only_dc) return JXL_FAILURE("Huffman symbols out of DC range"); 262 } 263 } 264 265 for (auto& scan : scan_info) { 266 JXL_RETURN_IF_ERROR( 267 visitor->U32(Val(1), Val(2), Val(3), Val(4), 1, &scan.num_components)); 268 if (scan.num_components >= 4) { 269 return JXL_FAILURE("Invalid number of components in SOS marker"); 270 } 271 JXL_RETURN_IF_ERROR(visitor->Bits(6, 0, &scan.Ss)); 272 JXL_RETURN_IF_ERROR(visitor->Bits(6, 63, &scan.Se)); 273 JXL_RETURN_IF_ERROR(visitor->Bits(4, 0, &scan.Al)); 274 JXL_RETURN_IF_ERROR(visitor->Bits(4, 0, &scan.Ah)); 275 for (size_t i = 0; i < scan.num_components; i++) { 276 JXL_RETURN_IF_ERROR(visitor->Bits(2, 0, &scan.components[i].comp_idx)); 277 if (scan.components[i].comp_idx >= components.size()) { 278 return JXL_FAILURE("Invalid component idx in SOS marker"); 279 } 280 JXL_RETURN_IF_ERROR(visitor->Bits(2, 0, &scan.components[i].ac_tbl_idx)); 281 JXL_RETURN_IF_ERROR(visitor->Bits(2, 0, &scan.components[i].dc_tbl_idx)); 282 } 283 // TODO(veluca): actually set and use this value. 284 JXL_RETURN_IF_ERROR(visitor->U32(Val(0), Val(1), Val(2), BitsOffset(3, 3), 285 kMaxNumPasses - 1, 286 &scan.last_needed_pass)); 287 } 288 289 // From here on, this is data that is not strictly necessary to get a valid 290 // JPEG, but necessary for bit-exact JPEG reconstruction. 291 if (info.has_dri) { 292 JXL_RETURN_IF_ERROR(visitor->Bits(16, 0, &restart_interval)); 293 } 294 295 for (auto& scan : scan_info) { 296 uint32_t num_reset_points = scan.reset_points.size(); 297 JXL_RETURN_IF_ERROR(visitor->U32(Val(0), BitsOffset(2, 1), BitsOffset(4, 4), 298 BitsOffset(16, 20), 0, &num_reset_points)); 299 if (visitor->IsReading()) { 300 scan.reset_points.resize(num_reset_points); 301 } 302 int last_block_idx = -1; 303 for (auto& block_idx : scan.reset_points) { 304 block_idx -= last_block_idx + 1; 305 JXL_RETURN_IF_ERROR(visitor->U32(Val(0), BitsOffset(3, 1), 306 BitsOffset(5, 9), BitsOffset(28, 41), 0, 307 &block_idx)); 308 block_idx += last_block_idx + 1; 309 if (block_idx >= (3u << 26)) { 310 // At most 8K x 8K x num_channels blocks are possible in a JPEG. 311 // So valid block indices are below 3 * 2^26. 312 return JXL_FAILURE("Invalid block ID: %u", block_idx); 313 } 314 last_block_idx = block_idx; 315 } 316 317 uint32_t num_extra_zero_runs = scan.extra_zero_runs.size(); 318 JXL_RETURN_IF_ERROR(visitor->U32(Val(0), BitsOffset(2, 1), BitsOffset(4, 4), 319 BitsOffset(16, 20), 0, 320 &num_extra_zero_runs)); 321 if (visitor->IsReading()) { 322 scan.extra_zero_runs.resize(num_extra_zero_runs); 323 } 324 last_block_idx = -1; 325 for (size_t i = 0; i < scan.extra_zero_runs.size(); ++i) { 326 uint32_t& block_idx = scan.extra_zero_runs[i].block_idx; 327 JXL_RETURN_IF_ERROR(visitor->U32( 328 Val(1), BitsOffset(2, 2), BitsOffset(4, 5), BitsOffset(8, 20), 1, 329 &scan.extra_zero_runs[i].num_extra_zero_runs)); 330 block_idx -= last_block_idx + 1; 331 JXL_RETURN_IF_ERROR(visitor->U32(Val(0), BitsOffset(3, 1), 332 BitsOffset(5, 9), BitsOffset(28, 41), 0, 333 &block_idx)); 334 block_idx += last_block_idx + 1; 335 if (block_idx > (3u << 26)) { 336 return JXL_FAILURE("Invalid block ID: %u", block_idx); 337 } 338 last_block_idx = block_idx; 339 } 340 } 341 std::vector<uint32_t> inter_marker_data_sizes; 342 inter_marker_data_sizes.reserve(info.num_intermarker); 343 for (size_t i = 0; i < info.num_intermarker; ++i) { 344 uint32_t len = visitor->IsReading() ? 0 : inter_marker_data[i].size(); 345 JXL_RETURN_IF_ERROR(visitor->Bits(16, 0, &len)); 346 if (visitor->IsReading()) inter_marker_data_sizes.emplace_back(len); 347 } 348 uint32_t tail_data_len = tail_data.size(); 349 if (!visitor->IsReading() && tail_data_len > 4260096) { 350 return JXL_FAILURE("Tail data too large (max size = 4260096, size = %u)", 351 tail_data_len); 352 } 353 JXL_RETURN_IF_ERROR(visitor->U32(Val(0), BitsOffset(8, 1), 354 BitsOffset(16, 257), BitsOffset(22, 65793), 355 0, &tail_data_len)); 356 357 JXL_RETURN_IF_ERROR(visitor->Bool(false, &has_zero_padding_bit)); 358 if (has_zero_padding_bit) { 359 uint32_t nbit = padding_bits.size(); 360 JXL_RETURN_IF_ERROR(visitor->Bits(24, 0, &nbit)); 361 if (visitor->IsReading()) { 362 JXL_RETURN_IF_ERROR(CheckHasEnoughBits(visitor, nbit)); 363 padding_bits.reserve(std::min<uint32_t>(1024u, nbit)); 364 for (uint32_t i = 0; i < nbit; i++) { 365 bool bbit = false; 366 JXL_RETURN_IF_ERROR(visitor->Bool(false, &bbit)); 367 padding_bits.push_back(TO_JXL_BOOL(bbit)); 368 } 369 } else { 370 for (uint8_t& bit : padding_bits) { 371 bool bbit = FROM_JXL_BOOL(bit); 372 JXL_RETURN_IF_ERROR(visitor->Bool(false, &bbit)); 373 bit = TO_JXL_BOOL(bbit); 374 } 375 } 376 } 377 378 { 379 size_t dht_index = 0; 380 size_t scan_index = 0; 381 bool is_progressive = false; 382 bool ac_ok[kMaxHuffmanTables] = {false}; 383 bool dc_ok[kMaxHuffmanTables] = {false}; 384 for (uint8_t marker : marker_order) { 385 if (marker == 0xC2) { 386 is_progressive = true; 387 } else if (marker == 0xC4) { 388 for (; dht_index < huffman_code.size();) { 389 const JPEGHuffmanCode& huff = huffman_code[dht_index++]; 390 size_t index = huff.slot_id; 391 if (index & 0x10) { 392 index -= 0x10; 393 ac_ok[index] = true; 394 } else { 395 dc_ok[index] = true; 396 } 397 if (huff.is_last) break; 398 } 399 } else if (marker == 0xDA) { 400 const JPEGScanInfo& si = scan_info[scan_index++]; 401 for (size_t i = 0; i < si.num_components; ++i) { 402 const JPEGComponentScanInfo& csi = si.components[i]; 403 size_t dc_tbl_idx = csi.dc_tbl_idx; 404 size_t ac_tbl_idx = csi.ac_tbl_idx; 405 bool want_dc = !is_progressive || (si.Ss == 0); 406 if (want_dc && !dc_ok[dc_tbl_idx]) { 407 return JXL_FAILURE("DC Huffman table used before defined"); 408 } 409 bool want_ac = !is_progressive || (si.Ss != 0) || (si.Se != 0); 410 if (want_ac && !ac_ok[ac_tbl_idx]) { 411 return JXL_FAILURE("AC Huffman table used before defined"); 412 } 413 } 414 } 415 } 416 } 417 418 // Apply postponed actions. 419 if (visitor->IsReading()) { 420 tail_data.resize(tail_data_len); 421 JXL_ASSERT(inter_marker_data_sizes.size() == info.num_intermarker); 422 inter_marker_data.reserve(info.num_intermarker); 423 for (size_t i = 0; i < info.num_intermarker; ++i) { 424 inter_marker_data.emplace_back(inter_marker_data_sizes[i]); 425 } 426 } 427 428 return true; 429 } 430 431 #endif // JPEGXL_ENABLE_TRANSCODE_JPEG 432 433 void JPEGData::CalculateMcuSize(const JPEGScanInfo& scan, int* MCUs_per_row, 434 int* MCU_rows) const { 435 const bool is_interleaved = (scan.num_components > 1); 436 const JPEGComponent& base_component = components[scan.components[0].comp_idx]; 437 // h_group / v_group act as numerators for converting number of blocks to 438 // number of MCU. In interleaved mode it is 1, so MCU is represented with 439 // max_*_samp_factor blocks. In non-interleaved mode we choose numerator to 440 // be the samping factor, consequently MCU is always represented with single 441 // block. 442 const int h_group = is_interleaved ? 1 : base_component.h_samp_factor; 443 const int v_group = is_interleaved ? 1 : base_component.v_samp_factor; 444 int max_h_samp_factor = 1; 445 int max_v_samp_factor = 1; 446 for (const auto& c : components) { 447 max_h_samp_factor = std::max(c.h_samp_factor, max_h_samp_factor); 448 max_v_samp_factor = std::max(c.v_samp_factor, max_v_samp_factor); 449 } 450 *MCUs_per_row = DivCeil(width * h_group, 8 * max_h_samp_factor); 451 *MCU_rows = DivCeil(height * v_group, 8 * max_v_samp_factor); 452 } 453 454 #if JPEGXL_ENABLE_TRANSCODE_JPEG 455 456 Status SetJPEGDataFromICC(const std::vector<uint8_t>& icc, 457 jpeg::JPEGData* jpeg_data) { 458 size_t icc_pos = 0; 459 for (size_t i = 0; i < jpeg_data->app_data.size(); i++) { 460 if (jpeg_data->app_marker_type[i] != jpeg::AppMarkerType::kICC) { 461 continue; 462 } 463 size_t len = jpeg_data->app_data[i].size() - 17; 464 if (icc_pos + len > icc.size()) { 465 return JXL_FAILURE( 466 "ICC length is less than APP markers: requested %" PRIuS 467 " more bytes, " 468 "%" PRIuS " available", 469 len, icc.size() - icc_pos); 470 } 471 memcpy(&jpeg_data->app_data[i][17], icc.data() + icc_pos, len); 472 icc_pos += len; 473 } 474 if (icc_pos != icc.size() && icc_pos != 0) { 475 return JXL_FAILURE("ICC length is more than APP markers"); 476 } 477 return true; 478 } 479 480 #endif // JPEGXL_ENABLE_TRANSCODE_JPEG 481 482 } // namespace jpeg 483 } // namespace jxl