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/04 20:39:23 UTC

svn commit: r1592410 - in /pdfbox/branches/1.8/pdfbox/src: main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java test/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMapTest.java

Author: tilman
Date: Sun May  4 18:39:22 2014
New Revision: 1592410

URL: http://svn.apache.org/r1592410
Log:
PDFBOX-2057: smask may must have the DeviceGray colorspace; added test

Modified:
    pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java
    pdfbox/branches/1.8/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMapTest.java

Modified: pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java?rev=1592410&r1=1592409&r2=1592410&view=diff
==============================================================================
--- pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java (original)
+++ pdfbox/branches/1.8/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java Sun May  4 18:39:22 2014
@@ -89,10 +89,35 @@ public class PDPixelMap extends PDXObjec
     public PDPixelMap(PDDocument doc, BufferedImage bi) throws IOException
     {
         super( doc, PNG);
-        createImageStream(doc, bi);
+        createImageStream(doc, bi, false);
     }
 
-    private void createImageStream(PDDocument doc, BufferedImage bi) throws IOException
+    /**
+     * Construct a pixel map image from an AWT image.
+     * 
+     * @param doc The PDF document to embed the image in.
+     * @param bi The image to read data from.
+     * @param mask true if this is a mask, false if not.
+     *
+     * @throws IOException If there is an error while embedding this image.
+     */
+    private PDPixelMap(PDDocument doc, BufferedImage bi, boolean mask) throws IOException
+    {
+        super(doc, PNG);
+        createImageStream(doc, bi, mask);
+    }
+
+    /**
+     * Create an image stream from an AWT image.
+     * 
+     * @param doc The PDF document to embed the image in.
+     * @param bi The image to read data from.
+     * @param mask true if this is a mask, false if not. If true, the image
+     * stream will be forced to be DeviceGray.
+     * 
+     * @throws IOException If there is an error while embedding this image.
+     */
+    private void createImageStream(PDDocument doc, BufferedImage bi, boolean mask) throws IOException
     {
         BufferedImage alphaImage = null;
         BufferedImage rgbImage = null;
@@ -128,11 +153,12 @@ public class PDPixelMap extends PDXObjec
             ByteArrayOutputStream bos = new ByteArrayOutputStream();
 
             //TODO: activate this when DeviceGray tests work
-//            if ((bi.getType() == BufferedImage.TYPE_BYTE_GRAY ||
+//            if (((mask || bi.getType() == BufferedImage.TYPE_BYTE_GRAY) ||
 //                    || bi.getType() == BufferedImage.TYPE_BYTE_BINARY)
 //                    && bi.getColorModel().getPixelSize() <= 8)
-            if (bi.getType() == BufferedImage.TYPE_BYTE_BINARY
-                    && bi.getColorModel().getPixelSize() <= 8)
+            if (mask || // PDFBOX-2057 force masks to be gray
+                    (bi.getType() == BufferedImage.TYPE_BYTE_BINARY
+                    && bi.getColorModel().getPixelSize() <= 8))
             {
                 setColorSpace(new PDDeviceGray());
                 MemoryCacheImageOutputStream mcios = new MemoryCacheImageOutputStream(bos);
@@ -182,7 +208,7 @@ public class PDPixelMap extends PDXObjec
             dic.setItem( COSName.TYPE, COSName.XOBJECT );
             if(alphaImage != null)
             {
-                PDPixelMap smask = new PDPixelMap(doc, alphaImage);
+                PDPixelMap smask = new PDPixelMap(doc, alphaImage, true);
                 dic.setItem(COSName.SMASK, smask);
             }
             setBitsPerComponent( bpc );
@@ -197,6 +223,7 @@ public class PDPixelMap extends PDXObjec
             }
         }
     }
