Add the ability to benchmark YCCK JPEG compression/decompression. This is particularly useful since that is the only way to test the performance of the "plain" upsampling routines, which are accelerated on some platforms.
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.4.x@1511 632fc199-4ca6-4c93-a231-07263d6284db
This commit is contained in:
@@ -1,3 +1,17 @@
|
||||
1.4.1
|
||||
=====
|
||||
|
||||
[1] tjbench now properly handles CMYK/YCCK JPEG files. Passing an argument of
|
||||
-cmyk (instead of, for instance, -rgb) will cause tjbench to internally convert
|
||||
the source bitmap to CMYK prior to compression, to generate YCCK JPEG files,
|
||||
and to internally convert the decompressed CMYK pixels back to RGB after
|
||||
decompression (the latter is done automatically if a CMYK or YCCK JPEG is
|
||||
passed to tjbench as a source image.) The CMYK<->RGB conversion operation is
|
||||
not benchmarked. NOTE: The quick & dirty CMYK<->RGB conversions that tjbench
|
||||
uses are suitable for testing only. Proper conversion between CMYK and RGB
|
||||
requires a color management system.
|
||||
|
||||
|
||||
1.4.0
|
||||
=====
|
||||
|
||||
|
||||
82
bmp.c
82
bmp.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2011 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2011, 2015 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -75,24 +75,84 @@ static void my_output_message(j_common_ptr cinfo)
|
||||
static void pixelconvert(unsigned char *srcbuf, int srcpf, int srcbottomup,
|
||||
unsigned char *dstbuf, int dstpf, int dstbottomup, int w, int h)
|
||||
{
|
||||
unsigned char *srcptr=srcbuf, *srcptr2;
|
||||
unsigned char *srcrowptr=srcbuf, *srccolptr;
|
||||
int srcps=tjPixelSize[srcpf];
|
||||
int srcstride=srcbottomup? -w*srcps:w*srcps;
|
||||
unsigned char *dstptr=dstbuf, *dstptr2;
|
||||
unsigned char *dstrowptr=dstbuf, *dstcolptr;
|
||||
int dstps=tjPixelSize[dstpf];
|
||||
int dststride=dstbottomup? -w*dstps:w*dstps;
|
||||
int row, col;
|
||||
|
||||
if(srcbottomup) srcptr=&srcbuf[w*srcps*(h-1)];
|
||||
if(dstbottomup) dstptr=&dstbuf[w*dstps*(h-1)];
|
||||
for(row=0; row<h; row++, srcptr+=srcstride, dstptr+=dststride)
|
||||
if(srcbottomup) srcrowptr=&srcbuf[w*srcps*(h-1)];
|
||||
if(dstbottomup) dstrowptr=&dstbuf[w*dstps*(h-1)];
|
||||
|
||||
/* NOTE: These quick & dirty CMYK<->RGB conversion routines are for testing
|
||||
purposes only. Properly converting between CMYK and RGB requires a color
|
||||
management system. */
|
||||
|
||||
if(dstpf==TJPF_CMYK)
|
||||
{
|
||||
for(col=0, srcptr2=srcptr, dstptr2=dstptr; col<w; col++, srcptr2+=srcps,
|
||||
dstptr2+=dstps)
|
||||
for(row=0; row<h; row++, srcrowptr+=srcstride, dstrowptr+=dststride)
|
||||
{
|
||||
dstptr2[tjRedOffset[dstpf]]=srcptr2[tjRedOffset[srcpf]];
|
||||
dstptr2[tjGreenOffset[dstpf]]=srcptr2[tjGreenOffset[srcpf]];
|
||||
dstptr2[tjBlueOffset[dstpf]]=srcptr2[tjBlueOffset[srcpf]];
|
||||
for(col=0, srccolptr=srcrowptr, dstcolptr=dstrowptr;
|
||||
col<w; col++, srccolptr+=srcps)
|
||||
{
|
||||
double c=1.0-((double)(srccolptr[tjRedOffset[srcpf]])/255.);
|
||||
double m=1.0-((double)(srccolptr[tjGreenOffset[srcpf]])/255.);
|
||||
double y=1.0-((double)(srccolptr[tjBlueOffset[srcpf]])/255.);
|
||||
double k=min(min(c,m),min(y,1.0));
|
||||
if(k==1.0) c=m=y=0.0;
|
||||
else
|
||||
{
|
||||
c=(c-k)/(1.0-k);
|
||||
m=(m-k)/(1.0-k);
|
||||
y=(y-k)/(1.0-k);
|
||||
}
|
||||
if(c>1.0) c=1.0; if(c<0.) c=0.;
|
||||
if(m>1.0) m=1.0; if(m<0.) m=0.;
|
||||
if(y>1.0) y=1.0; if(y<0.) y=0.;
|
||||
if(k>1.0) k=1.0; if(k<0.) k=0.;
|
||||
*dstcolptr++=(unsigned char)(255.0-c*255.0+0.5);
|
||||
*dstcolptr++=(unsigned char)(255.0-m*255.0+0.5);
|
||||
*dstcolptr++=(unsigned char)(255.0-y*255.0+0.5);
|
||||
*dstcolptr++=(unsigned char)(255.0-k*255.0+0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(srcpf==TJPF_CMYK)
|
||||
{
|
||||
for(row=0; row<h; row++, srcrowptr+=srcstride, dstrowptr+=dststride)
|
||||
{
|
||||
for(col=0, srccolptr=srcrowptr, dstcolptr=dstrowptr;
|
||||
col<w; col++, dstcolptr+=dstps)
|
||||
{
|
||||
double c=(double)(*srccolptr++);
|
||||
double m=(double)(*srccolptr++);
|
||||
double y=(double)(*srccolptr++);
|
||||
double k=(double)(*srccolptr++);
|
||||
double r=c*k/255.;
|
||||
double g=m*k/255.;
|
||||
double b=y*k/255.;
|
||||
if(r>255.0) r=255.0; if(r<0.) r=0.;
|
||||
if(g>255.0) g=255.0; if(g<0.) g=0.;
|
||||
if(b>255.0) b=255.0; if(b<0.) b=0.;
|
||||
dstcolptr[tjRedOffset[dstpf]]=(unsigned char)(r+0.5);
|
||||
dstcolptr[tjGreenOffset[dstpf]]=(unsigned char)(g+0.5);
|
||||
dstcolptr[tjBlueOffset[dstpf]]=(unsigned char)(b+0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(row=0; row<h; row++, srcrowptr+=srcstride, dstrowptr+=dststride)
|
||||
{
|
||||
for(col=0, srccolptr=srcrowptr, dstcolptr=dstrowptr;
|
||||
col<w; col++, srccolptr+=srcps, dstcolptr+=dstps)
|
||||
{
|
||||
dstcolptr[tjRedOffset[dstpf]]=srccolptr[tjRedOffset[srcpf]];
|
||||
dstcolptr[tjGreenOffset[dstpf]]=srccolptr[tjGreenOffset[srcpf]];
|
||||
dstcolptr[tjBlueOffset[dstpf]]=srccolptr[tjBlueOffset[srcpf]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
21
tjbench.c
21
tjbench.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C)2009-2014 D. R. Commander. All Rights Reserved.
|
||||
* Copyright (C)2009-2015 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -50,7 +50,7 @@ int flags=TJFLAG_NOREALLOC, componly=0, decomponly=0, doyuv=0, quiet=0,
|
||||
char *ext="ppm";
|
||||
const char *pixFormatStr[TJ_NUMPF]=
|
||||
{
|
||||
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY"
|
||||
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY", "", "", "", "", "CMYK"
|
||||
};
|
||||
const char *subNameLong[TJ_NUMSAMP]=
|
||||
{
|
||||
@@ -506,6 +506,10 @@ int decompTest(char *filename)
|
||||
_throwtj("executing tjInitTransform()");
|
||||
if(tjDecompressHeader3(handle, srcbuf, srcsize, &w, &h, &subsamp, &cs)==-1)
|
||||
_throwtj("executing tjDecompressHeader3()");
|
||||
if(cs==TJCS_YCCK || cs==TJCS_CMYK)
|
||||
{
|
||||
pf=TJPF_CMYK; ps=tjPixelSize[pf];
|
||||
}
|
||||
|
||||
if(quiet==1)
|
||||
{
|
||||
@@ -712,6 +716,9 @@ void usage(char *progname)
|
||||
printf(" tiles of varying sizes.\n");
|
||||
printf("-rgb, -bgr, -rgbx, -bgrx, -xbgr, -xrgb =\n");
|
||||
printf(" Test the specified color conversion path in the codec (default = BGR)\n");
|
||||
printf("-cmyk = Indirectly test YCCK JPEG compression/decompression (the source\n");
|
||||
printf(" and destination bitmaps are still RGB. The conversion is done\n");
|
||||
printf(" internally prior to compression or after decompression.)\n");
|
||||
printf("-fastupsample = Use the fastest chrominance upsampling algorithm available in\n");
|
||||
printf(" the underlying codec\n");
|
||||
printf("-fastdct = Use the fastest DCT/IDCT algorithms available in the underlying\n");
|
||||
@@ -820,6 +827,7 @@ int main(int argc, char *argv[])
|
||||
if(!strcasecmp(argv[i], "-bgrx")) pf=TJPF_BGRX;
|
||||
if(!strcasecmp(argv[i], "-xbgr")) pf=TJPF_XBGR;
|
||||
if(!strcasecmp(argv[i], "-xrgb")) pf=TJPF_XRGB;
|
||||
if(!strcasecmp(argv[i], "-cmyk")) pf=TJPF_CMYK;
|
||||
if(!strcasecmp(argv[i], "-bottomup")) flags|=TJFLAG_BOTTOMUP;
|
||||
if(!strcasecmp(argv[i], "-quiet")) quiet=1;
|
||||
if(!strcasecmp(argv[i], "-qq")) quiet=2;
|
||||
@@ -953,9 +961,12 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i=maxqual; i>=minqual; i--)
|
||||
fullTest(srcbuf, w, h, TJSAMP_GRAY, i, argv[1]);
|
||||
printf("\n");
|
||||
if(pf!=TJPF_CMYK)
|
||||
{
|
||||
for(i=maxqual; i>=minqual; i--)
|
||||
fullTest(srcbuf, w, h, TJSAMP_GRAY, i, argv[1]);
|
||||
printf("\n");
|
||||
}
|
||||
for(i=maxqual; i>=minqual; i--)
|
||||
fullTest(srcbuf, w, h, TJSAMP_420, i, argv[1]);
|
||||
printf("\n");
|
||||
|
||||
Reference in New Issue
Block a user