// Emit (or just count) a Huffman symbol. static void emit_symbol(phuff_entropy_encoder entropy, int tbl_no, int symbol) { if (entropy.gather_statistics) { entropy.count_ptrs[tbl_no][symbol]++; } else { c_derived_tbl tbl = entropy.derived_tbls[tbl_no]; emit_bits(entropy, tbl.ehufco[symbol], tbl.ehufsi[symbol]); } }
/// <summary> /// Expand a Huffman table definition into the derived format /// Compute the derived values for a Huffman table. /// This routine also performs some validation checks on the table. /// </summary> protected void jpeg_make_c_derived_tbl(bool isDC, int tblno, ref c_derived_tbl dtbl) { /* Note that huffsize[] and huffcode[] are filled in code-length order, * paralleling the order of the symbols themselves in htbl.huffval[]. */ /* Find the input Huffman table */ if (tblno < 0 || tblno >= JpegConstants.NUM_HUFF_TBLS) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno); } JHUFF_TBL htbl = isDC ? m_cinfo.m_dc_huff_tbl_ptrs[tblno] : m_cinfo.m_ac_huff_tbl_ptrs[tblno]; if (htbl == null) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno); } /* Allocate a workspace if we haven't already done so. */ if (dtbl == null) { dtbl = new c_derived_tbl(); } /* Figure C.1: make table of Huffman code length for each symbol */ int p = 0; char[] huffsize = new char[257]; for (int l = 1; l <= 16; l++) { int i = htbl.Bits[l]; if (i < 0 || p + i > 256) /* protect against table overrun */ { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); } while ((i--) != 0) { huffsize[p++] = (char)l; } } huffsize[p] = (char)0; int lastp = p; /* Figure C.2: generate the codes themselves */ /* We also validate that the counts represent a legal Huffman code tree. */ int code = 0; int si = huffsize[0]; p = 0; int[] huffcode = new int[257]; while (huffsize[p] != 0) { while (((int)huffsize[p]) == si) { huffcode[p++] = code; code++; } /* code is now 1 more than the last code used for codelength si; but * it must still fit in si bits, since no code is allowed to be all ones. */ if (code >= (1 << si)) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); } code <<= 1; si++; } /* Figure C.3: generate encoding tables */ /* These are code and size indexed by symbol value */ /* Set all codeless symbols to have code length 0; * this lets us detect duplicate VAL entries here, and later * allows emit_bits to detect any attempt to emit such symbols. */ Array.Clear(dtbl.ehufsi, 0, dtbl.ehufsi.Length); /* This is also a convenient place to check for out-of-range * and duplicated VAL entries. We allow 0..255 for AC symbols * but only 0..15 for DC. (We could constrain them further * based on data depth and mode, but this seems enough.) */ int maxsymbol = isDC ? 15 : 255; for (p = 0; p < lastp; p++) { int i = htbl.Huffval[p]; if (i < 0 || i > maxsymbol || dtbl.ehufsi[i] != 0) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); } dtbl.ehufco[i] = huffcode[p]; dtbl.ehufsi[i] = huffsize[p]; } }
/// <summary> /// Expand a Huffman table definition into the derived format /// Compute the derived values for a Huffman table. /// This routine also performs some validation checks on the table. /// </summary> protected void jpeg_make_c_derived_tbl(bool isDC, int tblno, ref c_derived_tbl dtbl) { /* Note that huffsize[] and huffcode[] are filled in code-length order, * paralleling the order of the symbols themselves in htbl.huffval[]. */ /* Find the input Huffman table */ if (tblno < 0 || tblno >= JpegConstants.NUM_HUFF_TBLS) m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno); JHUFF_TBL htbl = isDC ? m_cinfo.m_dc_huff_tbl_ptrs[tblno] : m_cinfo.m_ac_huff_tbl_ptrs[tblno]; if (htbl == null) m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno); /* Allocate a workspace if we haven't already done so. */ if (dtbl == null) dtbl = new c_derived_tbl(); /* Figure C.1: make table of Huffman code length for each symbol */ int p = 0; char[] huffsize = new char[257]; for (int l = 1; l <= 16; l++) { int i = htbl.Bits[l]; if (i < 0 || p + i> 256) /* protect against table overrun */ m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); while ((i--) != 0) huffsize[p++] = (char) l; } huffsize[p] = (char)0; int lastp = p; /* Figure C.2: generate the codes themselves */ /* We also validate that the counts represent a legal Huffman code tree. */ int code = 0; int si = huffsize[0]; p = 0; int[] huffcode = new int[257]; while (huffsize[p] != 0) { while (((int)huffsize[p]) == si) { huffcode[p++] = code; code++; } /* code is now 1 more than the last code used for codelength si; but * it must still fit in si bits, since no code is allowed to be all ones. */ if (code >= (1 << si)) m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); code <<= 1; si++; } /* Figure C.3: generate encoding tables */ /* These are code and size indexed by symbol value */ /* Set all codeless symbols to have code length 0; * this lets us detect duplicate VAL entries here, and later * allows emit_bits to detect any attempt to emit such symbols. */ Array.Clear(dtbl.ehufsi, 0, dtbl.ehufsi.Length); /* This is also a convenient place to check for out-of-range * and duplicated VAL entries. We allow 0..255 for AC symbols * but only 0..15 for DC. (We could constrain them further * based on data depth and mode, but this seems enough.) */ int maxsymbol = isDC ? 15 : 255; for (p = 0; p < lastp; p++) { int i = htbl.Huffval[p]; if (i < 0 || i> maxsymbol || dtbl.ehufsi[i] != 0) m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); dtbl.ehufco[i] = huffcode[p]; dtbl.ehufsi[i] = huffsize[p]; } }
// Expand a Huffman table definition into the derived format // Compute the derived values for a Huffman table. // This routine also performs some validation checks on the table. static void jpeg_make_c_derived_tbl(jpeg_compress cinfo, bool isDC, int tblno, ref c_derived_tbl pdtbl) { // Note that huffsize[] and huffcode[] are filled in code-length order, // paralleling the order of the symbols themselves in htbl.huffval[]. // Find the input Huffman table if(tblno<0||tblno>=NUM_HUFF_TBLS) ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno); JHUFF_TBL htbl=isDC?cinfo.dc_huff_tbl_ptrs[tblno]:cinfo.ac_huff_tbl_ptrs[tblno]; if(htbl==null) ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno); // Allocate a workspace if we haven't already done so. if(pdtbl==null) { try { pdtbl=new c_derived_tbl(); } catch { ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4); } } c_derived_tbl dtbl=pdtbl; // Figure C.1: make table of Huffman code length for each symbol byte[] huffsize=new byte[257]; int p=0; for(byte l=1; l<=16; l++) { int i=htbl.bits[l]; // protect against table overrun if(i<0||(p+i)>256) ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); while((i--)!=0) huffsize[p++]=l; } huffsize[p]=0; int lastp=p; // Figure C.2: generate the codes themselves // We also validate that the counts represent a legal Huffman code tree. uint[] huffcode=new uint[257]; uint code=0; int si=huffsize[0]; p=0; while(huffsize[p]!=0) { while(((int)huffsize[p])==si) { huffcode[p++]=code; code++; } // code is now 1 more than the last code used for codelength si; but // it must still fit in si bits, since no code is allowed to be all ones. if(((int)code)>=(1<<si)) ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); code<<=1; si++; } // Figure C.3: generate encoding tables // These are code and size indexed by symbol value // Set all codeless symbols to have code length 0; // this lets us detect duplicate VAL entries here, and later // allows emit_bits to detect any attempt to emit such symbols. for(int i=0; i<256; i++) dtbl.ehufsi[i]=0; // This is also a convenient place to check for out-of-range // and duplicated VAL entries. We allow 0..255 for AC symbols // but only 0..16 for DC. (We could constrain them further // based on data depth and mode, but this seems enough.) int maxsymbol=isDC?16:255; for(p=0; p<lastp; p++) { int i=htbl.huffval[p]; if(i<0||i>maxsymbol||dtbl.ehufsi[i]!=0) ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); dtbl.ehufco[i]=huffcode[p]; dtbl.ehufsi[i]=huffsize[p]; } }
/// <summary> /// Encode a single block's worth of coefficients /// </summary> private bool encode_one_block(savable_state state, short[] block, int last_dc_val, c_derived_tbl dctbl, c_derived_tbl actbl) { /* Encode the DC coefficient difference per section F.1.2.1 */ int temp = block[0] - last_dc_val; int temp2 = temp; if (temp < 0) { temp = -temp; /* temp is abs value of input */ /* For a negative input, want temp2 = bitwise complement of abs(input) */ /* This code assumes we are on a two's complement machine */ temp2--; } /* Find the number of bits needed for the magnitude of the coefficient */ int nbits = 0; while (temp != 0) { nbits++; temp >>= 1; } /* Check for out-of-range coefficient values. * Since we're encoding a difference, the range limit is twice as much. */ if (nbits > MAX_HUFFMAN_COEF_BITS + 1) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_DCT_COEF); } /* Emit the Huffman-coded symbol for the number of bits */ if (!emit_bits(state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits])) { return(false); } /* Emit that number of bits of the value, if positive, */ /* or the complement of its magnitude, if negative. */ if (nbits != 0) { /* emit_bits rejects calls with size 0 */ if (!emit_bits(state, temp2, nbits)) { return(false); } } /* Encode the AC coefficients per section F.1.2.2 */ int r = 0; /* r = run length of zeros */ for (int k = 1; k < JpegConstants.DCTSIZE2; k++) { temp = block[JpegUtils.jpeg_natural_order[k]]; if (temp == 0) { r++; } else { /* if run length > 15, must emit special run-length-16 codes (0xF0) */ while (r > 15) { if (!emit_bits(state, actbl.ehufco[0xF0], actbl.ehufsi[0xF0])) { return(false); } r -= 16; } temp2 = temp; if (temp < 0) { temp = -temp; /* temp is abs value of input */ /* This code assumes we are on a two's complement machine */ temp2--; } /* Find the number of bits needed for the magnitude of the coefficient */ nbits = 1; /* there must be at least one 1 bit */ while ((temp >>= 1) != 0) { nbits++; } /* Check for out-of-range coefficient values */ if (nbits > MAX_HUFFMAN_COEF_BITS) { m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_DCT_COEF); } /* Emit Huffman symbol for run length / number of bits */ int i = (r << 4) + nbits; if (!emit_bits(state, actbl.ehufco[i], actbl.ehufsi[i])) { return(false); } /* Emit that number of bits of the value, if positive, */ /* or the complement of its magnitude, if negative. */ if (!emit_bits(state, temp2, nbits)) { return(false); } r = 0; } } /* If the last coef(s) were zero, emit an end-of-block code */ if (r > 0) { if (!emit_bits(state, actbl.ehufco[0], actbl.ehufsi[0])) { return(false); } } return(true); }
/// <summary> /// Encode a single block's worth of coefficients /// </summary> private bool encode_one_block(savable_state state, short[] block, int last_dc_val, c_derived_tbl dctbl, c_derived_tbl actbl) { /* Encode the DC coefficient difference per section F.1.2.1 */ int temp = block[0] - last_dc_val; int temp2 = temp; if (temp < 0) { temp = -temp; /* temp is abs value of input */ /* For a negative input, want temp2 = bitwise complement of abs(input) */ /* This code assumes we are on a two's complement machine */ temp2--; } /* Find the number of bits needed for the magnitude of the coefficient */ int nbits = 0; while (temp != 0) { nbits++; temp >>= 1; } /* Check for out-of-range coefficient values. * Since we're encoding a difference, the range limit is twice as much. */ if (nbits > MAX_HUFFMAN_COEF_BITS + 1) m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_DCT_COEF); /* Emit the Huffman-coded symbol for the number of bits */ if (!emit_bits(state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits])) return false; /* Emit that number of bits of the value, if positive, */ /* or the complement of its magnitude, if negative. */ if (nbits != 0) { /* emit_bits rejects calls with size 0 */ if (!emit_bits(state, temp2, nbits)) return false; } /* Encode the AC coefficients per section F.1.2.2 */ int r = 0; /* r = run length of zeros */ for (int k = 1; k < JpegConstants.DCTSIZE2; k++) { temp = block[JpegUtils.jpeg_natural_order[k]]; if (temp == 0) { r++; } else { /* if run length > 15, must emit special run-length-16 codes (0xF0) */ while (r > 15) { if (!emit_bits(state, actbl.ehufco[0xF0], actbl.ehufsi[0xF0])) return false; r -= 16; } temp2 = temp; if (temp < 0) { temp = -temp; /* temp is abs value of input */ /* This code assumes we are on a two's complement machine */ temp2--; } /* Find the number of bits needed for the magnitude of the coefficient */ nbits = 1; /* there must be at least one 1 bit */ while ((temp >>= 1) != 0) nbits++; /* Check for out-of-range coefficient values */ if (nbits > MAX_HUFFMAN_COEF_BITS) m_cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_DCT_COEF); /* Emit Huffman symbol for run length / number of bits */ int i = (r << 4) + nbits; if (!emit_bits(state, actbl.ehufco[i], actbl.ehufsi[i])) return false; /* Emit that number of bits of the value, if positive, */ /* or the complement of its magnitude, if negative. */ if (!emit_bits(state, temp2, nbits)) return false; r = 0; } } /* If the last coef(s) were zero, emit an end-of-block code */ if (r > 0) { if (!emit_bits(state, actbl.ehufco[0], actbl.ehufsi[0])) return false; } return true; }
// Huffman coding optimization. // // We first scan the supplied data and count the number of uses of each symbol // that is to be Huffman-coded. (This process MUST agree with the code above.) // Then we build a Huffman coding tree for the observed counts. // Symbols which are not needed at all for the particular image are not // assigned any code, which saves space in the DHT marker as well as in // the compressed data. #if ENTROPY_OPT_SUPPORTED // Trial-encode one nMCU's worth of Huffman-compressed differences. // No data is actually output, so no suspension return is possible. static uint encode_mcus_gather_ls(jpeg_compress cinfo, int[][][] diff_buf, uint MCU_row_num, uint MCU_col_num, uint nMCU) { jpeg_lossless_c_codec losslsc = (jpeg_lossless_c_codec)cinfo.coef; lhuff_entropy_encoder entropy = (lhuff_entropy_encoder)losslsc.entropy_private; // Take care of restart intervals if needed if (cinfo.restart_interval != 0) { if (entropy.restarts_to_go == 0) { entropy.restarts_to_go = cinfo.restart_interval; // Update restart state } entropy.restarts_to_go--; } // Set input pointer locations based on MCU_col_num for (int ptrn = 0; ptrn < entropy.num_input_ptrs; ptrn++) { int ci = entropy.input_ptr_info[ptrn].ci; int yoffset = entropy.input_ptr_info[ptrn].yoffset; int MCU_width = entropy.input_ptr_info[ptrn].MCU_width; entropy.input_ptr[ptrn] = diff_buf[ci][MCU_row_num + yoffset]; entropy.input_ptr_ind[ptrn] = (int)MCU_col_num * MCU_width; } for (uint mcu_num = 0; mcu_num < nMCU; mcu_num++) { // Inner loop handles the samples in the MCU for (int sampn = 0; sampn < cinfo.block_in_MCU; sampn++) { c_derived_tbl dctbl = entropy.cur_tbls[sampn]; int[] counts = entropy.cur_counts[sampn]; // Encode the difference per section H.1.2.2 // Input the sample difference int temp3 = entropy.input_ptr_index[sampn]; int temp = entropy.input_ptr[temp3][entropy.input_ptr_ind[temp3]++]; if ((temp & 0x8000) != 0) { // instead of temp < 0 temp = (-temp) & 0x7FFF; // absolute value, mod 2^16 if (temp == 0) { temp = 0x8000; // special case: magnitude = 32768 } } else { temp &= 0x7FFF; // abs value mod 2^16 } // Find the number of bits needed for the magnitude of the difference int nbits = 0; while (temp != 0) { nbits++; temp >>= 1; } // Check for out-of-range difference values. if (nbits > MAX_DIFF_BITS) { ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_DIFF); } // Count the Huffman symbol for the number of bits counts[nbits]++; } } return(nMCU); }
// Encode and output one nMCU's worth of Huffman-compressed differences. static uint encode_mcus_huff_ls(jpeg_compress cinfo, int[][][] diff_buf, uint MCU_row_num, uint MCU_col_num, uint nMCU) { jpeg_lossless_c_codec losslsc = (jpeg_lossless_c_codec)cinfo.coef; lhuff_entropy_encoder entropy = (lhuff_entropy_encoder)losslsc.entropy_private; // Load up working state working_state_ls state; state.output_bytes = cinfo.dest.output_bytes; state.next_output_byte = cinfo.dest.next_output_byte; state.free_in_buffer = cinfo.dest.free_in_buffer; state.cur = entropy.saved; state.cinfo = cinfo; // Emit restart marker if needed if (cinfo.restart_interval != 0) { if (entropy.restarts_to_go == 0) { if (!emit_restart(ref state, entropy.next_restart_num)) { return(0); } } } // Set input pointer locations based on MCU_col_num for (int ptrn = 0; ptrn < entropy.num_input_ptrs; ptrn++) { int ci = entropy.input_ptr_info[ptrn].ci; int yoffset = entropy.input_ptr_info[ptrn].yoffset; int MCU_width = entropy.input_ptr_info[ptrn].MCU_width; entropy.input_ptr[ptrn] = diff_buf[ci][MCU_row_num + yoffset]; entropy.input_ptr_ind[ptrn] = (int)MCU_col_num * MCU_width; } for (uint mcu_num = 0; mcu_num < nMCU; mcu_num++) { // Inner loop handles the samples in the MCU for (int sampn = 0; sampn < cinfo.block_in_MCU; sampn++) { c_derived_tbl dctbl = entropy.cur_tbls[sampn]; // Encode the difference per section H.1.2.2 // Input the sample difference int temp3 = entropy.input_ptr_index[sampn]; int temp = entropy.input_ptr[temp3][entropy.input_ptr_ind[temp3]++]; int temp2; if ((temp & 0x8000) != 0) { // instead of temp < 0 temp = (-temp) & 0x7FFF; // absolute value, mod 2^16 if (temp == 0) { temp2 = temp = 0x8000; // special case: magnitude = 32768 } temp2 = ~temp; // one's complement of magnitude } else { temp &= 0x7FFF; // abs value mod 2^16 temp2 = temp; // magnitude } // Find the number of bits needed for the magnitude of the difference int nbits = 0; while (temp != 0) { nbits++; temp >>= 1; } // Check for out-of-range difference values. if (nbits > MAX_DIFF_BITS) { ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_DIFF); } // Emit the Huffman-coded symbol for the number of bits if (!emit_bits(ref state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits])) { return(mcu_num); } // Emit that number of bits of the value, if positive, // or the complement of its magnitude, if negative. if (nbits != 0 && // emit_bits rejects calls with size 0 nbits != 16) // special case: no bits should be emitted { if (!emit_bits(ref state, (uint)temp2, nbits)) { return(mcu_num); } } } // Completed MCU, so update state cinfo.dest.output_bytes = state.output_bytes; cinfo.dest.next_output_byte = state.next_output_byte; cinfo.dest.free_in_buffer = state.free_in_buffer; entropy.saved = state.cur; // Update restart-interval state too if (cinfo.restart_interval != 0) { if (entropy.restarts_to_go == 0) { entropy.restarts_to_go = cinfo.restart_interval; entropy.next_restart_num++; entropy.next_restart_num &= 7; } entropy.restarts_to_go--; } } return(nMCU); }
// Expand a Huffman table definition into the derived format // Compute the derived values for a Huffman table. // This routine also performs some validation checks on the table. static void jpeg_make_c_derived_tbl(jpeg_compress cinfo, bool isDC, int tblno, ref c_derived_tbl pdtbl) { // Note that huffsize[] and huffcode[] are filled in code-length order, // paralleling the order of the symbols themselves in htbl.huffval[]. // Find the input Huffman table if (tblno < 0 || tblno >= NUM_HUFF_TBLS) { ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno); } JHUFF_TBL htbl = isDC?cinfo.dc_huff_tbl_ptrs[tblno]:cinfo.ac_huff_tbl_ptrs[tblno]; if (htbl == null) { ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, tblno); } // Allocate a workspace if we haven't already done so. if (pdtbl == null) { try { pdtbl = new c_derived_tbl(); } catch { ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4); } } c_derived_tbl dtbl = pdtbl; // Figure C.1: make table of Huffman code length for each symbol byte[] huffsize = new byte[257]; int p = 0; for (byte l = 1; l <= 16; l++) { int i = htbl.bits[l]; // protect against table overrun if (i < 0 || (p + i) > 256) { ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); } while ((i--) != 0) { huffsize[p++] = l; } } huffsize[p] = 0; int lastp = p; // Figure C.2: generate the codes themselves // We also validate that the counts represent a legal Huffman code tree. uint[] huffcode = new uint[257]; uint code = 0; int si = huffsize[0]; p = 0; while (huffsize[p] != 0) { while (((int)huffsize[p]) == si) { huffcode[p++] = code; code++; } // code is now 1 more than the last code used for codelength si; but // it must still fit in si bits, since no code is allowed to be all ones. if (((int)code) >= (1 << si)) { ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); } code <<= 1; si++; } // Figure C.3: generate encoding tables // These are code and size indexed by symbol value // Set all codeless symbols to have code length 0; // this lets us detect duplicate VAL entries here, and later // allows emit_bits to detect any attempt to emit such symbols. for (int i = 0; i < 256; i++) { dtbl.ehufsi[i] = 0; } // This is also a convenient place to check for out-of-range // and duplicated VAL entries. We allow 0..255 for AC symbols // but only 0..16 for DC. (We could constrain them further // based on data depth and mode, but this seems enough.) int maxsymbol = isDC?16:255; for (p = 0; p < lastp; p++) { int i = htbl.huffval[p]; if (i < 0 || i > maxsymbol || dtbl.ehufsi[i] != 0) { ERREXIT(cinfo, J_MESSAGE_CODE.JERR_BAD_HUFF_TABLE); } dtbl.ehufco[i] = huffcode[p]; dtbl.ehufsi[i] = huffsize[p]; } }
// Encode a single block's worth of coefficients static bool encode_one_block(ref working_state_sq state, short[] block, int last_dc_val, c_derived_tbl dctbl, c_derived_tbl actbl) { // Encode the DC coefficient difference per section F.1.2.1 int temp=block[0]-last_dc_val; int temp2=temp; if(temp<0) { temp=-temp; // temp is abs value of input // For a negative input, want temp2 = bitwise complement of abs(input) // This code assumes we are on a two's complement machine temp2--; } // Find the number of bits needed for the magnitude of the coefficient int nbits=0; while(temp!=0) { nbits++; temp>>=1; } // Check for out-of-range coefficient values. // Since we're encoding a difference, the range limit is twice as much. if(nbits>MAX_COEF_BITS+1) ERREXIT(state.cinfo, J_MESSAGE_CODE.JERR_BAD_DCT_COEF); // Emit the Huffman-coded symbol for the number of bits if(!emit_bits(ref state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits])) return false; // Emit that number of bits of the value, if positive, // or the complement of its magnitude, if negative. if(nbits!=0) // emit_bits rejects calls with size 0 { if(!emit_bits(ref state, (uint)temp2, nbits)) return false; } // Encode the AC coefficients per section F.1.2.2 int r=0; // r = run length of zeros for(int k=1; k<DCTSIZE2; k++) { temp=block[jpeg_natural_order[k]]; if(temp==0) { r++; continue; } // if run length > 15, must emit special run-length-16 codes (0xF0) while(r>15) { if(!emit_bits(ref state, actbl.ehufco[0xF0], actbl.ehufsi[0xF0])) return false; r-=16; } temp2=temp; if(temp<0) { temp=-temp; // temp is abs value of input // This code assumes we are on a two's complement machine temp2--; } // Find the number of bits needed for the magnitude of the coefficient nbits=1; // there must be at least one 1 bit while((temp>>=1)!=0) nbits++; // Check for out-of-range coefficient values if(nbits>MAX_COEF_BITS) ERREXIT(state.cinfo, J_MESSAGE_CODE.JERR_BAD_DCT_COEF); // Emit Huffman symbol for run length / number of bits int i=(r<<4)+nbits; if(!emit_bits(ref state, actbl.ehufco[i], actbl.ehufsi[i])) return false; // Emit that number of bits of the value, if positive, // or the complement of its magnitude, if negative. if(!emit_bits(ref state, (uint)temp2, nbits)) return false; r=0; } // If the last coef(s) were zero, emit an end-of-block code if(r>0) { if(!emit_bits(ref state, actbl.ehufco[0], actbl.ehufsi[0])) return false; } return true; }
// Encode a single block's worth of coefficients static bool encode_one_block(ref working_state_sq state, short[] block, int last_dc_val, c_derived_tbl dctbl, c_derived_tbl actbl) { // Encode the DC coefficient difference per section F.1.2.1 int temp = block[0] - last_dc_val; int temp2 = temp; if (temp < 0) { temp = -temp; // temp is abs value of input // For a negative input, want temp2 = bitwise complement of abs(input) // This code assumes we are on a two's complement machine temp2--; } // Find the number of bits needed for the magnitude of the coefficient int nbits = 0; while (temp != 0) { nbits++; temp >>= 1; } // Check for out-of-range coefficient values. // Since we're encoding a difference, the range limit is twice as much. if (nbits > MAX_COEF_BITS + 1) { ERREXIT(state.cinfo, J_MESSAGE_CODE.JERR_BAD_DCT_COEF); } // Emit the Huffman-coded symbol for the number of bits if (!emit_bits(ref state, dctbl.ehufco[nbits], dctbl.ehufsi[nbits])) { return(false); } // Emit that number of bits of the value, if positive, // or the complement of its magnitude, if negative. if (nbits != 0) // emit_bits rejects calls with size 0 { if (!emit_bits(ref state, (uint)temp2, nbits)) { return(false); } } // Encode the AC coefficients per section F.1.2.2 int r = 0; // r = run length of zeros for (int k = 1; k < DCTSIZE2; k++) { temp = block[jpeg_natural_order[k]]; if (temp == 0) { r++; continue; } // if run length > 15, must emit special run-length-16 codes (0xF0) while (r > 15) { if (!emit_bits(ref state, actbl.ehufco[0xF0], actbl.ehufsi[0xF0])) { return(false); } r -= 16; } temp2 = temp; if (temp < 0) { temp = -temp; // temp is abs value of input // This code assumes we are on a two's complement machine temp2--; } // Find the number of bits needed for the magnitude of the coefficient nbits = 1; // there must be at least one 1 bit while ((temp >>= 1) != 0) { nbits++; } // Check for out-of-range coefficient values if (nbits > MAX_COEF_BITS) { ERREXIT(state.cinfo, J_MESSAGE_CODE.JERR_BAD_DCT_COEF); } // Emit Huffman symbol for run length / number of bits int i = (r << 4) + nbits; if (!emit_bits(ref state, actbl.ehufco[i], actbl.ehufsi[i])) { return(false); } // Emit that number of bits of the value, if positive, // or the complement of its magnitude, if negative. if (!emit_bits(ref state, (uint)temp2, nbits)) { return(false); } r = 0; } // If the last coef(s) were zero, emit an end-of-block code if (r > 0) { if (!emit_bits(ref state, actbl.ehufco[0], actbl.ehufsi[0])) { return(false); } } return(true); }