// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.
JPEG_VERIFY_LEN(2 * cinfo->comps_in_scan); bool is_interleaved = (cinfo->comps_in_scan > 1);
uint8_t ids_seen[256] = {0};
cinfo->blocks_in_MCU = 0; for (int i = 0; i < cinfo->comps_in_scan; ++i) { int id = ReadUint8(data, &pos); if (ids_seen[id]) { // (cf. section B.2.3, regarding CSj)
JPEGLI_ERROR("Duplicate ID %d in SOS.", id);
}
ids_seen[id] = 1;
jpeg_component_info* comp = nullptr; for (int j = 0; j < cinfo->num_components; ++j) { if (cinfo->comp_info[j].component_id == id) {
comp = &cinfo->comp_info[j];
cinfo->cur_comp_info[i] = comp;
}
} if (!comp) {
JPEGLI_ERROR("SOS marker: Could not find component with id %d", id);
} int c = ReadUint8(data, &pos);
comp->dc_tbl_no = c >> 4;
comp->ac_tbl_no = c & 0xf;
JPEG_VERIFY_INPUT(comp->dc_tbl_no, 0, 3);
JPEG_VERIFY_INPUT(comp->ac_tbl_no, 0, 3);
comp->MCU_width = is_interleaved ? comp->h_samp_factor : 1;
comp->MCU_height = is_interleaved ? comp->v_samp_factor : 1;
comp->MCU_blocks = comp->MCU_width * comp->MCU_height; if (cinfo->blocks_in_MCU + comp->MCU_blocks > D_MAX_BLOCKS_IN_MCU) {
JPEGLI_ERROR("Too many blocks in MCU.");
} for (int j = 0; j < comp->MCU_blocks; ++j) {
cinfo->MCU_membership[cinfo->blocks_in_MCU++] = i;
}
}
JPEG_VERIFY_LEN(3);
cinfo->Ss = ReadUint8(data, &pos);
cinfo->Se = ReadUint8(data, &pos);
JPEG_VERIFY_INPUT(cinfo->Ss, 0, 63);
JPEG_VERIFY_INPUT(cinfo->Se, cinfo->Ss, 63); int c = ReadUint8(data, &pos);
cinfo->Ah = c >> 4;
cinfo->Al = c & 0xf;
JPEG_VERIFY_MARKER_END();
if (cinfo->input_scan_number == 0) {
m->is_multiscan_ = (cinfo->comps_in_scan < cinfo->num_components ||
FROM_JXL_BOOL(cinfo->progressive_mode));
} if (cinfo->Ah != 0 && cinfo->Al != cinfo->Ah - 1) { // section G.1.1.1.2 : Successive approximation control only improves // by one bit at a time.
JPEGLI_ERROR("Invalid progressive parameters: Al=%d Ah=%d", cinfo->Al,
cinfo->Ah);
} if (!cinfo->progressive_mode) {
cinfo->Ss = 0;
cinfo->Se = 63;
cinfo->Ah = 0;
cinfo->Al = 0;
} const uint16_t scan_bitmask =
cinfo->Ah == 0 ? (0xffff << cinfo->Al) : (1u << cinfo->Al); const uint16_t refinement_bitmask = (1 << cinfo->Al) - 1; if (!cinfo->coef_bits) {
cinfo->coef_bits =
Allocate<int[DCTSIZE2]>(cinfo, cinfo->num_components * 2, JPOOL_IMAGE);
m->coef_bits_latch =
Allocate<int[SAVED_COEFS]>(cinfo, cinfo->num_components, JPOOL_IMAGE);
m->prev_coef_bits_latch =
Allocate<int[SAVED_COEFS]>(cinfo, cinfo->num_components, JPOOL_IMAGE);
for (int c = 0; c < cinfo->num_components; ++c) { for (int i = 0; i < DCTSIZE2; ++i) {
cinfo->coef_bits[c][i] = -1; if (i < SAVED_COEFS) {
m->coef_bits_latch[c][i] = -1;
}
}
}
}
for (int i = 0; i < cinfo->comps_in_scan; ++i) { int comp_idx = cinfo->cur_comp_info[i]->component_index; for (int k = cinfo->Ss; k <= cinfo->Se; ++k) { if (m->scan_progression_[comp_idx][k] & scan_bitmask) {
JPEGLI_ERROR( "Overlapping scans: component=%d k=%d prev_mask: %u cur_mask %u",
comp_idx, k, m->scan_progression_[i][k], scan_bitmask);
} if (m->scan_progression_[comp_idx][k] & refinement_bitmask) {
JPEGLI_ERROR( "Invalid scan order, a more refined scan was already done: " "component=%d k=%d prev_mask=%u cur_mask=%u",
comp_idx, k, m->scan_progression_[i][k], scan_bitmask);
}
m->scan_progression_[comp_idx][k] |= scan_bitmask;
}
} if (cinfo->Al > 10) {
JPEGLI_ERROR("Scan parameter Al=%d is not supported.", cinfo->Al);
}
}
// Reads the Define Huffman Table (DHT) marker segment and builds the Huffman // decoding table in either dc_huff_lut_ or ac_huff_lut_, depending on the type // and solt_id of Huffman code being read. void ProcessDHT(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
size_t pos = 2; if (pos == len) {
JPEGLI_ERROR("DHT marker: no Huffman table found");
} while (pos < len) {
JPEG_VERIFY_LEN(1 + kJpegHuffmanMaxBitLength); // The index of the Huffman code in the current set of Huffman codes. For AC // component Huffman codes, 0x10 is added to the index. int slot_id = ReadUint8(data, &pos); int huffman_index = slot_id; bool is_ac_table = ((slot_id & 0x10) != 0);
JHUFF_TBL** table; if (is_ac_table) {
huffman_index -= 0x10;
JPEG_VERIFY_INPUT(huffman_index, 0, NUM_HUFF_TBLS - 1);
table = &cinfo->ac_huff_tbl_ptrs[huffman_index];
} else {
JPEG_VERIFY_INPUT(huffman_index, 0, NUM_HUFF_TBLS - 1);
table = &cinfo->dc_huff_tbl_ptrs[huffman_index];
} if (*table == nullptr) {
*table = jpegli_alloc_huff_table(reinterpret_cast<j_common_ptr>(cinfo));
} int total_count = 0; for (size_t i = 1; i <= kJpegHuffmanMaxBitLength; ++i) { int count = ReadUint8(data, &pos);
(*table)->bits[i] = count;
total_count += count;
} if (is_ac_table) {
JPEG_VERIFY_INPUT(total_count, 0, kJpegHuffmanAlphabetSize);
} else { // Allow symbols up to 15 here, we check later whether any invalid symbols // are actually decoded. // TODO(szabadka) Make sure decoder works (does not crash) with up to // 15-nbits DC symbols and then increase kJpegDCAlphabetSize.
JPEG_VERIFY_INPUT(total_count, 0, 16);
}
JPEG_VERIFY_LEN(total_count); for (int i = 0; i < total_count; ++i) { int value = ReadUint8(data, &pos); if (!is_ac_table) {
JPEG_VERIFY_INPUT(value, 0, 15);
}
(*table)->huffval[i] = value;
} for (int i = total_count; i < kJpegHuffmanAlphabetSize; ++i) {
(*table)->huffval[i] = 0;
}
}
JPEG_VERIFY_MARKER_END();
}
void ProcessDQT(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
jpeg_decomp_master* m = cinfo->master; if (m->found_sos_) {
JPEGLI_ERROR("Updating quant tables between scans is not supported.");
}
size_t pos = 2; if (pos == len) {
JPEGLI_ERROR("DQT marker: no quantization table found");
} while (pos < len) {
JPEG_VERIFY_LEN(1); int quant_table_index = ReadUint8(data, &pos); int precision = quant_table_index >> 4;
JPEG_VERIFY_INPUT(precision, 0, 1);
quant_table_index &= 0xf;
JPEG_VERIFY_INPUT(quant_table_index, 0, NUM_QUANT_TBLS - 1);
JPEG_VERIFY_LEN((precision + 1) * DCTSIZE2);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.