| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| typedef struct { |
| unsigned int EOBRUN; |
| int last_dc_val[MAX_COMPS_IN_SCAN]; |
| } savable_state; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ((dest).EOBRUN = (src).EOBRUN, \ |
| (dest).last_dc_val[0] = (src).last_dc_val[0], \ |
| (dest).last_dc_val[1] = (src).last_dc_val[1], \ |
| (dest).last_dc_val[2] = (src).last_dc_val[2], \ |
| (dest).last_dc_val[3] = (src).last_dc_val[3]) |
| |
| |
| |
| |
| typedef struct { |
| struct jpeg_entropy_decoder pub; |
| |
| |
| |
| |
| bitread_perm_state bitstate; |
| savable_state saved; |
| |
| |
| unsigned int restarts_to_go; |
| |
| |
| d_derived_tbl *derived_tbls[NUM_HUFF_TBLS]; |
| |
| d_derived_tbl *ac_derived_tbl; |
| } phuff_entropy_decoder; |
| |
| typedef phuff_entropy_decoder *phuff_entropy_ptr; |
| |
| |
| METHODDEF(boolean) decode_mcu_DC_first(j_decompress_ptr cinfo, |
| JBLOCKROW *MCU_data); |
| METHODDEF(boolean) decode_mcu_AC_first(j_decompress_ptr cinfo, |
| JBLOCKROW *MCU_data); |
| METHODDEF(boolean) decode_mcu_DC_refine(j_decompress_ptr cinfo, |
| JBLOCKROW *MCU_data); |
| METHODDEF(boolean) decode_mcu_AC_refine(j_decompress_ptr cinfo, |
| JBLOCKROW *MCU_data); |
| |
| |
| |
| |
| |
| |
| METHODDEF(void) |
| start_pass_phuff_decoder(j_decompress_ptr cinfo) |
| { |
| phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy; |
| boolean is_DC_band, bad; |
| int ci, coefi, tbl; |
| d_derived_tbl **pdtbl; |
| int *coef_bit_ptr; |
| jpeg_component_info *compptr; |
| |
| is_DC_band = (cinfo->Ss == 0); |
| |
| |
| bad = FALSE; |
| if (is_DC_band) { |
| if (cinfo->Se != 0) |
| bad = TRUE; |
| } else { |
| |
| if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2) |
| bad = TRUE; |
| |
| if (cinfo->comps_in_scan != 1) |
| bad = TRUE; |
| } |
| if (cinfo->Ah != 0) { |
| |
| if (cinfo->Al != cinfo->Ah - 1) |
| bad = TRUE; |
| } |
| if (cinfo->Al > 13) |
| bad = TRUE; |
| |
| |
| |
| |
| |
| |
| if (bad) |
| ERREXIT4(cinfo, JERR_BAD_PROGRESSION, |
| cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); |
| |
| |
| |
| |
| for (ci = 0; ci < cinfo->comps_in_scan; ci++) { |
| int cindex = cinfo->cur_comp_info[ci]->component_index; |
| coef_bit_ptr = &cinfo->coef_bits[cindex][0]; |
| if (!is_DC_band && coef_bit_ptr[0] < 0) |
| WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0); |
| for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { |
| int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; |
| if (cinfo->Ah != expected) |
| WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi); |
| coef_bit_ptr[coefi] = cinfo->Al; |
| } |
| } |
| |
| |
| if (cinfo->Ah == 0) { |
| if (is_DC_band) |
| entropy->pub.decode_mcu = decode_mcu_DC_first; |
| else |
| entropy->pub.decode_mcu = decode_mcu_AC_first; |
| } else { |
| if (is_DC_band) |
| entropy->pub.decode_mcu = decode_mcu_DC_refine; |
| else |
| entropy->pub.decode_mcu = decode_mcu_AC_refine; |
| } |
| |
| for (ci = 0; ci < cinfo->comps_in_scan; ci++) { |
| compptr = cinfo->cur_comp_info[ci]; |
| |
| |
| |
| if (is_DC_band) { |
| if (cinfo->Ah == 0) { |
| tbl = compptr->dc_tbl_no; |
| pdtbl = (d_derived_tbl **)(entropy->derived_tbls) + tbl; |
| jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, pdtbl); |
| } |
| } else { |
| tbl = compptr->ac_tbl_no; |
| pdtbl = (d_derived_tbl **)(entropy->derived_tbls) + tbl; |
| jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, pdtbl); |
| |
| entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; |
| } |
| |
| entropy->saved.last_dc_val[ci] = 0; |
| } |
| |
| |
| entropy->bitstate.bits_left = 0; |
| entropy->bitstate.get_buffer = 0; |
| entropy->pub.insufficient_data = FALSE; |
| |
| |
| entropy->saved.EOBRUN = 0; |
| |
| |
| entropy->restarts_to_go = cinfo->restart_interval; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ((x) < (1 << ((s) - 1)) ? (x) + (((NEG_1) << (s)) + 1) : (x)) |
| |
| |
| |
| |
| ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) |
| |
| static const int extend_test[16] = { |
| 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, |
| 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 |
| }; |
| |
| static const int extend_offset[16] = { |
| 0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1, |
| ((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1, |
| ((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1, |
| ((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1 |
| }; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| LOCAL(boolean) |
| process_restart(j_decompress_ptr cinfo) |
| { |
| phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy; |
| int ci; |
| |
| |
| |
| cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; |
| entropy->bitstate.bits_left = 0; |
| |
| |
| if (!(*cinfo->marker->read_restart_marker) (cinfo)) |
| return FALSE; |
| |
| |
| for (ci = 0; ci < cinfo->comps_in_scan; ci++) |
| entropy->saved.last_dc_val[ci] = 0; |
| |
| entropy->saved.EOBRUN = 0; |
| |
| |
| entropy->restarts_to_go = cinfo->restart_interval; |
| |
| |
| |
| |
| |
| |
| if (cinfo->unread_marker == 0) |
| entropy->pub.insufficient_data = FALSE; |
| |
| return TRUE; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| METHODDEF(boolean) |
| decode_mcu_DC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) |
| { |
| phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy; |
| int Al = cinfo->Al; |
| register int s, r; |
| int blkn, ci; |
| JBLOCKROW block; |
| BITREAD_STATE_VARS; |
| savable_state state; |
| d_derived_tbl *tbl; |
| jpeg_component_info *compptr; |
| |
| |
| if (cinfo->restart_interval) { |
| if (entropy->restarts_to_go == 0) |
| if (!process_restart(cinfo)) |
| return FALSE; |
| } |
| |
| |
| |
| |
| if (!entropy->pub.insufficient_data) { |
| |
| |
| BITREAD_LOAD_STATE(cinfo, entropy->bitstate); |
| ASSIGN_STATE(state, entropy->saved); |
| |
| |
| |
| for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { |
| block = MCU_data[blkn]; |
| ci = cinfo->MCU_membership[blkn]; |
| compptr = cinfo->cur_comp_info[ci]; |
| tbl = entropy->derived_tbls[compptr->dc_tbl_no]; |
| |
| |
| |
| |
| HUFF_DECODE(s, br_state, tbl, return FALSE, label1); |
| if (s) { |
| CHECK_BIT_BUFFER(br_state, s, return FALSE); |
| r = GET_BITS(s); |
| s = HUFF_EXTEND(r, s); |
| } |
| |
| |
| if ((state.last_dc_val[ci] >= 0 && |
| s > INT_MAX - state.last_dc_val[ci]) || |
| (state.last_dc_val[ci] < 0 && s < INT_MIN - state.last_dc_val[ci])) |
| ERREXIT(cinfo, JERR_BAD_DCT_COEF); |
| s += state.last_dc_val[ci]; |
| state.last_dc_val[ci] = s; |
| |
| (*block)[0] = (JCOEF)LEFT_SHIFT(s, Al); |
| } |
| |
| |
| BITREAD_SAVE_STATE(cinfo, entropy->bitstate); |
| ASSIGN_STATE(entropy->saved, state); |
| } |
| |
| |
| entropy->restarts_to_go--; |
| |
| return TRUE; |
| } |
| |
| |
| |
| |
| |
| |
| |
| METHODDEF(boolean) |
| decode_mcu_AC_first(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) |
| { |
| phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy; |
| int Se = cinfo->Se; |
| int Al = cinfo->Al; |
| register int s, k, r; |
| unsigned int EOBRUN; |
| JBLOCKROW block; |
| BITREAD_STATE_VARS; |
| d_derived_tbl *tbl; |
| |
| |
| if (cinfo->restart_interval) { |
| if (entropy->restarts_to_go == 0) |
| if (!process_restart(cinfo)) |
| return FALSE; |
| } |
| |
| |
| |
| |
| if (!entropy->pub.insufficient_data) { |
| |
| |
| |
| |
| EOBRUN = entropy->saved.EOBRUN; |
| |
| |
| |
| if (EOBRUN > 0) |
| EOBRUN--; |
| else { |
| BITREAD_LOAD_STATE(cinfo, entropy->bitstate); |
| block = MCU_data[0]; |
| tbl = entropy->ac_derived_tbl; |
| |
| for (k = cinfo->Ss; k <= Se; k++) { |
| HUFF_DECODE(s, br_state, tbl, return FALSE, label2); |
| r = s >> 4; |
| s &= 15; |
| if (s) { |
| k += r; |
| CHECK_BIT_BUFFER(br_state, s, return FALSE); |
| r = GET_BITS(s); |
| s = HUFF_EXTEND(r, s); |
| |
| (*block)[jpeg_natural_order[k]] = (JCOEF)LEFT_SHIFT(s, Al); |
| } else { |
| if (r == 15) { |
| k += 15; |
| } else { |
| EOBRUN = 1 << r; |
| if (r) { |
| CHECK_BIT_BUFFER(br_state, r, return FALSE); |
| r = GET_BITS(r); |
| EOBRUN += r; |
| } |
| EOBRUN--; |
| break; |
| } |
| } |
| } |
| |
| BITREAD_SAVE_STATE(cinfo, entropy->bitstate); |
| } |
| |
| |
| entropy->saved.EOBRUN = EOBRUN; |
| } |
| |
| |
| entropy->restarts_to_go--; |
| |
| return TRUE; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| METHODDEF(boolean) |
| decode_mcu_DC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) |
| { |
| phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy; |
| int p1 = 1 << cinfo->Al; |
| int blkn; |
| JBLOCKROW block; |
| BITREAD_STATE_VARS; |
| |
| |
| if (cinfo->restart_interval) { |
| if (entropy->restarts_to_go == 0) |
| if (!process_restart(cinfo)) |
| return FALSE; |
| } |
| |
| |
| |
| |
| |
| |
| BITREAD_LOAD_STATE(cinfo, entropy->bitstate); |
| |
| |
| |
| for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { |
| block = MCU_data[blkn]; |
| |
| |
| CHECK_BIT_BUFFER(br_state, 1, return FALSE); |
| if (GET_BITS(1)) |
| (*block)[0] |= p1; |
| |
| } |
| |
| |
| BITREAD_SAVE_STATE(cinfo, entropy->bitstate); |
| |
| |
| entropy->restarts_to_go--; |
| |
| return TRUE; |
| } |
| |
| |
| |
| |
| |
| |
| METHODDEF(boolean) |
| decode_mcu_AC_refine(j_decompress_ptr cinfo, JBLOCKROW *MCU_data) |
| { |
| phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy; |
| int Se = cinfo->Se; |
| int p1 = 1 << cinfo->Al; |
| int m1 = (NEG_1) << cinfo->Al; |
| register int s, k, r; |
| unsigned int EOBRUN; |
| JBLOCKROW block; |
| JCOEFPTR thiscoef; |
| BITREAD_STATE_VARS; |
| d_derived_tbl *tbl; |
| int num_newnz; |
| int newnz_pos[DCTSIZE2]; |
| |
| |
| if (cinfo->restart_interval) { |
| if (entropy->restarts_to_go == 0) |
| if (!process_restart(cinfo)) |
| return FALSE; |
| } |
| |
| |
| |
| if (!entropy->pub.insufficient_data) { |
| |
| |
| BITREAD_LOAD_STATE(cinfo, entropy->bitstate); |
| EOBRUN = entropy->saved.EOBRUN; |
| |
| |
| block = MCU_data[0]; |
| tbl = entropy->ac_derived_tbl; |
| |
| |
| |
| |
| |
| |
| |
| num_newnz = 0; |
| |
| |
| k = cinfo->Ss; |
| |
| if (EOBRUN == 0) { |
| for (; k <= Se; k++) { |
| HUFF_DECODE(s, br_state, tbl, goto undoit, label3); |
| r = s >> 4; |
| s &= 15; |
| if (s) { |
| if (s != 1) |
| WARNMS(cinfo, JWRN_HUFF_BAD_CODE); |
| CHECK_BIT_BUFFER(br_state, 1, goto undoit); |
| if (GET_BITS(1)) |
| s = p1; |
| else |
| s = m1; |
| } else { |
| if (r != 15) { |
| EOBRUN = 1 << r; |
| if (r) { |
| CHECK_BIT_BUFFER(br_state, r, goto undoit); |
| r = GET_BITS(r); |
| EOBRUN += r; |
| } |
| break; |
| } |
| |
| } |
| |
| |
| |
| |
| do { |
| thiscoef = *block + jpeg_natural_order[k]; |
| if (*thiscoef != 0) { |
| CHECK_BIT_BUFFER(br_state, 1, goto undoit); |
| if (GET_BITS(1)) { |
| if ((*thiscoef & p1) == 0) { |
| if (*thiscoef >= 0) |
| *thiscoef += p1; |
| else |
| *thiscoef += m1; |
| } |
| } |
| } else { |
| if (--r < 0) |
| break; |
| } |
| k++; |
| } while (k <= Se); |
| if (s) { |
| int pos = jpeg_natural_order[k]; |
| |
| (*block)[pos] = (JCOEF)s; |
| |
| newnz_pos[num_newnz++] = pos; |
| } |
| } |
| } |
| |
| if (EOBRUN > 0) { |
| |
| |
| |
| |
| |
| for (; k <= Se; k++) { |
| thiscoef = *block + jpeg_natural_order[k]; |
| if (*thiscoef != 0) { |
| CHECK_BIT_BUFFER(br_state, 1, goto undoit); |
| if (GET_BITS(1)) { |
| if ((*thiscoef & p1) == 0) { |
| if (*thiscoef >= 0) |
| *thiscoef += p1; |
| else |
| *thiscoef += m1; |
| } |
| } |
| } |
| } |
| |
| EOBRUN--; |
| } |
| |
| |
| BITREAD_SAVE_STATE(cinfo, entropy->bitstate); |
| entropy->saved.EOBRUN = EOBRUN; |
| } |
| |
| |
| entropy->restarts_to_go--; |
| |
| return TRUE; |
| |
| undoit: |
| |
| while (num_newnz > 0) |
| (*block)[newnz_pos[--num_newnz]] = 0; |
| |
| return FALSE; |
| } |
| |
| |
| |
| |
| |
| |
| GLOBAL(void) |
| jinit_phuff_decoder(j_decompress_ptr cinfo) |
| { |
| phuff_entropy_ptr entropy; |
| int *coef_bit_ptr; |
| int ci, i; |
| |
| entropy = (phuff_entropy_ptr) |
| (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, |
| sizeof(phuff_entropy_decoder)); |
| cinfo->entropy = (struct jpeg_entropy_decoder *)entropy; |
| entropy->pub.start_pass = start_pass_phuff_decoder; |
| |
| |
| for (i = 0; i < NUM_HUFF_TBLS; i++) { |
| entropy->derived_tbls[i] = NULL; |
| } |
| |
| |
| cinfo->coef_bits = (int (*)[DCTSIZE2]) |
| (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, |
| cinfo->num_components * DCTSIZE2 * |
| sizeof(int)); |
| coef_bit_ptr = &cinfo->coef_bits[0][0]; |
| for (ci = 0; ci < cinfo->num_components; ci++) |
| for (i = 0; i < DCTSIZE2; i++) |
| *coef_bit_ptr++ = -1; |
| } |
| |
| |