| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| typedef struct { |
| struct jpeg_entropy_encoder pub; |
| |
| |
| void (*AC_first_prepare) (const JCOEF *block, |
| const int *jpeg_natural_order_start, int Sl, |
| int Al, JCOEF *values, size_t *zerobits); |
| |
| int (*AC_refine_prepare) (const JCOEF *block, |
| const int *jpeg_natural_order_start, int Sl, |
| int Al, JCOEF *absvalues, size_t *bits); |
| |
| |
| boolean gather_statistics; |
| |
| |
| |
| |
| JOCTET *next_output_byte; |
| size_t free_in_buffer; |
| size_t put_buffer; |
| int put_bits; |
| j_compress_ptr cinfo; |
| |
| |
| int last_dc_val[MAX_COMPS_IN_SCAN]; |
| |
| |
| int ac_tbl_no; |
| unsigned int EOBRUN; |
| unsigned int BE; |
| char *bit_buffer; |
| |
| |
| unsigned int restarts_to_go; |
| int next_restart_num; |
| |
| |
| |
| |
| |
| c_derived_tbl *derived_tbls[NUM_HUFF_TBLS]; |
| |
| |
| long *count_ptrs[NUM_HUFF_TBLS]; |
| } phuff_entropy_encoder; |
| |
| typedef phuff_entropy_encoder *phuff_entropy_ptr; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ((ishift_temp = (x)) < 0 ? \ |
| (ishift_temp >> (shft)) | ((~0) << (16 - (shft))) : \ |
| (ishift_temp >> (shft))) |
| |
| |
| |
| |
| |
| |
| |
| |
| METHODDEF(boolean) encode_mcu_DC_first(j_compress_ptr cinfo, |
| JBLOCKROW *MCU_data); |
| METHODDEF(void) encode_mcu_AC_first_prepare |
| (const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al, |
| JCOEF *values, size_t *zerobits); |
| METHODDEF(boolean) encode_mcu_AC_first(j_compress_ptr cinfo, |
| JBLOCKROW *MCU_data); |
| METHODDEF(boolean) encode_mcu_DC_refine(j_compress_ptr cinfo, |
| JBLOCKROW *MCU_data); |
| METHODDEF(int) encode_mcu_AC_refine_prepare |
| (const JCOEF *block, const int *jpeg_natural_order_start, int Sl, int Al, |
| JCOEF *absvalues, size_t *bits); |
| METHODDEF(boolean) encode_mcu_AC_refine(j_compress_ptr cinfo, |
| JBLOCKROW *MCU_data); |
| METHODDEF(void) finish_pass_phuff(j_compress_ptr cinfo); |
| METHODDEF(void) finish_pass_gather_phuff(j_compress_ptr cinfo); |
| |
| |
| |
| INLINE |
| METHODDEF(int) |
| count_zeroes(size_t *x) |
| { |
| int result; |
| |
| result = __builtin_ctzl(*x); |
| *x >>= result; |
| |
| _BitScanForward64(&result, *x); |
| *x >>= result; |
| |
| _BitScanForward(&result, *x); |
| *x >>= result; |
| |
| result = 0; |
| while ((*x & 1) == 0) { |
| ++result; |
| *x >>= 1; |
| } |
| |
| return result; |
| } |
| |
| |
| |
| |
| |
| |
| METHODDEF(void) |
| start_pass_phuff(j_compress_ptr cinfo, boolean gather_statistics) |
| { |
| phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy; |
| boolean is_DC_band; |
| int ci, tbl; |
| jpeg_component_info *compptr; |
| |
| entropy->cinfo = cinfo; |
| entropy->gather_statistics = gather_statistics; |
| |
| is_DC_band = (cinfo->Ss == 0); |
| |
| |
| |
| |
| if (cinfo->Ah == 0) { |
| if (is_DC_band) |
| entropy->pub.encode_mcu = encode_mcu_DC_first; |
| else |
| entropy->pub.encode_mcu = encode_mcu_AC_first; |
| if (jsimd_can_encode_mcu_AC_first_prepare()) |
| entropy->AC_first_prepare = jsimd_encode_mcu_AC_first_prepare; |
| else |
| entropy->AC_first_prepare = encode_mcu_AC_first_prepare; |
| } else { |
| if (is_DC_band) |
| entropy->pub.encode_mcu = encode_mcu_DC_refine; |
| else { |
| entropy->pub.encode_mcu = encode_mcu_AC_refine; |
| if (jsimd_can_encode_mcu_AC_refine_prepare()) |
| entropy->AC_refine_prepare = jsimd_encode_mcu_AC_refine_prepare; |
| else |
| entropy->AC_refine_prepare = encode_mcu_AC_refine_prepare; |
| |
| if (entropy->bit_buffer == NULL) |
| entropy->bit_buffer = (char *) |
| (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, |
| MAX_CORR_BITS * sizeof(char)); |
| } |
| } |
| if (gather_statistics) |
| entropy->pub.finish_pass = finish_pass_gather_phuff; |
| else |
| entropy->pub.finish_pass = finish_pass_phuff; |
| |
| |
| |
| |
| for (ci = 0; ci < cinfo->comps_in_scan; ci++) { |
| compptr = cinfo->cur_comp_info[ci]; |
| |
| entropy->last_dc_val[ci] = 0; |
| |
| if (is_DC_band) { |
| if (cinfo->Ah != 0) |
| continue; |
| tbl = compptr->dc_tbl_no; |
| } else { |
| entropy->ac_tbl_no = tbl = compptr->ac_tbl_no; |
| } |
| if (gather_statistics) { |
| |
| |
| if (tbl < 0 || tbl >= NUM_HUFF_TBLS) |
| ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl); |
| |
| |
| if (entropy->count_ptrs[tbl] == NULL) |
| entropy->count_ptrs[tbl] = (long *) |
| (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, |
| 257 * sizeof(long)); |
| MEMZERO(entropy->count_ptrs[tbl], 257 * sizeof(long)); |
| } else { |
| |
| |
| jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl, |
| &entropy->derived_tbls[tbl]); |
| } |
| } |
| |
| |
| entropy->EOBRUN = 0; |
| entropy->BE = 0; |
| |
| |
| entropy->put_buffer = 0; |
| entropy->put_bits = 0; |
| |
| |
| entropy->restarts_to_go = cinfo->restart_interval; |
| entropy->next_restart_num = 0; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| *(entropy)->next_output_byte++ = (JOCTET)(val); \ |
| if (--(entropy)->free_in_buffer == 0) \ |
| dump_buffer(entropy); \ |
| } |
| |
| |
| LOCAL(void) |
| dump_buffer(phuff_entropy_ptr entropy) |
| |
| { |
| struct jpeg_destination_mgr *dest = entropy->cinfo->dest; |
| |
| if (!(*dest->empty_output_buffer) (entropy->cinfo)) |
| ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND); |
| |
| entropy->next_output_byte = dest->next_output_byte; |
| entropy->free_in_buffer = dest->free_in_buffer; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| LOCAL(void) |
| emit_bits(phuff_entropy_ptr entropy, unsigned int code, int size) |
| |
| { |
| |
| register size_t put_buffer = (size_t)code; |
| register int put_bits = entropy->put_bits; |
| |
| |
| if (size == 0) |
| ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); |
| |
| if (entropy->gather_statistics) |
| return; |
| |
| put_buffer &= (((size_t)1) << size) - 1; |
| |
| put_bits += size; |
| |
| put_buffer <<= 24 - put_bits; |
| |
| put_buffer |= entropy->put_buffer; |
| |
| while (put_bits >= 8) { |
| int c = (int)((put_buffer >> 16) & 0xFF); |
| |
| emit_byte(entropy, c); |
| if (c == 0xFF) { |
| emit_byte(entropy, 0); |
| } |
| put_buffer <<= 8; |
| put_bits -= 8; |
| } |
| |
| entropy->put_buffer = put_buffer; |
| entropy->put_bits = put_bits; |
| } |
| |
| |
| LOCAL(void) |
| flush_bits(phuff_entropy_ptr entropy) |
| { |
| emit_bits(entropy, 0x7F, 7); |
| entropy->put_buffer = 0; |
| entropy->put_bits = 0; |
| } |
| |
| |
| |
| |
| |
| |
| LOCAL(void) |
| emit_symbol(phuff_entropy_ptr 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]); |
| } |
| } |
| |
| |
| |
| |
| |
| |
| LOCAL(void) |
| emit_buffered_bits(phuff_entropy_ptr entropy, char *bufstart, |
| unsigned int nbits) |
| { |
| if (entropy->gather_statistics) |
| return; |
| |
| while (nbits > 0) { |
| emit_bits(entropy, (unsigned int)(*bufstart), 1); |
| bufstart++; |
| nbits--; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| LOCAL(void) |
| emit_eobrun(phuff_entropy_ptr entropy) |
| { |
| register int temp, nbits; |
| |
| if (entropy->EOBRUN > 0) { |
| temp = entropy->EOBRUN; |
| nbits = JPEG_NBITS_NONZERO(temp) - 1; |
| |
| if (nbits > 14) |
| ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); |
| |
| emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4); |
| if (nbits) |
| emit_bits(entropy, entropy->EOBRUN, nbits); |
| |
| entropy->EOBRUN = 0; |
| |
| |
| emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE); |
| entropy->BE = 0; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| LOCAL(void) |
| emit_restart(phuff_entropy_ptr entropy, int restart_num) |
| { |
| int ci; |
| |
| emit_eobrun(entropy); |
| |
| if (!entropy->gather_statistics) { |
| flush_bits(entropy); |
| emit_byte(entropy, 0xFF); |
| emit_byte(entropy, JPEG_RST0 + restart_num); |
| } |
| |
| if (entropy->cinfo->Ss == 0) { |
| |
| for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++) |
| entropy->last_dc_val[ci] = 0; |
| } else { |
| |
| entropy->EOBRUN = 0; |
| entropy->BE = 0; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| METHODDEF(boolean) |
| encode_mcu_DC_first(j_compress_ptr cinfo, JBLOCKROW *MCU_data) |
| { |
| phuff_entropy_ptr entropy = (phuff_entropy_ptr)cinfo->entropy; |
| register int temp, temp2, temp3; |
| register int nbits; |
| int blkn, ci; |
| int Al = cinfo->Al; |
| JBLOCKROW block; |
| jpeg_component_info *compptr; |
| ISHIFT_TEMPS |
| |
| entropy->next_output_byte = cinfo->dest->next_output_byte; |
| entropy->free_in_buffer = cinfo->dest->free_in_buffer; |
| |
| |
| if (cinfo->restart_interval) |
| if (entropy->restarts_to_go == 0) |
| emit_restart(entropy, entropy->next_restart_num); |
| |
| |
| for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { |
| block = MCU_data[blkn]; |
| ci = cinfo->MCU_membership[blkn]; |
| compptr = cinfo->cur_comp_info[ci]; |
| |
| |
| |
| |
| temp2 = IRIGHT_SHIFT((int)((*block)[0]), Al); |
| |
| |
| temp = temp2 - entropy->last_dc_val[ci]; |
| entropy->last_dc_val[ci] = temp2; |
| |
| |
| |
| |
| |
| |
| |
| |
| temp3 = temp >> (CHAR_BIT * sizeof(int) - 1); |
| temp ^= temp3; |
| temp -= temp3; |
| |
| temp2 = temp ^ temp3; |
| |
| |
| nbits = JPEG_NBITS(temp); |
| |
| |
| |
| if (nbits > MAX_COEF_BITS + 1) |
| ERREXIT(cinfo, JERR_BAD_DCT_COEF); |
| |
| |
| emit_symbol(entropy, compptr->dc_tbl_no, nbits); |
| |
| |
| |
| if (nbits) |
| 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; |
| |
| |
| 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; |
| } |
| |
| |
| |
| |
| |
| |
| |
| for (k = 0; k < Sl; k++) { \ |
| temp = block[jpeg_natural_order_start[k]]; \ |
| if (temp == 0) \ |
| continue; \ |
| |
| |
| |
| |
| \ |
| temp2 = temp >> (CHAR_BIT * sizeof(int) - 1); \ |
| temp ^= temp2; \ |
| temp -= temp2; \ |
| temp >>= Al; \ |
| \ |
| if (temp == 0) \ |
| continue; \ |
| \ |
| temp2 ^= temp; \ |
| values[k] = temp; \ |
| values[k + DCTSIZE2] = temp2; \ |
| zerobits |= ((size_t)1U) << k; \ |
| } \ |
| } |
| |
| METHODDEF(void) |
| encode_mcu_AC_first_prepare(const JCOEF *block, |
| const int *jpeg_natural_order_start, int Sl, |
| int Al, JCOEF *values, size_t *bits) |
| { |
| register int k, temp, temp2; |
| size_t zerobits = 0U; |
| int Sl0 = Sl; |
| |
| |
| if (Sl0 > 32) |
| Sl0 = 32; |
| |
| |
| COMPUTE_ABSVALUES_AC_FIRST(Sl0); |
| |
| bits[0] = zerobits; |
| |
| zerobits = 0U; |
| |
| if (Sl > 32) { |
| Sl -= 32; |
| jpeg_natural_order_start += 32; |
| values += 32; |
| |
| COMPUTE_ABSVALUES_AC_FIRST(Sl); |
| } |
| bits[1] = zerobits; |
| |
| } |
| |
| |
| |
| |
| |
| |
| |
| while (zerobits) { \ |
| r = count_zeroes(&zerobits); \ |
| cvalue += r; \ |
| label \ |
| temp = cvalue[0]; \ |
| temp2 = cvalue[DCTSIZE2]; \ |
| \ |
| \ |
| while (r > 15) { \ |
| emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); \ |
| r -= 16; \ |
| } \ |
| \ |
| \ |
| nbits = JPEG_NBITS_NONZERO(temp); \ |
| \ |
| if (nbits > MAX_COEF_BITS) \ |
| ERREXIT(cinfo, JERR_BAD_DCT_COEF); \ |
| \ |
| \ |
| emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits); \ |
| \ |
| \ |
| \ |
| emit_bits(entropy, (unsigned int)temp2, nbits); \ |
| \ |
| cvalue++; \ |
| zerobits >>= 1; \ |
| } \ |
| } |
| |
| 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, r; |
| int Sl = cinfo->Se - cinfo->Ss + 1; |
| int Al = cinfo->Al; |
| JCOEF values_unaligned[2 * DCTSIZE2 + 15]; |
| JCOEF *values; |
| const JCOEF *cvalue; |
| size_t zerobits; |
| size_t bits[8 / SIZEOF_SIZE_T]; |
| |
| entropy->next_output_byte = cinfo->dest->next_output_byte; |
| entropy->free_in_buffer = cinfo->dest->free_in_buffer; |
| |
| |
| if (cinfo->restart_interval) |
| if (entropy->restarts_to_go == 0) |
| emit_restart(entropy, entropy->next_restart_num); |
| |
| |
| cvalue = values = (JCOEF *)PAD((size_t)values_unaligned, 16); |
| |
| |
| cvalue = values = values_unaligned; |
| |
| |
| |
| entropy->AC_first_prepare(MCU_data[0][0], jpeg_natural_order + cinfo->Ss, |
| Sl, Al, values, bits); |
| |
| zerobits = bits[0]; |
| |
| zerobits |= bits[1]; |
| |
| |
| |
| if (zerobits && (entropy->EOBRUN > 0)) |
| emit_eobrun(entropy); |
| |
| |
| zerobits = bits[0]; |
| |
| |
| |
| |
| ENCODE_COEFS_AC_FIRST((void)0;); |
| |
| |
| zerobits = bits[1]; |
| if (zerobits) { |
| int diff = ((values + DCTSIZE2 / 2) - cvalue); |
| r = count_zeroes(&zerobits); |
| r += diff; |
| cvalue += r; |
| goto first_iter_ac_first; |
| } |
| |
| ENCODE_COEFS_AC_FIRST(first_iter_ac_first:); |
| |
| |
| if (cvalue < (values + Sl)) { |
| entropy->EOBRUN++; |
| if (entropy->EOBRUN == 0x7FFF) |
| emit_eobrun(entropy); |
| } |
| |
| cinfo->dest->next_output_byte = entropy->next_output_byte; |
| cinfo->dest->free_in_buffer = entropy->free_in_buffer; |
| |
| |
| 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; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| if (cinfo->restart_interval) |
| if (entropy->restarts_to_go == 0) |
| emit_restart(entropy, entropy->next_restart_num); |
| |
| |
| for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { |
| block = MCU_data[blkn]; |
| |
| |
| 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; |
| |
| |
| 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; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| \ |
| for (k = 0; k < Sl; k++) { \ |
| temp = block[jpeg_natural_order_start[k]]; \ |
| |
| |
| |
| \ |
| temp2 = temp >> (CHAR_BIT * sizeof(int) - 1); \ |
| temp ^= temp2; \ |
| temp -= temp2; \ |
| temp >>= Al; \ |
| if (temp != 0) { \ |
| zerobits |= ((size_t)1U) << k; \ |
| signbits |= ((size_t)(temp2 + 1)) << k; \ |
| } \ |
| absvalues[k] = (JCOEF)temp; \ |
| if (temp == 1) \ |
| EOB = k + koffset; \ |
| } \ |
| } |
| |
| METHODDEF(int) |
| encode_mcu_AC_refine_prepare(const JCOEF *block, |
| const int *jpeg_natural_order_start, int Sl, |
| int Al, JCOEF *absvalues, size_t *bits) |
| { |
| register int k, temp, temp2; |
| int EOB = 0; |
| size_t zerobits = 0U, signbits = 0U; |
| int Sl0 = Sl; |
| |
| |
| if (Sl0 > 32) |
| Sl0 = 32; |
| |
| |
| COMPUTE_ABSVALUES_AC_REFINE(Sl0, 0); |
| |
| bits[0] = zerobits; |
| |
| bits[1] = signbits; |
| |
| bits[2] = signbits; |
| |
| zerobits = 0U; |
| signbits = 0U; |
| |
| if (Sl > 32) { |
| Sl -= 32; |
| jpeg_natural_order_start += 32; |
| absvalues += 32; |
| |
| COMPUTE_ABSVALUES_AC_REFINE(Sl, 32); |
| } |
| |
| bits[1] = zerobits; |
| bits[3] = signbits; |
| |
| |
| return EOB; |
| } |
| |
| |
| |
| |
| |
| |
| |
| while (zerobits) { \ |
| int idx = count_zeroes(&zerobits); \ |
| r += idx; \ |
| cabsvalue += idx; \ |
| signbits >>= idx; \ |
| label \ |
| \ |
| while (r > 15 && (cabsvalue <= EOBPTR)) { \ |
| \ |
| emit_eobrun(entropy); \ |
| \ |
| emit_symbol(entropy, entropy->ac_tbl_no, 0xF0); \ |
| r -= 16; \ |
| \ |
| emit_buffered_bits(entropy, BR_buffer, BR); \ |
| BR_buffer = entropy->bit_buffer; \ |
| BR = 0; \ |
| } \ |
| \ |
| temp = *cabsvalue++; \ |
| \ |
| |
| |
| |
| |
| \ |
| if (temp > 1) { \ |
| \ |
| BR_buffer[BR++] = (char)(temp & 1); \ |
| signbits >>= 1; \ |
| zerobits >>= 1; \ |
| continue; \ |
| } \ |
| \ |
| \ |
| emit_eobrun(entropy); \ |
| \ |
| \ |
| emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1); \ |
| \ |
| \ |
| temp = signbits & 1; \ |
| emit_bits(entropy, (unsigned int)temp, 1); \ |
| \ |
| \ |
| emit_buffered_bits(entropy, BR_buffer, BR); \ |
| BR_buffer = entropy->bit_buffer; \ |
| BR = 0; \ |
| r = 0; \ |
| signbits >>= 1; \ |
| zerobits >>= 1; \ |
| } \ |
| } |
| |
| 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, r; |
| char *BR_buffer; |
| unsigned int BR; |
| int Sl = cinfo->Se - cinfo->Ss + 1; |
| int Al = cinfo->Al; |
| JCOEF absvalues_unaligned[DCTSIZE2 + 15]; |
| JCOEF *absvalues; |
| const JCOEF *cabsvalue, *EOBPTR; |
| size_t zerobits, signbits; |
| size_t bits[16 / SIZEOF_SIZE_T]; |
| |
| entropy->next_output_byte = cinfo->dest->next_output_byte; |
| entropy->free_in_buffer = cinfo->dest->free_in_buffer; |
| |
| |
| if (cinfo->restart_interval) |
| if (entropy->restarts_to_go == 0) |
| emit_restart(entropy, entropy->next_restart_num); |
| |
| |
| cabsvalue = absvalues = (JCOEF *)PAD((size_t)absvalues_unaligned, 16); |
| |
| |
| cabsvalue = absvalues = absvalues_unaligned; |
| |
| |
| |
| EOBPTR = absvalues + |
| entropy->AC_refine_prepare(MCU_data[0][0], jpeg_natural_order + cinfo->Ss, |
| Sl, Al, absvalues, bits); |
| |
| |
| |
| r = 0; |
| BR = 0; |
| BR_buffer = entropy->bit_buffer + entropy->BE; |
| |
| zerobits = bits[0]; |
| |
| signbits = bits[1]; |
| |
| signbits = bits[2]; |
| |
| ENCODE_COEFS_AC_REFINE((void)0;); |
| |
| |
| zerobits = bits[1]; |
| signbits = bits[3]; |
| |
| if (zerobits) { |
| int diff = ((absvalues + DCTSIZE2 / 2) - cabsvalue); |
| int idx = count_zeroes(&zerobits); |
| signbits >>= idx; |
| idx += diff; |
| r += idx; |
| cabsvalue += idx; |
| goto first_iter_ac_refine; |
| } |
| |
| ENCODE_COEFS_AC_REFINE(first_iter_ac_refine:); |
| |
| |
| r |= (int)((absvalues + Sl) - cabsvalue); |
| |
| if (r > 0 || BR > 0) { |
| entropy->EOBRUN++; |
| entropy->BE += BR; |
| |
| |
| |
| |
| 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; |
| |
| |
| 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; |
| } |
| |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| emit_eobrun(entropy); |
| flush_bits(entropy); |
| |
| cinfo->dest->next_output_byte = entropy->next_output_byte; |
| cinfo->dest->free_in_buffer = entropy->free_in_buffer; |
| } |
| |
| |
| |
| |
| |
| |
| 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]; |
| |
| |
| emit_eobrun(entropy); |
| |
| is_DC_band = (cinfo->Ss == 0); |
| |
| |
| |
| |
| 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) |
| 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; |
| } |
| } |
| } |
| |
| |
| |
| |
| |
| |
| 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; |
| |
| |
| for (i = 0; i < NUM_HUFF_TBLS; i++) { |
| entropy->derived_tbls[i] = NULL; |
| entropy->count_ptrs[i] = NULL; |
| } |
| entropy->bit_buffer = NULL; |
| } |
| |
| |