Add TJBUFSIZEYUV() convenience function


git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@419 632fc199-4ca6-4c93-a231-07263d6284db
diff --git a/jpegut.c b/jpegut.c
index 31db1d0..10b5966 100644
--- a/jpegut.c
+++ b/jpegut.c
@@ -410,12 +410,8 @@
 {
 	unsigned char *bmpbuf=NULL;
 	const char *pixformat;  int _hdrw=0, _hdrh=0, _hdrsubsamp=-1;  double t;
-	unsigned long size=0;
-	int hsf=_hsf[subsamp], vsf=_vsf[subsamp];
-	int pw=PAD(w, hsf), ph=PAD(h, vsf);
 	int _w=(w+scalefactor-1)/scalefactor, _h=(h+scalefactor-1)/scalefactor;
-	int cw=pw/hsf, ch=ph/vsf;
-	int ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4);
+	unsigned long size=0;
 
 	if(yuv==YUVDECODE) flags|=TJ_YUV;
 	else if(yuv==YUVENCODE) return;
@@ -449,7 +445,7 @@
 	}
 
 	if(yuv==YUVDECODE)
-		size=ypitch*ph + (subsamp==TJ_GRAYSCALE? 0:uvpitch*ch*2);
+		size=TJBUFSIZEYUV(w, h, subsamp);
 	else
 		size=_w*_h*ps;
 	if((bmpbuf=(unsigned char *)malloc(size+1))==NULL)
@@ -465,7 +461,7 @@
 
 	if(yuv==YUVDECODE)
 	{
-		if(checkbufyuv(bmpbuf, size, pw, ph, subsamp))
+		if(checkbufyuv(bmpbuf, size, w, h, subsamp))
 			printf("Passed.");
 		else {printf("FAILED!");  exitstatus=-1;}
 	}
diff --git a/turbojpeg.h b/turbojpeg.h
index 48d8e86..32952da 100644
--- a/turbojpeg.h
+++ b/turbojpeg.h
@@ -153,9 +153,29 @@
 	unsigned char *dstbuf, unsigned long *size,
 	int jpegsubsamp, int jpegqual, int flags);
 
+/*
+  unsigned long TJBUFSIZE(int width, int height)
+
+  Convenience function which returns the maximum size of the buffer required to
+  hold a JPEG image with the given width and height
+
+  RETURNS: -1 if arguments are out of bounds
+*/
 DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height);
 
 /*
+  unsigned long TJBUFSIZEYUV(int width, int height, int subsamp)
+
+  Convenience function which returns the size of the buffer required to
+  hold a YUV planar image with the given width, height, and level of
+  chrominance subsampling
+
+  RETURNS: -1 if arguments are out of bounds
+*/
+DLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height,
+  int subsamp);
+
+/*
   tjhandle tjInitDecompress(void)
 
   Creates a new JPEG decompressor instance, allocates memory for the
diff --git a/turbojpegl.c b/turbojpegl.c
index 1e48234..8ba7fcc 100644
--- a/turbojpegl.c
+++ b/turbojpegl.c
@@ -114,8 +114,33 @@
 
 DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height)
 {
-	// This allows enough room in case the image doesn't compress
-	return ((width+15)&(~15)) * ((height+15)&(~15)) * 6 + 2048;
+	unsigned long retval=0;
+	if(width<1 || height<1)
+		_throw("Invalid argument in TJBUFSIZE()");
+
+	// 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.)
+	retval=((width+15)&(~15)) * ((height+15)&(~15)) * 6 + 2048;
+
+	bailout:
+	return retval;
+}
+
+DLLEXPORT unsigned long DLLCALL TJBUFSIZEYUV(int width, int height,
+	int subsamp)
+{
+	unsigned long retval=0;
+	int pw, ph, cw, ch;
+	if(width<1 || height<1 || subsamp<0 || subsamp>=NUMSUBOPT)
+		_throw("Invalid argument in TJBUFSIZEYUV()");
+	pw=PAD(width, hsampfactor[subsamp]);
+	ph=PAD(height, vsampfactor[subsamp]);
+	cw=pw/hsampfactor[subsamp];  ch=ph/vsampfactor[subsamp];
+	retval=PAD(pw, 4)*ph + (subsamp==TJ_GRAYSCALE? 0:PAD(cw, 4)*ch*2);
+
+	bailout:
+	return retval;
 }
 
 DLLEXPORT int DLLCALL tjCompress(tjhandle h,