如何使用苏泊尔耗的JPEG解码器?
如何使用苏泊尔耗的JPEG解码器?
色彩空间变换,位图的装配。这里生成的仍然不是windows的位图,windows的位图留在jpegwin32单元中完成。这样尽量让最少的单元依赖平台。
jpegbuf.h (目前仍不支持CMYK格式)
*******************************************************************************************************************
/**************************************************************************************************
superarhow's JPEG decoder
by superarhow(superarhow@hotmail.com).All rights reserved.
**************************************************************************************************/
#pragma once
#include "jpegdec2.h"
int jpeg_make_rgb_buffer(p_jpeg_dec_rec p_rec, BYTE** p_com_bufs, WORD* w_com_widths);
int jpeg_make_gray_buffer(p_jpeg_dec_rec p_rec, BYTE** p_com_bufs, WORD* w_com_widths);
*******************************************************************************************************************
jpegbuf.c
通过查表来优化,每个方向上会有+-1的精度损失。但问题不大。要知道人眼能分辨的色彩等级在每个方向上最多只有64级。
*******************************************************************************************************************
/**************************************************************************************************
superarhow's JPEG decoder
by superarhow(superarhow@hotmail.com).All rights reserved.
**************************************************************************************************/
#include "stdafx.h"
#include "jpegbuf.h"
/*
*生成BGR缓冲区
*/
int jpeg_make_rgb_buffer(p_jpeg_dec_rec p_rec, BYTE** p_com_bufs, WORD* w_com_widths)
{
/**********************************************
[Y,Cb,Cr] -> [R,G,B] 转换
-------------------------
R = Y + 1.402 *(Cr-128)
G = Y - 0.34414*(Cb-128) - 0.71414*(Cr-128)
B = Y + 1.772 *(Cb-128)
**********************************************/
// 依次为-128 * 1.402, -127 * 1.402... , 0 * 1.402, 1 * 1.402, ... , 127 * 1.402,下同
static SHORT MUL1_402[256] = {
-179, -178, -177, -175, -174, -172, -171, -170, -168, -167, -165, -164, -163, -161, -160, -158, -157, -156, -154, -153, -151, -150, -149, -147, -146, -144, -143, -142, -140, -139, -137, -136,
-135, -133, -132, -130, -129, -128, -126, -125, -123, -122, -121, -119, -118, -116, -115, -114, -112, -111, -109, -108, -107, -105, -104, -102, -101, -100, -98, -97, -95, -94, -93, -91,
-90, -88, -87, -86, -84, -83, -81, -80, -79, -77, -76, -74, -73, -72, -70, -69, -67, -66, -64, -63, -62, -60, -59, -57, -56, -55, -53, -52, -50, -49, -48, -46,
-45, -43, -42, -41, -39, -38, -36, -35, -34, -32, -31, -29, -28, -27, -25, -24, -22, -21, -20, -18, -17, -15, -14, -13, -11, -10, -8, -7, -6, -4, -3, -1,
0, 1, 3, 4, 6, 7, 8, 10, 11, 13, 14, 15, 17, 18, 20, 21, 22, 24, 25, 27, 28, 29, 31, 32, 34, 35, 36, 38, 39, 41, 42, 43,
45, 46, 48, 49, 50, 52, 53, 55, 56, 57, 59, 60, 62, 63, 64, 66, 67, 69, 70, 72, 73, 74, 76, 77, 79, 80, 81, 83, 84, 86, 87, 88,
90, 91, 93, 94, 95, 97, 98, 100, 101, 102, 104, 105, 107, 108, 109, 111, 112, 114, 115, 116, 118, 119, 121, 122, 123, 125, 126, 128, 129, 130, 132, 133,
135, 136, 137, 139, 140, 142, 143, 144, 146, 147, 149, 150, 151, 153, 154, 156, 157, 158, 160, 161, 163, 164, 165, 167, 168, 170, 171, 172, 174, 175, 177, 178
};
static SHORT MUL0_34414[256] = {
-44, -44, -43, -43, -43, -42, -42, -42, -41, -41, -41, -40, -40, -40, -39, -39, -39, -38, -38, -38, -37, -37, -36, -36, -36, -35, -35, -35, -34, -34, -34, -33,
-33, -33, -32, -32, -32, -31, -31, -31, -30, -30, -30, -29, -29, -29, -28, -28, -28, -27, -27, -26, -26, -26, -25, -25, -25, -24, -24, -24, -23, -23, -23, -22,
-22, -22, -21, -21, -21, -20, -20, -20, -19, -19, -19, -18, -18, -18, -17, -17, -17, -16, -16, -15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -12, -11,
-11, -11, -10, -10, -10, -9, -9, -9, -8, -8, -8, -7, -7, -7, -6, -6, -6, -5, -5, -4, -4, -4, -3, -3, -3, -2, -2, -2, -1, -1, -1, 0,
0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11,
11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22,
22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33,
33, 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44
};
static SHORT MUL0_71414[256] = {
-91, -91, -90, -89, -89, -88, -87, -86, -86, -85, -84, -84, -83, -82, -81, -81, -80, -79, -79, -78, -77, -76, -76, -75, -74, -74, -73, -72, -71, -71, -70, -69,
-69, -68, -67, -66, -66, -65, -64, -64, -63, -62, -61, -61, -60, -59, -59, -58, -57, -56, -56, -55, -54, -54, -53, -52, -51, -51, -50, -49, -49, -48, -47, -46,
-46, -45, -44, -44, -43, -42, -41, -41, -40, -39, -39, -38, -37, -36, -36, -35, -34, -34, -33, -32, -31, -31, -30, -29, -29, -28, -27, -26, -26, -25, -24, -24,
-23, -22, -21, -21, -20, -19, -19, -18, -17, -16, -16, -15, -14, -14, -13, -12, -11, -11, -10, -9, -9, -8, -7, -6, -6, -5, -4, -4, -3, -2, -1, -1,
0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 16, 17, 18, 19, 19, 20, 21, 21, 22,
23, 24, 24, 25, 26, 26, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36, 36, 37, 38, 39, 39, 40, 41, 41, 42, 43, 44, 44, 45,
46, 46, 47, 48, 49, 49, 50, 51, 51, 52, 53, 54, 54, 55, 56, 56, 57, 58, 59, 59, 60, 61, 61, 62, 63, 64, 64, 65, 66, 66, 67, 68,
69, 69, 70, 71, 71, 72, 73, 74, 74, 75, 76, 76, 77, 78, 79, 79, 80, 81, 81, 82, 83, 84, 84, 85, 86, 86, 87, 88, 89, 89, 90, 91
};
static short MUL1_772[256] = {
-227, -225, -223, -221, -220, -218, -216, -214, -213, -211, -209, -207, -206, -204, -202, -200, -198, -197, -195, -193, -191, -190, -188, -186, -184, -183, -181, -179, -177, -175, -174, -172,
-170, -168, -167, -165, -163, -161, -159, -158, -156, -154, -152, -151, -149, -147, -145, -144, -142, -140, -138, -136, -135, -133, -131, -129, -128, -126, -124, -122, -120, -119, -117, -115,
-113, -112, -110, -108, -106, -105, -103, -101, -99, -97, -96, -94, -92, -90, -89, -87, -85, -83, -82, -80, -78, -76, -74, -73, -71, -69, -67, -66, -64, -62, -60, -58,
-57, -55, -53, -51, -50, -48, -46, -44, -43, -41, -39, -37, -35, -34, -32, -30, -28, -27, -25, -23, -21, -19, -18, -16, -14, -12, -11, -9, -7, -5, -4, -2,
0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 18, 19, 21, 23, 25, 27, 28, 30, 32, 34, 35, 37, 39, 41, 43, 44, 46, 48, 50, 51, 53, 55,
57, 58, 60, 62, 64, 66, 67, 69, 71, 73, 74, 76, 78, 80, 82, 83, 85, 87, 89, 90, 92, 94, 96, 97, 99, 101, 103, 105, 106, 108, 110, 112,
113, 115, 117, 119, 120, 122, 124, 126, 128, 129, 131, 133, 135, 136, 138, 140, 142, 144, 145, 147, 149, 151, 152, 154, 156, 158, 159, 161, 163, 165, 167, 168,
170, 172, 174, 175, 177, 179, 181, 183, 184, 186, 188, 190, 191, 193, 195, 197, 198, 200, 202, 204, 206, 207, 209, 211, 213, 214, 216, 218, 220, 222, 223, 225
};
BYTE *p_buf_y, *p_buf_cr, *p_buf_cb;
BYTE *p_line_buf_y, *p_line_buf_cr, *p_line_buf_cb;
BYTE cnt_x_y, cnt_x_cr, cnt_x_cb;
BYTE cnt_y_y, cnt_y_cr, cnt_y_cb;
BYTE lim_x_y, lim_x_cr, lim_x_cb, lim_y_y, lim_y_cr, lim_y_cb;
DWORD inc_y, inc_cr, inc_cb;
DWORD x, y;
BYTE *p_bgr_line_buffer;
BYTE *p_buf;
DWORD n_bytes_per_line;
WORD n_width;
SHORT t;
lim_x_y = p_rec->n_horz_sample_coes_max / p_rec->n_horz_sample_coes[0];
lim_x_cr = p_rec->n_horz_sample_coes_max / p_rec->n_horz_sample_coes[1];
lim_x_cb = p_rec->n_horz_sample_coes_max / p_rec->n_horz_sample_coes[2];
lim_y_y = p_rec->n_vert_sample_coes_max / p_rec->n_vert_sample_coes[0];
lim_y_cr = p_rec->n_vert_sample_coes_max / p_rec->n_vert_sample_coes[1];
lim_y_cb = p_rec->n_vert_sample_coes_max / p_rec->n_vert_sample_coes[2];
inc_y = (DWORD)w_com_widths[0];
inc_cr = (DWORD)w_com_widths[1];
inc_cb = (DWORD)w_com_widths[2];
n_bytes_per_line = p_rec->n_bytes_per_line;
p_line_buf_y = p_com_bufs[0];
p_line_buf_cr = p_com_bufs[1];
p_line_buf_cb = p_com_bufs[2];
p_rec->p_bgr_buffer = (BYTE*)malloc(p_rec->n_bytes_per_line * (DWORD)p_rec->n_height);
p_bgr_line_buffer = p_rec->p_bgr_buffer;
n_width = p_rec->n_width;
for ( y = p_rec->n_height, cnt_y_y = lim_y_y, cnt_y_cr = lim_y_cr, cnt_y_cb = lim_y_cb; y > 0; --y ) {
p_buf_y = p_line_buf_y;
p_buf_cr = p_line_buf_cr;
p_buf_cb = p_line_buf_cb;
p_buf = p_bgr_line_buffer;
for ( x = n_width, cnt_x_y = lim_x_y, cnt_x_cr = lim_x_cr, cnt_x_cb = lim_x_cb; x > 0; --x ) {
t = MUL1_402[*p_buf_cr] + (*p_buf_y);
if (t < 0) t = 0; else if (t > 0xff) t = 0xff;
*p_buf++ = (BYTE)t;
t = (*p_buf_y) - MUL0_34414[*p_buf_cb] - MUL0_71414[*p_buf_cr];
if (t < 0) t = 0; else if (t > 0xff) t = 0xff;
*p_buf++ = (BYTE)t;
t = (*p_buf_y) + MUL1_772[*p_buf_cb];
if (t < 0) t = 0; else if (t > 0xff) t = 0xff;
*p_buf++ = (BYTE)t;
if ( --cnt_x_y == 0 ) {
cnt_x_y = lim_x_y;
++p_buf_y;
}
if ( --cnt_x_cr == 0 ) {
cnt_x_cr = lim_x_cr;
++p_buf_cr;
}
if ( --cnt_x_cb == 0 ) {
cnt_x_cb = lim_x_cb;
++p_buf_cb;
}
} /* x */
p_bgr_line_buffer += n_bytes_per_line;
if ( --cnt_y_y == 0 ) {
cnt_y_y = lim_y_y;
p_line_buf_y += inc_y;
}
if ( --cnt_y_cr == 0 ) {
cnt_y_cr = lim_y_cr;
p_line_buf_cr += inc_cr;
}
if ( --cnt_y_cb == 0 ) {
cnt_y_cb = lim_y_cb;
p_line_buf_cb += inc_cb;
}
} /* y */
return 1;
}
/*
*生成灰度缓冲区
*/
int jpeg_make_gray_buffer(p_jpeg_dec_rec p_rec, BYTE** p_com_bufs, WORD* w_com_widths)
{
BYTE *p_buf_y;
BYTE *p_line_buf_y;
BYTE cnt_x_y;
BYTE cnt_y_y;
BYTE lim_x_y, lim_y_y;
DWORD inc_y;
DWORD x, y;
BYTE *p_bgr_line_buffer;
BYTE *p_buf;
DWORD n_bytes_per_line;
WORD n_width;
SHORT t;
lim_x_y = p_rec->n_horz_sample_coes_max / p_rec->n_horz_sample_coes[0];
lim_y_y = p_rec->n_vert_sample_coes_max / p_rec->n_vert_sample_coes[0];
inc_y = (DWORD)w_com_widths[0];
n_bytes_per_line = p_rec->n_bytes_per_line;
p_line_buf_y = p_com_bufs[0];
p_rec->p_bgr_buffer = (BYTE*)malloc(p_rec->n_bytes_per_line * (DWORD)p_rec->n_height);
p_bgr_line_buffer = p_rec->p_bgr_buffer;
n_width = p_rec->n_width;
for ( y = p_rec->n_height, cnt_y_y = lim_y_y; y > 0; --y ) {
p_buf_y = p_line_buf_y;
p_buf = p_bgr_line_buffer;
for ( x = n_width, cnt_x_y = lim_x_y; x > 0; --x ) {
t = (*p_buf_y);
*p_buf++ = (BYTE)t;
*p_buf++ = (BYTE)t;
*p_buf++ = (BYTE)t;
if ( --cnt_x_y == 0 ) {
cnt_x_y = lim_x_y;
++p_buf_y;
}
} /* x */
p_bgr_line_buffer += n_bytes_per_line;
if ( --cnt_y_y == 0 ) {
cnt_y_y = lim_y_y;
p_line_buf_y += inc_y;
}
} /* y */
return 1;
}