You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ti...@apache.org on 2018/03/24 12:59:57 UTC

svn commit: r1827647 - /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/SampledImageReader.java

Author: tilman
Date: Sat Mar 24 12:59:57 2018
New Revision: 1827647

URL: http://svn.apache.org/viewvc?rev=1827647&view=rev
Log:
PDFBOX-4156: optimize reading of 8 bit images by using InterleavedRaster instead of BandedRaster, by Itai Shaked

Modified:
    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/image/SampledImageReader.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/SampledImageReader.java?rev=1827647&r1=1827646&r2=1827647&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 Sat Mar 24 12:59:57 2018
@@ -192,8 +192,8 @@ final class SampledImageReader
         // will be unpacked into a byte-backed raster. Images with 16bpc will be reduced
         // in depth to 8bpc as they will be drawn to TYPE_INT_RGB images anyway. All code
         // in PDColorSpace#toRGBImage expects an 8-bit range, i.e. 0-255.
-        //
-        WritableRaster raster = Raster.createBandedRaster(DataBuffer.TYPE_BYTE, width, height,
+        // Interleaved raster allows chunk-copying for 8-bit images.
+        WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, width, height,
                 numComponents, new Point(0, 0));
         final float[] defaultDecode = pdImage.getColorSpace().getDefaultDecode(8);
         if (bitsPerComponent == 8 && Arrays.equals(decode, defaultDecode) && colorKey == null)
@@ -356,7 +356,20 @@ final class SampledImageReader
             }
             final int numComponents = pdImage.getColorSpace().getNumberOfComponents();
             // get the raster's underlying byte buffer
-            byte[][] banks = ((DataBufferByte) raster.getDataBuffer()).getBankData();
+            byte[] bank = ((DataBufferByte) raster.getDataBuffer()).getData();
+            if (startx == 0 && starty == 0 && scanWidth == width && scanHeight == height && subsampling == 1)
+            {
+                // we just need to copy all sample data, then convert to RGB image.
+                long inputResult = input.read(bank);
+                if (Long.compare(inputResult, width * height * numComponents) != 0)
+                {
+                    LOG.debug("Tried reading " + width * height * numComponents + " bytes but only " + inputResult + " bytes read");
+                }
+                return pdImage.getColorSpace().toRGBImage(raster);
+            }
+
+            // either subsampling is required, or reading only part of the image, so its
+            // not possible to blindly copy all data.
             byte[] tempBytes = new byte[numComponents * inputWidth];
             // compromise between memory and time usage:
             // reading the whole image consumes too much memory
@@ -376,13 +389,22 @@ final class SampledImageReader
                     continue;
                 }
 
-                for (int x = startx; x < startx + scanWidth; x += subsampling)
+                if (subsampling == 1)
                 {
-                    for (int c = 0; c < numComponents; c++)
+                    // Not the entire region was requested, but if no subsampling should
+                    // be performed, we can still copy the entire part of this row
+                    System.arraycopy(tempBytes, startx * numComponents, bank, y * inputWidth * numComponents, scanWidth * numComponents);
+                }
+                else
+                {
+                    for (int x = startx; x < startx + scanWidth; x += subsampling)
                     {
-                        banks[c][i] = tempBytes[x * numComponents + c];
+                        for (int c = 0; c < numComponents; c++)
+                        {
+                            bank[i] = tempBytes[x * numComponents + c];
+                            ++i;
+                        }
                     }
-                    ++i;
                 }
             }
             // use the color space to convert the image to RGB