Added extended tjDecompressHeader() function which can determine the type of subsampling used in the JPEG image
This commit is contained in:
13
turbojpeg.h
13
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,
|
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
|
[INPUT] j = instance handle previously returned from a call to
|
||||||
tjInitDecompress()
|
tjInitDecompress()
|
||||||
@@ -180,9 +180,18 @@ DLLEXPORT tjhandle DLLCALL tjInitDecompress(void);
|
|||||||
[INPUT] size = size of the JPEG image buffer (in bytes)
|
[INPUT] size = size of the JPEG image buffer (in bytes)
|
||||||
[OUTPUT] width = width (in pixels) of the JPEG image
|
[OUTPUT] width = width (in pixels) of the JPEG image
|
||||||
[OUTPUT] height = height (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
|
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,
|
DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle j,
|
||||||
unsigned char *srcbuf, unsigned long size,
|
unsigned char *srcbuf, unsigned long size,
|
||||||
int *width, int *height);
|
int *width, int *height);
|
||||||
|
|||||||
55
turbojpegl.c
55
turbojpegl.c
@@ -86,6 +86,7 @@ typedef struct _jpgstruct
|
|||||||
|
|
||||||
static const int hsampfactor[NUMSUBOPT]={1, 2, 2, 1};
|
static const int hsampfactor[NUMSUBOPT]={1, 2, 2, 1};
|
||||||
static const int vsampfactor[NUMSUBOPT]={1, 1, 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 _throw(c) {sprintf(lasterror, "%s", c); return -1;}
|
||||||
#define _catch(f) {if((f)==-1) 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; i<NUMSUBOPT; i++)
|
||||||
|
{
|
||||||
|
if(j->dinfo.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; k<j->dinfo.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,
|
DLLEXPORT int DLLCALL tjDecompress(tjhandle h,
|
||||||
unsigned char *srcbuf, unsigned long size,
|
unsigned char *srcbuf, unsigned long size,
|
||||||
unsigned char *dstbuf, int width, int pitch, int height, int ps,
|
unsigned char *dstbuf, int width, int pitch, int height, int ps,
|
||||||
|
|||||||
Reference in New Issue
Block a user