📄 tinyjpeg.c
字号:
Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = (priv->width*3*2) - 16*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; 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; y = (*Y++) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); y = (*Y++) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); y = (Y[16-2]) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); y = (Y[16-1]) << SCALEBITS; r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); } Y += 16; p += offset_to_next_row; p2 += offset_to_next_row; }#undef SCALEBITS#undef ONE_HALF#undef FIX}/* * YCrCb -> BGR24 (2x2) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */static void YCrCB_to_BGR24_2x2(struct jdec_private *priv){ const unsigned char *Y, *Cb, *Cr; unsigned char *p, *p2; 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]; p2 = priv->plane[0] + priv->width*3; Y = priv->Y; Cb = priv->Cb; Cr = priv->Cr; offset_to_next_row = (priv->width*3*2) - 16*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; 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; y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); y = (*Y++) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p++ = clamp(r); y = (Y[16-2]) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); y = (Y[16-1]) << SCALEBITS; b = (y + add_b) >> SCALEBITS; *p2++ = clamp(b); g = (y + add_g) >> SCALEBITS; *p2++ = clamp(g); r = (y + add_r) >> SCALEBITS; *p2++ = clamp(r); } Y += 16; p += offset_to_next_row; p2 += offset_to_next_row; }#undef SCALEBITS#undef ONE_HALF#undef FIX}/** * YCrCb -> Grey (1x1) * .---. * | 1 | * `---' */static void YCrCB_to_Grey_1x1(struct jdec_private *priv){ const unsigned char *y; unsigned char *p; unsigned int i; int offset_to_next_row; p = priv->plane[0]; y = priv->Y; offset_to_next_row = priv->width; for (i=0; i<8; i++) { memcpy(p, y, 8); y+=8; p += offset_to_next_row; }}/** * YCrCb -> Grey (2x1) * .-------. * | 1 | 2 | * `-------' */static void YCrCB_to_Grey_2x1(struct jdec_private *priv){ const unsigned char *y; unsigned char *p; unsigned int i; p = priv->plane[0]; y = priv->Y; for (i=0; i<8; i++) { memcpy(p, y, 16); y += 16; p += priv->width; }}/** * YCrCb -> Grey (1x2) * .---. * | 1 | * |---| * | 2 | * `---' */static void YCrCB_to_Grey_1x2(struct jdec_private *priv){ const unsigned char *y; unsigned char *p; unsigned int i; p = priv->plane[0]; y = priv->Y; for (i=0; i<16; i++) { memcpy(p, y, 8); y += 8; p += priv->width; }}/** * YCrCb -> Grey (2x2) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */static void YCrCB_to_Grey_2x2(struct jdec_private *priv){ const unsigned char *y; unsigned char *p; unsigned int i; p = priv->plane[0]; y = priv->Y; for (i=0; i<16; i++) { memcpy(p, y, 16); y += 16; p += priv->width; }}/* * Decode all the 3 components for 1x1 */static void decode_MCU_1x1_3planes(struct jdec_private *priv){ // Y process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 8); // Cb process_Huffman_data_unit(priv, cCb); IDCT(&priv->component_infos[cCb], priv->Cb, 8); // Cr process_Huffman_data_unit(priv, cCr); IDCT(&priv->component_infos[cCr], priv->Cr, 8);}/* * Decode a 1x1 directly in 1 color */static void decode_MCU_1x1_1plane(struct jdec_private *priv){ // Y process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 8); // Cb process_Huffman_data_unit(priv, cCb); IDCT(&priv->component_infos[cCb], priv->Cb, 8); // Cr process_Huffman_data_unit(priv, cCr); IDCT(&priv->component_infos[cCr], priv->Cr, 8);}/* * Decode a 2x1 * .-------. * | 1 | 2 | * `-------' */static void decode_MCU_2x1_3planes(struct jdec_private *priv){ // Y process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 16); process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+8, 16); // Cb process_Huffman_data_unit(priv, cCb); IDCT(&priv->component_infos[cCb], priv->Cb, 8); // Cr process_Huffman_data_unit(priv, cCr); IDCT(&priv->component_infos[cCr], priv->Cr, 8);}/* * Decode a 2x1 * .-------. * | 1 | 2 | * `-------' */static void decode_MCU_2x1_1plane(struct jdec_private *priv){ // Y process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 16); process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+8, 16); // Cb process_Huffman_data_unit(priv, cCb); // Cr process_Huffman_data_unit(priv, cCr);}/* * Decode a 2x2 * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */static void decode_MCU_2x2_3planes(struct jdec_private *priv){ // Y process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 16); process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+8, 16); process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64*2, 16); process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16); // Cb process_Huffman_data_unit(priv, cCb); IDCT(&priv->component_infos[cCb], priv->Cb, 8); // Cr process_Huffman_data_unit(priv, cCr); IDCT(&priv->component_infos[cCr], priv->Cr, 8);}/* * Decode a 2x2 directly in GREY format (8bits) * .-------. * | 1 | 2 | * |---+---| * | 3 | 4 | * `-------' */static void decode_MCU_2x2_1plane(struct jdec_private *priv){ // Y process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 16); process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+8, 16); process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64*2, 16); process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64*2+8, 16); // Cb process_Huffman_data_unit(priv, cCb); // Cr process_Huffman_data_unit(priv, cCr);}/* * Decode a 1x2 mcu * .---. * | 1 | * |---| * | 2 | * `---' */static void decode_MCU_1x2_3planes(struct jdec_private *priv){ // Y process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 8); process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64, 8); // Cb process_Huffman_data_unit(priv, cCb); IDCT(&priv->component_infos[cCb], priv->Cb, 8); // Cr process_Huffman_data_unit(priv, cCr); IDCT(&priv->component_infos[cCr], priv->Cr, 8);}/* * Decode a 1x2 mcu * .---. * | 1 | * |---| * | 2 | * `---' */static void decode_MCU_1x2_1plane(struct jdec_private *priv){ // Y process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y, 8); process_Huffman_data_unit(priv, cY); IDCT(&priv->component_infos[cY], priv->Y+64, 8); // Cb process_Huffman_data_unit(priv, cCb); // Cr process_Huffman_data_unit(priv, cCr);}static void print_SOF(const unsigned char *stream){ int width, height, nr_components, precision;#if DEBUG const char *nr_components_to_string[] = { "????", "Grayscale", "????", "YCbCr", "CYMK" };#endif precision = stream[2]; height = be16_to_cpu(stream+3); width = be16_to_cpu(stream+5); nr_components = stream[7]; trace("> SOF marker\n"); trace("Size:%dx%d nr_components:%d (%s) precision:%d\n", width, height, nr_components, nr_components_to_string[nr_components], precision);}/******************************************************************************* * * JPEG/JFIF Parsing functions * * Note: only a small subset of the jpeg file format is supported. No markers, * nor progressive stream is supported. * ******************************************************************************/static void build_quantization_table(float *qtable, const unsigned char *ref_table){ /* Taken from libjpeg. Copyright Independent JPEG Group's LLM idct. * For float AA&N IDCT method, divisors are equal to quantization * coefficients scaled by scalefactor[row]*scalefactor[col], where * scalefactor[0] = 1 * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 * We apply a further scale factor of 8. * What's actually stored is 1/divisor so that the inner loop can * use a multiplication rather than a division. */ int i, j; static const double aanscalefactor[8] = { 1.0, 1.387039845, 1.306562965, 1.175875602, 1.0, 0.785694958, 0.541196100, 0.275899379 }; const unsigned char *zz = zigzag; for (i=0; i<8; i++) { for (j=0; j<8; j++) { *qtable++ = ref_table[*zz++] * aanscalefactor[i] * aanscalefactor[j]; } }}static int parse_DQT(struct jdec_private *priv, const unsigned char *stream){ int qi; float *table; const unsigned char *dqt_block_end; trace("> DQT marker\n"); dqt_block_end = stream + be16_to_cpu(stream); stream += 2; /* Skip length */ while (stream < dqt_block_end) { qi = *stream++;#if SANITY_CHECK if (qi>>4) error("16 bits quantization table is not supported\n"); if (qi>4) error("No more 4 quantization table is supported (got %d)\n", qi);#endif table = priv->Q_tables[qi]; build_quantization_table(table, stream); stream += 64; } trace("< DQT marker\n"); return 0;}static int parse_SOF(struct jdec_private *priv, const unsigned char *stream){ int i, width, height, nr_components, cid, sampling_factor; int Q_table; struct component *c; trace("> SOF marker\n"); print_SOF(stream); height = be16_to_cpu(stream+3); width = be16_to_cpu(stream+5); nr_components = stream[7];#if SANITY_CHECK if (stream[2] != 8) error("Precision other than 8 is not supported\n"); if (width>JPEG_MAX_WIDTH || height>JPEG_MAX_HEIGHT) error("Width and Height (%dx%d) seems suspicious\n", width, height); if (nr_components != 3) error("We only support YUV images\n"); if (height%16) error("Height need to be a multiple of 16 (current height is %d)\n", height); if (width%16) error("Width need to be a multiple of 16 (current Width is %d)\n", width);#endif stream += 8; for (i=0; i<nr_components; i++) { cid = *stream++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -