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 2016/07/21 16:09:57 UTC

svn commit: r1753707 - in /pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox: cos/COSStream.java pdmodel/graphics/image/LosslessFactory.java

Author: tilman
Date: Thu Jul 21 16:09:57 2016
New Revision: 1753707

URL: http://svn.apache.org/viewvc?rev=1753707&view=rev
Log:
PDFBOX-3433: add optimizations by Michael Doswald

Modified:
    pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/cos/COSStream.java
    pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java

Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/cos/COSStream.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/cos/COSStream.java?rev=1753707&r1=1753706&r2=1753707&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/cos/COSStream.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/cos/COSStream.java Thu Jul 21 16:09:57 2016
@@ -24,7 +24,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.pdfbox.filter.Filter;
@@ -213,6 +212,12 @@ public class COSStream extends COSDictio
         return new FilterOutputStream(cosOut)
         {
             @Override
+            public void write(byte[] b, int off, int len) throws IOException
+            {
+                this.out.write(b, off, len);
+            }
+            
+            @Override
             public void close() throws IOException
             {
                 super.close();
@@ -256,6 +261,12 @@ public class COSStream extends COSDictio
         return new FilterOutputStream(out)
         {
             @Override
+            public void write(byte[] b, int off, int len) throws IOException
+            {
+                this.out.write(b, off, len);
+            }
+            
+            @Override
             public void close() throws IOException
             {
                 super.close();

Modified: pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java?rev=1753707&r1=1753706&r2=1753707&view=diff
==============================================================================
--- pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java (original)
+++ pdfbox/branches/2.0/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java Thu Jul 21 16:09:57 2016
@@ -15,7 +15,6 @@
  */
 package org.apache.pdfbox.pdmodel.graphics.image;
 
-import java.awt.Color;
 import java.awt.Transparency;
 import java.awt.image.BufferedImage;
 import java.awt.image.WritableRaster;
@@ -58,50 +57,59 @@ public final class LosslessFactory
         int bpc;
         PDDeviceColorSpace deviceColorSpace;
 
-        ByteArrayOutputStream bos = new ByteArrayOutputStream();
         int height = image.getHeight();
         int width = image.getWidth();
+        int[] rgbLineBuffer = new int[width];
+        byte[] imageData;
 
         if ((image.getType() == BufferedImage.TYPE_BYTE_GRAY && image.getColorModel().getPixelSize() <= 8)
                 || (image.getType() == BufferedImage.TYPE_BYTE_BINARY && image.getColorModel().getPixelSize() == 1))
         {
-            MemoryCacheImageOutputStream mcios = new MemoryCacheImageOutputStream(bos);
-
             // grayscale images need one color per sample
             bpc = image.getColorModel().getPixelSize();
             deviceColorSpace = PDDeviceGray.INSTANCE;
+            
+            ByteArrayOutputStream bos = new ByteArrayOutputStream((width*bpc/8)+(width*bpc%8 != 0 ? 1:0)*height);
+            MemoryCacheImageOutputStream mcios = new MemoryCacheImageOutputStream(bos);
+            
             for (int y = 0; y < height; ++y)
             {
-                for (int x = 0; x < width; ++x)
+                for (int pixel : image.getRGB(0, y, width, 1, rgbLineBuffer, 0, width))
                 {
-                    mcios.writeBits(image.getRGB(x, y) & 0xFF, bpc);
+                    mcios.writeBits(pixel & 0xFF, bpc);
                 }
-                while (mcios.getBitOffset() != 0)
+                
+                int bitOffset = mcios.getBitOffset();
+                if (bitOffset != 0)
                 {
-                    mcios.writeBit(0);
+                    mcios.writeBits(0, 8-bitOffset);
                 }
             }
             mcios.flush();
             mcios.close();
+            
+            imageData = bos.toByteArray();
         }
         else
         {
             // RGB
             bpc = 8;
             deviceColorSpace = PDDeviceRGB.INSTANCE;
+            imageData = new byte[width*height*3];
+            int byteIdx = 0;
+            
             for (int y = 0; y < height; ++y)
             {
-                for (int x = 0; x < width; ++x)
+                for (int pixel : image.getRGB(0, y, width, 1, rgbLineBuffer, 0, width))
                 {
-                    Color color = new Color(image.getRGB(x, y));
-                    bos.write(color.getRed());
-                    bos.write(color.getGreen());
-                    bos.write(color.getBlue());
+                    imageData[byteIdx++] = (byte)((pixel >> 16) & 0xFF);
+                    imageData[byteIdx++] = (byte)((pixel >> 8) & 0xFF);
+                    imageData[byteIdx++] = (byte)(pixel & 0xFF);
                 }
             }
         }
 
-        PDImageXObject pdImage = prepareImageXObject(document, bos.toByteArray(), 
+        PDImageXObject pdImage = prepareImageXObject(document, imageData, 
                 image.getWidth(), image.getHeight(), bpc, deviceColorSpace);
 
         // alpha -> soft mask
@@ -248,7 +256,8 @@ public final class LosslessFactory
             byte [] byteArray, int width, int height, int bitsPerComponent, 
             PDColorSpace initColorSpace) throws IOException
     {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        //pre-size the output stream to half of the input
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(byteArray.length/2);
 
         Filter filter = FilterFactory.INSTANCE.getFilter(COSName.FLATE_DECODE);
         filter.encode(new ByteArrayInputStream(byteArray), baos, new COSDictionary(), 0);