You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2016/12/04 12:28:03 UTC

svn commit: r1772528 - /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java

Author: lehmi
Date: Sun Dec  4 12:28:03 2016
New Revision: 1772528

URL: http://svn.apache.org/viewvc?rev=1772528&view=rev
Log:
PDFBOX-3569: added a pure java CMYK2RGB conversion due to a performance regression when using ColorConvertOp.filter

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java?rev=1772528&r1=1772527&r2=1772528&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceCMYK.java Sun Dec  4 12:28:03 2016
@@ -17,8 +17,11 @@
 package org.apache.pdfbox.pdmodel.graphics.color;
 
 import java.net.URL;
+import java.util.Arrays;
+
 import org.apache.pdfbox.cos.COSName;
 
+import java.awt.color.ColorSpace;
 import java.awt.color.ICC_ColorSpace;
 import java.awt.color.ICC_Profile;
 import java.awt.image.BufferedImage;
@@ -45,6 +48,7 @@ public class PDDeviceCMYK extends PDDevi
 
     private final PDColor initialColor = new PDColor(new float[] { 0, 0, 0, 1 }, this);
     private volatile ICC_ColorSpace awtColorSpace;
+    private boolean usePureJavaCMYKConversion = false;
 
     protected PDDeviceCMYK()
     {
@@ -79,6 +83,8 @@ public class PDDeviceCMYK extends PDDevi
             // condition caused by lazy initialization of the color transform, so we perform
             // an initial color conversion while we're still in a static context, see PDFBOX-2184
             awtColorSpace.toRGB(new float[] { 0, 0, 0, 0 });
+            usePureJavaCMYKConversion = System
+                    .getProperty("org.apache.pdfbox.rendering.UsePureJavaCMYKConversion") != null;
         }
     }
 
@@ -141,4 +147,51 @@ public class PDDeviceCMYK extends PDDevi
         init();
         return toRGBImageAWT(raster, awtColorSpace);
     }
+
+    @Override
+    protected BufferedImage toRGBImageAWT(WritableRaster raster, ColorSpace colorSpace)
+    {
+        if (usePureJavaCMYKConversion)
+        {
+            BufferedImage dest = new BufferedImage(raster.getWidth(), raster.getHeight(),
+                    BufferedImage.TYPE_INT_RGB);
+            ColorSpace destCS = dest.getColorModel().getColorSpace();
+            WritableRaster destRaster = dest.getRaster();
+            float[] srcValues = new float[4];
+            float[] lastValues = new float[] { -1.0f, -1.0f, -1.0f, -1.0f };
+            float[] destValues = new float[3];
+            int width = raster.getWidth();
+            int startX = raster.getMinX();
+            int height = raster.getHeight();
+            int startY = raster.getMinY();
+            for (int x = startX; x < width + startX; x++)
+            {
+                for (int y = startY; y < height + startY; y++)
+                {
+                    raster.getPixel(x, y, srcValues);
+                    // check if the last value can be reused
+                    if (!Arrays.equals(lastValues, srcValues))
+                    {
+                        for (int k = 0; k < 4; k++)
+                        {
+                            lastValues[k] = srcValues[k];
+                            srcValues[k] = srcValues[k] / 255f;
+                        }
+                        // use CIEXYZ as intermediate format to optimize the color conversion
+                        destValues = destCS.fromCIEXYZ(colorSpace.toCIEXYZ(srcValues));
+                        for (int k = 0; k < destValues.length; k++)
+                        {
+                            destValues[k] = destValues[k] * 255f;
+                        }
+                    }
+                    destRaster.setPixel(x, y, destValues);
+                }
+            }
+            return dest;
+        }
+        else
+        {
+            return super.toRGBImageAWT(raster, colorSpace);
+        }
+    }
 }