Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
jcphuff.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #define JPEG_INTERNALS
00016 #include "jinclude.h"
00017 #include "jpeglib.h"
00018 #include "jchuff.h"
00019
00020 #ifdef C_PROGRESSIVE_SUPPORTED
00021
00022
00023
00024 typedef struct {
00025 struct jpeg_entropy_encoder pub;
00026
00027
00028 boolean gather_statistics;
00029
00030
00031
00032
00033 JOCTET * next_output_byte;
00034 size_t free_in_buffer;
00035 INT32 put_buffer;
00036 int put_bits;
00037 j_compress_ptr cinfo;
00038
00039
00040 int last_dc_val[MAX_COMPS_IN_SCAN];
00041
00042
00043 int ac_tbl_no;
00044 unsigned int EOBRUN;
00045 unsigned int BE;
00046 char * bit_buffer;
00047
00048
00049 unsigned int restarts_to_go;
00050 int next_restart_num;
00051
00052
00053
00054
00055
00056 c_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
00057
00058
00059 long * count_ptrs[NUM_HUFF_TBLS];
00060 } phuff_entropy_encoder;
00061
00062 typedef phuff_entropy_encoder * phuff_entropy_ptr;
00063
00064
00065
00066
00067
00068
00069
00070 #define MAX_CORR_BITS 1000
00071
00072
00073
00074
00075
00076
00077 #ifdef RIGHT_SHIFT_IS_UNSIGNED
00078 #define ISHIFT_TEMPS int ishift_temp;
00079 #define IRIGHT_SHIFT(x,shft) \
00080 ((ishift_temp = (x)) < 0 ? \
00081 (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
00082 (ishift_temp >> (shft)))
00083 #else
00084 #define ISHIFT_TEMPS
00085 #define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
00086 #endif
00087
00088
00089 METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,
00090 JBLOCKROW *MCU_data));
00091 METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,
00092 JBLOCKROW *MCU_data));
00093 METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
00094 JBLOCKROW *MCU_data));
00095 METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,
00096 JBLOCKROW *MCU_data));
00097 METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));
00098 METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));
00099
00100
00101
00102
00103
00104
00105 METHODDEF(void)
00106 start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
00107 {
00108 phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
00109 boolean is_DC_band;
00110 int ci, tbl;
00111 jpeg_component_info * compptr;
00112
00113 entropy->cinfo = cinfo;
00114 entropy->gather_statistics = gather_statistics;
00115
00116 is_DC_band = (cinfo->Ss == 0);
00117
00118
00119
00120
00121 if (cinfo->Ah == 0) {
00122 if (is_DC_band)
00123 entropy->pub.encode_mcu = encode_mcu_DC_first;
00124 else
00125 entropy->pub.encode_mcu = encode_mcu_AC_first;
00126 } else {
00127 if (is_DC_band)
00128 entropy->pub.encode_mcu = encode_mcu_DC_refine;
00129 else {
00130 entropy->pub.encode_mcu = encode_mcu_AC_refine;
00131
00132 if (entropy->bit_buffer == NULL)
00133 entropy->bit_buffer = (char *)
00134 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00135 MAX_CORR_BITS * SIZEOF(char));
00136 }
00137 }
00138 if (gather_statistics)
00139 entropy->pub.finish_pass = finish_pass_gather_phuff;
00140 else
00141 entropy->pub.finish_pass = finish_pass_phuff;
00142
00143
00144
00145
00146 for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
00147 compptr = cinfo->cur_comp_info[ci];
00148
00149 entropy->last_dc_val[ci] = 0;
00150
00151 if (is_DC_band) {
00152 if (cinfo->Ah != 0)
00153 continue;
00154 tbl = compptr->dc_tbl_no;
00155 } else {
00156 entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
00157 }
00158 if (gather_statistics) {
00159
00160
00161 if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
00162 ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
00163
00164
00165 if (entropy->count_ptrs[tbl] == NULL)
00166 entropy->count_ptrs[tbl] = (long *)
00167 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00168 257 * SIZEOF(long));
00169 MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
00170 } else {
00171
00172
00173 jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
00174 & entropy->derived_tbls[tbl]);
00175 }
00176 }
00177
00178
00179 entropy->EOBRUN = 0;
00180 entropy->BE = 0;
00181
00182
00183 entropy->put_buffer = 0;
00184 entropy->put_bits = 0;
00185
00186
00187 entropy->restarts_to_go = cinfo->restart_interval;
00188 entropy->next_restart_num = 0;
00189 }
00190
00191
00192
00193
00194
00195
00196
00197
00198 #define emit_byte(entropy,val) \
00199 { *(entropy)->next_output_byte++ = (JOCTET) (val); \
00200 if (--(entropy)->free_in_buffer == 0) \
00201 dump_buffer(entropy); }
00202
00203
00204 LOCAL(void)
00205 dump_buffer (phuff_entropy_ptr entropy)
00206
00207 {
00208 struct jpeg_destination_mgr * dest = entropy->cinfo->dest;
00209
00210 if (! (*dest->empty_output_buffer) (entropy->cinfo))
00211 ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);
00212
00213 entropy->next_output_byte = dest->next_output_byte;
00214 entropy->free_in_buffer = dest->free_in_buffer;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 INLINE
00227 LOCAL(void)
00228 emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
00229
00230 {
00231
00232 register INT32 put_buffer = (INT32) code;
00233 register int put_bits = entropy->put_bits;
00234
00235
00236 if (size == 0)
00237 ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
00238
00239 if (entropy->gather_statistics)
00240 return;
00241
00242 put_buffer &= (((INT32) 1)<<size) - 1;
00243
00244 put_bits += size;
00245
00246 put_buffer <<= 24 - put_bits;
00247
00248 put_buffer |= entropy->put_buffer;
00249
00250 while (put_bits >= 8) {
00251 int c = (int) ((put_buffer >> 16) & 0xFF);
00252
00253 emit_byte(entropy, c);
00254 if (c == 0xFF) {
00255 emit_byte(entropy, 0);
00256 }
00257 put_buffer <<= 8;
00258 put_bits -= 8;
00259 }
00260
00261 entropy->put_buffer = put_buffer;
00262 entropy->put_bits = put_bits;
00263 }
00264
00265
00266 LOCAL(void)
00267 flush_bits (phuff_entropy_ptr entropy)
00268 {
00269 emit_bits(entropy, 0x7F, 7);
00270 entropy->put_buffer = 0;
00271 entropy->put_bits = 0;
00272 }
00273
00274
00275
00276
00277
00278
00279 INLINE
00280 LOCAL(void)
00281 emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
00282 {
00283 if (entropy->gather_statistics)
00284 entropy->count_ptrs[tbl_no][symbol]++;
00285 else {
00286 c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
00287 emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
00288 }
00289 }
00290
00291
00292
00293
00294
00295
00296 LOCAL(void)
00297 emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
00298 unsigned int nbits)
00299 {
00300 if (entropy->gather_statistics)
00301 return;
00302
00303 while (nbits > 0) {
00304 emit_bits(entropy, (unsigned int) (*bufstart), 1);
00305 bufstart++;
00306 nbits--;
00307 }
00308 }
00309
00310
00311
00312
00313
00314
00315 LOCAL(void)
00316 emit_eobrun (phuff_entropy_ptr entropy)
00317 {
00318 register int temp, nbits;
00319
00320 if (entropy->EOBRUN > 0) {
00321 temp = entropy->EOBRUN;
00322 nbits = 0;
00323 while ((temp >>= 1))
00324 nbits++;
00325
00326 if (nbits > 14)
00327 ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
00328
00329 emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
00330 if (nbits)
00331 emit_bits(entropy, entropy->EOBRUN, nbits);
00332
00333 entropy->EOBRUN = 0;
00334
00335
00336 emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);
00337 entropy->BE = 0;
00338 }
00339 }
00340
00341
00342
00343
00344
00345
00346 LOCAL(void)
00347 emit_restart (phuff_entropy_ptr entropy, int restart_num)
00348 {
00349 int ci;
00350
00351 emit_eobrun(entropy);
00352
00353 if (! entropy->gather_statistics) {
00354 flush_bits(entropy);
00355 emit_byte(entropy, 0xFF);
00356 emit_byte(entropy, JPEG_RST0 + restart_num);
00357 }
00358
00359 if (entropy->cinfo->Ss == 0) {
00360
00361 for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)
00362 entropy->last_dc_val[ci] = 0;
00363 } else {
00364
00365 entropy->EOBRUN = 0;
00366 entropy->BE = 0;
00367 }
00368 }
00369
00370
00371
00372
00373
00374
00375
00376 METHODDEF(boolean)
00377 encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
00378 {
00379 phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
00380 register int temp, temp2;
00381 register int nbits;
00382 int blkn, ci;
00383 int Al = cinfo->Al;
00384 JBLOCKROW block;
00385 jpeg_component_info * compptr;
00386 ISHIFT_TEMPS
00387
00388 entropy->next_output_byte = cinfo->dest->next_output_byte;
00389 entropy->free_in_buffer = cinfo->dest->free_in_buffer;
00390
00391
00392 if (cinfo->restart_interval)
00393 if (entropy->restarts_to_go == 0)
00394 emit_restart(entropy, entropy->next_restart_num);
00395
00396
00397 for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
00398 block = MCU_data[blkn];
00399 ci = cinfo->MCU_membership[blkn];
00400 compptr = cinfo->cur_comp_info[ci];
00401
00402
00403
00404
00405 temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
00406
00407
00408 temp = temp2 - entropy->last_dc_val[ci];
00409 entropy->last_dc_val[ci] = temp2;
00410
00411
00412 temp2 = temp;
00413 if (temp < 0) {
00414 temp = -temp;
00415
00416
00417 temp2--;
00418 }
00419
00420
00421 nbits = 0;
00422 while (temp) {
00423 nbits++;
00424 temp >>= 1;
00425 }
00426
00427
00428
00429 if (nbits > MAX_COEF_BITS+1)
00430 ERREXIT(cinfo, JERR_BAD_DCT_COEF);
00431
00432
00433 emit_symbol(entropy, compptr->dc_tbl_no, nbits);
00434
00435
00436
00437 if (nbits)
00438 emit_bits(entropy, (unsigned int) temp2, nbits);
00439 }
00440
00441 cinfo->dest->next_output_byte = entropy->next_output_byte;
00442 cinfo->dest->free_in_buffer = entropy->free_in_buffer;
00443
00444
00445 if (cinfo->restart_interval) {
00446 if (entropy->restarts_to_go == 0) {
00447 entropy->restarts_to_go = cinfo->restart_interval;
00448 entropy->next_restart_num++;
00449 entropy->next_restart_num &= 7;
00450 }
00451 entropy->restarts_to_go--;
00452 }
00453
00454 return TRUE;
00455 }
00456
00457
00458
00459
00460
00461
00462
00463 METHODDEF(boolean)
00464 encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
00465 {
00466 phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
00467 register int temp, temp2;
00468 register int nbits;
00469 register int r, k;
00470 int Se = cinfo->Se;
00471 int Al = cinfo->Al;
00472 JBLOCKROW block;
00473
00474 entropy->next_output_byte = cinfo->dest->next_output_byte;
00475 entropy->free_in_buffer = cinfo->dest->free_in_buffer;
00476
00477
00478 if (cinfo->restart_interval)
00479 if (entropy->restarts_to_go == 0)
00480 emit_restart(entropy, entropy->next_restart_num);
00481
00482
00483 block = MCU_data[0];
00484
00485
00486
00487 r = 0;
00488
00489 for (k = cinfo->Ss; k <= Se; k++) {
00490 if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
00491 r++;
00492 continue;
00493 }
00494
00495
00496
00497
00498
00499 if (temp < 0) {
00500 temp = -temp;
00501 temp >>= Al;
00502
00503 temp2 = ~temp;
00504 } else {
00505 temp >>= Al;
00506 temp2 = temp;
00507 }
00508
00509 if (temp == 0) {
00510 r++;
00511 continue;
00512 }
00513
00514
00515 if (entropy->EOBRUN > 0)
00516 emit_eobrun(entropy);
00517
00518 while (r > 15) {
00519 emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
00520 r -= 16;
00521 }
00522
00523
00524 nbits = 1;
00525 while ((temp >>= 1))
00526 nbits++;
00527
00528 if (nbits > MAX_COEF_BITS)
00529 ERREXIT(cinfo, JERR_BAD_DCT_COEF);
00530
00531
00532 emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
00533
00534
00535
00536 emit_bits(entropy, (unsigned int) temp2, nbits);
00537
00538 r = 0;
00539 }
00540
00541 if (r > 0) {
00542 entropy->EOBRUN++;
00543 if (entropy->EOBRUN == 0x7FFF)
00544 emit_eobrun(entropy);
00545 }
00546
00547 cinfo->dest->next_output_byte = entropy->next_output_byte;
00548 cinfo->dest->free_in_buffer = entropy->free_in_buffer;
00549
00550
00551 if (cinfo->restart_interval) {
00552 if (entropy->restarts_to_go == 0) {
00553 entropy->restarts_to_go = cinfo->restart_interval;
00554 entropy->next_restart_num++;
00555 entropy->next_restart_num &= 7;
00556 }
00557 entropy->restarts_to_go--;
00558 }
00559
00560 return TRUE;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570 METHODDEF(boolean)
00571 encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
00572 {
00573 phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
00574 register int temp;
00575 int blkn;
00576 int Al = cinfo->Al;
00577 JBLOCKROW block;
00578
00579 entropy->next_output_byte = cinfo->dest->next_output_byte;
00580 entropy->free_in_buffer = cinfo->dest->free_in_buffer;
00581
00582
00583 if (cinfo->restart_interval)
00584 if (entropy->restarts_to_go == 0)
00585 emit_restart(entropy, entropy->next_restart_num);
00586
00587
00588 for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
00589 block = MCU_data[blkn];
00590
00591
00592 temp = (*block)[0];
00593 emit_bits(entropy, (unsigned int) (temp >> Al), 1);
00594 }
00595
00596 cinfo->dest->next_output_byte = entropy->next_output_byte;
00597 cinfo->dest->free_in_buffer = entropy->free_in_buffer;
00598
00599
00600 if (cinfo->restart_interval) {
00601 if (entropy->restarts_to_go == 0) {
00602 entropy->restarts_to_go = cinfo->restart_interval;
00603 entropy->next_restart_num++;
00604 entropy->next_restart_num &= 7;
00605 }
00606 entropy->restarts_to_go--;
00607 }
00608
00609 return TRUE;
00610 }
00611
00612
00613
00614
00615
00616
00617 METHODDEF(boolean)
00618 encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
00619 {
00620 phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
00621 register int temp;
00622 register int r, k;
00623 int EOB;
00624 char *BR_buffer;
00625 unsigned int BR;
00626 int Se = cinfo->Se;
00627 int Al = cinfo->Al;
00628 JBLOCKROW block;
00629 int absvalues[DCTSIZE2];
00630
00631 entropy->next_output_byte = cinfo->dest->next_output_byte;
00632 entropy->free_in_buffer = cinfo->dest->free_in_buffer;
00633
00634
00635 if (cinfo->restart_interval)
00636 if (entropy->restarts_to_go == 0)
00637 emit_restart(entropy, entropy->next_restart_num);
00638
00639
00640 block = MCU_data[0];
00641
00642
00643
00644
00645 EOB = 0;
00646 for (k = cinfo->Ss; k <= Se; k++) {
00647 temp = (*block)[jpeg_natural_order[k]];
00648
00649
00650
00651
00652 if (temp < 0)
00653 temp = -temp;
00654 temp >>= Al;
00655 absvalues[k] = temp;
00656 if (temp == 1)
00657 EOB = k;
00658 }
00659
00660
00661
00662 r = 0;
00663 BR = 0;
00664 BR_buffer = entropy->bit_buffer + entropy->BE;
00665
00666 for (k = cinfo->Ss; k <= Se; k++) {
00667 if ((temp = absvalues[k]) == 0) {
00668 r++;
00669 continue;
00670 }
00671
00672
00673 while (r > 15 && k <= EOB) {
00674
00675 emit_eobrun(entropy);
00676
00677 emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
00678 r -= 16;
00679
00680 emit_buffered_bits(entropy, BR_buffer, BR);
00681 BR_buffer = entropy->bit_buffer;
00682 BR = 0;
00683 }
00684
00685
00686
00687
00688
00689
00690 if (temp > 1) {
00691
00692 BR_buffer[BR++] = (char) (temp & 1);
00693 continue;
00694 }
00695
00696
00697 emit_eobrun(entropy);
00698
00699
00700 emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1);
00701
00702
00703 temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1;
00704 emit_bits(entropy, (unsigned int) temp, 1);
00705
00706
00707 emit_buffered_bits(entropy, BR_buffer, BR);
00708 BR_buffer = entropy->bit_buffer;
00709 BR = 0;
00710 r = 0;
00711 }
00712
00713 if (r > 0 || BR > 0) {
00714 entropy->EOBRUN++;
00715 entropy->BE += BR;
00716
00717
00718
00719
00720 if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1))
00721 emit_eobrun(entropy);
00722 }
00723
00724 cinfo->dest->next_output_byte = entropy->next_output_byte;
00725 cinfo->dest->free_in_buffer = entropy->free_in_buffer;
00726
00727
00728 if (cinfo->restart_interval) {
00729 if (entropy->restarts_to_go == 0) {
00730 entropy->restarts_to_go = cinfo->restart_interval;
00731 entropy->next_restart_num++;
00732 entropy->next_restart_num &= 7;
00733 }
00734 entropy->restarts_to_go--;
00735 }
00736
00737 return TRUE;
00738 }
00739
00740
00741
00742
00743
00744
00745 METHODDEF(void)
00746 finish_pass_phuff (j_compress_ptr cinfo)
00747 {
00748 phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
00749
00750 entropy->next_output_byte = cinfo->dest->next_output_byte;
00751 entropy->free_in_buffer = cinfo->dest->free_in_buffer;
00752
00753
00754 emit_eobrun(entropy);
00755 flush_bits(entropy);
00756
00757 cinfo->dest->next_output_byte = entropy->next_output_byte;
00758 cinfo->dest->free_in_buffer = entropy->free_in_buffer;
00759 }
00760
00761
00762
00763
00764
00765
00766 METHODDEF(void)
00767 finish_pass_gather_phuff (j_compress_ptr cinfo)
00768 {
00769 phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
00770 boolean is_DC_band;
00771 int ci, tbl;
00772 jpeg_component_info * compptr;
00773 JHUFF_TBL **htblptr;
00774 boolean did[NUM_HUFF_TBLS];
00775
00776
00777 emit_eobrun(entropy);
00778
00779 is_DC_band = (cinfo->Ss == 0);
00780
00781
00782
00783
00784 MEMZERO(did, SIZEOF(did));
00785
00786 for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
00787 compptr = cinfo->cur_comp_info[ci];
00788 if (is_DC_band) {
00789 if (cinfo->Ah != 0)
00790 continue;
00791 tbl = compptr->dc_tbl_no;
00792 } else {
00793 tbl = compptr->ac_tbl_no;
00794 }
00795 if (! did[tbl]) {
00796 if (is_DC_band)
00797 htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
00798 else
00799 htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
00800 if (*htblptr == NULL)
00801 *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
00802 jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]);
00803 did[tbl] = TRUE;
00804 }
00805 }
00806 }
00807
00808
00809
00810
00811
00812
00813 GLOBAL(void)
00814 jinit_phuff_encoder (j_compress_ptr cinfo)
00815 {
00816 phuff_entropy_ptr entropy;
00817 int i;
00818
00819 entropy = (phuff_entropy_ptr)
00820 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00821 SIZEOF(phuff_entropy_encoder));
00822 cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
00823 entropy->pub.start_pass = start_pass_phuff;
00824
00825
00826 for (i = 0; i < NUM_HUFF_TBLS; i++) {
00827 entropy->derived_tbls[i] = NULL;
00828 entropy->count_ptrs[i] = NULL;
00829 }
00830 entropy->bit_buffer = NULL;
00831 }
00832
00833 #endif