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