📄 tinyjpeg.c
字号:
if (huff_code) { get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]); DCT[0] += c->previous_DC; c->previous_DC = DCT[0]; } else { DCT[0] = c->previous_DC; } /* AC coefficient decoding */ j = 1; while (j<64) { huff_code = get_next_huffman_code(priv, c->AC_table); size_val = huff_code & 0xF; count_0 = huff_code >> 4; if (size_val == 0) { /* RLE */ if (count_0 == 0) break; /* EOB found, go out */ else if (count_0 == 0xF) j += 16; /* skip 16 zeros */ } else { j += count_0; /* skip count_0 zeroes */ if (j < 64) { get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]); j++; } } } if (j > 64) { snprintf(priv->error_string, sizeof(priv->error_string), "error: more then 63 AC components (%d) in huffman unit\n", (int)j); longjmp(priv->jump_state, -EIO); } for (j = 0; j < 64; j++) c->DCT[j] = DCT[zigzag[j]];}/* identical as above both with *_nbits replaced with pixart_*_nbits */static void pixart_process_Huffman_data_unit(struct jdec_private *priv, int component){ unsigned char j; unsigned int huff_code; unsigned char size_val, count_0; struct component *c = &priv->component_infos[component]; short int DCT[64]; /* Initialize the DCT coef table */ memset(DCT, 0, sizeof(DCT)); /* DC coefficient decoding */ huff_code = pixart_get_next_huffman_code(priv, c->DC_table); if (huff_code) { pixart_get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, huff_code, DCT[0]); DCT[0] += c->previous_DC; c->previous_DC = DCT[0]; } else { DCT[0] = c->previous_DC; } /* AC coefficient decoding */ j = 1; while (j<64) { huff_code = pixart_get_next_huffman_code(priv, c->AC_table); size_val = huff_code & 0xF; count_0 = huff_code >> 4; if (size_val == 0) { /* RLE */ if (count_0 == 0) break; /* EOB found, go out */ else if (count_0 == 0xF) j += 16; /* skip 16 zeros */ } else { j += count_0; /* skip count_0 zeroes */ if (j < 64 ) { pixart_get_nbits(priv->reservoir, priv->nbits_in_reservoir, priv->stream, size_val, DCT[j]); j++; } } } if (j > 64) { snprintf(priv->error_string, sizeof(priv->error_string), "error: more then 63 AC components (%d) in huffman unit\n", (int)j); longjmp(priv->jump_state, -EIO); } for (j = 0; j < 64; j++) c->DCT[j] = DCT[zigzag[j]];}/* * Takes two array of bits, and build the huffman table for size, and code * * lookup will return the symbol if the code is less or equal than HUFFMAN_HASH_NBITS. * code_size will be used to known how many bits this symbol is encoded. * slowtable will be used when the first lookup didn't give the result. */static int build_huffman_table(struct jdec_private *priv, const unsigned char *bits, const unsigned char *vals, struct huffman_table *table){ unsigned int i, j, code, code_size, val, nbits; unsigned char huffsize[257], *hz; unsigned int huffcode[257], *hc; int next_free_entry; int slowtable_used[16-HUFFMAN_HASH_NBITS]; /* * Build a temp array * huffsize[X] => numbers of bits to write vals[X] */ hz = huffsize; for (i=1; i<=16; i++) { for (j=1; j<=bits[i]; j++) *hz++ = i; } *hz = 0; memset(table->lookup, 0xff, sizeof(table->lookup)); for (i=0; i<(16-HUFFMAN_HASH_NBITS); i++) slowtable_used[i] = 0; /* Build a temp array * huffcode[X] => code used to write vals[X] */ code = 0; hc = huffcode; hz = huffsize; nbits = *hz; while (*hz) { while (*hz == nbits) { *hc++ = code++; hz++; } code <<= 1; nbits++; } /* * Build the lookup table, and the slowtable if needed. */ next_free_entry = -1; for (i=0; huffsize[i]; i++) { val = vals[i]; code = huffcode[i]; code_size = huffsize[i]; trace("val=%2.2x code=%8.8x codesize=%2.2d\n", i, code, code_size); table->code_size[val] = code_size; if (code_size <= HUFFMAN_HASH_NBITS) { /* * Good: val can be put in the lookup table, so fill all value of this * column with value val */ int repeat = 1UL<<(HUFFMAN_HASH_NBITS - code_size); code <<= HUFFMAN_HASH_NBITS - code_size; while ( repeat-- ) table->lookup[code++] = val; } else { /* Perhaps sorting the array will be an optimization */ int slowtable_index = code_size-HUFFMAN_HASH_NBITS-1; if (slowtable_used[slowtable_index] == 254) error("slow Huffman table overflow\n"); table->slowtable[slowtable_index][slowtable_used[slowtable_index]] = code; table->slowtable[slowtable_index][slowtable_used[slowtable_index] + 1] = val; slowtable_used[slowtable_index] += 2; } } for (i=0; i<(16-HUFFMAN_HASH_NBITS); i++) table->slowtable[i][slowtable_used[i]] = 0; return 0;}static int build_default_huffman_tables(struct jdec_private *priv){ if ( (priv->flags & TINYJPEG_FLAGS_MJPEG_TABLE) && priv->default_huffman_table_initialized) return 0; if (build_huffman_table(priv, bits_dc_luminance, val_dc_luminance, &priv->HTDC[0])) return -1; if (build_huffman_table(priv, bits_ac_luminance, val_ac_luminance, &priv->HTAC[0])) return -1; if (build_huffman_table(priv, bits_dc_chrominance, val_dc_chrominance, &priv->HTDC[1])) return -1; if (build_huffman_table(priv, bits_ac_chrominance, val_ac_chrominance, &priv->HTAC[1])) return -1; priv->default_huffman_table_initialized = 1; return 0;}/******************************************************************************* * * Colorspace conversion routine * * * Note: * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. * The conversion equations to be implemented are therefore * R = Y + 1.40200 * Cr * G = Y - 0.34414 * Cb - 0.71414 * Cr * B = Y + 1.77200 * Cb * ******************************************************************************/static unsigned char clamp(int i){ if (i<0) return 0; else if (i>255) return 255; else return i;}/** * YCrCb -> YUV420P (1x1) * .---. * | 1 | * `---' */static void YCrCB_to_YUV420P_1x1(struct jdec_private *priv){ const unsigned char *s, *y; unsigned char *p; int i,j; p = priv->plane[0]; y = priv->Y; for (i=0; i<8; i++) { memcpy(p, y, 8); p+=priv->width; y+=8; } p = priv->plane[1]; s = priv->Cb; for (i=0; i<8; i+=2) { for (j=0; j<8; j+=2, s+=2) *p++ = *s; s += 8; /* Skip one line */ p += priv->width/2 - 4; } p = priv->plane[2]; s = priv->Cr; for (i=0; i<8; i+=2) { for (j=0; j<8; j+=2, s+=2) *p++ = *s; s += 8; /* Skip one line */ p += priv->width/2 - 4; }}/** * YCrCb -> YUV420P (2x1) * .-------. * | 1 | 2 | * `-------' */static void YCrCB_to_YUV420P_2x1(struct jdec_private *priv){ unsigned char *p; const unsigned char *s, *y1; unsigned int i; p = priv->plane[0]; y1 = priv->Y; for (i=0; i<8; i++) { memcpy(p, y1, 16); p += priv->width; y1 += 16; } p = priv->plane[1]; s = priv->Cb; for (i=0; i<8; i+=2) { memcpy(p, s, 8); s += 16; /* Skip one line */ p += priv->width/2; } p = priv->plane[2]; s = priv->Cr; for (i=0; i<8; i+=2) { memcpy(p, s, 8); s += 16; /* Skip one line */ p += priv->width/2; }}/** * YCrCb -> YUV420P (1x2) * .---. * | 1 | * |---| * | 2 | * `---' */static void YCrCB_to_YUV420P_1x2(struct jdec_private *priv){ const unsigned char *s, *y; unsigned char *p; int i,j; p = priv->plane[0]; y = priv->Y; for (i=0; i<16; i++) { memcpy(p, y, 8); p+=priv->width; y+=8; } p = priv->plane[1]; s = priv->Cb; for (i=0; i<8; i++) { for (j=0; j<8; j+=2, s+=2) *p++ = *s; p += priv->width/2 - 4; } p = priv->plane[2]; s = priv->Cr; for (i=0; i<8; i++) { for (j=0; j<8; j+=2, s+=2) *p++ = *s; p += priv->width/2 - 4; }}/** * YCrCb -> YUV420P (2x2) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */static void YCrCB_to_YUV420P_2x2(struct jdec_private *priv){ unsigned char *p; const unsigned char *s, *y1; unsigned int i; p = priv->plane[0]; y1 = priv->Y; for (i=0; i<16; i++) { memcpy(p, y1, 16); p += priv->width; y1 += 16; } p = priv->plane[1]; s = priv->Cb; for (i=0; i<8; i++) { memcpy(p, s, 8); s += 8; p += priv->width/2; } p = priv->plane[2]; s = priv->Cr; for (i=0; i<8; i++) { memcpy(p, s, 8); s += 8; p += priv->width/2; }}/** * YCrCb -> RGB24 (1x1) * .---. * | 1 | * `---' */static void YCrCB_to_RGB24_1x1(struct jdec_private *priv){ const unsigned char *Y, *Cb, *Cr; unsigned char *p; int i,j; int offset_to_next_row;#define SCALEBITS 10#define ONE_HALF (1UL << (SCALEBITS-1))#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) p = priv->plane[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = priv->width*3 - 8*3; for (i=0; i<8; i++) { for (j=0; j<8; j++) { int y, cb, cr; int add_r, add_g, add_b; int r, g , b; y = (*Y++) << SCALEBITS; cb = *Cb++ - 128; cr = *Cr++ - 128; add_r = FIX(1.40200) * cr + ONE_HALF; add_g = - FIX(0.34414) * cb - FIX(0.71414) * cr + ONE_HALF; add_b = FIX(1.77200) * cb + ONE_HALF; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); } p += offset_to_next_row; }#undef SCALEBITS#undef ONE_HALF#undef FIX}/** * YCrCb -> BGR24 (1x1) * .---. * | 1 | * `---' */static void YCrCB_to_BGR24_1x1(struct jdec_private *priv){ const unsigned char *Y, *Cb, *Cr; unsigned char *p; int i,j; int offset_to_next_row;#define SCALEBITS 10#define ONE_HALF (1UL << (SCALEBITS-1))#define FIX(x) ((int)((x) * (1UL<<SCALEBITS) + 0.5)) p = priv->plane[0]; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = priv->width*3 - 8*3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -