decode.cc (37293B)
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/jpegli/decode.h" 7 8 #include <string.h> 9 10 #include <vector> 11 12 #include "lib/jpegli/color_quantize.h" 13 #include "lib/jpegli/decode_internal.h" 14 #include "lib/jpegli/decode_marker.h" 15 #include "lib/jpegli/decode_scan.h" 16 #include "lib/jpegli/error.h" 17 #include "lib/jpegli/memory_manager.h" 18 #include "lib/jpegli/render.h" 19 #include "lib/jxl/base/byte_order.h" 20 #include "lib/jxl/base/status.h" 21 22 namespace jpegli { 23 24 void InitializeImage(j_decompress_ptr cinfo) { 25 cinfo->restart_interval = 0; 26 cinfo->saw_JFIF_marker = FALSE; 27 cinfo->JFIF_major_version = 1; 28 cinfo->JFIF_minor_version = 1; 29 cinfo->density_unit = 0; 30 cinfo->X_density = 1; 31 cinfo->Y_density = 1; 32 cinfo->saw_Adobe_marker = FALSE; 33 cinfo->Adobe_transform = 0; 34 cinfo->CCIR601_sampling = FALSE; // not used 35 cinfo->marker_list = nullptr; 36 cinfo->comp_info = nullptr; 37 cinfo->input_scan_number = 0; 38 cinfo->input_iMCU_row = 0; 39 cinfo->output_scan_number = 0; 40 cinfo->output_iMCU_row = 0; 41 cinfo->output_scanline = 0; 42 cinfo->unread_marker = 0; 43 cinfo->coef_bits = nullptr; 44 // We set all these to zero since we don't yet support arithmetic coding. 45 memset(cinfo->arith_dc_L, 0, sizeof(cinfo->arith_dc_L)); 46 memset(cinfo->arith_dc_U, 0, sizeof(cinfo->arith_dc_U)); 47 memset(cinfo->arith_ac_K, 0, sizeof(cinfo->arith_ac_K)); 48 // Initialize the private fields. 49 jpeg_decomp_master* m = cinfo->master; 50 m->input_buffer_.clear(); 51 m->input_buffer_pos_ = 0; 52 m->codestream_bits_ahead_ = 0; 53 m->is_multiscan_ = false; 54 m->found_soi_ = false; 55 m->found_dri_ = false; 56 m->found_sof_ = false; 57 m->found_eoi_ = false; 58 m->icc_index_ = 0; 59 m->icc_total_ = 0; 60 m->icc_profile_.clear(); 61 memset(m->dc_huff_lut_, 0, sizeof(m->dc_huff_lut_)); 62 memset(m->ac_huff_lut_, 0, sizeof(m->ac_huff_lut_)); 63 // Initialize the values to an invalid symbol so that we can recognize it 64 // when reading the bit stream using a Huffman code with space > 0. 65 for (size_t i = 0; i < kAllHuffLutSize; ++i) { 66 m->dc_huff_lut_[i].bits = 0; 67 m->dc_huff_lut_[i].value = 0xffff; 68 m->ac_huff_lut_[i].bits = 0; 69 m->ac_huff_lut_[i].value = 0xffff; 70 } 71 m->colormap_lut_ = nullptr; 72 m->pixels_ = nullptr; 73 m->scanlines_ = nullptr; 74 m->regenerate_inverse_colormap_ = true; 75 for (int i = 0; i < kMaxComponents; ++i) { 76 m->dither_[i] = nullptr; 77 m->error_row_[i] = nullptr; 78 } 79 m->output_passes_done_ = 0; 80 m->xoffset_ = 0; 81 m->dequant_ = nullptr; 82 } 83 84 void InitializeDecompressParams(j_decompress_ptr cinfo) { 85 cinfo->jpeg_color_space = JCS_UNKNOWN; 86 cinfo->out_color_space = JCS_UNKNOWN; 87 cinfo->scale_num = 1; 88 cinfo->scale_denom = 1; 89 cinfo->output_gamma = 0.0f; 90 cinfo->buffered_image = FALSE; 91 cinfo->raw_data_out = FALSE; 92 cinfo->dct_method = JDCT_DEFAULT; 93 cinfo->do_fancy_upsampling = TRUE; 94 cinfo->do_block_smoothing = TRUE; 95 cinfo->quantize_colors = FALSE; 96 cinfo->dither_mode = JDITHER_FS; 97 cinfo->two_pass_quantize = TRUE; 98 cinfo->desired_number_of_colors = 256; 99 cinfo->enable_1pass_quant = FALSE; 100 cinfo->enable_external_quant = FALSE; 101 cinfo->enable_2pass_quant = FALSE; 102 cinfo->actual_number_of_colors = 0; 103 cinfo->colormap = nullptr; 104 } 105 106 void InitProgressMonitor(j_decompress_ptr cinfo, bool coef_only) { 107 if (!cinfo->progress) return; 108 jpeg_decomp_master* m = cinfo->master; 109 int nc = cinfo->num_components; 110 int estimated_num_scans = 111 cinfo->progressive_mode ? 2 + 3 * nc : (m->is_multiscan_ ? nc : 1); 112 cinfo->progress->pass_limit = cinfo->total_iMCU_rows * estimated_num_scans; 113 cinfo->progress->pass_counter = 0; 114 if (coef_only) { 115 cinfo->progress->total_passes = 1; 116 } else { 117 int input_passes = !cinfo->buffered_image && m->is_multiscan_ ? 1 : 0; 118 bool two_pass_quant = FROM_JXL_BOOL(cinfo->quantize_colors) && 119 (cinfo->colormap != nullptr) && 120 FROM_JXL_BOOL(cinfo->two_pass_quantize) && 121 FROM_JXL_BOOL(cinfo->enable_2pass_quant); 122 cinfo->progress->total_passes = input_passes + (two_pass_quant ? 2 : 1); 123 } 124 cinfo->progress->completed_passes = 0; 125 } 126 127 void InitProgressMonitorForOutput(j_decompress_ptr cinfo) { 128 if (!cinfo->progress) return; 129 jpeg_decomp_master* m = cinfo->master; 130 int passes_per_output = cinfo->enable_2pass_quant ? 2 : 1; 131 int output_passes_left = cinfo->buffered_image && !m->found_eoi_ ? 2 : 1; 132 cinfo->progress->total_passes = 133 m->output_passes_done_ + passes_per_output * output_passes_left; 134 cinfo->progress->completed_passes = m->output_passes_done_; 135 } 136 137 void ProgressMonitorInputPass(j_decompress_ptr cinfo) { 138 if (!cinfo->progress) return; 139 cinfo->progress->pass_counter = 140 ((cinfo->input_scan_number - 1) * cinfo->total_iMCU_rows + 141 cinfo->input_iMCU_row); 142 if (cinfo->progress->pass_counter > cinfo->progress->pass_limit) { 143 cinfo->progress->pass_limit = 144 cinfo->input_scan_number * cinfo->total_iMCU_rows; 145 } 146 (*cinfo->progress->progress_monitor)(reinterpret_cast<j_common_ptr>(cinfo)); 147 } 148 149 void ProgressMonitorOutputPass(j_decompress_ptr cinfo) { 150 if (!cinfo->progress) return; 151 jpeg_decomp_master* m = cinfo->master; 152 int input_passes = !cinfo->buffered_image && m->is_multiscan_ ? 1 : 0; 153 cinfo->progress->pass_counter = cinfo->output_scanline; 154 cinfo->progress->pass_limit = cinfo->output_height; 155 cinfo->progress->completed_passes = input_passes + m->output_passes_done_; 156 (*cinfo->progress->progress_monitor)(reinterpret_cast<j_common_ptr>(cinfo)); 157 } 158 159 void BuildHuffmanLookupTable(j_decompress_ptr cinfo, JHUFF_TBL* table, 160 HuffmanTableEntry* huff_lut) { 161 uint32_t counts[kJpegHuffmanMaxBitLength + 1] = {}; 162 counts[0] = 0; 163 int total_count = 0; 164 int space = 1 << kJpegHuffmanMaxBitLength; 165 int max_depth = 1; 166 for (size_t i = 1; i <= kJpegHuffmanMaxBitLength; ++i) { 167 int count = table->bits[i]; 168 if (count != 0) { 169 max_depth = i; 170 } 171 counts[i] = count; 172 total_count += count; 173 space -= count * (1 << (kJpegHuffmanMaxBitLength - i)); 174 } 175 uint32_t values[kJpegHuffmanAlphabetSize + 1] = {}; 176 uint8_t values_seen[256] = {0}; 177 for (int i = 0; i < total_count; ++i) { 178 int value = table->huffval[i]; 179 if (values_seen[value]) { 180 return JPEGLI_ERROR("Duplicate Huffman code value %d", value); 181 } 182 values_seen[value] = 1; 183 values[i] = value; 184 } 185 // Add an invalid symbol that will have the all 1 code. 186 ++counts[max_depth]; 187 values[total_count] = kJpegHuffmanAlphabetSize; 188 space -= (1 << (kJpegHuffmanMaxBitLength - max_depth)); 189 if (space < 0) { 190 JPEGLI_ERROR("Invalid Huffman code lengths."); 191 } else if (space > 0 && huff_lut[0].value != 0xffff) { 192 // Re-initialize the values to an invalid symbol so that we can recognize 193 // it when reading the bit stream using a Huffman code with space > 0. 194 for (int i = 0; i < kJpegHuffmanLutSize; ++i) { 195 huff_lut[i].bits = 0; 196 huff_lut[i].value = 0xffff; 197 } 198 } 199 BuildJpegHuffmanTable(&counts[0], &values[0], huff_lut); 200 } 201 202 void PrepareForScan(j_decompress_ptr cinfo) { 203 jpeg_decomp_master* m = cinfo->master; 204 for (int i = 0; i < cinfo->comps_in_scan; ++i) { 205 int comp_idx = cinfo->cur_comp_info[i]->component_index; 206 int* prev_coef_bits = cinfo->coef_bits[comp_idx + cinfo->num_components]; 207 for (int k = std::min(cinfo->Ss, 1); k <= std::max(cinfo->Se, 9); k++) { 208 prev_coef_bits[k] = 209 (cinfo->input_scan_number > 0) ? cinfo->coef_bits[comp_idx][k] : 0; 210 } 211 for (int k = cinfo->Ss; k <= cinfo->Se; ++k) { 212 cinfo->coef_bits[comp_idx][k] = cinfo->Al; 213 } 214 } 215 AddStandardHuffmanTables(reinterpret_cast<j_common_ptr>(cinfo), 216 /*is_dc=*/false); 217 AddStandardHuffmanTables(reinterpret_cast<j_common_ptr>(cinfo), 218 /*is_dc=*/true); 219 // Check that all the Huffman tables needed for this scan are defined and 220 // build derived lookup tables. 221 for (int i = 0; i < cinfo->comps_in_scan; ++i) { 222 if (cinfo->Ss == 0) { 223 int dc_tbl_idx = cinfo->cur_comp_info[i]->dc_tbl_no; 224 JHUFF_TBL* table = cinfo->dc_huff_tbl_ptrs[dc_tbl_idx]; 225 HuffmanTableEntry* huff_lut = 226 &m->dc_huff_lut_[dc_tbl_idx * kJpegHuffmanLutSize]; 227 if (!table) { 228 return JPEGLI_ERROR("DC Huffman table %d not found", dc_tbl_idx); 229 } 230 BuildHuffmanLookupTable(cinfo, table, huff_lut); 231 } 232 if (cinfo->Se > 0) { 233 int ac_tbl_idx = cinfo->cur_comp_info[i]->ac_tbl_no; 234 JHUFF_TBL* table = cinfo->ac_huff_tbl_ptrs[ac_tbl_idx]; 235 HuffmanTableEntry* huff_lut = 236 &m->ac_huff_lut_[ac_tbl_idx * kJpegHuffmanLutSize]; 237 if (!table) { 238 return JPEGLI_ERROR("AC Huffman table %d not found", ac_tbl_idx); 239 } 240 BuildHuffmanLookupTable(cinfo, table, huff_lut); 241 } 242 } 243 // Copy quantization tables into comp_info. 244 for (int i = 0; i < cinfo->comps_in_scan; ++i) { 245 jpeg_component_info* comp = cinfo->cur_comp_info[i]; 246 if (comp->quant_table == nullptr) { 247 comp->quant_table = Allocate<JQUANT_TBL>(cinfo, 1, JPOOL_IMAGE); 248 memcpy(comp->quant_table, cinfo->quant_tbl_ptrs[comp->quant_tbl_no], 249 sizeof(JQUANT_TBL)); 250 } 251 } 252 if (cinfo->comps_in_scan == 1) { 253 const auto& comp = *cinfo->cur_comp_info[0]; 254 cinfo->MCUs_per_row = DivCeil(cinfo->image_width * comp.h_samp_factor, 255 cinfo->max_h_samp_factor * DCTSIZE); 256 cinfo->MCU_rows_in_scan = DivCeil(cinfo->image_height * comp.v_samp_factor, 257 cinfo->max_v_samp_factor * DCTSIZE); 258 m->mcu_rows_per_iMCU_row_ = cinfo->cur_comp_info[0]->v_samp_factor; 259 } else { 260 cinfo->MCU_rows_in_scan = cinfo->total_iMCU_rows; 261 cinfo->MCUs_per_row = m->iMCU_cols_; 262 m->mcu_rows_per_iMCU_row_ = 1; 263 size_t mcu_size = 0; 264 for (int i = 0; i < cinfo->comps_in_scan; ++i) { 265 jpeg_component_info* comp = cinfo->cur_comp_info[i]; 266 mcu_size += comp->h_samp_factor * comp->v_samp_factor; 267 } 268 if (mcu_size > D_MAX_BLOCKS_IN_MCU) { 269 JPEGLI_ERROR("MCU size too big"); 270 } 271 } 272 memset(m->last_dc_coeff_, 0, sizeof(m->last_dc_coeff_)); 273 m->restarts_to_go_ = cinfo->restart_interval; 274 m->next_restart_marker_ = 0; 275 m->eobrun_ = -1; 276 m->scan_mcu_row_ = 0; 277 m->scan_mcu_col_ = 0; 278 m->codestream_bits_ahead_ = 0; 279 ++cinfo->input_scan_number; 280 cinfo->input_iMCU_row = 0; 281 PrepareForiMCURow(cinfo); 282 cinfo->global_state = kDecProcessScan; 283 } 284 285 int ConsumeInput(j_decompress_ptr cinfo) { 286 jpeg_decomp_master* m = cinfo->master; 287 if (cinfo->global_state == kDecProcessScan && m->streaming_mode_ && 288 cinfo->input_iMCU_row > cinfo->output_iMCU_row) { 289 // Prevent input from getting ahead of output in streaming mode. 290 return JPEG_SUSPENDED; 291 } 292 jpeg_source_mgr* src = cinfo->src; 293 int status; 294 for (;;) { 295 const uint8_t* data; 296 size_t len; 297 if (m->input_buffer_.empty()) { 298 data = cinfo->src->next_input_byte; 299 len = cinfo->src->bytes_in_buffer; 300 } else { 301 data = &m->input_buffer_[m->input_buffer_pos_]; 302 len = m->input_buffer_.size() - m->input_buffer_pos_; 303 } 304 size_t pos = 0; 305 if (cinfo->global_state == kDecProcessScan) { 306 status = ProcessScan(cinfo, data, len, &pos, &m->codestream_bits_ahead_); 307 } else { 308 status = ProcessMarkers(cinfo, data, len, &pos); 309 } 310 if (m->input_buffer_.empty()) { 311 cinfo->src->next_input_byte += pos; 312 cinfo->src->bytes_in_buffer -= pos; 313 } else { 314 m->input_buffer_pos_ += pos; 315 size_t bytes_left = m->input_buffer_.size() - m->input_buffer_pos_; 316 if (bytes_left <= src->bytes_in_buffer) { 317 src->next_input_byte += (src->bytes_in_buffer - bytes_left); 318 src->bytes_in_buffer = bytes_left; 319 m->input_buffer_.clear(); 320 m->input_buffer_pos_ = 0; 321 } 322 } 323 if (status == kHandleRestart) { 324 JXL_DASSERT(m->input_buffer_.size() <= 325 m->input_buffer_pos_ + src->bytes_in_buffer); 326 m->input_buffer_.clear(); 327 m->input_buffer_pos_ = 0; 328 if (cinfo->unread_marker == 0xd0 + m->next_restart_marker_) { 329 cinfo->unread_marker = 0; 330 } else { 331 if (!(*cinfo->src->resync_to_restart)(cinfo, m->next_restart_marker_)) { 332 return JPEG_SUSPENDED; 333 } 334 } 335 m->next_restart_marker_ += 1; 336 m->next_restart_marker_ &= 0x7; 337 m->restarts_to_go_ = cinfo->restart_interval; 338 if (cinfo->unread_marker != 0) { 339 JPEGLI_WARN("Failed to resync to next restart marker, skipping scan."); 340 return JPEG_SCAN_COMPLETED; 341 } 342 continue; 343 } 344 if (status == kHandleMarkerProcessor) { 345 JXL_DASSERT(m->input_buffer_.size() <= 346 m->input_buffer_pos_ + src->bytes_in_buffer); 347 m->input_buffer_.clear(); 348 m->input_buffer_pos_ = 0; 349 if (!(*GetMarkerProcessor(cinfo))(cinfo)) { 350 return JPEG_SUSPENDED; 351 } 352 cinfo->unread_marker = 0; 353 continue; 354 } 355 if (status != kNeedMoreInput) { 356 break; 357 } 358 if (m->input_buffer_.empty()) { 359 JXL_DASSERT(m->input_buffer_pos_ == 0); 360 m->input_buffer_.assign(src->next_input_byte, 361 src->next_input_byte + src->bytes_in_buffer); 362 } 363 if (!(*cinfo->src->fill_input_buffer)(cinfo)) { 364 m->input_buffer_.clear(); 365 m->input_buffer_pos_ = 0; 366 return JPEG_SUSPENDED; 367 } 368 if (src->bytes_in_buffer == 0) { 369 JPEGLI_ERROR("Empty input."); 370 } 371 m->input_buffer_.insert(m->input_buffer_.end(), src->next_input_byte, 372 src->next_input_byte + src->bytes_in_buffer); 373 } 374 if (status == JPEG_SCAN_COMPLETED) { 375 cinfo->global_state = kDecProcessMarkers; 376 } else if (status == JPEG_REACHED_SOS) { 377 if (cinfo->global_state == kDecInHeader) { 378 cinfo->global_state = kDecHeaderDone; 379 } else { 380 PrepareForScan(cinfo); 381 } 382 } 383 return status; 384 } 385 386 bool IsInputReady(j_decompress_ptr cinfo) { 387 if (cinfo->master->found_eoi_) { 388 return true; 389 } 390 if (cinfo->input_scan_number > cinfo->output_scan_number) { 391 return true; 392 } 393 if (cinfo->input_scan_number < cinfo->output_scan_number) { 394 return false; 395 } 396 if (cinfo->input_iMCU_row == cinfo->total_iMCU_rows) { 397 return true; 398 } 399 return cinfo->input_iMCU_row > 400 cinfo->output_iMCU_row + (cinfo->master->streaming_mode_ ? 0 : 2); 401 } 402 403 bool ReadOutputPass(j_decompress_ptr cinfo) { 404 jpeg_decomp_master* m = cinfo->master; 405 if (!m->pixels_) { 406 size_t stride = cinfo->out_color_components * cinfo->output_width; 407 size_t num_samples = cinfo->output_height * stride; 408 m->pixels_ = Allocate<uint8_t>(cinfo, num_samples, JPOOL_IMAGE); 409 m->scanlines_ = 410 Allocate<JSAMPROW>(cinfo, cinfo->output_height, JPOOL_IMAGE); 411 for (size_t i = 0; i < cinfo->output_height; ++i) { 412 m->scanlines_[i] = &m->pixels_[i * stride]; 413 } 414 } 415 size_t num_output_rows = 0; 416 while (num_output_rows < cinfo->output_height) { 417 if (IsInputReady(cinfo)) { 418 ProgressMonitorOutputPass(cinfo); 419 ProcessOutput(cinfo, &num_output_rows, m->scanlines_, 420 cinfo->output_height); 421 } else if (ConsumeInput(cinfo) == JPEG_SUSPENDED) { 422 return false; 423 } 424 } 425 cinfo->output_scanline = 0; 426 cinfo->output_iMCU_row = 0; 427 return true; 428 } 429 430 boolean PrepareQuantizedOutput(j_decompress_ptr cinfo) { 431 jpeg_decomp_master* m = cinfo->master; 432 if (cinfo->raw_data_out) { 433 JPEGLI_ERROR("Color quantization is not supported in raw data mode."); 434 } 435 if (m->output_data_type_ != JPEGLI_TYPE_UINT8) { 436 JPEGLI_ERROR("Color quantization must use 8-bit mode."); 437 } 438 if (cinfo->colormap) { 439 m->quant_mode_ = 3; 440 } else if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) { 441 m->quant_mode_ = 2; 442 } else if (cinfo->enable_1pass_quant) { 443 m->quant_mode_ = 1; 444 } else { 445 JPEGLI_ERROR("Invalid quantization mode change"); 446 } 447 if (m->quant_mode_ > 1 && cinfo->dither_mode == JDITHER_ORDERED) { 448 cinfo->dither_mode = JDITHER_FS; 449 } 450 if (m->quant_mode_ == 1) { 451 ChooseColorMap1Pass(cinfo); 452 } else if (m->quant_mode_ == 2) { 453 m->quant_pass_ = 0; 454 if (!ReadOutputPass(cinfo)) { 455 return FALSE; 456 } 457 ChooseColorMap2Pass(cinfo); 458 } 459 if (m->quant_mode_ == 2 || 460 (m->quant_mode_ == 3 && m->regenerate_inverse_colormap_)) { 461 CreateInverseColorMap(cinfo); 462 } 463 if (cinfo->dither_mode == JDITHER_ORDERED) { 464 CreateOrderedDitherTables(cinfo); 465 } else if (cinfo->dither_mode == JDITHER_FS) { 466 InitFSDitherState(cinfo); 467 } 468 m->quant_pass_ = 1; 469 return TRUE; 470 } 471 472 void AllocateCoefficientBuffer(j_decompress_ptr cinfo) { 473 jpeg_decomp_master* m = cinfo->master; 474 j_common_ptr comptr = reinterpret_cast<j_common_ptr>(cinfo); 475 jvirt_barray_ptr* coef_arrays = jpegli::Allocate<jvirt_barray_ptr>( 476 cinfo, cinfo->num_components, JPOOL_IMAGE); 477 for (int c = 0; c < cinfo->num_components; ++c) { 478 jpeg_component_info* comp = &cinfo->comp_info[c]; 479 size_t height_in_blocks = 480 m->streaming_mode_ ? comp->v_samp_factor : comp->height_in_blocks; 481 coef_arrays[c] = (*cinfo->mem->request_virt_barray)( 482 comptr, JPOOL_IMAGE, TRUE, comp->width_in_blocks, height_in_blocks, 483 comp->v_samp_factor); 484 } 485 cinfo->master->coef_arrays = coef_arrays; 486 (*cinfo->mem->realize_virt_arrays)(comptr); 487 } 488 489 void AllocateOutputBuffers(j_decompress_ptr cinfo) { 490 jpeg_decomp_master* m = cinfo->master; 491 size_t iMCU_width = cinfo->max_h_samp_factor * m->min_scaled_dct_size; 492 size_t output_stride = m->iMCU_cols_ * iMCU_width; 493 m->need_context_rows_ = false; 494 for (int c = 0; c < cinfo->num_components; ++c) { 495 if (cinfo->do_fancy_upsampling && m->v_factor[c] == 2) { 496 m->need_context_rows_ = true; 497 } 498 } 499 for (int c = 0; c < cinfo->num_components; ++c) { 500 const auto& comp = cinfo->comp_info[c]; 501 size_t cheight = comp.v_samp_factor * m->scaled_dct_size[c]; 502 int downsampled_width = output_stride / m->h_factor[c]; 503 m->raw_height_[c] = cinfo->total_iMCU_rows * cheight; 504 if (m->need_context_rows_) { 505 cheight *= 3; 506 } 507 m->raw_output_[c].Allocate(cinfo, cheight, downsampled_width); 508 } 509 int num_all_components = 510 std::max(cinfo->out_color_components, cinfo->num_components); 511 for (int c = 0; c < num_all_components; ++c) { 512 m->render_output_[c].Allocate(cinfo, cinfo->max_v_samp_factor, 513 output_stride); 514 } 515 m->idct_scratch_ = Allocate<float>(cinfo, 5 * DCTSIZE2, JPOOL_IMAGE_ALIGNED); 516 // Padding for horizontal chroma upsampling. 517 constexpr size_t kPaddingLeft = 64; 518 constexpr size_t kPaddingRight = 64; 519 m->upsample_scratch_ = Allocate<float>( 520 cinfo, output_stride + kPaddingLeft + kPaddingRight, JPOOL_IMAGE_ALIGNED); 521 size_t bytes_per_sample = jpegli_bytes_per_sample(m->output_data_type_); 522 size_t bytes_per_pixel = cinfo->out_color_components * bytes_per_sample; 523 size_t scratch_stride = RoundUpTo(output_stride, HWY_ALIGNMENT); 524 m->output_scratch_ = Allocate<uint8_t>( 525 cinfo, bytes_per_pixel * scratch_stride, JPOOL_IMAGE_ALIGNED); 526 m->smoothing_scratch_ = 527 Allocate<int16_t>(cinfo, DCTSIZE2, JPOOL_IMAGE_ALIGNED); 528 size_t coeffs_per_block = cinfo->num_components * DCTSIZE2; 529 m->nonzeros_ = Allocate<int>(cinfo, coeffs_per_block, JPOOL_IMAGE_ALIGNED); 530 m->sumabs_ = Allocate<int>(cinfo, coeffs_per_block, JPOOL_IMAGE_ALIGNED); 531 m->biases_ = Allocate<float>(cinfo, coeffs_per_block, JPOOL_IMAGE_ALIGNED); 532 m->dequant_ = Allocate<float>(cinfo, coeffs_per_block, JPOOL_IMAGE_ALIGNED); 533 memset(m->dequant_, 0, coeffs_per_block * sizeof(float)); 534 } 535 536 } // namespace jpegli 537 538 void jpegli_CreateDecompress(j_decompress_ptr cinfo, int version, 539 size_t structsize) { 540 cinfo->mem = nullptr; 541 if (structsize != sizeof(*cinfo)) { 542 JPEGLI_ERROR("jpeg_decompress_struct has wrong size."); 543 } 544 jpegli::InitMemoryManager(reinterpret_cast<j_common_ptr>(cinfo)); 545 cinfo->is_decompressor = TRUE; 546 cinfo->progress = nullptr; 547 cinfo->src = nullptr; 548 for (auto& quant_tbl_ptr : cinfo->quant_tbl_ptrs) { 549 quant_tbl_ptr = nullptr; 550 } 551 for (int i = 0; i < NUM_HUFF_TBLS; i++) { 552 cinfo->dc_huff_tbl_ptrs[i] = nullptr; 553 cinfo->ac_huff_tbl_ptrs[i] = nullptr; 554 } 555 cinfo->global_state = jpegli::kDecStart; 556 cinfo->sample_range_limit = nullptr; // not used 557 cinfo->rec_outbuf_height = 1; // output works with any buffer height 558 cinfo->master = new jpeg_decomp_master; 559 jpeg_decomp_master* m = cinfo->master; 560 for (auto& app_marker_parser : m->app_marker_parsers) { 561 app_marker_parser = nullptr; 562 } 563 m->com_marker_parser = nullptr; 564 memset(m->markers_to_save_, 0, sizeof(m->markers_to_save_)); 565 jpegli::InitializeDecompressParams(cinfo); 566 jpegli::InitializeImage(cinfo); 567 } 568 569 void jpegli_destroy_decompress(j_decompress_ptr cinfo) { 570 jpegli_destroy(reinterpret_cast<j_common_ptr>(cinfo)); 571 } 572 573 void jpegli_abort_decompress(j_decompress_ptr cinfo) { 574 jpegli_abort(reinterpret_cast<j_common_ptr>(cinfo)); 575 } 576 577 void jpegli_save_markers(j_decompress_ptr cinfo, int marker_code, 578 unsigned int length_limit) { 579 // TODO(szabadka) Limit our memory usage by taking into account length_limit. 580 jpeg_decomp_master* m = cinfo->master; 581 if (marker_code < 0xe0) { 582 JPEGLI_ERROR("jpegli_save_markers: invalid marker code %d", marker_code); 583 } 584 m->markers_to_save_[marker_code - 0xe0] = 1; 585 } 586 587 void jpegli_set_marker_processor(j_decompress_ptr cinfo, int marker_code, 588 jpeg_marker_parser_method routine) { 589 jpeg_decomp_master* m = cinfo->master; 590 if (marker_code == 0xfe) { 591 m->com_marker_parser = routine; 592 } else if (marker_code >= 0xe0 && marker_code <= 0xef) { 593 m->app_marker_parsers[marker_code - 0xe0] = routine; 594 } else { 595 JPEGLI_ERROR("jpegli_set_marker_processor: invalid marker code %d", 596 marker_code); 597 } 598 } 599 600 int jpegli_consume_input(j_decompress_ptr cinfo) { 601 if (cinfo->global_state == jpegli::kDecStart) { 602 (*cinfo->err->reset_error_mgr)(reinterpret_cast<j_common_ptr>(cinfo)); 603 (*cinfo->src->init_source)(cinfo); 604 jpegli::InitializeDecompressParams(cinfo); 605 jpegli::InitializeImage(cinfo); 606 cinfo->global_state = jpegli::kDecInHeader; 607 } 608 if (cinfo->global_state == jpegli::kDecHeaderDone) { 609 return JPEG_REACHED_SOS; 610 } 611 if (cinfo->master->found_eoi_) { 612 return JPEG_REACHED_EOI; 613 } 614 if (cinfo->global_state == jpegli::kDecInHeader || 615 cinfo->global_state == jpegli::kDecProcessMarkers || 616 cinfo->global_state == jpegli::kDecProcessScan) { 617 return jpegli::ConsumeInput(cinfo); 618 } 619 JPEGLI_ERROR("Unexpected state %d", cinfo->global_state); 620 return JPEG_REACHED_EOI; // return value does not matter 621 } 622 623 int jpegli_read_header(j_decompress_ptr cinfo, boolean require_image) { 624 if (cinfo->global_state != jpegli::kDecStart && 625 cinfo->global_state != jpegli::kDecInHeader) { 626 JPEGLI_ERROR("jpegli_read_header: unexpected state %d", 627 cinfo->global_state); 628 } 629 if (cinfo->src == nullptr) { 630 JPEGLI_ERROR("Missing source."); 631 } 632 for (;;) { 633 int retcode = jpegli_consume_input(cinfo); 634 if (retcode == JPEG_SUSPENDED) { 635 return retcode; 636 } else if (retcode == JPEG_REACHED_SOS) { 637 break; 638 } else if (retcode == JPEG_REACHED_EOI) { 639 if (require_image) { 640 JPEGLI_ERROR("jpegli_read_header: unexpected EOI marker."); 641 } 642 jpegli_abort_decompress(cinfo); 643 return JPEG_HEADER_TABLES_ONLY; 644 } 645 }; 646 return JPEG_HEADER_OK; 647 } 648 649 boolean jpegli_read_icc_profile(j_decompress_ptr cinfo, JOCTET** icc_data_ptr, 650 unsigned int* icc_data_len) { 651 if (cinfo->global_state == jpegli::kDecStart || 652 cinfo->global_state == jpegli::kDecInHeader) { 653 JPEGLI_ERROR("jpegli_read_icc_profile: unexpected state %d", 654 cinfo->global_state); 655 } 656 if (icc_data_ptr == nullptr || icc_data_len == nullptr) { 657 JPEGLI_ERROR("jpegli_read_icc_profile: invalid output buffer"); 658 } 659 jpeg_decomp_master* m = cinfo->master; 660 if (m->icc_profile_.empty()) { 661 *icc_data_ptr = nullptr; 662 *icc_data_len = 0; 663 return FALSE; 664 } 665 *icc_data_len = m->icc_profile_.size(); 666 *icc_data_ptr = static_cast<JOCTET*>(malloc(*icc_data_len)); 667 if (*icc_data_ptr == nullptr) { 668 JPEGLI_ERROR("jpegli_read_icc_profile: Out of memory"); 669 } 670 memcpy(*icc_data_ptr, m->icc_profile_.data(), *icc_data_len); 671 return TRUE; 672 } 673 674 void jpegli_core_output_dimensions(j_decompress_ptr cinfo) { 675 jpeg_decomp_master* m = cinfo->master; 676 if (!m->found_sof_) { 677 JPEGLI_ERROR("No SOF marker found."); 678 } 679 if (cinfo->raw_data_out) { 680 if (cinfo->scale_num != 1 || cinfo->scale_denom != 1) { 681 JPEGLI_ERROR("Output scaling is not supported in raw output mode"); 682 } 683 } 684 if (cinfo->scale_num != 1 || cinfo->scale_denom != 1) { 685 int dctsize = 16; 686 while (cinfo->scale_num * DCTSIZE <= cinfo->scale_denom * (dctsize - 1)) { 687 --dctsize; 688 } 689 m->min_scaled_dct_size = dctsize; 690 cinfo->output_width = 691 jpegli::DivCeil(cinfo->image_width * dctsize, DCTSIZE); 692 cinfo->output_height = 693 jpegli::DivCeil(cinfo->image_height * dctsize, DCTSIZE); 694 for (int c = 0; c < cinfo->num_components; ++c) { 695 m->scaled_dct_size[c] = m->min_scaled_dct_size; 696 } 697 } else { 698 cinfo->output_width = cinfo->image_width; 699 cinfo->output_height = cinfo->image_height; 700 m->min_scaled_dct_size = DCTSIZE; 701 for (int c = 0; c < cinfo->num_components; ++c) { 702 m->scaled_dct_size[c] = DCTSIZE; 703 } 704 } 705 } 706 707 void jpegli_calc_output_dimensions(j_decompress_ptr cinfo) { 708 jpeg_decomp_master* m = cinfo->master; 709 jpegli_core_output_dimensions(cinfo); 710 for (int c = 0; c < cinfo->num_components; ++c) { 711 jpeg_component_info* comp = &cinfo->comp_info[c]; 712 m->h_factor[c] = cinfo->max_h_samp_factor / comp->h_samp_factor; 713 m->v_factor[c] = cinfo->max_v_samp_factor / comp->v_samp_factor; 714 } 715 if (cinfo->scale_num != 1 || cinfo->scale_denom != 1) { 716 for (int c = 0; c < cinfo->num_components; ++c) { 717 // Prefer IDCT scaling over 2x upsampling. 718 while (m->scaled_dct_size[c] < DCTSIZE && (m->v_factor[c] % 2) == 0 && 719 (m->h_factor[c] % 2) == 0) { 720 m->scaled_dct_size[c] *= 2; 721 m->v_factor[c] /= 2; 722 m->h_factor[c] /= 2; 723 } 724 } 725 } 726 if (cinfo->out_color_space == JCS_GRAYSCALE) { 727 cinfo->out_color_components = 1; 728 } else if (cinfo->out_color_space == JCS_RGB || 729 cinfo->out_color_space == JCS_YCbCr) { 730 cinfo->out_color_components = 3; 731 } else if (cinfo->out_color_space == JCS_CMYK || 732 cinfo->out_color_space == JCS_YCCK) { 733 cinfo->out_color_components = 4; 734 } else { 735 cinfo->out_color_components = cinfo->num_components; 736 } 737 cinfo->output_components = 738 cinfo->quantize_colors ? 1 : cinfo->out_color_components; 739 cinfo->rec_outbuf_height = 1; 740 } 741 742 boolean jpegli_has_multiple_scans(j_decompress_ptr cinfo) { 743 if (cinfo->input_scan_number == 0) { 744 JPEGLI_ERROR("No SOS marker found."); 745 } 746 return TO_JXL_BOOL(cinfo->master->is_multiscan_); 747 } 748 749 boolean jpegli_input_complete(j_decompress_ptr cinfo) { 750 return TO_JXL_BOOL(cinfo->master->found_eoi_); 751 } 752 753 boolean jpegli_start_decompress(j_decompress_ptr cinfo) { 754 jpeg_decomp_master* m = cinfo->master; 755 if (cinfo->global_state == jpegli::kDecHeaderDone) { 756 m->streaming_mode_ = !m->is_multiscan_ && 757 !FROM_JXL_BOOL(cinfo->buffered_image) && 758 (!FROM_JXL_BOOL(cinfo->quantize_colors) || 759 !FROM_JXL_BOOL(cinfo->two_pass_quantize)); 760 jpegli::AllocateCoefficientBuffer(cinfo); 761 jpegli_calc_output_dimensions(cinfo); 762 jpegli::PrepareForScan(cinfo); 763 if (cinfo->quantize_colors) { 764 if (cinfo->colormap != nullptr) { 765 cinfo->enable_external_quant = TRUE; 766 } else if (cinfo->two_pass_quantize && 767 cinfo->out_color_space == JCS_RGB) { 768 cinfo->enable_2pass_quant = TRUE; 769 } else { 770 cinfo->enable_1pass_quant = TRUE; 771 } 772 } 773 jpegli::InitProgressMonitor(cinfo, /*coef_only=*/false); 774 jpegli::AllocateOutputBuffers(cinfo); 775 if (cinfo->buffered_image == TRUE) { 776 cinfo->output_scan_number = 0; 777 return TRUE; 778 } 779 } else if (!m->is_multiscan_) { 780 JPEGLI_ERROR("jpegli_start_decompress: unexpected state %d", 781 cinfo->global_state); 782 } 783 if (m->is_multiscan_) { 784 if (cinfo->global_state != jpegli::kDecProcessScan && 785 cinfo->global_state != jpegli::kDecProcessMarkers) { 786 JPEGLI_ERROR("jpegli_start_decompress: unexpected state %d", 787 cinfo->global_state); 788 } 789 while (!m->found_eoi_) { 790 jpegli::ProgressMonitorInputPass(cinfo); 791 if (jpegli::ConsumeInput(cinfo) == JPEG_SUSPENDED) { 792 return FALSE; 793 } 794 } 795 } 796 cinfo->output_scan_number = cinfo->input_scan_number; 797 jpegli::PrepareForOutput(cinfo); 798 if (cinfo->quantize_colors) { 799 return jpegli::PrepareQuantizedOutput(cinfo); 800 } else { 801 return TRUE; 802 } 803 } 804 805 boolean jpegli_start_output(j_decompress_ptr cinfo, int scan_number) { 806 jpeg_decomp_master* m = cinfo->master; 807 if (!cinfo->buffered_image) { 808 JPEGLI_ERROR("jpegli_start_output: buffered image mode was not set"); 809 } 810 if (cinfo->global_state != jpegli::kDecProcessScan && 811 cinfo->global_state != jpegli::kDecProcessMarkers) { 812 JPEGLI_ERROR("jpegli_start_output: unexpected state %d", 813 cinfo->global_state); 814 } 815 cinfo->output_scan_number = std::max(1, scan_number); 816 if (m->found_eoi_) { 817 cinfo->output_scan_number = 818 std::min(cinfo->output_scan_number, cinfo->input_scan_number); 819 } 820 jpegli::InitProgressMonitorForOutput(cinfo); 821 jpegli::PrepareForOutput(cinfo); 822 if (cinfo->quantize_colors) { 823 return jpegli::PrepareQuantizedOutput(cinfo); 824 } else { 825 return TRUE; 826 } 827 } 828 829 boolean jpegli_finish_output(j_decompress_ptr cinfo) { 830 if (!cinfo->buffered_image) { 831 JPEGLI_ERROR("jpegli_finish_output: buffered image mode was not set"); 832 } 833 if (cinfo->global_state != jpegli::kDecProcessScan && 834 cinfo->global_state != jpegli::kDecProcessMarkers) { 835 JPEGLI_ERROR("jpegli_finish_output: unexpected state %d", 836 cinfo->global_state); 837 } 838 // Advance input to the start of the next scan, or to the end of input. 839 while (cinfo->input_scan_number <= cinfo->output_scan_number && 840 !cinfo->master->found_eoi_) { 841 if (jpegli::ConsumeInput(cinfo) == JPEG_SUSPENDED) { 842 return FALSE; 843 } 844 } 845 return TRUE; 846 } 847 848 JDIMENSION jpegli_read_scanlines(j_decompress_ptr cinfo, JSAMPARRAY scanlines, 849 JDIMENSION max_lines) { 850 jpeg_decomp_master* m = cinfo->master; 851 if (cinfo->global_state != jpegli::kDecProcessScan && 852 cinfo->global_state != jpegli::kDecProcessMarkers) { 853 JPEGLI_ERROR("jpegli_read_scanlines: unexpected state %d", 854 cinfo->global_state); 855 } 856 if (cinfo->buffered_image) { 857 if (cinfo->output_scan_number == 0) { 858 JPEGLI_ERROR( 859 "jpegli_read_scanlines: " 860 "jpegli_start_output() was not called"); 861 } 862 } else if (m->is_multiscan_ && !m->found_eoi_) { 863 JPEGLI_ERROR( 864 "jpegli_read_scanlines: " 865 "jpegli_start_decompress() did not finish"); 866 } 867 if (cinfo->output_scanline + max_lines > cinfo->output_height) { 868 max_lines = cinfo->output_height - cinfo->output_scanline; 869 } 870 jpegli::ProgressMonitorOutputPass(cinfo); 871 size_t num_output_rows = 0; 872 while (num_output_rows < max_lines) { 873 if (jpegli::IsInputReady(cinfo)) { 874 jpegli::ProcessOutput(cinfo, &num_output_rows, scanlines, max_lines); 875 } else if (jpegli::ConsumeInput(cinfo) == JPEG_SUSPENDED) { 876 break; 877 } 878 } 879 return num_output_rows; 880 } 881 882 JDIMENSION jpegli_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) { 883 // TODO(szabadka) Skip the IDCT for skipped over blocks. 884 return jpegli_read_scanlines(cinfo, nullptr, num_lines); 885 } 886 887 void jpegli_crop_scanline(j_decompress_ptr cinfo, JDIMENSION* xoffset, 888 JDIMENSION* width) { 889 jpeg_decomp_master* m = cinfo->master; 890 if ((cinfo->global_state != jpegli::kDecProcessScan && 891 cinfo->global_state != jpegli::kDecProcessMarkers) || 892 cinfo->output_scanline != 0) { 893 JPEGLI_ERROR("jpegli_crop_decompress: unexpected state %d", 894 cinfo->global_state); 895 } 896 if (cinfo->raw_data_out) { 897 JPEGLI_ERROR("Output cropping is not supported in raw data mode"); 898 } 899 if (xoffset == nullptr || width == nullptr || *width == 0 || 900 *xoffset + *width > cinfo->output_width) { 901 JPEGLI_ERROR("jpegli_crop_scanline: Invalid arguments"); 902 } 903 // TODO(szabadka) Skip the IDCT for skipped over blocks. 904 size_t xend = *xoffset + *width; 905 size_t iMCU_width = m->min_scaled_dct_size * cinfo->max_h_samp_factor; 906 *xoffset = (*xoffset / iMCU_width) * iMCU_width; 907 *width = xend - *xoffset; 908 cinfo->master->xoffset_ = *xoffset; 909 cinfo->output_width = *width; 910 } 911 912 JDIMENSION jpegli_read_raw_data(j_decompress_ptr cinfo, JSAMPIMAGE data, 913 JDIMENSION max_lines) { 914 if ((cinfo->global_state != jpegli::kDecProcessScan && 915 cinfo->global_state != jpegli::kDecProcessMarkers) || 916 !cinfo->raw_data_out) { 917 JPEGLI_ERROR("jpegli_read_raw_data: unexpected state %d", 918 cinfo->global_state); 919 } 920 size_t iMCU_height = cinfo->max_v_samp_factor * DCTSIZE; 921 if (max_lines < iMCU_height) { 922 JPEGLI_ERROR("jpegli_read_raw_data: output buffer too small"); 923 } 924 jpegli::ProgressMonitorOutputPass(cinfo); 925 while (!jpegli::IsInputReady(cinfo)) { 926 if (jpegli::ConsumeInput(cinfo) == JPEG_SUSPENDED) { 927 return 0; 928 } 929 } 930 if (cinfo->output_iMCU_row < cinfo->total_iMCU_rows) { 931 jpegli::ProcessRawOutput(cinfo, data); 932 return iMCU_height; 933 } 934 return 0; 935 } 936 937 jvirt_barray_ptr* jpegli_read_coefficients(j_decompress_ptr cinfo) { 938 jpeg_decomp_master* m = cinfo->master; 939 m->streaming_mode_ = false; 940 if (!cinfo->buffered_image && cinfo->global_state == jpegli::kDecHeaderDone) { 941 jpegli::AllocateCoefficientBuffer(cinfo); 942 jpegli_calc_output_dimensions(cinfo); 943 jpegli::InitProgressMonitor(cinfo, /*coef_only=*/true); 944 jpegli::PrepareForScan(cinfo); 945 } 946 if (cinfo->global_state != jpegli::kDecProcessScan && 947 cinfo->global_state != jpegli::kDecProcessMarkers) { 948 JPEGLI_ERROR("jpegli_read_coefficients: unexpected state %d", 949 cinfo->global_state); 950 } 951 if (!cinfo->buffered_image) { 952 while (!m->found_eoi_) { 953 jpegli::ProgressMonitorInputPass(cinfo); 954 if (jpegli::ConsumeInput(cinfo) == JPEG_SUSPENDED) { 955 return nullptr; 956 } 957 } 958 cinfo->output_scanline = cinfo->output_height; 959 } 960 return m->coef_arrays; 961 } 962 963 boolean jpegli_finish_decompress(j_decompress_ptr cinfo) { 964 if (cinfo->global_state != jpegli::kDecProcessScan && 965 cinfo->global_state != jpegli::kDecProcessMarkers) { 966 JPEGLI_ERROR("jpegli_finish_decompress: unexpected state %d", 967 cinfo->global_state); 968 } 969 if (!cinfo->buffered_image && cinfo->output_scanline < cinfo->output_height) { 970 JPEGLI_ERROR("Incomplete output"); 971 } 972 while (!cinfo->master->found_eoi_) { 973 if (jpegli::ConsumeInput(cinfo) == JPEG_SUSPENDED) { 974 return FALSE; 975 } 976 } 977 (*cinfo->src->term_source)(cinfo); 978 jpegli_abort_decompress(cinfo); 979 return TRUE; 980 } 981 982 boolean jpegli_resync_to_restart(j_decompress_ptr cinfo, int desired) { 983 JPEGLI_WARN("Invalid restart marker found: 0x%02x vs 0x%02x.", 984 cinfo->unread_marker, 0xd0 + desired); 985 // This is a trivial implementation, we just let the decoder skip the entire 986 // scan and attempt to render the partial input. 987 return TRUE; 988 } 989 990 void jpegli_new_colormap(j_decompress_ptr cinfo) { 991 if (cinfo->global_state != jpegli::kDecProcessScan && 992 cinfo->global_state != jpegli::kDecProcessMarkers) { 993 JPEGLI_ERROR("jpegli_new_colormap: unexpected state %d", 994 cinfo->global_state); 995 } 996 if (!cinfo->buffered_image) { 997 JPEGLI_ERROR("jpegli_new_colormap: not in buffered image mode"); 998 } 999 if (!cinfo->enable_external_quant) { 1000 JPEGLI_ERROR("external colormap quantizer was not enabled"); 1001 } 1002 if (!cinfo->quantize_colors || cinfo->colormap == nullptr) { 1003 JPEGLI_ERROR("jpegli_new_colormap: not in external colormap mode"); 1004 } 1005 cinfo->master->regenerate_inverse_colormap_ = true; 1006 } 1007 1008 void jpegli_set_output_format(j_decompress_ptr cinfo, JpegliDataType data_type, 1009 JpegliEndianness endianness) { 1010 switch (data_type) { 1011 case JPEGLI_TYPE_UINT8: 1012 case JPEGLI_TYPE_UINT16: 1013 case JPEGLI_TYPE_FLOAT: 1014 cinfo->master->output_data_type_ = data_type; 1015 break; 1016 default: 1017 JPEGLI_ERROR("Unsupported data type %d", data_type); 1018 } 1019 switch (endianness) { 1020 case JPEGLI_NATIVE_ENDIAN: 1021 cinfo->master->swap_endianness_ = false; 1022 break; 1023 case JPEGLI_LITTLE_ENDIAN: 1024 cinfo->master->swap_endianness_ = !IsLittleEndian(); 1025 break; 1026 case JPEGLI_BIG_ENDIAN: 1027 cinfo->master->swap_endianness_ = IsLittleEndian(); 1028 break; 1029 default: 1030 JPEGLI_ERROR("Unsupported endianness %d", endianness); 1031 } 1032 }