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 2014/05/19 21:44:08 UTC

svn commit: r1596007 - in /pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox: cos/ filter/ pdmodel/graphics/xobject/ util/ util/operator/pagedrawer/

Author: tilman
Date: Mon May 19 19:44:07 2014
New Revision: 1596007

URL: http://svn.apache.org/r1596007
Log:
PDFBOX-2084: separate ImageIOUtils from TestAll

Modified:
    pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java
    pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/filter/CCITTFaxDecodeFilter.java
    pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDCcitt.java
    pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDInlinedImage.java
    pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/util/ImageParameters.java
    pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/BeginInlineImage.java

Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java?rev=1596007&r1=1596006&r2=1596007&view=diff
==============================================================================
--- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java (original)
+++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/cos/COSName.java Mon May 19 19:44:07 2014
@@ -775,6 +775,10 @@ public final class COSName extends COSBa
     */
     public static final COSName IDENTITY_H = new COSName( "Identity-H" );
     /**
+     * A common COSName value.
+     */
+    public static final COSName IM = new COSName( "IM" );
+    /**
     * A common COSName value.
     */
     public static final COSName IMAGE = new COSName( "Image" );

Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/filter/CCITTFaxDecodeFilter.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/filter/CCITTFaxDecodeFilter.java?rev=1596007&r1=1596006&r2=1596007&view=diff
==============================================================================
--- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/filter/CCITTFaxDecodeFilter.java (original)
+++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/filter/CCITTFaxDecodeFilter.java Mon May 19 19:44:07 2014
@@ -16,6 +16,7 @@
  */
 package org.apache.pdfbox.filter;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -69,7 +70,6 @@ public class CCITTFaxDecodeFilter implem
         {
             decodeParms =  (COSDictionary)((COSArray)decodeP).getObject(filterIndex);
         }
-        byte[] compressed = IOUtils.toByteArray(compressedData);
         int cols = decodeParms.getInt(COSName.COLUMNS, 1728);
         int rows = decodeParms.getInt(COSName.ROWS, 0);
         int height = options.getInt(COSName.HEIGHT, COSName.H, 0);
@@ -89,26 +89,45 @@ public class CCITTFaxDecodeFilter implem
         TIFFFaxDecoder faxDecoder = new TIFFFaxDecoder(1, cols, rows);
         // TODO possible options??
         long tiffOptions = 0;
+        byte[] compressed = IOUtils.toByteArray(compressedData);
+        byte[] decompressed = null;
         if (k == 0)
         {
             InputStream in = new CCITTFaxG31DDecodeInputStream(
-                    new java.io.ByteArrayInputStream(compressed), cols, encodedByteAlign);
+                    new ByteArrayInputStream(compressed), cols, encodedByteAlign);
             in = new FillOrderChangeInputStream(in); //Decorate to change fill order
-            IOUtils.copy(in, result);
+            decompressed = IOUtils.toByteArray(in);
             in.close();
         }
         else if (k > 0)
         {
-            byte[] decompressed = new byte[arraySize];
+            decompressed = new byte[arraySize];
             faxDecoder.decode2D(decompressed, compressed, 0, rows, tiffOptions);
-            result.write(decompressed);
         }
         else if (k < 0)
         {
-            byte[] decompressed = new byte[arraySize];
+            decompressed = new byte[arraySize];
             faxDecoder.decodeT6(decompressed, compressed, 0, rows, tiffOptions, encodedByteAlign);
-            result.write(decompressed);
         }
