📄 jcphuff.c
字号:
} /* Find the number of bits needed for the magnitude of the coefficient */ nbits = 0; while (temp) { 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(cinfo, JERR_BAD_DCT_COEF); /* Count/emit the Huffman-coded symbol for the number of bits */ emit_symbol(entropy, compptr->dc_tbl_no, nbits); /* Emit that number of bits of the value, if positive, */ /* or the complement of its magnitude, if negative. */ if (nbits) /* emit_bits rejects calls with size 0 */ emit_bits(entropy, (unsigned int) temp2, nbits); } cinfo->dest->next_output_byte = entropy->next_output_byte; cinfo->dest->free_in_buffer = entropy->free_in_buffer; /* Update restart-interval state too */ if (cinfo->restart_interval) { 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 TRUE;}/* * MCU encoding for AC initial scan (either spectral selection, * or first pass of successive approximation). */METHODDEF(boolean)encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data){ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; register int temp, temp2; register int nbits; register int r, k; int Se = cinfo->Se; int Al = cinfo->Al; JBLOCKROW block; entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; /* Emit restart marker if needed */ if (cinfo->restart_interval) if (entropy->restarts_to_go == 0) emit_restart(entropy, entropy->next_restart_num); /* Encode the MCU data block */ block = MCU_data[0]; /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */ r = 0; /* r = run length of zeros */ for (k = cinfo->Ss; k <= Se; k++) { if ((temp = (*block)[jpeg_natural_order[k]]) == 0) { r++; continue; } /* We must apply the point transform by Al. For AC coefficients this * is an integer division with rounding towards 0. To do this portably * in C, we shift after obtaining the absolute value; so the code is * interwoven with finding the abs value (temp) and output bits (temp2). */ if (temp < 0) { temp = -temp; /* temp is abs value of input */ temp >>= Al; /* apply the point transform */ /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ temp2 = ~temp; } else { temp >>= Al; /* apply the point transform */ temp2 = temp; } /* Watch out for case that nonzero coef is zero after point transform */ if (temp == 0) { r++; continue; } /* Emit any pending EOBRUN */ if (entropy->EOBRUN > 0) emit_eobrun(entropy); /* if run length > 15, must emit special run-length-16 codes (0xF0) */ while (r > 15) { emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); r -= 16; } /* 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)) nbits++; /* Check for out-of-range coefficient values */ if (nbits > MAX_COEF_BITS) ERREXIT(cinfo, JERR_BAD_DCT_COEF); /* Count/emit Huffman symbol for run length / number of bits */ emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits); /* Emit that number of bits of the value, if positive, */ /* or the complement of its magnitude, if negative. */ emit_bits(entropy, (unsigned int) temp2, nbits); r = 0; /* reset zero run length */ } if (r > 0) { /* If there are trailing zeroes, */ entropy->EOBRUN++; /* count an EOB */ if (entropy->EOBRUN == 0x7FFF) emit_eobrun(entropy); /* force it out to avoid overflow */ } cinfo->dest->next_output_byte = entropy->next_output_byte; cinfo->dest->free_in_buffer = entropy->free_in_buffer; /* Update restart-interval state too */ if (cinfo->restart_interval) { 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 TRUE;}/* * MCU encoding for DC successive approximation refinement scan. * Note: we assume such scans can be multi-component, although the spec * is not very clear on the point. */METHODDEF(boolean)encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data){ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; register int temp; int blkn; int Al = cinfo->Al; JBLOCKROW block; entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; /* Emit restart marker if needed */ if (cinfo->restart_interval) if (entropy->restarts_to_go == 0) emit_restart(entropy, entropy->next_restart_num); /* Encode the MCU data blocks */ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { block = MCU_data[blkn]; /* We simply emit the Al'th bit of the DC coefficient value. */ temp = (*block)[0]; emit_bits(entropy, (unsigned int) (temp >> Al), 1); } cinfo->dest->next_output_byte = entropy->next_output_byte; cinfo->dest->free_in_buffer = entropy->free_in_buffer; /* Update restart-interval state too */ if (cinfo->restart_interval) { 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 TRUE;}/* * MCU encoding for AC successive approximation refinement scan. */METHODDEF(boolean)encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data){ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; register int temp; register int r, k; int EOB; char *BR_buffer; unsigned int BR; int Se = cinfo->Se; int Al = cinfo->Al; JBLOCKROW block; int absvalues[DCTSIZE2]; entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; /* Emit restart marker if needed */ if (cinfo->restart_interval) if (entropy->restarts_to_go == 0) emit_restart(entropy, entropy->next_restart_num); /* Encode the MCU data block */ block = MCU_data[0]; /* It is convenient to make a pre-pass to determine the transformed * coefficients' absolute values and the EOB position. */ EOB = 0; for (k = cinfo->Ss; k <= Se; k++) { temp = (*block)[jpeg_natural_order[k]]; /* We must apply the point transform by Al. For AC coefficients this * is an integer division with rounding towards 0. To do this portably * in C, we shift after obtaining the absolute value. */ if (temp < 0) temp = -temp; /* temp is abs value of input */ temp >>= Al; /* apply the point transform */ absvalues[k] = temp; /* save abs value for main pass */ if (temp == 1) EOB = k; /* EOB = index of last newly-nonzero coef */ } /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */ r = 0; /* r = run length of zeros */ BR = 0; /* BR = count of buffered bits added now */ BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */ for (k = cinfo->Ss; k <= Se; k++) { if ((temp = absvalues[k]) == 0) { r++; continue; } /* Emit any required ZRLs, but not if they can be folded into EOB */ while (r > 15 && k <= EOB) { /* emit any pending EOBRUN and the BE correction bits */ emit_eobrun(entropy); /* Emit ZRL */ emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); r -= 16; /* Emit buffered correction bits that must be associated with ZRL */ emit_buffered_bits(entropy, BR_buffer, BR); BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ BR = 0; } /* If the coef was previously nonzero, it only needs a correction bit. * NOTE: a straight translation of the spec's figure G.7 would suggest * that we also need to test r > 15. But if r > 15, we can only get here * if k > EOB, which implies that this coefficient is not 1. */ if (temp > 1) { /* The correction bit is the next bit of the absolute value. */ BR_buffer[BR++] = (char) (temp & 1); continue; } /* Emit any pending EOBRUN and the BE correction bits */ emit_eobrun(entropy); /* Count/emit Huffman symbol for run length / number of bits */ emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1); /* Emit output bit for newly-nonzero coef */ temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1; emit_bits(entropy, (unsigned int) temp, 1); /* Emit buffered correction bits that must be associated with this code */ emit_buffered_bits(entropy, BR_buffer, BR); BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ BR = 0; r = 0; /* reset zero run length */ } if (r > 0 || BR > 0) { /* If there are trailing zeroes, */ entropy->EOBRUN++; /* count an EOB */ entropy->BE += BR; /* concat my correction bits to older ones */ /* We force out the EOB if we risk either: * 1. overflow of the EOB counter; * 2. overflow of the correction bit buffer during the next MCU. */ if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1)) emit_eobrun(entropy); } cinfo->dest->next_output_byte = entropy->next_output_byte; cinfo->dest->free_in_buffer = entropy->free_in_buffer; /* Update restart-interval state too */ if (cinfo->restart_interval) { 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 TRUE;}/* * Finish up at the end of a Huffman-compressed progressive scan. */METHODDEF(void)finish_pass_phuff (j_compress_ptr cinfo){ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; /* Flush out any buffered data */ emit_eobrun(entropy); flush_bits(entropy); cinfo->dest->next_output_byte = entropy->next_output_byte; cinfo->dest->free_in_buffer = entropy->free_in_buffer;}/* * Finish up a statistics-gathering pass and create the new Huffman tables. */METHODDEF(void)finish_pass_gather_phuff (j_compress_ptr cinfo){ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; boolean is_DC_band; int ci, tbl; jpeg_component_info * compptr; JHUFF_TBL **htblptr; boolean did[NUM_HUFF_TBLS]; /* Flush out buffered data (all we care about is counting the EOB symbol) */ emit_eobrun(entropy); is_DC_band = (cinfo->Ss == 0); /* It's important not to apply jpeg_gen_optimal_table more than once * per table, because it clobbers the input frequency counts! */ MEMZERO(did, SIZEOF(did)); for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; if (is_DC_band) { if (cinfo->Ah != 0) /* DC refinement needs no table */ continue; tbl = compptr->dc_tbl_no; } else { tbl = compptr->ac_tbl_no; } if (! did[tbl]) { if (is_DC_band) htblptr = & cinfo->dc_huff_tbl_ptrs[tbl]; else htblptr = & cinfo->ac_huff_tbl_ptrs[tbl]; if (*htblptr == NULL) *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]); did[tbl] = TRUE; } }}/* * Module initialization routine for progressive Huffman entropy encoding. */GLOBAL(void)jinit_phuff_encoder (j_compress_ptr cinfo){ phuff_entropy_ptr entropy; int i; entropy = (phuff_entropy_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(phuff_entropy_encoder)); cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; entropy->pub.start_pass = start_pass_phuff; /* Mark tables unallocated */ for (i = 0; i < NUM_HUFF_TBLS; i++) { entropy->derived_tbls[i] = NULL; entropy->count_ptrs[i] = NULL; } entropy->bit_buffer = NULL; /* needed only in AC refinement scan */}#endif /* C_PROGRESSIVE_SUPPORTED */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -