libjpeg-turbo has never really supported such compilers, since (AFAIK) they are non-existent on any modern computing platform and thus impossible for us to test. (Also, the TurboJPEG API would break without unsigned chars.) Furthermore, the unified CMake-based build system introduced in 2.0 always defines HAVE_UNSIGNED_CHAR, so retaining other code paths is pointless. Eliminating support for compilers without unsigned char eliminates the need for the GETJSAMPLE() macro, which improves the readability of many parts of the code as well as improving the performance of writing Targa and Windows BMP files. Fixes #317
385 lines
11 KiB
C
385 lines
11 KiB
C
/*
|
|
* jdcol565.c
|
|
*
|
|
* This file was part of the Independent JPEG Group's software:
|
|
* Copyright (C) 1991-1997, Thomas G. Lane.
|
|
* Modifications:
|
|
* Copyright (C) 2013, Linaro Limited.
|
|
* Copyright (C) 2014-2015, D. R. Commander.
|
|
* For conditions of distribution and use, see the accompanying README.ijg
|
|
* file.
|
|
*
|
|
* This file contains output colorspace conversion routines.
|
|
*/
|
|
|
|
/* This file is included by jdcolor.c */
|
|
|
|
|
|
INLINE
|
|
LOCAL(void)
|
|
ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|
JDIMENSION input_row, JSAMPARRAY output_buf,
|
|
int num_rows)
|
|
{
|
|
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
|
register int y, cb, cr;
|
|
register JSAMPROW outptr;
|
|
register JSAMPROW inptr0, inptr1, inptr2;
|
|
register JDIMENSION col;
|
|
JDIMENSION num_cols = cinfo->output_width;
|
|
/* copy these pointers into registers if possible */
|
|
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
|
register int *Crrtab = cconvert->Cr_r_tab;
|
|
register int *Cbbtab = cconvert->Cb_b_tab;
|
|
register JLONG *Crgtab = cconvert->Cr_g_tab;
|
|
register JLONG *Cbgtab = cconvert->Cb_g_tab;
|
|
SHIFT_TEMPS
|
|
|
|
while (--num_rows >= 0) {
|
|
JLONG rgb;
|
|
unsigned int r, g, b;
|
|
inptr0 = input_buf[0][input_row];
|
|
inptr1 = input_buf[1][input_row];
|
|
inptr2 = input_buf[2][input_row];
|
|
input_row++;
|
|
outptr = *output_buf++;
|
|
|
|
if (PACK_NEED_ALIGNMENT(outptr)) {
|
|
y = *inptr0++;
|
|
cb = *inptr1++;
|
|
cr = *inptr2++;
|
|
r = range_limit[y + Crrtab[cr]];
|
|
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
|
SCALEBITS))];
|
|
b = range_limit[y + Cbbtab[cb]];
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
outptr += 2;
|
|
num_cols--;
|
|
}
|
|
for (col = 0; col < (num_cols >> 1); col++) {
|
|
y = *inptr0++;
|
|
cb = *inptr1++;
|
|
cr = *inptr2++;
|
|
r = range_limit[y + Crrtab[cr]];
|
|
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
|
SCALEBITS))];
|
|
b = range_limit[y + Cbbtab[cb]];
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
|
|
y = *inptr0++;
|
|
cb = *inptr1++;
|
|
cr = *inptr2++;
|
|
r = range_limit[y + Crrtab[cr]];
|
|
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
|
SCALEBITS))];
|
|
b = range_limit[y + Cbbtab[cb]];
|
|
rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
|
|
|
|
WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
|
|
outptr += 4;
|
|
}
|
|
if (num_cols & 1) {
|
|
y = *inptr0;
|
|
cb = *inptr1;
|
|
cr = *inptr2;
|
|
r = range_limit[y + Crrtab[cr]];
|
|
g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
|
SCALEBITS))];
|
|
b = range_limit[y + Cbbtab[cb]];
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
INLINE
|
|
LOCAL(void)
|
|
ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|
JDIMENSION input_row, JSAMPARRAY output_buf,
|
|
int num_rows)
|
|
{
|
|
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
|
|
register int y, cb, cr;
|
|
register JSAMPROW outptr;
|
|
register JSAMPROW inptr0, inptr1, inptr2;
|
|
register JDIMENSION col;
|
|
JDIMENSION num_cols = cinfo->output_width;
|
|
/* copy these pointers into registers if possible */
|
|
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
|
register int *Crrtab = cconvert->Cr_r_tab;
|
|
register int *Cbbtab = cconvert->Cb_b_tab;
|
|
register JLONG *Crgtab = cconvert->Cr_g_tab;
|
|
register JLONG *Cbgtab = cconvert->Cb_g_tab;
|
|
JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
|
|
SHIFT_TEMPS
|
|
|
|
while (--num_rows >= 0) {
|
|
JLONG rgb;
|
|
unsigned int r, g, b;
|
|
|
|
inptr0 = input_buf[0][input_row];
|
|
inptr1 = input_buf[1][input_row];
|
|
inptr2 = input_buf[2][input_row];
|
|
input_row++;
|
|
outptr = *output_buf++;
|
|
if (PACK_NEED_ALIGNMENT(outptr)) {
|
|
y = *inptr0++;
|
|
cb = *inptr1++;
|
|
cr = *inptr2++;
|
|
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
|
|
g = range_limit[DITHER_565_G(y +
|
|
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
|
SCALEBITS)), d0)];
|
|
b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
outptr += 2;
|
|
num_cols--;
|
|
}
|
|
for (col = 0; col < (num_cols >> 1); col++) {
|
|
y = *inptr0++;
|
|
cb = *inptr1++;
|
|
cr = *inptr2++;
|
|
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
|
|
g = range_limit[DITHER_565_G(y +
|
|
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
|
SCALEBITS)), d0)];
|
|
b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
|
|
d0 = DITHER_ROTATE(d0);
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
|
|
y = *inptr0++;
|
|
cb = *inptr1++;
|
|
cr = *inptr2++;
|
|
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
|
|
g = range_limit[DITHER_565_G(y +
|
|
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
|
SCALEBITS)), d0)];
|
|
b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
|
|
d0 = DITHER_ROTATE(d0);
|
|
rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
|
|
|
|
WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
|
|
outptr += 4;
|
|
}
|
|
if (num_cols & 1) {
|
|
y = *inptr0;
|
|
cb = *inptr1;
|
|
cr = *inptr2;
|
|
r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
|
|
g = range_limit[DITHER_565_G(y +
|
|
((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
|
|
SCALEBITS)), d0)];
|
|
b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
INLINE
|
|
LOCAL(void)
|
|
rgb_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|
JDIMENSION input_row, JSAMPARRAY output_buf,
|
|
int num_rows)
|
|
{
|
|
register JSAMPROW outptr;
|
|
register JSAMPROW inptr0, inptr1, inptr2;
|
|
register JDIMENSION col;
|
|
JDIMENSION num_cols = cinfo->output_width;
|
|
SHIFT_TEMPS
|
|
|
|
while (--num_rows >= 0) {
|
|
JLONG rgb;
|
|
unsigned int r, g, b;
|
|
|
|
inptr0 = input_buf[0][input_row];
|
|
inptr1 = input_buf[1][input_row];
|
|
inptr2 = input_buf[2][input_row];
|
|
input_row++;
|
|
outptr = *output_buf++;
|
|
if (PACK_NEED_ALIGNMENT(outptr)) {
|
|
r = *inptr0++;
|
|
g = *inptr1++;
|
|
b = *inptr2++;
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
outptr += 2;
|
|
num_cols--;
|
|
}
|
|
for (col = 0; col < (num_cols >> 1); col++) {
|
|
r = *inptr0++;
|
|
g = *inptr1++;
|
|
b = *inptr2++;
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
|
|
r = *inptr0++;
|
|
g = *inptr1++;
|
|
b = *inptr2++;
|
|
rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
|
|
|
|
WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
|
|
outptr += 4;
|
|
}
|
|
if (num_cols & 1) {
|
|
r = *inptr0;
|
|
g = *inptr1;
|
|
b = *inptr2;
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
INLINE
|
|
LOCAL(void)
|
|
rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|
JDIMENSION input_row, JSAMPARRAY output_buf,
|
|
int num_rows)
|
|
{
|
|
register JSAMPROW outptr;
|
|
register JSAMPROW inptr0, inptr1, inptr2;
|
|
register JDIMENSION col;
|
|
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
|
JDIMENSION num_cols = cinfo->output_width;
|
|
JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
|
|
SHIFT_TEMPS
|
|
|
|
while (--num_rows >= 0) {
|
|
JLONG rgb;
|
|
unsigned int r, g, b;
|
|
|
|
inptr0 = input_buf[0][input_row];
|
|
inptr1 = input_buf[1][input_row];
|
|
inptr2 = input_buf[2][input_row];
|
|
input_row++;
|
|
outptr = *output_buf++;
|
|
if (PACK_NEED_ALIGNMENT(outptr)) {
|
|
r = range_limit[DITHER_565_R(*inptr0++, d0)];
|
|
g = range_limit[DITHER_565_G(*inptr1++, d0)];
|
|
b = range_limit[DITHER_565_B(*inptr2++, d0)];
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
outptr += 2;
|
|
num_cols--;
|
|
}
|
|
for (col = 0; col < (num_cols >> 1); col++) {
|
|
r = range_limit[DITHER_565_R(*inptr0++, d0)];
|
|
g = range_limit[DITHER_565_G(*inptr1++, d0)];
|
|
b = range_limit[DITHER_565_B(*inptr2++, d0)];
|
|
d0 = DITHER_ROTATE(d0);
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
|
|
r = range_limit[DITHER_565_R(*inptr0++, d0)];
|
|
g = range_limit[DITHER_565_G(*inptr1++, d0)];
|
|
b = range_limit[DITHER_565_B(*inptr2++, d0)];
|
|
d0 = DITHER_ROTATE(d0);
|
|
rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
|
|
|
|
WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
|
|
outptr += 4;
|
|
}
|
|
if (num_cols & 1) {
|
|
r = range_limit[DITHER_565_R(*inptr0, d0)];
|
|
g = range_limit[DITHER_565_G(*inptr1, d0)];
|
|
b = range_limit[DITHER_565_B(*inptr2, d0)];
|
|
rgb = PACK_SHORT_565(r, g, b);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
INLINE
|
|
LOCAL(void)
|
|
gray_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|
JDIMENSION input_row, JSAMPARRAY output_buf,
|
|
int num_rows)
|
|
{
|
|
register JSAMPROW inptr, outptr;
|
|
register JDIMENSION col;
|
|
JDIMENSION num_cols = cinfo->output_width;
|
|
|
|
while (--num_rows >= 0) {
|
|
JLONG rgb;
|
|
unsigned int g;
|
|
|
|
inptr = input_buf[0][input_row++];
|
|
outptr = *output_buf++;
|
|
if (PACK_NEED_ALIGNMENT(outptr)) {
|
|
g = *inptr++;
|
|
rgb = PACK_SHORT_565(g, g, g);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
outptr += 2;
|
|
num_cols--;
|
|
}
|
|
for (col = 0; col < (num_cols >> 1); col++) {
|
|
g = *inptr++;
|
|
rgb = PACK_SHORT_565(g, g, g);
|
|
g = *inptr++;
|
|
rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
|
|
WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
|
|
outptr += 4;
|
|
}
|
|
if (num_cols & 1) {
|
|
g = *inptr;
|
|
rgb = PACK_SHORT_565(g, g, g);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
INLINE
|
|
LOCAL(void)
|
|
gray_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
|
|
JDIMENSION input_row, JSAMPARRAY output_buf,
|
|
int num_rows)
|
|
{
|
|
register JSAMPROW inptr, outptr;
|
|
register JDIMENSION col;
|
|
register JSAMPLE *range_limit = cinfo->sample_range_limit;
|
|
JDIMENSION num_cols = cinfo->output_width;
|
|
JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
|
|
|
|
while (--num_rows >= 0) {
|
|
JLONG rgb;
|
|
unsigned int g;
|
|
|
|
inptr = input_buf[0][input_row++];
|
|
outptr = *output_buf++;
|
|
if (PACK_NEED_ALIGNMENT(outptr)) {
|
|
g = *inptr++;
|
|
g = range_limit[DITHER_565_R(g, d0)];
|
|
rgb = PACK_SHORT_565(g, g, g);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
outptr += 2;
|
|
num_cols--;
|
|
}
|
|
for (col = 0; col < (num_cols >> 1); col++) {
|
|
g = *inptr++;
|
|
g = range_limit[DITHER_565_R(g, d0)];
|
|
rgb = PACK_SHORT_565(g, g, g);
|
|
d0 = DITHER_ROTATE(d0);
|
|
|
|
g = *inptr++;
|
|
g = range_limit[DITHER_565_R(g, d0)];
|
|
rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
|
|
d0 = DITHER_ROTATE(d0);
|
|
|
|
WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
|
|
outptr += 4;
|
|
}
|
|
if (num_cols & 1) {
|
|
g = *inptr;
|
|
g = range_limit[DITHER_565_R(g, d0)];
|
|
rgb = PACK_SHORT_565(g, g, g);
|
|
*(INT16 *)outptr = (INT16)rgb;
|
|
}
|
|
}
|
|
}
|