📄 tinyjpeg.cxx
字号:
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[8-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 += 8;
p += offset_to_next_row;
p2 += offset_to_next_row;
}
#undef SCALEBITS
#undef ONE_HALF
#undef FIX
}
/**
* YCrCb -> RGB24 (2x2)
* .-------.
* | 1 | 2 |
* |---+---|
* | 3 | 4 |
* `-------'
*/
static void YCrCB_to_RGB24_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;
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-8;
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -