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/09 18:16:59 UTC

svn commit: r1593569 - in /pdfbox/trunk/pdfbox/src: main/java/org/apache/pdfbox/pdmodel/graphics/image/ test/java/org/apache/pdfbox/pdmodel/graphics/image/

Author: tilman
Date: Fri May  9 16:16:59 2014
New Revision: 1593569

URL: http://svn.apache.org/r1593569
Log:
PDFBOX-2057: fixed bug with lossless images with BITMASK Transparency, thanks David Keller
PDFBOX-2068: extra filter parameter for PDImageXObject(document, filteredStream) constructor

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/CCITTFactory.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/JPEGFactory.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PDImageXObject.java
    pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/CCITTFactoryTest.java
    pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactoryTest.java
    pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/ValidateXImage.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/CCITTFactory.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/CCITTFactory.java?rev=1593569&r1=1593568&r2=1593569&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/CCITTFactory.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/CCITTFactory.java Fri May  9 16:16:59 2014
@@ -25,7 +25,6 @@ import org.apache.pdfbox.cos.COSDictiona
 import org.apache.pdfbox.cos.COSName;
 import org.apache.pdfbox.io.RandomAccess;
 import org.apache.pdfbox.pdmodel.PDDocument;
-import org.apache.pdfbox.pdmodel.common.PDStream;
 import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceGray;
 
 /**
@@ -54,13 +53,10 @@ public final class CCITTFactory
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         extractFromTiff(reader, bos, decodeParms);
         ByteArrayInputStream byteStream = new ByteArrayInputStream(bos.toByteArray());
-        PDImageXObject pdImage = new PDImageXObject(document, byteStream);
+        PDImageXObject pdImage = new PDImageXObject(document, byteStream, COSName.CCITTFAX_DECODE);
 
         COSDictionary dict = pdImage.getCOSStream();
 
-        dict.setItem(COSName.FILTER, COSName.CCITTFAX_DECODE);
-        dict.setItem(COSName.SUBTYPE, COSName.IMAGE);
-        dict.setItem(COSName.TYPE, COSName.XOBJECT);
         dict.setItem(COSName.DECODE_PARMS, decodeParms);
 
         pdImage.setBitsPerComponent(1);

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/JPEGFactory.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/JPEGFactory.java?rev=1593569&r1=1593568&r2=1593569&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/JPEGFactory.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/JPEGFactory.java Fri May  9 16:16:59 2014
@@ -64,10 +64,7 @@ public final class JPEGFactory extends I
         byteStream.reset();
 
         // create Image XObject from stream
-        PDImageXObject pdImage = new PDImageXObject(document, byteStream);
-
-        // add DCT filter
-        pdImage.getCOSStream().setItem(COSName.FILTER, COSName.DCT_DECODE);
+        PDImageXObject pdImage = new PDImageXObject(document, byteStream, COSName.DCT_DECODE);
 
         // no alpha
         if (awtImage.getColorModel().hasAlpha())
@@ -175,17 +172,13 @@ public final class JPEGFactory extends I
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ImageIOUtil.writeImage(awtColorImage, "jpeg", baos, dpi, quality);
         ByteArrayInputStream byteStream = new ByteArrayInputStream(baos.toByteArray());
-        PDImageXObject pdImage = new PDImageXObject(document, byteStream);
-        
-        // add DCT filter
-        COSStream dict = pdImage.getCOSStream();
-        dict.setItem(COSName.FILTER, COSName.DCT_DECODE);
+        PDImageXObject pdImage = new PDImageXObject(document, byteStream, COSName.DCT_DECODE);
 
         // alpha -> soft mask
         if (awtAlphaImage != null)
         {
             PDImage xAlpha = JPEGFactory.createFromImage(document, awtAlphaImage, quality);
-            dict.setItem(COSName.SMASK, xAlpha);
+            pdImage.getCOSStream().setItem(COSName.SMASK, xAlpha);
         }
         
         // set properties (width, height, depth, color space, etc.)

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java?rev=1593569&r1=1593568&r2=1593569&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactory.java Fri May  9 16:16:59 2014
@@ -16,6 +16,7 @@
 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;
 import java.io.ByteArrayInputStream;
@@ -103,10 +104,7 @@ public class LosslessFactory
         filter.encode(bais, bos2, new COSDictionary(), 0);
 
         ByteArrayInputStream filteredByteStream = new ByteArrayInputStream(bos2.toByteArray());
-        PDImageXObject pdImage = new PDImageXObject(document, filteredByteStream);
-
-        COSDictionary dict = pdImage.getCOSStream();
-        dict.setItem(COSName.FILTER, COSName.FLATE_DECODE);
+        PDImageXObject pdImage = new PDImageXObject(document, filteredByteStream, COSName.FLATE_DECODE);
 
         pdImage.setColorSpace(deviceColorSpace);
         pdImage.setBitsPerComponent(bpc);
@@ -117,14 +115,14 @@ public class LosslessFactory
         PDImage xAlpha = createAlphaFromARGBImage(document, image);
         if (xAlpha != null)
         {
-            dict.setItem(COSName.SMASK, xAlpha);
+            pdImage.getCOSStream().setItem(COSName.SMASK, xAlpha);
         }
 
         return pdImage;
     }
 
     /**
-     * Creates a grayscale PDImageXObject from the alpha channel of an image.
+     * Creates a grayscale Flate encoded PDImageXObject from the alpha channel of an image.
      *
      * @param document the document where the image will be created.
      * @param image an ARGB image.
@@ -140,9 +138,6 @@ public class LosslessFactory
         // SinglePixelPackedSampleModel, i.e. the values can be used 1:1 for
         // the stream. 
         // Sadly the type of the databuffer is TYPE_INT and not TYPE_BYTE.
-        //TODO: optimize this to lessen the memory footprint.
-        // possible idea? Derive an inputStream that reads from the raster.
-
         if (!image.getColorModel().hasAlpha())
         {
             return null;
@@ -156,9 +151,29 @@ public class LosslessFactory
                 alphaRaster.getSampleModel().getHeight(),
                 (int[]) null);
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        for (int pixel : pixels)
+        int bpc;
+        if (image.getTransparency() == Transparency.BITMASK)
+        {
+            bpc = 1;
+            MemoryCacheImageOutputStream mcios = new MemoryCacheImageOutputStream(bos);
+            for (int pixel : pixels)
+            {
+                mcios.writeBit(pixel);
+            }
+            while (mcios.getBitOffset() != 0)
+            {
+                mcios.writeBit(0);
+            }
+            mcios.flush();
+            mcios.close();            
+        }
+        else
         {
-            bos.write(pixel);
+            bpc = 8;
+            for (int pixel : pixels)
+            {
+                bos.write(pixel);
+            }
         }
         ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());
 
@@ -167,17 +182,16 @@ public class LosslessFactory
         filter.encode(bais, bos2, new COSDictionary(), 0);
 
         ByteArrayInputStream filteredByteStream = new ByteArrayInputStream(bos2.toByteArray());
-        PDImageXObject pdImage = new PDImageXObject(document, filteredByteStream);
-
-        COSDictionary dict = pdImage.getCOSStream();
-        dict.setItem(COSName.FILTER, COSName.FLATE_DECODE);
+        PDImageXObject pdImage = new PDImageXObject(document, filteredByteStream, COSName.FLATE_DECODE);
 
         pdImage.setColorSpace(PDDeviceGray.INSTANCE);
-        pdImage.setBitsPerComponent(8);
+        pdImage.setBitsPerComponent(bpc);
         pdImage.setHeight(image.getHeight());
         pdImage.setWidth(image.getWidth());
 
         return pdImage;
     }
+    
+
 
 }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PDImageXObject.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PDImageXObject.java?rev=1593569&r1=1593568&r2=1593569&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PDImageXObject.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/image/PDImageXObject.java Fri May  9 16:16:59 2014
@@ -65,6 +65,7 @@ public final class PDImageXObject extend
     /**
      * Creates an Image XObject in the given document.
      * @param document the current document
+     * @throws java.io.IOException if there is an error creating the XObject.
      */
     public PDImageXObject(PDDocument document) throws IOException
     {
@@ -75,11 +76,13 @@ public final class PDImageXObject extend
      * Creates an Image XObject in the given document using the given filtered stream.
      * @param document the current document
      * @param filteredStream a filtered stream of image data
-     * @throws IOException
+     * @param cosFilter the filter or a COSArray of filters
+     * @throws IOException if there is an error creating the XObject.
      */
-    public PDImageXObject(PDDocument document, InputStream filteredStream) throws IOException
+    public PDImageXObject(PDDocument document, InputStream filteredStream, COSBase cosFilter) throws IOException
     {
         super(new PDStream(document, filteredStream, true), COSName.IMAGE);
+        getCOSStream().setItem(COSName.FILTER, cosFilter);
         colorSpaces = null;
         colorSpace = null;
     }
@@ -88,6 +91,7 @@ public final class PDImageXObject extend
      * Creates an Image XObject with the given stream as its contents and current color spaces.
      * @param stream the XObject stream to read
      * @param colorSpaces the color spaces in the current resources dictionary, null for masks
+     * @throws java.io.IOException if there is an error creating the XObject.
      */
     public PDImageXObject(PDStream stream, Map<String, PDColorSpace> colorSpaces) throws IOException
     {
@@ -155,6 +159,7 @@ public final class PDImageXObject extend
      * {@inheritDoc}
      * The returned images are cached for the lifetime of this XObject.
      */
+    @Override
     public BufferedImage getImage() throws IOException
     {
         if (cachedImage != null)
@@ -189,6 +194,7 @@ public final class PDImageXObject extend
      * {@inheritDoc}
      * The returned images are not cached.
      */
+    @Override
     public BufferedImage getStencilImage(Paint paint) throws IOException
     {
         if (!isStencil())
@@ -318,6 +324,7 @@ public final class PDImageXObject extend
         return null;
     }
 
+    @Override
     public int getBitsPerComponent()
     {
         if (isStencil())
@@ -330,11 +337,13 @@ public final class PDImageXObject extend
         }
     }
 
+    @Override
     public void setBitsPerComponent(int bpc)
     {
         getCOSStream().setInt(COSName.BITS_PER_COMPONENT, bpc);
     }
 
+    @Override
     public PDColorSpace getColorSpace() throws IOException
     {
         if (colorSpace == null)
@@ -358,41 +367,49 @@ public final class PDImageXObject extend
         return colorSpace;
     }
 
+    @Override
     public PDStream getStream() throws IOException
     {
         return getPDStream();
     }
 
+    @Override
     public void setColorSpace(PDColorSpace cs)
     {
         getCOSStream().setItem(COSName.COLORSPACE, cs != null ? cs.getCOSObject() : null);
     }
 
+    @Override
     public int getHeight()
     {
         return getCOSStream().getInt(COSName.HEIGHT);
     }
 
+    @Override
     public void setHeight(int h)
     {
         getCOSStream().setInt(COSName.HEIGHT, h);
     }
 
+    @Override
     public int getWidth()
     {
         return getCOSStream().getInt(COSName.WIDTH);
     }
 
+    @Override
     public void setWidth(int w)
     {
         getCOSStream().setInt(COSName.WIDTH, w);
     }
 
+    @Override
     public void setDecode(COSArray decode)
     {
         getCOSStream().setItem(COSName.DECODE, decode);
     }
 
+    @Override
     public COSArray getDecode()
     {
         COSBase decode = getCOSStream().getDictionaryObject(COSName.DECODE);
@@ -403,11 +420,13 @@ public final class PDImageXObject extend
         return null;
     }
 
+    @Override
     public boolean isStencil()
     {
         return getCOSStream().getBoolean(COSName.IMAGE_MASK, false);
     }
 
+    @Override
     public void setStencil(boolean isStencil)
     {
         getCOSStream().setBoolean(COSName.IMAGE_MASK, isStencil);

Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/CCITTFactoryTest.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/CCITTFactoryTest.java?rev=1593569&r1=1593568&r2=1593569&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/CCITTFactoryTest.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/CCITTFactoryTest.java Fri May  9 16:16:59 2014
@@ -23,7 +23,6 @@ import org.apache.pdfbox.io.RandomAccess
 import org.apache.pdfbox.io.RandomAccessFile;
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceGray;
-import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
 import static org.apache.pdfbox.pdmodel.graphics.image.ValidateXImage.validate;
 
 /**

Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactoryTest.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactoryTest.java?rev=1593569&r1=1593568&r2=1593569&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactoryTest.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/LosslessFactoryTest.java Fri May  9 16:16:59 2014
@@ -15,10 +15,16 @@
  */
 package org.apache.pdfbox.pdmodel.graphics.image;
 
+import java.awt.BasicStroke;
+import java.awt.Color;
 import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Transparency;
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
+import java.util.Random;
 import javax.imageio.ImageIO;
 import junit.framework.TestCase;
 import org.apache.pdfbox.pdmodel.PDDocument;
@@ -148,6 +154,117 @@ public class LosslessFactoryTest extends
     }
 
     /**
+     * Tests ARGB LosslessFactoryTest#createFromImage(PDDocument document,
+     * BufferedImage image) with BITMASK transparency
+     *
+     * @throws java.io.IOException
+     */
+    public void testCreateLosslessFromImageBITMASK() throws IOException
+    {
+        PDDocument document = new PDDocument();
+        
+        int width = 256;
+        int height = 256;
+
+        // create an ARGB image
+        BufferedImage argbImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+        
+        // from there, create an image with Transparency.BITMASK
+        Graphics2D g = argbImage.createGraphics();
+        GraphicsConfiguration gc = g.getDeviceConfiguration();
+        argbImage = gc.createCompatibleImage(width, height, Transparency.BITMASK);
+        g.dispose();
+        // create a red rectangle
+        g = argbImage.createGraphics();
+        g.setColor(Color.red);
+        g.fillRect(0, 0, width, height);
+        g.dispose();
+
+        Random random = new Random();
+        random.setSeed(12345);
+        // create a transparency cross: only pixels in the 
+        // interval max/2 - max/8 ... max/2 + max/8 will be visible
+        int startX = width / 2 - width / 8;
+        int endX   = width / 2 + width / 8;
+        int startY = height / 2 - height / 8;
+        int endY   = height / 2 + height / 8;
+        for (int x = 0; x < width; ++x)
+        {
+            for (int y = 0; y < height; ++y)
+            {
+                // create pseudorandom alpha values, but those within the cross
+                // must be >= 128 and those outside must be < 128
+                int alpha;
+                if ((x >= startX && x <= endX) || y >= startY && y <= endY)
+                {
+                    alpha = 128 + (int) (random.nextFloat() * 127);
+                    assertTrue(alpha >= 128);
+                    argbImage.setRGB(x, y, (argbImage.getRGB(x, y) & 0xFFFFFF) | (alpha << 24));
+                    assertEquals(255, argbImage.getRGB(x, y) >>> 24);
+                }
+                else
+                {
+                    alpha = (int) (random.nextFloat() * 127);
+                    assertTrue(alpha < 128);
+                    argbImage.setRGB(x, y, (argbImage.getRGB(x, y) & 0xFFFFFF) | (alpha << 24));
+                    assertEquals(0, argbImage.getRGB(x, y) >>> 24);
+                }
+            }
+        }
+
+        PDImageXObject ximage = LosslessFactory.createFromImage(document, argbImage);
+        validate(ximage, 8, width, height, "png", PDDeviceRGB.INSTANCE.getName());
+        checkIdent(argbImage, ximage.getImage());
+        checkIdentRGB(argbImage, SampledImageReader.getRGBImage(ximage, null));
+
+        assertNotNull(ximage.getSoftMask());
+        validate(ximage.getSoftMask(), 1, width, height, "png", PDDeviceGray.INSTANCE.getName());
+        assertEquals(2, colorCount(ximage.getSoftMask().getImage()));
+
+        // check whether the mask is a b/w cross
+        BufferedImage maskImage = ximage.getSoftMask().getImage();
+        assertEquals(Transparency.OPAQUE, maskImage.getTransparency());
+        for (int x = 0; x < width; ++x)
+        {
+            for (int y = 0; y < height; ++y)
+            {
+                if ((x >= startX && x <= endX) || y >= startY && y <= endY)
+                {
+                    assertEquals(0xFFFFFF, maskImage.getRGB(x, y) & 0xFFFFFF);
+                }
+                else
+                {
+                    assertEquals(0, maskImage.getRGB(x, y) & 0xFFFFFF);
+                }
+            }
+        }
+        
+        // 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.
+
+        // Create a rectangle
+        BufferedImage rectImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        g = rectImage.createGraphics();
+        g.setColor(Color.blue);
+        g.fillRect(0, 0, width, height);
+        g.dispose();
+        PDImageXObject ximage2 = LosslessFactory.createFromImage(document, rectImage);
+        
+        PDPage page = new PDPage();
+        document.addPage(page);
+        PDPageContentStream contentStream = new PDPageContentStream(document, page, true, false);
+        contentStream.drawXObject(ximage2, 150, 300, ximage2.getWidth(), ximage2.getHeight());
+        contentStream.drawXObject(ximage, 150, 300, ximage.getWidth(), ximage.getHeight());
+        contentStream.close();
+        File pdfFile = new File(testResultsDir, "bitmaskargb.pdf");
+        document.save(pdfFile);
+        document.close();
+        document = PDDocument.loadNonSeq(pdfFile, null);
+        document.close();
+    }
+
+    /**
      * Tests 4BYTE_ABGR LosslessFactoryTest#createFromImage(PDDocument document,
      * BufferedImage image)
      *
@@ -175,12 +292,12 @@ public class LosslessFactoryTest extends
         }
         
         PDImageXObject ximage = LosslessFactory.createFromImage(document, argbImage);
-        validate(ximage, 8, 344, 287, "png", PDDeviceRGB.INSTANCE.getName());
+        validate(ximage, 8, w, h, "png", PDDeviceRGB.INSTANCE.getName());
         checkIdent(argbImage, ximage.getImage());
         checkIdentRGB(argbImage, SampledImageReader.getRGBImage(ximage, null));
 
         assertNotNull(ximage.getSoftMask());
-        validate(ximage.getSoftMask(), 8, 344, 287, "png", PDDeviceGray.INSTANCE.getName());
+        validate(ximage.getSoftMask(), 8, w, h, "png", PDDeviceGray.INSTANCE.getName());
         assertTrue(colorCount(ximage.getSoftMask().getImage()) > image.getHeight() / 10);
 
         // This part isn't really needed because this test doesn't break
@@ -192,7 +309,7 @@ public class LosslessFactoryTest extends
         contentStream.drawXObject(ximage, 150, 300, ximage.getWidth(), ximage.getHeight());
         contentStream.drawXObject(ximage, 200, 350, ximage.getWidth(), ximage.getHeight());
         contentStream.close();
-        File pdfFile = new File(testResultsDir, "4bargb.pdf");
+        File pdfFile = new File(testResultsDir, "4babgr.pdf");
         document.save(pdfFile);
         document.close();
         document = PDDocument.loadNonSeq(pdfFile, null);

Modified: pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/ValidateXImage.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/ValidateXImage.java?rev=1593569&r1=1593568&r2=1593569&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/ValidateXImage.java (original)
+++ pdfbox/trunk/pdfbox/src/test/java/org/apache/pdfbox/pdmodel/graphics/image/ValidateXImage.java Fri May  9 16:16:59 2014
@@ -23,6 +23,8 @@ import java.util.Set;
 import static junit.framework.TestCase.assertEquals;
 import static junit.framework.TestCase.assertNotNull;
 import static junit.framework.TestCase.assertTrue;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSStream;
 import org.apache.pdfbox.util.ImageIOUtil;
 
 /**
@@ -36,7 +38,10 @@ public class ValidateXImage
     {
         // check the dictionary
         assertNotNull(ximage);
-        assertNotNull(ximage.getCOSStream());
+        COSStream cosStream = ximage.getCOSStream();
+        assertNotNull(cosStream);
+        assertEquals(COSName.XOBJECT, cosStream.getItem(COSName.TYPE));
+        assertEquals(COSName.IMAGE, cosStream.getItem(COSName.SUBTYPE));
         assertTrue(ximage.getCOSStream().getFilteredLength() > 0);
         assertEquals(bpc, ximage.getBitsPerComponent());
         assertEquals(width, ximage.getWidth());