From f0d2577482e258c54a3a2eed93722f51a92a25fc Mon Sep 17 00:00:00 2001 From: DRC Date: Tue, 14 Dec 2010 01:21:29 +0000 Subject: [PATCH] Added extended tjDecompressHeader() function which can determine the type of subsampling used in the JPEG image --- turbojpeg.h | 13 +++++++++++-- turbojpegl.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/turbojpeg.h b/turbojpeg.h index e80512b6..b9cb9b56 100644 --- a/turbojpeg.h +++ b/turbojpeg.h @@ -169,9 +169,9 @@ DLLEXPORT tjhandle DLLCALL tjInitDecompress(void); /* - int tjDecompressHeader(tjhandle j, + int tjDecompressHeader2(tjhandle j, unsigned char *srcbuf, unsigned long size, - int *width, int *height) + int *width, int *height, int *jpegsub) [INPUT] j = instance handle previously returned from a call to tjInitDecompress() @@ -180,9 +180,18 @@ DLLEXPORT tjhandle DLLCALL tjInitDecompress(void); [INPUT] size = size of the JPEG image buffer (in bytes) [OUTPUT] width = width (in pixels) of the JPEG image [OUTPUT] height = height (in pixels) of the JPEG image + [OUTPUT] jpegsub = type of chrominance subsampling used when compressing the + JPEG image RETURNS: 0 on success, -1 on error */ +DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle j, + unsigned char *srcbuf, unsigned long size, + int *width, int *height, int *jpegsub); + +/* + Deprecated version of the above function +*/ DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle j, unsigned char *srcbuf, unsigned long size, int *width, int *height); diff --git a/turbojpegl.c b/turbojpegl.c index 8e9605a7..0583a07f 100644 --- a/turbojpegl.c +++ b/turbojpegl.c @@ -86,6 +86,7 @@ typedef struct _jpgstruct static const int hsampfactor[NUMSUBOPT]={1, 2, 2, 1}; static const int vsampfactor[NUMSUBOPT]={1, 1, 2, 1}; +static const int pixelsize[NUMSUBOPT]={3, 3, 3, 1}; #define _throw(c) {sprintf(lasterror, "%s", c); return -1;} #define _catch(f) {if((f)==-1) return -1;} @@ -400,6 +401,60 @@ DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle h, } +DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle h, + unsigned char *srcbuf, unsigned long size, + int *width, int *height, int *jpegsub) +{ + int i, k; + + checkhandle(h); + + if(srcbuf==NULL || size<=0 || width==NULL || height==NULL || jpegsub==NULL) + _throw("Invalid argument in tjDecompressHeader()"); + if(!j->initd) _throw("Instance has not been initialized for decompression"); + + if(setjmp(j->jerr.jb)) + { // this will execute if LIBJPEG has an error + return -1; + } + + j->jsms.bytes_in_buffer = size; + j->jsms.next_input_byte = srcbuf; + + jpeg_read_header(&j->dinfo, TRUE); + + *width=j->dinfo.image_width; *height=j->dinfo.image_height; + *jpegsub=-1; + for(i=0; idinfo.num_components==pixelsize[i]) + { + if(j->dinfo.comp_info[0].h_samp_factor==hsampfactor[i] + && j->dinfo.comp_info[0].v_samp_factor==vsampfactor[i]) + { + int match=0; + for(k=1; kdinfo.num_components; k++) + { + if(j->dinfo.comp_info[k].h_samp_factor==1 + && j->dinfo.comp_info[k].v_samp_factor==1) + match++; + } + if(match==j->dinfo.num_components-1) + { + *jpegsub=i; break; + } + } + } + } + + jpeg_abort_decompress(&j->dinfo); + + if(*jpegsub<0) _throw("Could not determine subsampling type for JPEG image"); + if(*width<1 || *height<1) _throw("Invalid data returned in header"); + return 0; +} + + DLLEXPORT int DLLCALL tjDecompress(tjhandle h, unsigned char *srcbuf, unsigned long size, unsigned char *dstbuf, int width, int pitch, int height, int ps,