123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137 |
- #define JPEG_INTERNALS
- #include "jinclude.h"
- #include "jpeglib.h"
- #include "jsimd.h"
- #include "jconfigint.h"
- #include <limits.h>
- #if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \
- defined(_M_ARM) || defined(_M_ARM64)
- #if !defined(__thumb__) || defined(__thumb2__)
- #define USE_CLZ_INTRINSIC
- #endif
- #endif
- #ifdef USE_CLZ_INTRINSIC
- #if defined(_MSC_VER) && !defined(__clang__)
- #define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x))
- #else
- #define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x))
- #endif
- #define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0)
- #else
- #include "jpeg_nbits_table.h"
- #define JPEG_NBITS(x) (jpeg_nbits_table[x])
- #define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x)
- #endif
- #if defined(__x86_64__) && defined(__ILP32__)
- typedef unsigned long long bit_buf_type;
- #else
- typedef size_t bit_buf_type;
- #endif
- #if defined(WITH_SIMD) && !(defined(__arm__) || defined(__aarch64__) || \
- defined(_M_ARM) || defined(_M_ARM64))
- typedef unsigned long long simd_bit_buf_type;
- #else
- typedef bit_buf_type simd_bit_buf_type;
- #endif
- #if (defined(SIZEOF_SIZE_T) && SIZEOF_SIZE_T == 8) || defined(_WIN64) || \
- (defined(__x86_64__) && defined(__ILP32__))
- #define BIT_BUF_SIZE 64
- #elif (defined(SIZEOF_SIZE_T) && SIZEOF_SIZE_T == 4) || defined(_WIN32)
- #define BIT_BUF_SIZE 32
- #else
- #error Cannot determine word size
- #endif
- #define SIMD_BIT_BUF_SIZE (sizeof(simd_bit_buf_type) * 8)
- typedef struct {
- union {
- bit_buf_type c;
- simd_bit_buf_type simd;
- } put_buffer;
- int free_bits;
-
- int last_dc_val[MAX_COMPS_IN_SCAN];
- } savable_state;
- typedef struct {
- struct jpeg_entropy_encoder pub;
- savable_state saved;
-
- unsigned int restarts_to_go;
- int next_restart_num;
-
- c_derived_tbl *dc_derived_tbls[NUM_HUFF_TBLS];
- c_derived_tbl *ac_derived_tbls[NUM_HUFF_TBLS];
- #ifdef ENTROPY_OPT_SUPPORTED
- long *dc_count_ptrs[NUM_HUFF_TBLS];
- long *ac_count_ptrs[NUM_HUFF_TBLS];
- #endif
- int simd;
- } huff_entropy_encoder;
- typedef huff_entropy_encoder *huff_entropy_ptr;
- typedef struct {
- JOCTET *next_output_byte;
- size_t free_in_buffer;
- savable_state cur;
- j_compress_ptr cinfo;
- int simd;
- } working_state;
- METHODDEF(boolean) encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data);
- METHODDEF(void) finish_pass_huff(j_compress_ptr cinfo);
- #ifdef ENTROPY_OPT_SUPPORTED
- METHODDEF(boolean) encode_mcu_gather(j_compress_ptr cinfo,
- JBLOCKROW *MCU_data);
- METHODDEF(void) finish_pass_gather(j_compress_ptr cinfo);
- #endif
- METHODDEF(void)
- start_pass_huff(j_compress_ptr cinfo, boolean gather_statistics)
- {
- huff_entropy_ptr entropy = (huff_entropy_ptr)cinfo->entropy;
- int ci, dctbl, actbl;
- jpeg_component_info *compptr;
- if (gather_statistics) {
- #ifdef ENTROPY_OPT_SUPPORTED
- entropy->pub.encode_mcu = encode_mcu_gather;
- entropy->pub.finish_pass = finish_pass_gather;
- #else
- ERREXIT(cinfo, JERR_NOT_COMPILED);
- #endif
- } else {
- entropy->pub.encode_mcu = encode_mcu_huff;
- entropy->pub.finish_pass = finish_pass_huff;
- }
- entropy->simd = jsimd_can_huff_encode_one_block();
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- dctbl = compptr->dc_tbl_no;
- actbl = compptr->ac_tbl_no;
- if (gather_statistics) {
- #ifdef ENTROPY_OPT_SUPPORTED
-
-
- if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
- if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
-
-
- if (entropy->dc_count_ptrs[dctbl] == NULL)
- entropy->dc_count_ptrs[dctbl] = (long *)
- (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
- 257 * sizeof(long));
- memset(entropy->dc_count_ptrs[dctbl], 0, 257 * sizeof(long));
- if (entropy->ac_count_ptrs[actbl] == NULL)
- entropy->ac_count_ptrs[actbl] = (long *)
- (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
- 257 * sizeof(long));
- memset(entropy->ac_count_ptrs[actbl], 0, 257 * sizeof(long));
- #endif
- } else {
-
-
- jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
- &entropy->dc_derived_tbls[dctbl]);
- jpeg_make_c_derived_tbl(cinfo, FALSE, actbl,
- &entropy->ac_derived_tbls[actbl]);
- }
-
- entropy->saved.last_dc_val[ci] = 0;
- }
-
- if (entropy->simd) {
- entropy->saved.put_buffer.simd = 0;
- #if defined(__aarch64__) && !defined(NEON_INTRINSICS)
- entropy->saved.free_bits = 0;
- #else
- entropy->saved.free_bits = SIMD_BIT_BUF_SIZE;
- #endif
- } else {
- entropy->saved.put_buffer.c = 0;
- entropy->saved.free_bits = BIT_BUF_SIZE;
- }
-
- entropy->restarts_to_go = cinfo->restart_interval;
- entropy->next_restart_num = 0;
- }
- GLOBAL(void)
- jpeg_make_c_derived_tbl(j_compress_ptr cinfo, boolean isDC, int tblno,
- c_derived_tbl **pdtbl)
- {
- JHUFF_TBL *htbl;
- c_derived_tbl *dtbl;
- int p, i, l, lastp, si, maxsymbol;
- char huffsize[257];
- unsigned int huffcode[257];
- unsigned int code;
-
-
- if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
- htbl =
- isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
- if (htbl == NULL)
- ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
-
- if (*pdtbl == NULL)
- *pdtbl = (c_derived_tbl *)
- (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
- sizeof(c_derived_tbl));
- dtbl = *pdtbl;
-
- p = 0;
- for (l = 1; l <= 16; l++) {
- i = (int)htbl->bits[l];
- if (i < 0 || p + i > 256)
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
- while (i--)
- huffsize[p++] = (char)l;
- }
- huffsize[p] = 0;
- lastp = p;
-
-
- code = 0;
- si = huffsize[0];
- p = 0;
- while (huffsize[p]) {
- while (((int)huffsize[p]) == si) {
- huffcode[p++] = code;
- code++;
- }
-
- if (((JLONG)code) >= (((JLONG)1) << si))
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
- code <<= 1;
- si++;
- }
-
-
-
- memset(dtbl->ehufco, 0, sizeof(dtbl->ehufco));
- memset(dtbl->ehufsi, 0, sizeof(dtbl->ehufsi));
-
- maxsymbol = isDC ? 15 : 255;
- for (p = 0; p < lastp; p++) {
- i = htbl->huffval[p];
- if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
- ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
- dtbl->ehufco[i] = huffcode[p];
- dtbl->ehufsi[i] = huffsize[p];
- }
- }
- #define emit_byte(state, val, action) { \
- *(state)->next_output_byte++ = (JOCTET)(val); \
- if (--(state)->free_in_buffer == 0) \
- if (!dump_buffer(state)) \
- { action; } \
- }
- LOCAL(boolean)
- dump_buffer(working_state *state)
- {
- struct jpeg_destination_mgr *dest = state->cinfo->dest;
- if (!(*dest->empty_output_buffer) (state->cinfo))
- return FALSE;
-
- state->next_output_byte = dest->next_output_byte;
- state->free_in_buffer = dest->free_in_buffer;
- return TRUE;
- }
- #define EMIT_BYTE(b) { \
- buffer[0] = (JOCTET)(b); \
- buffer[1] = 0; \
- buffer -= -2 + ((JOCTET)(b) < 0xFF); \
- }
- #if BIT_BUF_SIZE == 64
- #define FLUSH() { \
- if (put_buffer & 0x8080808080808080 & ~(put_buffer + 0x0101010101010101)) { \
- EMIT_BYTE(put_buffer >> 56) \
- EMIT_BYTE(put_buffer >> 48) \
- EMIT_BYTE(put_buffer >> 40) \
- EMIT_BYTE(put_buffer >> 32) \
- EMIT_BYTE(put_buffer >> 24) \
- EMIT_BYTE(put_buffer >> 16) \
- EMIT_BYTE(put_buffer >> 8) \
- EMIT_BYTE(put_buffer ) \
- } else { \
- buffer[0] = (JOCTET)(put_buffer >> 56); \
- buffer[1] = (JOCTET)(put_buffer >> 48); \
- buffer[2] = (JOCTET)(put_buffer >> 40); \
- buffer[3] = (JOCTET)(put_buffer >> 32); \
- buffer[4] = (JOCTET)(put_buffer >> 24); \
- buffer[5] = (JOCTET)(put_buffer >> 16); \
- buffer[6] = (JOCTET)(put_buffer >> 8); \
- buffer[7] = (JOCTET)(put_buffer); \
- buffer += 8; \
- } \
- }
- #else
- #define FLUSH() { \
- if (put_buffer & 0x80808080 & ~(put_buffer + 0x01010101)) { \
- EMIT_BYTE(put_buffer >> 24) \
- EMIT_BYTE(put_buffer >> 16) \
- EMIT_BYTE(put_buffer >> 8) \
- EMIT_BYTE(put_buffer ) \
- } else { \
- buffer[0] = (JOCTET)(put_buffer >> 24); \
- buffer[1] = (JOCTET)(put_buffer >> 16); \
- buffer[2] = (JOCTET)(put_buffer >> 8); \
- buffer[3] = (JOCTET)(put_buffer); \
- buffer += 4; \
- } \
- }
- #endif
- #define PUT_AND_FLUSH(code, size) { \
- put_buffer = (put_buffer << (size + free_bits)) | (code >> -free_bits); \
- FLUSH() \
- free_bits += BIT_BUF_SIZE; \
- put_buffer = code; \
- }
- #define PUT_BITS(code, size) { \
- free_bits -= size; \
- if (free_bits < 0) \
- PUT_AND_FLUSH(code, size) \
- else \
- put_buffer = (put_buffer << size) | code; \
- }
- #define PUT_CODE(code, size) { \
- temp &= (((JLONG)1) << nbits) - 1; \
- temp |= code << nbits; \
- nbits += size; \
- PUT_BITS(temp, nbits) \
- }
- #define BUFSIZE (DCTSIZE2 * 8)
- #define LOAD_BUFFER() { \
- if (state->free_in_buffer < BUFSIZE) { \
- localbuf = 1; \
- buffer = _buffer; \
- } else \
- buffer = state->next_output_byte; \
- }
- #define STORE_BUFFER() { \
- if (localbuf) { \
- size_t bytes, bytestocopy; \
- bytes = buffer - _buffer; \
- buffer = _buffer; \
- while (bytes > 0) { \
- bytestocopy = MIN(bytes, state->free_in_buffer); \
- memcpy(state->next_output_byte, buffer, bytestocopy); \
- state->next_output_byte += bytestocopy; \
- buffer += bytestocopy; \
- state->free_in_buffer -= bytestocopy; \
- if (state->free_in_buffer == 0) \
- if (!dump_buffer(state)) return FALSE; \
- bytes -= bytestocopy; \
- } \
- } else { \
- state->free_in_buffer -= (buffer - state->next_output_byte); \
- state->next_output_byte = buffer; \
- } \
- }
- LOCAL(boolean)
- flush_bits(working_state *state)
- {
- JOCTET _buffer[BUFSIZE], *buffer, temp;
- simd_bit_buf_type put_buffer; int put_bits;
- int localbuf = 0;
- if (state->simd) {
- #if defined(__aarch64__) && !defined(NEON_INTRINSICS)
- put_bits = state->cur.free_bits;
- #else
- put_bits = SIMD_BIT_BUF_SIZE - state->cur.free_bits;
- #endif
- put_buffer = state->cur.put_buffer.simd;
- } else {
- put_bits = BIT_BUF_SIZE - state->cur.free_bits;
- put_buffer = state->cur.put_buffer.c;
- }
- LOAD_BUFFER()
- while (put_bits >= 8) {
- put_bits -= 8;
- temp = (JOCTET)(put_buffer >> put_bits);
- EMIT_BYTE(temp)
- }
- if (put_bits) {
-
- temp = (JOCTET)((put_buffer << (8 - put_bits)) | (0xFF >> put_bits));
- EMIT_BYTE(temp)
- }
- if (state->simd) {
- state->cur.put_buffer.simd = 0;
- #if defined(__aarch64__) && !defined(NEON_INTRINSICS)
- state->cur.free_bits = 0;
- #else
- state->cur.free_bits = SIMD_BIT_BUF_SIZE;
- #endif
- } else {
- state->cur.put_buffer.c = 0;
- state->cur.free_bits = BIT_BUF_SIZE;
- }
- STORE_BUFFER()
- return TRUE;
- }
- LOCAL(boolean)
- encode_one_block_simd(working_state *state, JCOEFPTR block, int last_dc_val,
- c_derived_tbl *dctbl, c_derived_tbl *actbl)
- {
- JOCTET _buffer[BUFSIZE], *buffer;
- int localbuf = 0;
- LOAD_BUFFER()
- buffer = jsimd_huff_encode_one_block(state, buffer, block, last_dc_val,
- dctbl, actbl);
- STORE_BUFFER()
- return TRUE;
- }
- LOCAL(boolean)
- encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val,
- c_derived_tbl *dctbl, c_derived_tbl *actbl)
- {
- int temp, nbits, free_bits;
- bit_buf_type put_buffer;
- JOCTET _buffer[BUFSIZE], *buffer;
- int localbuf = 0;
- free_bits = state->cur.free_bits;
- put_buffer = state->cur.put_buffer.c;
- LOAD_BUFFER()
-
- temp = block[0] - last_dc_val;
-
- nbits = temp >> (CHAR_BIT * sizeof(int) - 1);
- temp += nbits;
- nbits ^= temp;
-
- nbits = JPEG_NBITS(nbits);
-
- PUT_CODE(dctbl->ehufco[nbits], dctbl->ehufsi[nbits])
-
- {
- int r = 0;
- #define kloop(jpeg_natural_order_of_k) { \
- if ((temp = block[jpeg_natural_order_of_k]) == 0) { \
- r += 16; \
- } else { \
- \
- nbits = temp >> (CHAR_BIT * sizeof(int) - 1); \
- temp += nbits; \
- nbits ^= temp; \
- nbits = JPEG_NBITS_NONZERO(nbits); \
- \
- while (r >= 16 * 16) { \
- r -= 16 * 16; \
- PUT_BITS(actbl->ehufco[0xf0], actbl->ehufsi[0xf0]) \
- } \
- \
- r += nbits; \
- PUT_CODE(actbl->ehufco[r], actbl->ehufsi[r]) \
- r = 0; \
- } \
- }
-
- kloop(1); kloop(8); kloop(16); kloop(9); kloop(2); kloop(3);
- kloop(10); kloop(17); kloop(24); kloop(32); kloop(25); kloop(18);
- kloop(11); kloop(4); kloop(5); kloop(12); kloop(19); kloop(26);
- kloop(33); kloop(40); kloop(48); kloop(41); kloop(34); kloop(27);
- kloop(20); kloop(13); kloop(6); kloop(7); kloop(14); kloop(21);
- kloop(28); kloop(35); kloop(42); kloop(49); kloop(56); kloop(57);
- kloop(50); kloop(43); kloop(36); kloop(29); kloop(22); kloop(15);
- kloop(23); kloop(30); kloop(37); kloop(44); kloop(51); kloop(58);
- kloop(59); kloop(52); kloop(45); kloop(38); kloop(31); kloop(39);
- kloop(46); kloop(53); kloop(60); kloop(61); kloop(54); kloop(47);
- kloop(55); kloop(62); kloop(63);
-
- if (r > 0) {
- PUT_BITS(actbl->ehufco[0], actbl->ehufsi[0])
- }
- }
- state->cur.put_buffer.c = put_buffer;
- state->cur.free_bits = free_bits;
- STORE_BUFFER()
- return TRUE;
- }
- LOCAL(boolean)
- emit_restart(working_state *state, int restart_num)
- {
- int ci;
- if (!flush_bits(state))
- return FALSE;
- emit_byte(state, 0xFF, return FALSE);
- emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
-
- for (ci = 0; ci < state->cinfo->comps_in_scan; ci++)
- state->cur.last_dc_val[ci] = 0;
-
- return TRUE;
- }
- METHODDEF(boolean)
- encode_mcu_huff(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- huff_entropy_ptr entropy = (huff_entropy_ptr)cinfo->entropy;
- working_state state;
- int blkn, ci;
- jpeg_component_info *compptr;
-
- 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;
- state.simd = entropy->simd;
-
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0)
- if (!emit_restart(&state, entropy->next_restart_num))
- return FALSE;
- }
-
- if (entropy->simd) {
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- ci = cinfo->MCU_membership[blkn];
- compptr = cinfo->cur_comp_info[ci];
- if (!encode_one_block_simd(&state,
- MCU_data[blkn][0], state.cur.last_dc_val[ci],
- entropy->dc_derived_tbls[compptr->dc_tbl_no],
- entropy->ac_derived_tbls[compptr->ac_tbl_no]))
- return FALSE;
-
- state.cur.last_dc_val[ci] = MCU_data[blkn][0][0];
- }
- } else {
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- ci = cinfo->MCU_membership[blkn];
- compptr = cinfo->cur_comp_info[ci];
- if (!encode_one_block(&state,
- MCU_data[blkn][0], state.cur.last_dc_val[ci],
- entropy->dc_derived_tbls[compptr->dc_tbl_no],
- entropy->ac_derived_tbls[compptr->ac_tbl_no]))
- return FALSE;
-
- state.cur.last_dc_val[ci] = MCU_data[blkn][0][0];
- }
- }
-
- cinfo->dest->next_output_byte = state.next_output_byte;
- cinfo->dest->free_in_buffer = state.free_in_buffer;
- entropy->saved = state.cur;
-
- 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_huff(j_compress_ptr cinfo)
- {
- huff_entropy_ptr entropy = (huff_entropy_ptr)cinfo->entropy;
- working_state state;
-
- 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;
- state.simd = entropy->simd;
-
- if (!flush_bits(&state))
- ERREXIT(cinfo, JERR_CANT_SUSPEND);
-
- cinfo->dest->next_output_byte = state.next_output_byte;
- cinfo->dest->free_in_buffer = state.free_in_buffer;
- entropy->saved = state.cur;
- }
- #ifdef ENTROPY_OPT_SUPPORTED
- LOCAL(void)
- htest_one_block(j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
- long dc_counts[], long ac_counts[])
- {
- register int temp;
- register int nbits;
- register int k, r;
-
- temp = block[0] - last_dc_val;
- if (temp < 0)
- temp = -temp;
-
- nbits = 0;
- while (temp) {
- nbits++;
- temp >>= 1;
- }
-
- if (nbits > MAX_COEF_BITS + 1)
- ERREXIT(cinfo, JERR_BAD_DCT_COEF);
-
- dc_counts[nbits]++;
-
- r = 0;
- for (k = 1; k < DCTSIZE2; k++) {
- if ((temp = block[jpeg_natural_order[k]]) == 0) {
- r++;
- } else {
-
- while (r > 15) {
- ac_counts[0xF0]++;
- r -= 16;
- }
-
- if (temp < 0)
- temp = -temp;
-
- nbits = 1;
- while ((temp >>= 1))
- nbits++;
-
- if (nbits > MAX_COEF_BITS)
- ERREXIT(cinfo, JERR_BAD_DCT_COEF);
-
- ac_counts[(r << 4) + nbits]++;
- r = 0;
- }
- }
-
- if (r > 0)
- ac_counts[0]++;
- }
- METHODDEF(boolean)
- encode_mcu_gather(j_compress_ptr cinfo, JBLOCKROW *MCU_data)
- {
- huff_entropy_ptr entropy = (huff_entropy_ptr)cinfo->entropy;
- int blkn, ci;
- jpeg_component_info *compptr;
-
- if (cinfo->restart_interval) {
- if (entropy->restarts_to_go == 0) {
-
- for (ci = 0; ci < cinfo->comps_in_scan; ci++)
- entropy->saved.last_dc_val[ci] = 0;
-
- entropy->restarts_to_go = cinfo->restart_interval;
- }
- entropy->restarts_to_go--;
- }
- for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
- ci = cinfo->MCU_membership[blkn];
- compptr = cinfo->cur_comp_info[ci];
- htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
- entropy->dc_count_ptrs[compptr->dc_tbl_no],
- entropy->ac_count_ptrs[compptr->ac_tbl_no]);
- entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0];
- }
- return TRUE;
- }
- GLOBAL(void)
- jpeg_gen_optimal_table(j_compress_ptr cinfo, JHUFF_TBL *htbl, long freq[])
- {
- #define MAX_CLEN 32
- UINT8 bits[MAX_CLEN + 1];
- int codesize[257];
- int others[257];
- int c1, c2;
- int p, i, j;
- long v;
-
- memset(bits, 0, sizeof(bits));
- memset(codesize, 0, sizeof(codesize));
- for (i = 0; i < 257; i++)
- others[i] = -1;
- freq[256] = 1;
-
-
- for (;;) {
-
-
- c1 = -1;
- v = 1000000000L;
- for (i = 0; i <= 256; i++) {
- if (freq[i] && freq[i] <= v) {
- v = freq[i];
- c1 = i;
- }
- }
-
-
- c2 = -1;
- v = 1000000000L;
- for (i = 0; i <= 256; i++) {
- if (freq[i] && freq[i] <= v && i != c1) {
- v = freq[i];
- c2 = i;
- }
- }
-
- if (c2 < 0)
- break;
-
- freq[c1] += freq[c2];
- freq[c2] = 0;
-
- codesize[c1]++;
- while (others[c1] >= 0) {
- c1 = others[c1];
- codesize[c1]++;
- }
- others[c1] = c2;
-
- codesize[c2]++;
- while (others[c2] >= 0) {
- c2 = others[c2];
- codesize[c2]++;
- }
- }
-
- for (i = 0; i <= 256; i++) {
- if (codesize[i]) {
-
-
- if (codesize[i] > MAX_CLEN)
- ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
- bits[codesize[i]]++;
- }
- }
-
- for (i = MAX_CLEN; i > 16; i--) {
- while (bits[i] > 0) {
- j = i - 2;
- while (bits[j] == 0)
- j--;
- bits[i] -= 2;
- bits[i - 1]++;
- bits[j + 1] += 2;
- bits[j]--;
- }
- }
-
- while (bits[i] == 0)
- i--;
- bits[i]--;
-
- memcpy(htbl->bits, bits, sizeof(htbl->bits));
-
-
- p = 0;
- for (i = 1; i <= MAX_CLEN; i++) {
- for (j = 0; j <= 255; j++) {
- if (codesize[j] == i) {
- htbl->huffval[p] = (UINT8)j;
- p++;
- }
- }
- }
-
- htbl->sent_table = FALSE;
- }
- METHODDEF(void)
- finish_pass_gather(j_compress_ptr cinfo)
- {
- huff_entropy_ptr entropy = (huff_entropy_ptr)cinfo->entropy;
- int ci, dctbl, actbl;
- jpeg_component_info *compptr;
- JHUFF_TBL **htblptr;
- boolean did_dc[NUM_HUFF_TBLS];
- boolean did_ac[NUM_HUFF_TBLS];
-
- memset(did_dc, 0, sizeof(did_dc));
- memset(did_ac, 0, sizeof(did_ac));
- for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- compptr = cinfo->cur_comp_info[ci];
- dctbl = compptr->dc_tbl_no;
- actbl = compptr->ac_tbl_no;
- if (!did_dc[dctbl]) {
- htblptr = &cinfo->dc_huff_tbl_ptrs[dctbl];
- if (*htblptr == NULL)
- *htblptr = jpeg_alloc_huff_table((j_common_ptr)cinfo);
- jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]);
- did_dc[dctbl] = TRUE;
- }
- if (!did_ac[actbl]) {
- htblptr = &cinfo->ac_huff_tbl_ptrs[actbl];
- if (*htblptr == NULL)
- *htblptr = jpeg_alloc_huff_table((j_common_ptr)cinfo);
- jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]);
- did_ac[actbl] = TRUE;
- }
- }
- }
- #endif
- GLOBAL(void)
- jinit_huff_encoder(j_compress_ptr cinfo)
- {
- huff_entropy_ptr entropy;
- int i;
- entropy = (huff_entropy_ptr)
- (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
- sizeof(huff_entropy_encoder));
- cinfo->entropy = (struct jpeg_entropy_encoder *)entropy;
- entropy->pub.start_pass = start_pass_huff;
-
- for (i = 0; i < NUM_HUFF_TBLS; i++) {
- entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
- #ifdef ENTROPY_OPT_SUPPORTED
- entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL;
- #endif
- }
- }
|