+    
     /**
      * Returns a {@link java.awt.image.BufferedImage} of the COSStream
      * set in the constructor or null if the COSStream could not be encoded.

Modified: pdfbox/branches/1.8/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMapTest.java
URL: http://svn.apache.org/viewvc/pdfbox/branches/1.8/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMapTest.java?rev=1592410&r1=1592409&r2=1592410&view=diff
==============================================================================
--- pdfbox/branches/1.8/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMapTest.java (original)
+++ pdfbox/branches/1.8/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMapTest.java Sun May  4 18:39:22 2014
@@ -16,12 +16,19 @@
 
 package org.apache.pdfbox.pdmodel.graphics.xobject;
 
+import java.awt.Color;
 import java.awt.Graphics;
 import java.awt.image.BufferedImage;
+import java.io.File;
 import java.io.IOException;
 import javax.imageio.ImageIO;
 import junit.framework.TestCase;
+import org.apache.pdfbox.exceptions.COSVisitorException;
 import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.pdmodel.PDPage;
+import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
+import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceGray;
+import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
 import org.apache.pdfbox.util.ImageIOUtil;
 
 /**
@@ -30,6 +37,15 @@ import org.apache.pdfbox.util.ImageIOUti
  */
 public class PDPixelMapTest extends TestCase
 {
+    private final File testResultsDir = new File("target/test-output");
+
+    @Override
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        testResultsDir.mkdirs();
+    }
+
     /**
      * Tests RGB PDPixelMapTest() with color, gray and bitonal image
      *
@@ -41,7 +57,7 @@ public class PDPixelMapTest extends Test
         BufferedImage image = ImageIO.read(this.getClass().getResourceAsStream("png.png"));
 
         PDXObjectImage ximage = new PDPixelMap(document, image);
-        validate(ximage, 8, 344, 287, "png");
+        validate(ximage, 8, 344, 287, "png", PDDeviceRGB.NAME);
         checkIdent(image, ximage.getRGBImage());
 
         // Create a grayscale image
@@ -49,9 +65,9 @@ public class PDPixelMapTest extends Test
         Graphics g = grayImage.getGraphics();
         g.drawImage(image, 0, 0, null);
         g.dispose();
-        
+
         ximage = new PDPixelMap(document, grayImage);
-        validate(ximage, 8, 344, 287, "png");
+        validate(ximage, 8, 344, 287, "png", PDDeviceRGB.NAME);
         checkIdent(grayImage, ximage.getRGBImage());
 
         // Create a bitonal image
@@ -59,10 +75,10 @@ public class PDPixelMapTest extends Test
         g = bitonalImage.getGraphics();
         g.drawImage(image, 0, 0, null);
         g.dispose();
-        
+
         ximage = new PDPixelMap(document, bitonalImage);
         checkIdent(bitonalImage, ximage.getRGBImage());
-        validate(ximage, 1, 344, 287, "png"); 
+        validate(ximage, 1, 344, 287, "png", PDDeviceGray.NAME);
         document.close();
     }
 
@@ -78,10 +94,54 @@ public class PDPixelMapTest extends Test
 
         PDXObjectImage ximage = new PDPixelMap(document, imageFromBitonalGif);
         checkIdent(imageFromBitonalGif, ximage.getRGBImage());
-        validate(ximage, 1, 344, 287, "png");
+        validate(ximage, 1, 344, 287, "png", PDDeviceGray.NAME);
+        document.close();
+    }
+
+    /**
+     * Tests RGB PDPixelMapTest() with TYPE_4BYTE_ABGR image.
+     *
+     * @throws java.io.IOException
+     */
+    public void testCreateLossless4BYTE_ABGR() throws IOException, COSVisitorException
+    {
+        PDDocument document = new PDDocument();
+        BufferedImage awtImage = new BufferedImage(300, 300, BufferedImage.TYPE_4BYTE_ABGR);
+
+        // draw something
+        Graphics g = awtImage.getGraphics();
+        g.setColor(Color.blue);
+        g.fillRect(0, 0, 100, 300);
+        g.setColor(Color.white);
+        g.fillRect(100, 0, 100, 300);
+        g.setColor(Color.red);
+        g.fillRect(200, 0, 100, 300);
+        g.setColor(Color.black);
+        g.drawRect(0, 0, 299, 299);
+        g.dispose();
+
+        PDPixelMap ximage = new PDPixelMap(document, awtImage);
+        validate(ximage, 8, 300, 300, "png", PDDeviceRGB.NAME);
+        validate(ximage.getSMaskImage(), 8, 300, 300, "png", PDDeviceGray.NAME);
+        assertEquals(ximage.getColorSpace().getName(), PDDeviceRGB.NAME);
+        assertEquals(ximage.getSMaskImage().getColorSpace().getName(), PDDeviceGray.NAME);
+        checkIdent(awtImage, ximage.getRGBImage());
+
+        // This part isn't really needed because this test doesn't break
+        // if the mask has the wrong colorspace (PDFBOX-2057), but it is still useful
+        // if something goes wrong in the future and we want to have a PDF to open.
+        PDPage page = new PDPage();
+        document.addPage(page);
+        PDPageContentStream contentStream = new PDPageContentStream(document, page);
+        contentStream.drawXObject(ximage, 150, 300, ximage.getWidth(), ximage.getHeight());
+        contentStream.close();
+        File pdfFile = new File(testResultsDir, "4babgr.pdf");
+        document.save(pdfFile);
+        document.close();
+        document = PDDocument.loadNonSeq(pdfFile, null);
         document.close();
     }
-        
+
     /**
      * Tests RGB PDPixelMapTest() with image from a color GIF
      *
@@ -93,11 +153,11 @@ public class PDPixelMapTest extends Test
         BufferedImage imageFromColorGif = ImageIO.read(this.getClass().getResourceAsStream("color.gif"));
         PDXObjectImage ximage = new PDPixelMap(document, imageFromColorGif);
         checkIdent(imageFromColorGif, ximage.getRGBImage());
-        validate(ximage, 8, 344, 287, "png");
+        validate(ximage, 8, 344, 287, "png", PDDeviceRGB.NAME);
         document.close();
     }
 
-    static public void validate(PDXObjectImage ximage, int bpc, int width, int height, String format) throws IOException
+    static public void validate(PDXObjectImage ximage, int bpc, int width, int height, String format, String colorSpaceName) throws IOException
     {
         // check the dictionary
         assertNotNull(ximage);
@@ -107,6 +167,7 @@ public class PDPixelMapTest extends Test
         assertEquals(width, ximage.getWidth());
         assertEquals(height, ximage.getHeight());
         assertEquals(format, ximage.getSuffix());
+        assertEquals(colorSpaceName, ximage.getColorSpace().getName());
 
         // check the image
         assertNotNull(ximage.getRGBImage());