Emulate colorspace extensions if they are not present in the libjpeg API. This allows the TurboJPEG wrapper to be used with libjpeg rather than libjpeg-turbo. Not useful within the context of our project, but other projects prefer to include the TurboJPEG wrapper in-tree, and this allows them to be linked against either libjpeg-turbo or libjpeg.

This commit is contained in:
DRC
2012-03-23 19:47:57 +00:00
parent c2dab98ea0
commit 9d7101c8f6

View File

@@ -172,12 +172,17 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo,
cinfo->in_color_space=JCS_EXT_XBGR; break;
#else
case TJPF_RGB:
if(RGB_RED==0 && RGB_GREEN==1 && RGB_BLUE==2 && RGB_PIXELSIZE==3)
{
cinfo->in_color_space=JCS_RGB; break;
}
default:
_throw("Unsupported pixel format");
case TJPF_BGR:
case TJPF_RGBX:
case TJPF_BGRX:
case TJPF_XRGB:
case TJPF_XBGR:
case TJPF_RGBA:
case TJPF_BGRA:
case TJPF_ARGB:
case TJPF_ABGR:
cinfo->in_color_space=JCS_RGB; pixelFormat=TJPF_RGB;
break;
#endif
}
@@ -201,9 +206,6 @@ static int setCompDefaults(struct jpeg_compress_struct *cinfo,
cinfo->comp_info[1].v_samp_factor=1;
cinfo->comp_info[2].v_samp_factor=1;
#if JCS_EXTENSIONS!=1
bailout:
#endif
return retval;
}
@@ -241,10 +243,16 @@ static int setDecompDefaults(struct jpeg_decompress_struct *dinfo,
#endif
#else
case TJPF_RGB:
if(RGB_RED==0 && RGB_GREEN==1 && RGB_BLUE==2 && RGB_PIXELSIZE==3)
{
dinfo->out_color_space=JCS_RGB; break;
}
case TJPF_BGR:
case TJPF_RGBX:
case TJPF_BGRX:
case TJPF_XRGB:
case TJPF_XBGR:
case TJPF_RGBA:
case TJPF_BGRA:
case TJPF_ARGB:
case TJPF_ABGR:
dinfo->out_color_space=JCS_RGB; break;
#endif
default:
_throw("Unsupported pixel format");
@@ -283,6 +291,149 @@ static int getSubsamp(j_decompress_ptr dinfo)
}
#ifndef JCS_EXTENSIONS
/* Conversion functions to emulate the colorspace extensions. This allows the
TurboJPEG wrapper to be used with libjpeg */
#define TORGB(PS, ROFFSET, GOFFSET, BOFFSET) { \
int rowPad=pitch-width*PS; \
while(height--) \
{ \
unsigned char *endOfRow=src+width*PS; \
while(src<endOfRow) \
{ \
dst[RGB_RED]=src[ROFFSET]; \
dst[RGB_GREEN]=src[GOFFSET]; \
dst[RGB_BLUE]=src[BOFFSET]; \
dst+=RGB_PIXELSIZE; src+=PS; \
} \
src+=rowPad; \
} \
}
static unsigned char *toRGB(unsigned char *src, int width, int pitch,
int height, int pixelFormat, unsigned char *dst)
{
unsigned char *retval=src;
switch(pixelFormat)
{
case TJPF_RGB:
#if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=3
retval=dst; TORGB(3, 0, 1, 2);
#endif
break;
case TJPF_BGR:
#if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=3
retval=dst; TORGB(3, 2, 1, 0);
#endif
break;
case TJPF_RGBX:
case TJPF_RGBA:
#if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4
retval=dst; TORGB(4, 0, 1, 2);
#endif
break;
case TJPF_BGRX:
case TJPF_BGRA:
#if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4
retval=dst; TORGB(4, 2, 1, 0);
#endif
break;
case TJPF_XRGB:
case TJPF_ARGB:
#if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4
retval=dst; TORGB(4, 1, 2, 3);
#endif
break;
case TJPF_XBGR:
case TJPF_ABGR:
#if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4
retval=dst; TORGB(4, 3, 2, 1);
#endif
break;
}
return retval;
}
#define FROMRGB(PS, ROFFSET, GOFFSET, BOFFSET, SETALPHA) { \
int rowPad=pitch-width*PS; \
while(height--) \
{ \
unsigned char *endOfRow=dst+width*PS; \
while(dst<endOfRow) \
{ \
dst[ROFFSET]=src[RGB_RED]; \
dst[GOFFSET]=src[RGB_GREEN]; \
dst[BOFFSET]=src[RGB_BLUE]; \
SETALPHA \
dst+=PS; src+=RGB_PIXELSIZE; \
} \
dst+=rowPad; \
} \
}
static void fromRGB(unsigned char *src, unsigned char *dst, int width,
int pitch, int height, int pixelFormat)
{
switch(pixelFormat)
{
case TJPF_RGB:
#if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=3
FROMRGB(3, 0, 1, 2,);
#endif
break;
case TJPF_BGR:
#if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=3
FROMRGB(3, 2, 1, 0,);
#endif
break;
case TJPF_RGBX:
#if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4
FROMRGB(4, 0, 1, 2,);
#endif
break;
case TJPF_RGBA:
#if RGB_RED!=0 || RGB_GREEN!=1 || RGB_BLUE!=2 || RGB_PIXELSIZE!=4
FROMRGB(4, 0, 1, 2, dst[3]=0xFF;);
#endif
break;
case TJPF_BGRX:
#if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4
FROMRGB(4, 2, 1, 0,);
#endif
break;
case TJPF_BGRA:
#if RGB_RED!=2 || RGB_GREEN!=1 || RGB_BLUE!=0 || RGB_PIXELSIZE!=4
FROMRGB(4, 2, 1, 0, dst[3]=0xFF;); return;
#endif
break;
case TJPF_XRGB:
#if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4
FROMRGB(4, 1, 2, 3,); return;
#endif
break;
case TJPF_ARGB:
#if RGB_RED!=1 || RGB_GREEN!=2 || RGB_BLUE!=3 || RGB_PIXELSIZE!=4
FROMRGB(4, 1, 2, 3, dst[0]=0xFF;); return;
#endif
break;
case TJPF_XBGR:
#if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4
FROMRGB(4, 3, 2, 1,); return;
#endif
break;
case TJPF_ABGR:
#if RGB_RED!=3 || RGB_GREEN!=2 || RGB_BLUE!=1 || RGB_PIXELSIZE!=4
FROMRGB(4, 3, 2, 1, dst[0]=0xFF;); return;
#endif
break;
}
}
#endif
/* General API functions */
DLLEXPORT char* DLLCALL tjGetErrorStr(void)
@@ -423,6 +574,9 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf,
unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags)
{
int i, retval=0, alloc=1; JSAMPROW *row_pointer=NULL;
#ifndef JCS_EXTENSIONS
unsigned char *rgbBuf=NULL;
#endif
getinstance(handle)
if((this->init&COMPRESS)==0)
@@ -442,6 +596,16 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf,
if(pitch==0) pitch=width*tjPixelSize[pixelFormat];
#ifndef JCS_EXTENSIONS
if(pixelFormat!=TJPF_GRAY)
{
rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE);
if(!rgbBuf) _throw("tjCompress2(): Memory allocation failure");
srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf);
pitch=width*RGB_PIXELSIZE;
}
#endif
cinfo->image_width=width;
cinfo->image_height=height;
@@ -474,6 +638,9 @@ DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf,
bailout:
if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
#ifndef JCS_EXTENSIONS
if(rgbBuf && rgbBuf!=srcBuf) free(rgbBuf);
#endif
if(row_pointer) free(row_pointer);
return retval;
}
@@ -510,8 +677,11 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
JSAMPROW *outbuf[MAX_COMPONENTS];
int row, pw, ph, cw[MAX_COMPONENTS], ch[MAX_COMPONENTS];
JSAMPLE *ptr=dstBuf;
unsigned long yuvsize=0;
unsigned long yuvsize=0;
jpeg_component_info *compptr;
#ifndef JCS_EXTENSIONS
unsigned char *rgbBuf=NULL;
#endif
getinstance(handle);
if((this->init&COMPRESS)==0)
@@ -537,6 +707,16 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
if(pitch==0) pitch=width*tjPixelSize[pixelFormat];
#ifndef JCS_EXTENSIONS
if(pixelFormat!=TJPF_GRAY)
{
rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE);
if(!rgbBuf) _throw("tjEncodeYUV2(): Memory allocation failure");
srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf);
pitch=width*RGB_PIXELSIZE;
}
#endif
cinfo->image_width=width;
cinfo->image_height=height;
@@ -619,6 +799,9 @@ DLLEXPORT int DLLCALL tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf,
bailout:
if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
#ifndef JCS_EXTENSIONS
if(rgbBuf && rgbBuf!=srcBuf) free(rgbBuf);
#endif
if(row_pointer) free(row_pointer);
for(i=0; i<MAX_COMPONENTS; i++)
{
@@ -746,6 +929,10 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf,
{
int i, retval=0; JSAMPROW *row_pointer=NULL;
int jpegwidth, jpegheight, scaledw, scaledh;
#ifndef JCS_EXTENSIONS
unsigned char *rgbBuf=NULL;
unsigned char *_dstBuf=NULL; int _pitch=0;
#endif
getinstance(handle);
if((this->init&DECOMPRESS)==0)
@@ -793,6 +980,21 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf,
jpeg_start_decompress(dinfo);
if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat];
#ifndef JCS_EXTENSIONS
if(pixelFormat!=TJPF_GRAY &&
(RGB_RED!=tjRedOffset[pixelFormat] ||
RGB_GREEN!=tjGreenOffset[pixelFormat] ||
RGB_BLUE!=tjBlueOffset[pixelFormat] ||
RGB_PIXELSIZE!=tjPixelSize[pixelFormat]))
{
rgbBuf=(unsigned char *)malloc(width*height*3);
if(!rgbBuf) _throw("tjDecompress2(): Memory allocation failure");
_pitch=pitch; pitch=width*3;
_dstBuf=dstBuf; dstBuf=rgbBuf;
}
#endif
if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)
*dinfo->output_height))==NULL)
_throw("tjDecompress2(): Memory allocation failure");
@@ -809,8 +1011,15 @@ DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf,
}
jpeg_finish_decompress(dinfo);
#ifndef JCS_EXTENSIONS
fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat);
#endif
bailout:
if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo);
#ifndef JCS_EXTENSIONS
if(rgbBuf && rgbBuf!=dstBuf) free(rgbBuf);
#endif
if(row_pointer) free(row_pointer);
return retval;
}