Make the scaling API a bit more friendly
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@422 632fc199-4ca6-4c93-a231-07263d6284db
diff --git a/turbojpegl.c b/turbojpegl.c
index 8ba7fcc..93f4b6a 100644
--- a/turbojpegl.c
+++ b/turbojpegl.c
@@ -120,7 +120,7 @@
// This allows for rare corner cases in which a JPEG image can actually be
// larger than the uncompressed input (we wouldn't mention it if it hadn't
- // happened.)
+ // happened before.)
retval=((width+15)&(~15)) * ((height+15)&(~15)) * 6 + 2048;
bailout:
@@ -319,6 +319,7 @@
-(unsigned long)(j->jdms.free_in_buffer);
bailout:
+ if(j->cinfo.global_state>CSTATE_START) jpeg_abort_compress(&j->cinfo);
if(row_pointer) free(row_pointer);
for(i=0; i<MAX_COMPONENTS; i++)
{
@@ -443,15 +444,44 @@
}
-DLLEXPORT int DLLCALL tjDecompress2(tjhandle h,
+DLLEXPORT int DLLCALL tjScaledSize(int input_width, int input_height,
+ int *output_width, int *output_height)
+{
+ int i, retval=0, scaledw=0, scaledh=0;
+
+ if(input_width<1 || input_height<1 || output_width==NULL
+ || output_height==NULL || *output_width<0 || *output_height<0)
+ _throw("Invalid argument in tjScaledSize()");
+
+ if(*output_width==0) *output_width=input_width;
+ if(*output_height==0) *output_height=input_height;
+ if(*output_width<input_width || *output_height<input_height)
+ {
+ for(i=1; i<=8; i*=2)
+ {
+ scaledw=(input_width+i-1)/i;
+ scaledh=(input_height+i-1)/i;
+ if(scaledw<=*output_width && scaledh<=*output_height)
+ break;
+ }
+ *output_width=scaledw; *output_height=scaledh;
+ }
+
+ bailout:
+ return retval;
+}
+
+
+DLLEXPORT int DLLCALL tjDecompress(tjhandle h,
unsigned char *srcbuf, unsigned long size,
- unsigned char *dstbuf, int pitch, int ps,
- int scale_num, int scale_denom, int flags)
+ unsigned char *dstbuf, int width, int pitch, int height, int ps,
+ int flags)
{
int i, row, retval=0; JSAMPROW *row_pointer=NULL, *outbuf[MAX_COMPONENTS];
int cw[MAX_COMPONENTS], ch[MAX_COMPONENTS], iw[MAX_COMPONENTS],
tmpbufsize=0, usetmpbuf=0, th[MAX_COMPONENTS];
JSAMPLE *_tmpbuf=NULL; JSAMPROW *tmpbuf[MAX_COMPONENTS];
+ int scale_num=1, scale_denom=1, jpegwidth, jpegheight, scaledw, scaledh;
checkhandle(h);
@@ -460,16 +490,13 @@
tmpbuf[i]=NULL; outbuf[i]=NULL;
}
- if(srcbuf==NULL || size<=0 || dstbuf==NULL || pitch<0)
- _throw("Invalid argument in tjDecompress2()");
+ if(srcbuf==NULL || size<=0
+ || dstbuf==NULL || width<0 || pitch<0 || height<0)
+ _throw("Invalid argument in tjDecompress()");
if(ps!=3 && ps!=4 && ps!=1)
_throw("This decompressor can only handle 24-bit and 32-bit RGB or 8-bit grayscale output");
if(!j->initd) _throw("Instance has not been initialized for decompression");
- if(scale_num!=1 || scale_denom<1 || scale_denom>8
- || (scale_denom&(scale_denom-1))!=0)
- _throw("Unsupported scaling factor");
-
if(flags&TJ_FORCEMMX) putenv("JSIMD_FORCEMMX=1");
else if(flags&TJ_FORCESSE) putenv("JSIMD_FORCESSE=1");
else if(flags&TJ_FORCESSE2) putenv("JSIMD_FORCESSE2=1");
@@ -485,6 +512,24 @@
jpeg_read_header(&j->dinfo, TRUE);
+ jpegwidth=j->dinfo.image_width; jpegheight=j->dinfo.image_height;
+ if(width==0) width=jpegwidth;
+ if(height==0) height=jpegheight;
+ if(width<jpegwidth || height<jpegheight)
+ {
+ for(i=1; i<=8; i*=2)
+ {
+ scaledw=(jpegwidth+i-1)/i;
+ scaledh=(jpegheight+i-1)/i;
+ if(scaledw<=width && scaledh<=height)
+ break;
+ }
+ if(scaledw>width || scaledh>height)
+ _throw("Could not scale down to desired image dimensions");
+ width=scaledw; height=scaledh;
+ scale_denom=i;
+ }
+
if(flags&TJ_YUV)
{
j_decompress_ptr dinfo=&j->dinfo;
@@ -591,10 +636,7 @@
if(pitch==0) pitch=j->dinfo.output_width*ps;
if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)
*j->dinfo.output_height))==NULL)
- {
- jpeg_finish_decompress(&j->dinfo);
_throw("Memory allocation failed in tjInitDecompress()");
- }
for(i=0; i<j->dinfo.output_height; i++)
{
if(flags&TJ_BOTTOMUP)
@@ -610,6 +652,7 @@
jpeg_finish_decompress(&j->dinfo);
bailout:
+ if(j->dinfo.global_state>DSTATE_START) jpeg_abort_decompress(&j->dinfo);
for(i=0; i<MAX_COMPONENTS; i++)
{
if(tmpbuf[i]) free(tmpbuf[i]);
@@ -621,19 +664,6 @@
}
-DLLEXPORT int DLLCALL tjDecompress(tjhandle h,
- unsigned char *srcbuf, unsigned long size,
- unsigned char *dstbuf, int width, int pitch, int height, int ps,
- int flags)
-{
- if(width<=0 || height<=0)
- {
- sprintf(lasterror, "Invalid argument in tjDecompress()");
- return -1;
- }
- return tjDecompress2(h, srcbuf, size, dstbuf, pitch, ps, 1, 1, flags);
-}
-
// General
DLLEXPORT char* DLLCALL tjGetErrorStr(void)