]> granicus.if.org Git - libjpeg-turbo/commitdiff
Add the ability to benchmark YCCK JPEG compression/decompression. This is particular...
authorDRC <dcommander@users.sourceforge.net>
Fri, 16 Jan 2015 06:29:52 +0000 (06:29 +0000)
committerDRC <dcommander@users.sourceforge.net>
Fri, 16 Jan 2015 06:29:52 +0000 (06:29 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/branches/1.4.x@1511 632fc199-4ca6-4c93-a231-07263d6284db

ChangeLog.txt
bmp.c
tjbench.c

index 8866455136c24c14c0cc89e0aea5ad20936aff3b..05cef74e8fdcb0ea046e4cb9e053cba8965c8514 100644 (file)
@@ -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
 =====
 
diff --git a/bmp.c b/bmp.c
index 4986055c1e936800da667397b351840770286cda..9fcf7bbd5d6257801997ba85013e14efae60f50b 100644 (file)
--- a/bmp.c
+++ b/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(row=0; row<h; row++, srcrowptr+=srcstride, dstrowptr+=dststride)
+               {
+                       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(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, dstcolptr+=dstps)
+                       {
+                               dstcolptr[tjRedOffset[dstpf]]=srccolptr[tjRedOffset[srcpf]];
+                               dstcolptr[tjGreenOffset[dstpf]]=srccolptr[tjGreenOffset[srcpf]];
+                               dstcolptr[tjBlueOffset[dstpf]]=srccolptr[tjBlueOffset[srcpf]];
+                       }
                }
        }
 }
index 741dc7e790ad2b46c43b64a3807134dbcb713a8c..29ed3d0f878e7bc2ba38da46067f8056b53b1373 100644 (file)
--- a/tjbench.c
+++ b/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");