You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ja...@apache.org on 2014/04/04 23:17:06 UTC

svn commit: r1584914 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics: color/PDColorSpace.java color/PDDeviceRGB.java image/SampledImageReader.java

Author: jahewson
Date: Fri Apr  4 21:17:06 2014
New Revision: 1584914

URL: http://svn.apache.org/r1584914
Log:
PDFBOX-2007: Speed up SampledImageReader for common 8-bit images

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDColorSpace.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceRGB.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/SampledImageReader.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDColorSpace.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDColorSpace.java?rev=1584914&r1=1584913&r2=1584914&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDColorSpace.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDColorSpace.java Fri Apr  4 21:17:06 2014
@@ -216,7 +216,7 @@ public abstract class PDColorSpace imple
 
         // ICC Profile color transforms are only fast when performed using ColorConvertOp
         ColorModel colorModel = new ComponentColorModel(colorSpace,
-            false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+            false, false, Transparency.OPAQUE, raster.getDataBuffer().getDataType());
 
         BufferedImage src = new BufferedImage(colorModel, raster, false, null);
         BufferedImage dest = new BufferedImage(raster.getWidth(), raster.getHeight(),

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceRGB.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceRGB.java?rev=1584914&r1=1584913&r2=1584914&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceRGB.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/color/PDDeviceRGB.java Fri Apr  4 21:17:06 2014
@@ -86,7 +86,7 @@ public final class PDDeviceRGB extends P
     public BufferedImage toRGBImage(WritableRaster raster) throws IOException
     {
         ColorModel colorModel = new ComponentColorModel(COLOR_SPACE_RGB,
-                false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
+                false, false, Transparency.OPAQUE, raster.getDataBuffer().getDataType());
 
         return new BufferedImage(colorModel, raster, false, null);
     }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/SampledImageReader.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/SampledImageReader.java?rev=1584914&r1=1584913&r2=1584914&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/SampledImageReader.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/SampledImageReader.java Fri Apr  4 21:17:06 2014
@@ -19,15 +19,24 @@ package org.apache.pdfbox.pdmodel.graphi
 import java.awt.Graphics2D;
 import java.awt.Paint;
 import java.awt.Point;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
 import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
 import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.PackedColorModel;
 import java.awt.image.Raster;
 import java.awt.image.WritableRaster;
 import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.io.IOUtils;
 import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
 import org.apache.pdfbox.pdmodel.graphics.color.PDIndexed;
 
@@ -42,6 +51,7 @@ import org.apache.pdfbox.pdmodel.common.
 final class SampledImageReader
 {
     private static final Log LOG = LogFactory.getLog(SampledImageReader.class);
+    private static final ColorSpace COLOR_SPACE_RGB = ColorSpace.getInstance(ColorSpace.CS_sRGB);
 
     /**
      * Returns an ARGB image filled with the given paint and using the given image as a mask.
@@ -138,6 +148,64 @@ final class SampledImageReader
         WritableRaster raster = Raster.createBandedRaster(DataBuffer.TYPE_BYTE, width, height,
                 numComponents, new Point(0, 0));
 
+        // convert image, faster path for non-decoded, non-colormasked 8-bit images
+        final float[] defaultDecode = pdImage.getColorSpace().getDefaultDecode(8);
+        if (bitsPerComponent == 8 && Arrays.equals(decode, defaultDecode) && colorKey == null)
+        {
+            return from8bit(pdImage, raster);
+        }
+        else
+        {
+            return fromAny(pdImage, raster, colorKey);
+        }
+    }
+
+    // faster, 8-bit non-decoded, non-colormasked image conversion
+    private static BufferedImage from8bit(PDImage pdImage, WritableRaster raster)
+            throws IOException
+    {
+        InputStream input = pdImage.getStream().createInputStream();
+        try
+        {
+            // get the raster's underlying byte buffer
+            byte[][] banks = ((DataBufferByte) raster.getDataBuffer()).getBankData();
+            byte[] source = IOUtils.toByteArray(input);
+
+            final int width = pdImage.getWidth();
+            final int height = pdImage.getHeight();
+            final int numComponents = pdImage.getColorSpace().getNumberOfComponents();
+
+            for (int c = 0; c < numComponents; c++)
+            {
+                int sourceOffset = c;
+                int max = width * height;
+                for (int i = 0; i < max; i++)
+                {
+                    banks[c][i] = source[sourceOffset];
+                    sourceOffset += numComponents;
+                }
+            }
+
+            // use the color space to convert the image to RGB
+            return pdImage.getColorSpace().toRGBImage(raster);
+        }
+        finally
+        {
+            IOUtils.closeQuietly(input);
+        }
+    }
+
+    // slower, general-purpose image conversion from any image format
+    private static BufferedImage fromAny(PDImage pdImage, WritableRaster raster, COSArray colorKey)
+            throws IOException
+    {
+        final PDColorSpace colorSpace = pdImage.getColorSpace();
+        final int numComponents = colorSpace.getNumberOfComponents();
+        final int width = pdImage.getWidth();
+        final int height = pdImage.getHeight();
+        final int bitsPerComponent = pdImage.getBitsPerComponent();
+        final float[] decode = getDecodeArray(pdImage);
+
         // read bit stream
         ImageInputStream iis = null;
         try