+
+        // invert bitmap
+        boolean blackIsOne = decodeParms.getBoolean(COSName.BLACK_IS_1, false);
+        if (!blackIsOne)
+        {
+            // Inverting the bitmap
+            // Note the previous approach with starting from an IndexColorModel didn't work
+            // reliably. In some cases the image wouldn't be painted for some reason.
+            // So a safe but slower approach was taken.
+            invertBitmap(decompressed);
+        }
+        
+        // repair missing color space
+        if (!options.containsKey(COSName.COLORSPACE))
+        {
+            options.setName(COSName.COLORSPACE, COSName.DEVICEGRAY.getName());
+        }        
+        
+        result.write(decompressed);        
     }
 
     /**
@@ -119,4 +138,13 @@ public class CCITTFaxDecodeFilter implem
     {
         log.warn("CCITTFaxDecode.encode is not implemented yet, skipping this stream.");
     }
+
+    private void invertBitmap(byte[] bufferData)
+    {
+        for (int i = 0, c = bufferData.length; i < c; i++)
+        {
+            bufferData[i] = (byte) (~bufferData[i] & 0xFF);
+        }
+    }
+
 }

Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDCcitt.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDCcitt.java?rev=1596007&r1=1596006&r2=1596007&view=diff
==============================================================================
--- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDCcitt.java (original)
+++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDCcitt.java Mon May 19 19:44:07 2014
@@ -148,14 +148,6 @@ public class PDCcitt extends PDXObjectIm
             // at least one of the values has to have a valid value
             rows = Math.max(rows, height);
         }
-        boolean blackIsOne = decodeParms.getBoolean(COSName.BLACK_IS_1, false);
-        // maybe a decode array is defined
-        COSArray decode = getDecode();
-        if (decode != null && decode.getInt(0) == 1)
-        {
-            // [1.0, 0.0] -> invert the "color" values
-            blackIsOne = !blackIsOne;
-        }
         byte[] bufferData = null;
         ColorModel colorModel = null;
         PDColorSpace colorspace = getColorSpace();
@@ -186,12 +178,10 @@ public class PDCcitt extends PDXObjectIm
         IOUtils.populateBuffer(is, bufferData);
         IOUtils.closeQuietly(is);
         BufferedImage image = new BufferedImage(colorModel, raster, false, null);
-        if (!blackIsOne)
+        // maybe a decode array is defined
+        COSArray decode = getDecode();
+        if (decode != null && decode.getInt(0) == 1)
         {
-            // Inverting the bitmap
-            // Note the previous approach with starting from an IndexColorModel didn't work
-            // reliably. In some cases the image wouldn't be painted for some reason.
-            // So a safe but slower approach was taken.
             invertBitmap(bufferData);
         }
         /*

Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDInlinedImage.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDInlinedImage.java?rev=1596007&r1=1596006&r2=1596007&view=diff
==============================================================================
--- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDInlinedImage.java (original)
+++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDInlinedImage.java Mon May 19 19:44:07 2014
@@ -28,8 +28,11 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
-import org.apache.pdfbox.filter.CCITTFaxDecodeFilter;
-
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.filter.Filter;
 import org.apache.pdfbox.filter.FilterManager;
 import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
@@ -43,6 +46,11 @@ import org.apache.pdfbox.util.ImageParam
  */
 public class PDInlinedImage
 {
+    /**
+     * Log instance.
+     */
+    private static final Log LOG = LogFactory.getLog(PDInlinedImage.class);
+
     private ImageParameters params;
     private byte[] imageData;
 
@@ -136,7 +144,7 @@ public class PDInlinedImage
 
         //verify again pci32.pdf before changing below
         PDColorSpace pcs = params.getColorSpace( colorSpaces );
-        ColorModel colorModel = null;
+        ColorModel colorModel;
         if(pcs != null)
         {
             colorModel =
@@ -151,9 +159,30 @@ public class PDInlinedImage
             colorModel = new IndexColorModel( 1, 2,
                     colors, colors, colors, transparentColors );
         }
-        boolean isCCITTFax = false;
+        
+        boolean invert = false;
+        // maybe a decode array is defined
+        COSBase dictObj = params.getDictionary().getDictionaryObject(COSName.DECODE, COSName.D);
+        if (dictObj != null && dictObj instanceof COSArray)
+        {
+            COSArray decode = (COSArray) dictObj;
+            if (decode.getInt(0) == 1)
+            {
+                if (params.getBitsPerComponent() == 1)
+                {
+                    // [1.0, 0.0] -> invert the "color" values
+                    invert = true;
+                }
+                else
+                {
+                    //TODO implement decode array for BPC > 1
+                    LOG.warn("decode array is not implemented for BPC > 1");
+                }
+            }
+        }
+        
         List filters = params.getFilters();
-        byte[] finalData = null;
+        byte[] finalData;
         if( filters == null )
         {
             finalData = getImageData();
@@ -169,10 +198,6 @@ public class PDInlinedImage
                 Filter filter = filterManager.getFilter( (String)filters.get( i ) );
                 filter.decode( in, out, params.getDictionary(), i );
                 in = new ByteArrayInputStream( out.toByteArray() );
-                if (filter instanceof CCITTFaxDecodeFilter)
-                {
-                    isCCITTFax = true;
-                }
             }
             finalData = out.toByteArray();
         }
