Replace the TJ_YUV flag with two new API functions, and add TJBUFSIZEYUV() from trunk

git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.1.x@440 632fc199-4ca6-4c93-a231-07263d6284db
This commit is contained in:
DRC 2011-02-25 00:02:04 +00:00
Родитель 5cb1b68d39
Коммит eeab6957dd
5 изменённых файлов: 249 добавлений и 92 удалений

Просмотреть файл

@ -225,8 +225,7 @@ int checkbuf(unsigned char *buf, int w, int h, int ps, int subsamp, int flags)
#define PAD(v, p) ((v+(p)-1)&(~((p)-1)))
int checkbufyuv(unsigned char *buf, unsigned long size, int w, int h,
int subsamp)
int checkbufyuv(unsigned char *buf, int w, int h, int subsamp)
{
int i, j;
int hsf=_hsf[subsamp], vsf=_vsf[subsamp];
@ -234,13 +233,6 @@ int checkbufyuv(unsigned char *buf, unsigned long size, int w, int h,
int cw=pw/hsf, ch=ph/vsf;
int ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4);
int retval=1;
unsigned long correctsize=ypitch*ph + (subsamp==TJ_GRAYSCALE? 0:uvpitch*ch*2);
if(size!=correctsize)
{
printf("\nIncorrect size %lu. Should be %lu\n", size, correctsize);
retval=0; goto bailout;
}
for(i=0; i<16; i++)
{
@ -349,8 +341,6 @@ void gentestjpeg(tjhandle hnd, unsigned char *jpegbuf, unsigned long *size,
char tempstr[1024]; unsigned char *bmpbuf=NULL;
const char *pixformat; double t;
if(yuv==YUVENCODE) flags|=TJ_YUV;
if(flags&TJ_BGR)
{
if(ps==3) pixformat="BGR";
@ -374,10 +364,20 @@ void gentestjpeg(tjhandle hnd, unsigned char *jpegbuf, unsigned long *size,
printf("ERROR: Could not allocate buffer\n"); bailout();
}
initbuf(bmpbuf, w, h, ps, flags);
memset(jpegbuf, 0, TJBUFSIZE(w, h));
memset(jpegbuf, 0,
yuv==YUVENCODE? TJBUFSIZEYUV(w, h, subsamp):TJBUFSIZE(w, h));
t=rrtime();
_catch(tjCompress(hnd, bmpbuf, w, 0, h, ps, jpegbuf, size, subsamp, qual, flags));
if(yuv==YUVENCODE)
{
_catch(tjEncodeYUV(hnd, bmpbuf, w, 0, h, ps, jpegbuf, subsamp, flags));
*size=TJBUFSIZEYUV(w, h, subsamp);
}
else
{
_catch(tjCompress(hnd, bmpbuf, w, 0, h, ps, jpegbuf, size, subsamp, qual,
flags));
}
t=rrtime()-t;
if(yuv==YUVENCODE)
@ -389,7 +389,7 @@ void gentestjpeg(tjhandle hnd, unsigned char *jpegbuf, unsigned long *size,
writejpeg(jpegbuf, *size, tempstr);
if(yuv==YUVENCODE)
{
if(checkbufyuv(jpegbuf, *size, w, h, subsamp)) printf("Passed.");
if(checkbufyuv(jpegbuf, w, h, subsamp)) printf("Passed.");
else {printf("FAILED!"); exitstatus=-1;}
}
else printf("Done.");
@ -405,13 +405,8 @@ void gentestbmp(tjhandle hnd, unsigned char *jpegbuf, unsigned long jpegsize,
unsigned char *bmpbuf=NULL;
const char *pixformat; int _w=0, _h=0; double t;
unsigned long size=0;
int hsf=_hsf[subsamp], vsf=_vsf[subsamp];
int pw=PAD(w, hsf), ph=PAD(h, vsf);
int cw=pw/hsf, ch=ph/vsf;
int ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4);
if(yuv==YUVDECODE) flags|=TJ_YUV;
else if(yuv==YUVENCODE) return;
if(yuv==YUVENCODE) return;
if(flags&TJ_BGR)
{
@ -436,24 +431,29 @@ void gentestbmp(tjhandle hnd, unsigned char *jpegbuf, unsigned long jpegsize,
printf("Incorrect JPEG header\n"); bailout();
}
if(yuv==YUVDECODE)
size=ypitch*ph + (subsamp==TJ_GRAYSCALE? 0:uvpitch*ch*2);
else
size=w*h*ps;
if((bmpbuf=(unsigned char *)malloc(size+1))==NULL)
if(yuv==YUVDECODE) size=TJBUFSIZEYUV(w, h, subsamp);
else size=w*h*ps+1;
if((bmpbuf=(unsigned char *)malloc(size))==NULL)
{
printf("ERROR: Could not allocate buffer\n"); bailout();
}
memset(bmpbuf, 0, size+1);
memset(bmpbuf, 0, size);
t=rrtime();
_catch(tjDecompress(hnd, jpegbuf, jpegsize, bmpbuf, w, w*ps, h, ps, flags));
if(yuv==YUVDECODE)
{
_catch(tjDecompressToYUV(hnd, jpegbuf, jpegsize, bmpbuf, flags));
}
else
{
_catch(tjDecompress(hnd, jpegbuf, jpegsize, bmpbuf, w, w*ps, h, ps,
flags));
}
t=rrtime()-t;
if(yuv==YUVDECODE)
{
if(checkbufyuv(bmpbuf, size, pw, ph, subsamp))
printf("Passed.");
if(checkbufyuv(bmpbuf, w, h, subsamp)) printf("Passed.");
else {printf("FAILED!"); exitstatus=-1;}
}
else
@ -476,7 +476,8 @@ void dotest(int w, int h, int ps, int subsamp, char *basefilename)
tjhandle hnd=NULL, dhnd=NULL; unsigned char *jpegbuf=NULL;
unsigned long size;
if((jpegbuf=(unsigned char *)malloc(TJBUFSIZE(w, h))) == NULL)
size=(yuv==YUVENCODE? TJBUFSIZEYUV(w, h, subsamp):TJBUFSIZE(w, h));
if((jpegbuf=(unsigned char *)malloc(size)) == NULL)
{
puts("ERROR: Could not allocate buffer."); bailout();
}

Просмотреть файл

@ -43,8 +43,6 @@ const int _bindex[BMPPIXELFORMATS]={2, 2, 0, 0, 1, 3};
const char *_pfname[]={"RGB", "RGBX", "BGR", "BGRX", "XBGR", "XRGB"};
const char *_subnamel[NUMSUBOPT]={"4:4:4", "4:2:2", "4:2:0", "GRAY"};
const char *_subnames[NUMSUBOPT]={"444", "422", "420", "GRAY"};
const int _hsf[NUMSUBOPT]={1, 2, 2, 1};
const int _vsf[NUMSUBOPT]={1, 1, 2, 1};
void printsigfig(double val, int figs)
{
@ -78,16 +76,12 @@ void dotest(unsigned char *srcbuf, int w, int h, int pf, int bu,
|(fastupsample?TJ_FASTUPSAMPLE:0);
int ps=_ps[pf], tilen;
int pitch=w*ps, yuvsize;
int hsf=_hsf[jpegsub], vsf=_vsf[jpegsub];
int pw=PAD(w, hsf), ph=PAD(h, vsf);
int cw=pw/hsf, ch=ph/vsf;
int ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4);
flags |= _flags[pf];
if(bu) flags |= TJ_BOTTOMUP;
if(yuv==YUVENCODE) flags |= TJ_YUV;
yuvsize=ypitch*ph + (jpegsub==TJ_GRAYSCALE? 0:uvpitch*ch*2);
yuvsize=TJBUFSIZEYUV(w, h, jpegsub);
if((rgbbuf=(unsigned char *)malloc(max(yuvsize, pitch*h))) == NULL)
_throwunix("allocating image buffer");
@ -125,7 +119,14 @@ void dotest(unsigned char *srcbuf, int w, int h, int pf, int bu,
for(i=0; i<h; i++) memcpy(&rgbbuf[pitch*i], &srcbuf[w*ps*i], w*ps);
if((hnd=tjInitCompress())==NULL)
_throwtj("executing tjInitCompress()");
if(tjCompress(hnd, rgbbuf, tilesizex, pitch, tilesizey, ps,
if(yuv==YUVENCODE)
{
if(tjEncodeYUV(hnd, rgbbuf, tilesizex, pitch, tilesizey, ps,
jpegbuf[0], jpegsub, flags)==-1)
_throwtj("executing tjEncodeYUV()");
comptilesize[0]=TJBUFSIZEYUV(tilesizex, tilesizey, jpegsub);
}
else if(tjCompress(hnd, rgbbuf, tilesizex, pitch, tilesizey, ps,
jpegbuf[0], &comptilesize[0], jpegsub, qual, flags)==-1)
_throwtj("executing tjCompress()");
ITER=0;
@ -138,7 +139,14 @@ void dotest(unsigned char *srcbuf, int w, int h, int pf, int bu,
for(j=0; j<w; j+=tilesizex)
{
int tempw=min(tilesizex, w-j), temph=min(tilesizey, h-i);
if(tjCompress(hnd, &rgbbuf[pitch*i+j*ps], tempw, pitch,
if(yuv==YUVENCODE)
{
if(tjEncodeYUV(hnd, &rgbbuf[pitch*i+j*ps], tempw, pitch,
temph, ps, jpegbuf[tilen], jpegsub, flags)==-1)
_throwtj("executing tjEncodeYUV()");
comptilesize[tilen]=TJBUFSIZEYUV(tempw, temph, jpegsub);
}
else if(tjCompress(hnd, &rgbbuf[pitch*i+j*ps], tempw, pitch,
temph, ps, jpegbuf[tilen], &comptilesize[tilen], jpegsub, qual,
flags)==-1)
_throwtj("executing tjCompress()");
@ -194,11 +202,15 @@ void dotest(unsigned char *srcbuf, int w, int h, int pf, int bu,
}
// Decompression test
if(yuv==YUVDECODE) flags |= TJ_YUV;
memset(rgbbuf, 127, max(yuvsize, pitch*h)); // Grey image means decompressor did nothing
if((hnd=tjInitDecompress())==NULL)
_throwtj("executing tjInitDecompress()");
if(tjDecompress(hnd, jpegbuf[0], jpgbufsize, rgbbuf, tilesizex, pitch,
if(yuv==YUVDECODE)
{
if(tjDecompressToYUV(hnd, jpegbuf[0], jpgbufsize, rgbbuf, flags)==-1)
_throwtj("executing tjDecompressToYUV()");
}
else if(tjDecompress(hnd, jpegbuf[0], jpgbufsize, rgbbuf, tilesizex, pitch,
tilesizey, ps, flags)==-1)
_throwtj("executing tjDecompress()");
ITER=0;
@ -211,7 +223,13 @@ void dotest(unsigned char *srcbuf, int w, int h, int pf, int bu,
for(j=0; j<w; j+=tilesizex)
{
int tempw=min(tilesizex, w-j), temph=min(tilesizey, h-i);
if(tjDecompress(hnd, jpegbuf[tilen], comptilesize[tilen],
if(yuv==YUVDECODE)
{
if(tjDecompressToYUV(hnd, jpegbuf[tilen], comptilesize[tilen],
&rgbbuf[pitch*i+ps*j], flags)==-1)
_throwtj("executing tjDecompressToYUV()");
}
else if(tjDecompress(hnd, jpegbuf[tilen], comptilesize[tilen],
&rgbbuf[pitch*i+ps*j], tempw, pitch, temph, ps, flags)==-1)
_throwtj("executing tjDecompress()");
tilen++;
@ -321,11 +339,10 @@ void dodecomptest(char *filename, int pf, int bu, int useppm,
|(fastupsample?TJ_FASTUPSAMPLE:0);
int ps=_ps[pf], pitch, jpegsub=-1;
char *temp=NULL;
int hsf, vsf, pw, ph, cw, ch, ypitch, uvpitch, yuvsize;
int yuvsize, bufsize;
flags |= _flags[pf];
if(bu) flags |= TJ_BOTTOMUP;
if(yuv==YUVDECODE) flags |= TJ_YUV;
if((file=fopen(filename, "rb"))==NULL)
_throwunix("opening file");
@ -346,11 +363,7 @@ void dodecomptest(char *filename, int pf, int bu, int useppm,
if(tjDecompressHeader2(hnd, jpegbuf, jpgbufsize, &w, &h, &jpegsub)==-1)
_throwtj("executing tjDecompressHeader2()");
hsf=_hsf[jpegsub], vsf=_vsf[jpegsub];
pw=PAD(w, hsf), ph=PAD(h, vsf);
cw=pw/hsf, ch=ph/vsf;
ypitch=PAD(pw, 4), uvpitch=PAD(cw, 4);
yuvsize=ypitch*ph + (jpegsub==TJ_GRAYSCALE? 0:uvpitch*ch*2);
yuvsize=TJBUFSIZEYUV(w, h, jpegsub);
pitch=w*ps;
@ -362,7 +375,8 @@ void dodecomptest(char *filename, int pf, int bu, int useppm,
printf("%s\t%s\t%-4d %-4d\t", _pfname[pf], bu?"BU":"TD", w, h);
}
if((rgbbuf=(unsigned char *)malloc(max(yuvsize, pitch*h)))==NULL)
bufsize=(yuv==YUVDECODE? yuvsize:pitch*h);
if((rgbbuf=(unsigned char *)malloc(bufsize))==NULL)
_throwunix("allocating image buffer");
if(!quiet)
@ -375,15 +389,26 @@ void dodecomptest(char *filename, int pf, int bu, int useppm,
printf("\nImage size: %d x %d\n", w, h);
}
memset(rgbbuf, 127, max(yuvsize, pitch*h)); // Grey image means decompressor did nothing
if(tjDecompress(hnd, jpegbuf, jpgbufsize, rgbbuf, w, pitch, h, ps, flags)==-1)
memset(rgbbuf, 127, bufsize); // Grey image means decompressor did nothing
if(yuv==YUVDECODE)
{
if(tjDecompressToYUV(hnd, jpegbuf, jpgbufsize, rgbbuf, flags)==-1)
_throwtj("executing tjDecompressToYUV()");
}
else if(tjDecompress(hnd, jpegbuf, jpgbufsize, rgbbuf, w, pitch, h, ps,
flags)==-1)
_throwtj("executing tjDecompress()");
ITER=0;
start=rrtime();
do
{
if(tjDecompress(hnd, jpegbuf, jpgbufsize, rgbbuf, w, pitch, h, ps, flags)
==-1)
if(yuv==YUVDECODE)
{
if(tjDecompressToYUV(hnd, jpegbuf, jpgbufsize, rgbbuf, flags)==-1)
_throwtj("executing tjDecompressToYUV()");
}
else if(tjDecompress(hnd, jpegbuf, jpgbufsize, rgbbuf, w, pitch, h, ps,
flags)==-1)
_throwtj("executing tjDecompress()");
ITER++;
} while((elapsed=rrtime()-start)<5.);

Просмотреть файл

@ -16,5 +16,8 @@ TURBOJPEG_1.0
TURBOJPEG_1.1
{
global:
TJBUFSIZEYUV;
tjDecompressHeader2;
tjDecompressToYUV;
tjEncodeYUV;
} TURBOJPEG_1.0;

Просмотреть файл

@ -54,26 +54,7 @@ enum {TJ_444=0, TJ_422, TJ_420, TJ_GRAYSCALE};
/* Use fast, inaccurate 4:2:2 and 4:2:0 YUV upsampling routines
(libjpeg and libjpeg-turbo versions only) */
#define TJ_YUV 512
/* If passed to tjCompress(), this causes TurboJPEG to use the accelerated
color conversion routines in the underlying codec to produce a planar
YUV image that is suitable for X Video. Specifically, if the chrominance
components are subsampled along the horizontal dimension, then the width
of the luminance plane is padded to 2 in the output image (same goes for
the height of the luminance plane, if the chrominance components are
subsampled along the vertical dimension.) Also, each line of each plane
in the output image is padded to 4 bytes. Although this will work with
any subsampling option, it is really only useful in combination with
TJ_420, which produces an image compatible with the I420 (AKA "YUV420P")
format.
If passed to tjDecompress(), this tells TurboJPEG to perform JPEG
decompression but to leave out the color conversion step, so a planar YUV
image is generated instead of an RGB image. The padding of the planes in
this image is the same as in the above case. Note that, if the width or
height of the output image is not a multiple of 8 (or a multiple of 16
along any dimension in which chrominance subsampling is used), then an
intermediate buffer copy will be performed within TurboJPEG.
*/
/* Nothing to see here. Pay no attention to the man behind the curtain. */
typedef void* tjhandle;
@ -96,7 +77,8 @@ extern "C" {
and returns a handle to the instance. Most applications will only
need to call this once at the beginning of the program or once for each
concurrent thread. Don't try to create a new instance every time you
compress an image, because this will cause performance to suffer.
compress an image, because this may cause performance to suffer in some
TurboJPEG implementations.
RETURNS: NULL on error
*/
@ -113,7 +95,7 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void);
tjInitCompress()
[INPUT] srcbuf = pointer to user-allocated image buffer containing RGB or
grayscale pixels to be compressed
[INPUT] width = width (in pixels) of the source image
[INPUT] width = width (in pixels) of the source image
[INPUT] pitch = bytes per line of the source image (width*pixelsize if the
bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the bitmap
is padded to the nearest 32-bit boundary, such as is the case for Windows
@ -128,12 +110,12 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void);
the appropriate size for this buffer based on the image width and height.
[OUTPUT] size = pointer to unsigned long which receives the size (in bytes)
of the compressed image
[INPUT] jpegsubsamp = Specifies either 4:2:0, 4:2:2, or 4:4:4 subsampling.
When the image is converted from the RGB to YCbCr colorspace as part of
the JPEG compression process, every other Cb and Cr (chrominance) pixel
can be discarded to produce a smaller image with little perceptible loss
of image clarity (the human eye is more sensitive to small changes in
brightness than small changes in color.)
[INPUT] jpegsubsamp = Specifies either 4:2:0, 4:2:2, 4:4:4, or grayscale
subsampling. When the image is converted from the RGB to YCbCr colorspace
as part of the JPEG compression process, every other Cb and Cr
(chrominance) pixel can be discarded to produce a smaller image with
little perceptible loss of image clarity (the human eye is more sensitive
to small changes in brightness than small changes in color.)
TJ_420: 4:2:0 subsampling. Discards every other Cb, Cr pixel in both
horizontal and vertical directions
@ -153,8 +135,77 @@ DLLEXPORT int DLLCALL tjCompress(tjhandle j,
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);
/*
int tjEncodeYUV(tjhandle j,
unsigned char *srcbuf, int width, int pitch, int height, int pixelsize,
unsigned char *dstbuf, int subsamp, int flags)
This function uses the accelerated color conversion routines in TurboJPEG's
underlying codec to produce a planar YUV image that is suitable for X Video.
Specifically, if the chrominance components are subsampled along the
horizontal dimension, then the width of the luminance plane is padded to 2 in
the output image (same goes for the height of the luminance plane, if the
chrominance components are subsampled along the vertical dimension.) Also,
each line of each plane in the output image is padded to 4 bytes. Although
this will work with any subsampling option, it is really only useful in
combination with TJ_420, which produces an image compatible with the I420
(AKA "YUV420P") format.
[INPUT] j = instance handle previously returned from a call to
tjInitCompress()
[INPUT] srcbuf = pointer to user-allocated image buffer containing RGB or
grayscale pixels to be encoded
[INPUT] width = width (in pixels) of the source image
[INPUT] pitch = bytes per line of the source image (width*pixelsize if the
bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the bitmap
is padded to the nearest 32-bit boundary, such as is the case for Windows
bitmaps. You can also be clever and use this parameter to skip lines,
etc. Setting this parameter to 0 is the equivalent of setting it to
width*pixelsize.
[INPUT] height = height (in pixels) of the source image
[INPUT] pixelsize = size (in bytes) of each pixel in the source image
RGBX/BGRX/XRGB/XBGR: 4, RGB/BGR: 3, Grayscale: 1
[INPUT] dstbuf = pointer to user-allocated image buffer which will receive
the YUV image. Use the TJBUFSIZEYUV(width, height, subsamp) function to
determine the appropriate size for this buffer based on the image width,
height, and level of subsampling.
[INPUT] subsamp = Specifies either 4:2:0, 4:2:2, 4:4:4, or grayscale
subsampling (see description under tjCompress())
[INPUT] flags = the bitwise OR of one or more of the flags described in the
"Flags" section above
RETURNS: 0 on success, -1 on error
*/
DLLEXPORT int DLLCALL tjEncodeYUV(tjhandle j,
unsigned char *srcbuf, int width, int pitch, int height, int pixelsize,
unsigned char *dstbuf, int subsamp, int flags);
/*
tjhandle tjInitDecompress(void)
@ -162,7 +213,8 @@ DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height);
structures, and returns a handle to the instance. Most applications will
only need to call this once at the beginning of the program or once for each
concurrent thread. Don't try to create a new instance every time you
decompress an image, because this will cause performance to suffer.
decompress an image, because this may cause performance to suffer in some
TurboJPEG implementations.
RETURNS: NULL on error
*/
@ -176,8 +228,7 @@ DLLEXPORT tjhandle DLLCALL tjInitDecompress(void);
[INPUT] j = instance handle previously returned from a call to
tjInitDecompress()
[INPUT] srcbuf = pointer to a user-allocated buffer containing the JPEG image
to decompress
[INPUT] srcbuf = pointer to a user-allocated buffer containing a JPEG image
[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
@ -213,7 +264,7 @@ DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle j,
the bitmap image. This buffer should normally be pitch*height
bytes in size, although this pointer may also be used to decompress into
a specific region of a larger buffer.
[INPUT] width = width (in pixels) of the destination image
[INPUT] width = width (in pixels) of the destination image
[INPUT] pitch = bytes per line of the destination image (width*pixelsize if
the bitmap is unpadded, else TJPAD(width*pixelsize) if each line of the
bitmap is padded to the nearest 32-bit boundary, such as is the case for
@ -234,6 +285,37 @@ DLLEXPORT int DLLCALL tjDecompress(tjhandle j,
int flags);
/*
int tjDecompressToYUV(tjhandle j,
unsigned char *srcbuf, unsigned long size,
unsigned char *dstbuf, int flags)
This function performs JPEG decompression but leaves out the color conversion
step, so a planar YUV image is generated instead of an RGB image. The
padding of the planes in this image is the same as in tjEncodeYUV().
Note that, if the width or height of the output image is not a multiple of 8
(or a multiple of 16 along any dimension in which chrominance subsampling is
used), then an intermediate buffer copy will be performed within TurboJPEG.
[INPUT] j = instance handle previously returned from a call to
tjInitDecompress()
[INPUT] srcbuf = pointer to a user-allocated buffer containing the JPEG image
to decompress
[INPUT] size = size of the JPEG image buffer (in bytes)
[INPUT] dstbuf = pointer to user-allocated image buffer which will receive
the YUV image. Use the TJBUFSIZEYUV(width, height, subsamp) function to
determine the appropriate size for this buffer based on the image width,
height, and level of subsampling.
[INPUT] flags = the bitwise OR of one or more of the flags described in the
"Flags" section above.
RETURNS: 0 on success, -1 on error
*/
DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle j,
unsigned char *srcbuf, unsigned long size,
unsigned char *dstbuf, int flags);
/*
int tjDestroy(tjhandle h)

Просмотреть файл

@ -112,12 +112,40 @@ DLLEXPORT tjhandle DLLCALL tjInitCompress(void)
return (tjhandle)j;
}
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 before.)
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,
unsigned char *srcbuf, int width, int pitch, int height, int ps,
unsigned char *dstbuf, unsigned long *size,
@ -308,6 +336,16 @@ DLLEXPORT int DLLCALL tjCompress(tjhandle h,
}
DLLEXPORT int DLLCALL tjEncodeYUV(tjhandle h,
unsigned char *srcbuf, int width, int pitch, int height, int ps,
unsigned char *dstbuf, int subsamp, int flags)
{
unsigned long size;
return tjCompress(h, srcbuf, width, pitch, height, ps, dstbuf, &size,
subsamp, 0, flags|TJ_YUV);
}
// DEC
static boolean fill_input_buffer (struct jpeg_decompress_struct *dinfo)
@ -471,10 +509,10 @@ DLLEXPORT int DLLCALL tjDecompress(tjhandle h,
int ih;
iw[i]=compptr->width_in_blocks*DCTSIZE;
ih=compptr->height_in_blocks*DCTSIZE;
cw[i]=PAD(width, dinfo->max_h_samp_factor)*compptr->h_samp_factor
/dinfo->max_h_samp_factor;
ch[i]=PAD(height, dinfo->max_v_samp_factor)*compptr->v_samp_factor
/dinfo->max_v_samp_factor;
cw[i]=PAD(dinfo->image_width, dinfo->max_h_samp_factor)
*compptr->h_samp_factor/dinfo->max_h_samp_factor;
ch[i]=PAD(dinfo->image_height, dinfo->max_v_samp_factor)
*compptr->v_samp_factor/dinfo->max_v_samp_factor;
if(iw[i]!=cw[i] || ih!=ch[i]) usetmpbuf=1;
th[i]=compptr->v_samp_factor*DCTSIZE;
tmpbufsize+=iw[i]*th[i];
@ -589,6 +627,14 @@ DLLEXPORT int DLLCALL tjDecompress(tjhandle h,
}
DLLEXPORT int DLLCALL tjDecompressToYUV(tjhandle h,
unsigned char *srcbuf, unsigned long size,
unsigned char *dstbuf, int flags)
{
return tjDecompress(h, srcbuf, size, dstbuf, 1, 0, 1, 3, flags|TJ_YUV);
}
// General
DLLEXPORT char* DLLCALL tjGetErrorStr(void)