| Index: turbojpeg.c
|
| ===================================================================
|
| --- turbojpeg.c (revision 134206)
|
| +++ turbojpeg.c (working copy)
|
| @@ -1,5 +1,5 @@
|
| /*
|
| - * Copyright (C)2009-2011 D. R. Commander. All Rights Reserved.
|
| + * Copyright (C)2009-2012 D. R. Commander. All Rights Reserved.
|
| *
|
| * Redistribution and use in source and binary forms, with or without
|
| * modification, are permitted provided that the following conditions are met:
|
| @@ -92,10 +92,22 @@
|
| JXFORM_TRANSVERSE, JXFORM_ROT_90, JXFORM_ROT_180, JXFORM_ROT_270
|
| };
|
|
|
| -#define NUMSF 4
|
| +#define NUMSF 16
|
| static const tjscalingfactor sf[NUMSF]={
|
| + {2, 1},
|
| + {15, 8},
|
| + {7, 4},
|
| + {13, 8},
|
| + {3, 2},
|
| + {11, 8},
|
| + {5, 4},
|
| + {9, 8},
|
| {1, 1},
|
| + {7, 8},
|
| + {3, 4},
|
| + {5, 8},
|
| {1, 2},
|
| + {3, 8},
|
| {1, 4},
|
| {1, 8}
|
| };
|
| @@ -160,12 +172,17 @@
|
| 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
|
| }
|
|
|
| @@ -189,9 +206,6 @@
|
| cinfo->comp_info[1].v_samp_factor=1;
|
| cinfo->comp_info[2].v_samp_factor=1;
|
|
|
| - #if JCS_EXTENSIONS!=1
|
| - bailout:
|
| - #endif
|
| return retval;
|
| }
|
|
|
| @@ -229,10 +243,16 @@
|
| #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");
|
| @@ -271,6 +291,149 @@
|
| }
|
|
|
|
|
| +#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)
|
| @@ -411,6 +574,9 @@
|
| 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)
|
| @@ -430,6 +596,16 @@
|
|
|
| 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;
|
|
|
| @@ -462,6 +638,9 @@
|
|
|
| bailout:
|
| if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
|
| + #ifndef JCS_EXTENSIONS
|
| + if(rgbBuf) free(rgbBuf);
|
| + #endif
|
| if(row_pointer) free(row_pointer);
|
| return retval;
|
| }
|
| @@ -498,8 +677,11 @@
|
| 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)
|
| @@ -525,6 +707,16 @@
|
|
|
| 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;
|
|
|
| @@ -607,6 +799,9 @@
|
|
|
| bailout:
|
| if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo);
|
| + #ifndef JCS_EXTENSIONS
|
| + if(rgbBuf) free(rgbBuf);
|
| + #endif
|
| if(row_pointer) free(row_pointer);
|
| for(i=0; i<MAX_COMPONENTS; i++)
|
| {
|
| @@ -734,6 +929,10 @@
|
| {
|
| 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)
|
| @@ -756,7 +955,10 @@
|
|
|
| jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize);
|
| jpeg_read_header(dinfo, TRUE);
|
| - if(setDecompDefaults(dinfo, pixelFormat)==-1) return -1;
|
| + if(setDecompDefaults(dinfo, pixelFormat)==-1)
|
| + {
|
| + retval=-1; goto bailout;
|
| + }
|
|
|
| if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE;
|
|
|
| @@ -778,6 +980,21 @@
|
|
|
| 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");
|
| @@ -794,8 +1011,15 @@
|
| }
|
| 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) free(rgbBuf);
|
| + #endif
|
| if(row_pointer) free(row_pointer);
|
| return retval;
|
| }
|
| @@ -1065,7 +1289,7 @@
|
| &xinfo[i]);
|
| if(t[i].customFilter)
|
| {
|
| - int ci, by, y;
|
| + int ci, y; JDIMENSION by;
|
| for(ci=0; ci<cinfo->num_components; ci++)
|
| {
|
| jpeg_component_info *compptr=&cinfo->comp_info[ci];
|
|
|