@@ -191,9 +216,8 @@ public class PDInlinedImage
             DataBufferByte byteBuffer = (DataBufferByte)rasterBuffer;
             byte[] data = byteBuffer.getData();
             System.arraycopy( finalData, 0, data, 0, data.length );
-            if (isCCITTFax)
+            if (invert)
             {
-                // PDFBOX-2080: do the inversion that is done in PDCcitt
                 invertBitmap(data);
             }
         }
@@ -203,11 +227,14 @@ public class PDInlinedImage
             int[] data = byteBuffer.getData();
             for( int i=0; i<finalData.length; i++ )
             {
-                data[i] = (finalData[i]+256)%256;
+                data[i] = (finalData[i] + 256) % 256;
+                if (invert)
+                {
+                    data[i] = (~data[i] & 0xFF);
+                }
             }
         }
-        BufferedImage image = new BufferedImage(
-                colorModel, raster, false, null );
+        BufferedImage image = new BufferedImage(colorModel, raster, false, null);
         image.setData( raster );
         return image;
     }

Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/util/ImageParameters.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/util/ImageParameters.java?rev=1596007&r1=1596006&r2=1596007&view=diff
==============================================================================
--- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/util/ImageParameters.java (original)
+++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/util/ImageParameters.java Mon May 19 19:44:07 2014
@@ -232,4 +232,25 @@ public class ImageParameters
         COSBase obj = COSArrayList.convertStringListToCOSNameCOSArray( filters );
         dictionary.setItem( "Filter", obj );
     }
+    
+    /**
+     * Returns true if the image is a stencil mask.
+     *
+     * @return true if the image is a stencil mask.
+     */
+    public boolean isStencil()
+    {
+        return dictionary.getBoolean(COSName.IM, COSName.IMAGE_MASK, false);
+    }
+    
+    /**
+     * Sets whether or not the image is a stencil.
+     * This corresponds to the {@code ImageMask} entry in the image stream's dictionary.
+     * @param isStencil True to make the image a stencil.
+     */
+    public void setStencil(boolean isStencil)
+    {
+        dictionary.setBoolean(COSName.IM, isStencil);
+    }    
+    
 }
\ No newline at end of file

Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/BeginInlineImage.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/BeginInlineImage.java?rev=1596007&r1=1596006&r2=1596007&view=diff
==============================================================================
--- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/BeginInlineImage.java (original)
+++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/BeginInlineImage.java Mon May 19 19:44:07 2014
@@ -44,7 +44,7 @@ public class BeginInlineImage extends Op
     /**
      * Log instance.
      */
-    private static final Log log = LogFactory.getLog(BeginInlineImage.class);
+    private static final Log LOG = LogFactory.getLog(BeginInlineImage.class);
 
     /**
      * process : BI : begin inline image.
@@ -61,11 +61,16 @@ public class BeginInlineImage extends Op
         PDInlinedImage image = new PDInlinedImage();
         image.setImageParameters( params );
         image.setImageData( operator.getImageData() );
+        if (params.isStencil())
+        {
+            //TODO implement inline image stencil masks 
+            LOG.warn("Stencil masks are not implemented, background may be incorrect");
+        }
         BufferedImage awtImage = image.createImage( context.getColorSpaces() );
 
         if (awtImage == null) 
         {
-            log.warn("BeginInlineImage.process(): createImage returned NULL");
+            LOG.warn("BeginInlineImage.process(): createImage returned NULL");
             return;
         }
         int imageWidth = awtImage.getWidth();