/// <summary> /// Decode and return one MCU's worth of Huffman-compressed coefficients. /// The coefficients are reordered from zigzag order into natural array order, /// but are not dequantized. /// /// The i'th block of the MCU is stored into the block pointed to by /// MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. /// (Wholesale zeroing is usually a little faster than retail...) /// /// Returns false if data source requested suspension. In that case no /// changes have been made to permanent state. (Exception: some output /// coefficients may already have been assigned. This is harmless for /// this module, since we'll just re-assign them on the next call.) /// </summary> public override bool decode_mcu(JBLOCK[] MCU_data) { /* Process restart marker if needed; may have to suspend */ if (m_cinfo.m_restart_interval != 0) { if (m_restarts_to_go == 0) { if (!process_restart()) return false; } } /* If we've run out of data, just leave the MCU set to zeroes. * This way, we return uniform gray for the remainder of the segment. */ if (!m_insufficient_data) { /* Load up working state */ int get_buffer; int bits_left; bitread_working_state br_state = new bitread_working_state(); BITREAD_LOAD_STATE(m_bitstate, out get_buffer, out bits_left, ref br_state); savable_state state = new savable_state(); state.Assign(m_saved); /* Outer loop handles each block in the MCU */ for (int blkn = 0; blkn < m_cinfo.m_blocks_in_MCU; blkn++) { /* Decode a single block's worth of coefficients */ /* Section F.2.2.1: decode the DC coefficient difference */ int s; if (!HUFF_DECODE(out s, ref br_state, m_dc_cur_tbls[blkn], ref get_buffer, ref bits_left)) return false; if (s != 0) { if (!CHECK_BIT_BUFFER(ref br_state, s, ref get_buffer, ref bits_left)) return false; int r = GET_BITS(s, get_buffer, ref bits_left); s = HUFF_EXTEND(r, s); } if (m_dc_needed[blkn]) { /* Convert DC difference to actual value, update last_dc_val */ int ci = m_cinfo.m_MCU_membership[blkn]; s += state.last_dc_val[ci]; state.last_dc_val[ci] = s; /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ MCU_data[blkn][0] = (short) s; } if (m_ac_needed[blkn]) { /* Section F.2.2.2: decode the AC coefficients */ /* Since zeroes are skipped, output area must be cleared beforehand */ for (int k = 1; k < JpegConstants.DCTSIZE2; k++) { if (!HUFF_DECODE(out s, ref br_state, m_ac_cur_tbls[blkn], ref get_buffer, ref bits_left)) return false; int r = s >> 4; s &= 15; if (s != 0) { k += r; if (!CHECK_BIT_BUFFER(ref br_state, s, ref get_buffer, ref bits_left)) return false; r = GET_BITS(s, get_buffer, ref bits_left); s = HUFF_EXTEND(r, s); /* Output coefficient in natural (dezigzagged) order. * Note: the extra entries in jpeg_natural_order[] will save us * if k >= DCTSIZE2, which could happen if the data is corrupted. */ MCU_data[blkn][JpegUtils.jpeg_natural_order[k]] = (short) s; } else { if (r != 15) break; k += 15; } } } else { /* Section F.2.2.2: decode the AC coefficients */ /* In this path we just discard the values */ for (int k = 1; k < JpegConstants.DCTSIZE2; k++) { if (!HUFF_DECODE(out s, ref br_state, m_ac_cur_tbls[blkn], ref get_buffer, ref bits_left)) return false; int r = s >> 4; s &= 15; if (s != 0) { k += r; if (!CHECK_BIT_BUFFER(ref br_state, s, ref get_buffer, ref bits_left)) return false; DROP_BITS(s, ref bits_left); } else { if (r != 15) break; k += 15; } } } } /* Completed MCU, so update state */ BITREAD_SAVE_STATE(ref m_bitstate, get_buffer, bits_left); m_saved.Assign(state); } /* Account for restart interval (no-op if not using restarts) */ m_restarts_to_go--; return true; }
/* * Huffman MCU decoding. * Each of these routines decodes and returns one MCU's worth of * Huffman-compressed coefficients. * The coefficients are reordered from zigzag order into natural array order, * but are not dequantized. * * The i'th block of the MCU is stored into the block pointed to by * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. * * We return false if data source requested suspension. In that case no * changes have been made to permanent state. (Exception: some output * coefficients may already have been assigned. This is harmless for * spectral selection, since we'll just re-assign them on the next call. * Successive approximation AC refinement has to be more careful, however.) */ /// <summary> /// MCU decoding for DC initial scan (either spectral selection, /// or first pass of successive approximation). /// </summary> private bool decode_mcu_DC_first(JBLOCK[] MCU_data) { /* Process restart marker if needed; may have to suspend */ if (m_cinfo.m_restart_interval != 0) { if (m_restarts_to_go == 0) { if (!process_restart()) return false; } } /* If we've run out of data, just leave the MCU set to zeroes. * This way, we return uniform gray for the remainder of the segment. */ if (!m_insufficient_data) { /* Load up working state */ int get_buffer; int bits_left; bitread_working_state br_state = new bitread_working_state(); BITREAD_LOAD_STATE(m_bitstate, out get_buffer, out bits_left, ref br_state); savable_state state = new savable_state(); state.Assign(m_saved); /* Outer loop handles each block in the MCU */ for (int blkn = 0; blkn < m_cinfo.m_blocks_in_MCU; blkn++) { int ci = m_cinfo.m_MCU_membership[blkn]; /* Decode a single block's worth of coefficients */ /* Section F.2.2.1: decode the DC coefficient difference */ int s; if (!HUFF_DECODE(out s, ref br_state, m_derived_tbls[m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[ci]].Dc_tbl_no], ref get_buffer, ref bits_left)) return false; if (s != 0) { if (!CHECK_BIT_BUFFER(ref br_state, s, ref get_buffer, ref bits_left)) return false; int r = GET_BITS(s, get_buffer, ref bits_left); s = HUFF_EXTEND(r, s); } /* Convert DC difference to actual value, update last_dc_val */ s += state.last_dc_val[ci]; state.last_dc_val[ci] = s; /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */ MCU_data[blkn][0] = (short)(s << m_cinfo.m_Al); } /* Completed MCU, so update state */ BITREAD_SAVE_STATE(ref m_bitstate, get_buffer, bits_left); m_saved.Assign(state); } /* Account for restart interval (no-op if not using restarts) */ m_restarts_to_go--; return true; }
/// <summary> /// Decode and return one MCU's worth of Huffman-compressed coefficients. /// The coefficients are reordered from zigzag order into natural array order, /// but are not dequantized. /// /// The i'th block of the MCU is stored into the block pointed to by /// MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. /// (Wholesale zeroing is usually a little faster than retail...) /// /// Returns false if data source requested suspension. In that case no /// changes have been made to permanent state. (Exception: some output /// coefficients may already have been assigned. This is harmless for /// this module, since we'll just re-assign them on the next call.) /// </summary> public override bool decode_mcu(JBLOCK[] MCU_data) { /* Process restart marker if needed; may have to suspend */ if (m_cinfo.m_restart_interval != 0) { if (m_restarts_to_go == 0) { if (!process_restart()) { return(false); } } } /* If we've run out of data, just leave the MCU set to zeroes. * This way, we return uniform gray for the remainder of the segment. */ if (!m_insufficient_data) { /* Load up working state */ int get_buffer; int bits_left; bitread_working_state br_state = new bitread_working_state(); BITREAD_LOAD_STATE(m_bitstate, out get_buffer, out bits_left, ref br_state); savable_state state = new savable_state(); state.Assign(m_saved); /* Outer loop handles each block in the MCU */ for (int blkn = 0; blkn < m_cinfo.m_blocks_in_MCU; blkn++) { /* Decode a single block's worth of coefficients */ /* Section F.2.2.1: decode the DC coefficient difference */ int s; if (!HUFF_DECODE(out s, ref br_state, m_dc_cur_tbls[blkn], ref get_buffer, ref bits_left)) { return(false); } if (s != 0) { if (!CHECK_BIT_BUFFER(ref br_state, s, ref get_buffer, ref bits_left)) { return(false); } int r = GET_BITS(s, get_buffer, ref bits_left); s = HUFF_EXTEND(r, s); } if (m_dc_needed[blkn]) { /* Convert DC difference to actual value, update last_dc_val */ int ci = m_cinfo.m_MCU_membership[blkn]; s += state.last_dc_val[ci]; state.last_dc_val[ci] = s; /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ MCU_data[blkn][0] = (short)s; } if (m_ac_needed[blkn]) { /* Section F.2.2.2: decode the AC coefficients */ /* Since zeroes are skipped, output area must be cleared beforehand */ for (int k = 1; k < JpegConstants.DCTSIZE2; k++) { if (!HUFF_DECODE(out s, ref br_state, m_ac_cur_tbls[blkn], ref get_buffer, ref bits_left)) { return(false); } int r = s >> 4; s &= 15; if (s != 0) { k += r; if (!CHECK_BIT_BUFFER(ref br_state, s, ref get_buffer, ref bits_left)) { return(false); } r = GET_BITS(s, get_buffer, ref bits_left); s = HUFF_EXTEND(r, s); /* Output coefficient in natural (dezigzagged) order. * Note: the extra entries in jpeg_natural_order[] will save us * if k >= DCTSIZE2, which could happen if the data is corrupted. */ MCU_data[blkn][JpegUtils.jpeg_natural_order[k]] = (short)s; } else { if (r != 15) { break; } k += 15; } } } else { /* Section F.2.2.2: decode the AC coefficients */ /* In this path we just discard the values */ for (int k = 1; k < JpegConstants.DCTSIZE2; k++) { if (!HUFF_DECODE(out s, ref br_state, m_ac_cur_tbls[blkn], ref get_buffer, ref bits_left)) { return(false); } int r = s >> 4; s &= 15; if (s != 0) { k += r; if (!CHECK_BIT_BUFFER(ref br_state, s, ref get_buffer, ref bits_left)) { return(false); } DROP_BITS(s, ref bits_left); } else { if (r != 15) { break; } k += 15; } } } } /* Completed MCU, so update state */ BITREAD_SAVE_STATE(ref m_bitstate, get_buffer, bits_left); m_saved.Assign(state); } /* Account for restart interval (no-op if not using restarts) */ m_restarts_to_go--; return(true); }
/* * Huffman MCU decoding. * Each of these routines decodes and returns one MCU's worth of * Huffman-compressed coefficients. * The coefficients are reordered from zigzag order into natural array order, * but are not dequantized. * * The i'th block of the MCU is stored into the block pointed to by * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER. * * We return false if data source requested suspension. In that case no * changes have been made to permanent state. (Exception: some output * coefficients may already have been assigned. This is harmless for * spectral selection, since we'll just re-assign them on the next call. * Successive approximation AC refinement has to be more careful, however.) */ /// <summary> /// MCU decoding for DC initial scan (either spectral selection, /// or first pass of successive approximation). /// </summary> private bool decode_mcu_DC_first(JBLOCK[] MCU_data) { /* Process restart marker if needed; may have to suspend */ if (m_cinfo.m_restart_interval != 0) { if (m_restarts_to_go == 0) { if (!process_restart()) { return(false); } } } /* If we've run out of data, just leave the MCU set to zeroes. * This way, we return uniform gray for the remainder of the segment. */ if (!m_insufficient_data) { /* Load up working state */ int get_buffer; int bits_left; bitread_working_state br_state = new bitread_working_state(); BITREAD_LOAD_STATE(m_bitstate, out get_buffer, out bits_left, ref br_state); savable_state state = new savable_state(); state.Assign(m_saved); /* Outer loop handles each block in the MCU */ for (int blkn = 0; blkn < m_cinfo.m_blocks_in_MCU; blkn++) { int ci = m_cinfo.m_MCU_membership[blkn]; /* Decode a single block's worth of coefficients */ /* Section F.2.2.1: decode the DC coefficient difference */ int s; if (!HUFF_DECODE(out s, ref br_state, m_derived_tbls[m_cinfo.Comp_info[m_cinfo.m_cur_comp_info[ci]].Dc_tbl_no], ref get_buffer, ref bits_left)) { return(false); } if (s != 0) { if (!CHECK_BIT_BUFFER(ref br_state, s, ref get_buffer, ref bits_left)) { return(false); } int r = GET_BITS(s, get_buffer, ref bits_left); s = HUFF_EXTEND(r, s); } /* Convert DC difference to actual value, update last_dc_val */ s += state.last_dc_val[ci]; state.last_dc_val[ci] = s; /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */ MCU_data[blkn][0] = (short)(s << m_cinfo.m_Al); } /* Completed MCU, so update state */ BITREAD_SAVE_STATE(ref m_bitstate, get_buffer, bits_left); m_saved.Assign(state); } /* Account for restart interval (no-op if not using restarts) */ m_restarts_to_go--; return(true); }