You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by le...@apache.org on 2011/10/12 19:53:12 UTC

svn commit: r1182494 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox: pdmodel/graphics/xobject/PDPixelMap.java pdmodel/graphics/xobject/PDXObjectImage.java util/operator/pagedrawer/Invoke.java

Author: lehmi
Date: Wed Oct 12 17:53:11 2011
New Revision: 1182494

URL: http://svn.apache.org/viewvc?rev=1182494&view=rev
Log:
PDFBOX-1128: use DeviceGray when ImageMasked == 1 and create a stencil masked image using the current non stroking color

Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java?rev=1182494&r1=1182493&r2=1182494&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.java Wed Oct 12 17:53:11 2011
@@ -16,6 +16,8 @@
  */
 package org.apache.pdfbox.pdmodel.graphics.xobject;
 
+import java.awt.AlphaComposite;
+import java.awt.Graphics2D;
 import java.awt.Transparency;
 import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
@@ -317,9 +319,21 @@ public class PDPixelMap extends PDXObjec
 
                 return rgbImage;
             }
+            else if (getImageMask())
+            {
+                BufferedImage stencilMask = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+                Graphics2D graphics = (Graphics2D)stencilMask.getGraphics();
+                graphics.setColor(getStencilColor().getJavaColor());
+                graphics.fillRect(0, 0, width, height);
+                // assume default values ([0,1]) for the DecodeArray
+                // TODO DecodeArray == [1,0]
+                graphics.setComposite(AlphaComposite.DstIn);
+                graphics.drawImage(image, null, 0, 0);
+                return stencilMask;
+            }
             else
             {
-                // But if there is no soft mask, use the unaltered image.
+                // if there is no mask, use the unaltered image.
                 return image;
             }
         }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java?rev=1182494&r1=1182493&r2=1182494&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDXObjectImage.java Wed Oct 12 17:53:11 2011
@@ -32,8 +32,8 @@ import org.apache.pdfbox.pdmodel.PDDocum
 import org.apache.pdfbox.pdmodel.common.PDStream;
 import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
 import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpaceFactory;
+import org.apache.pdfbox.pdmodel.graphics.color.PDColorState;
 import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceGray;
-import org.apache.pdfbox.pdmodel.graphics.PDGraphicsState;
 
 /**
  * The prototype for all PDImages.
@@ -48,7 +48,7 @@ public abstract class PDXObjectImage ext
     /**
      * Log instance.
      */
-    private static final Log log = LogFactory.getLog(PDXObjectImage.class);
+    private static final Log LOG = LogFactory.getLog(PDXObjectImage.class);
 
     /**
      * The XObject subtype.
@@ -60,10 +60,10 @@ public abstract class PDXObjectImage ext
      */
     private String suffix;
 
-    private PDGraphicsState graphicsState;
-
+    private PDColorState stencilColor;
+    
     /**
-     * Standard constuctor.
+     * Standard constructor.
      *
      * @param imageStream The XObject is passed as a COSStream.
      * @param fileSuffix The file suffix, jpg/png.
@@ -149,13 +149,12 @@ public abstract class PDXObjectImage ext
         }
     }
 
-        /**
+    /**
      * Writes the image to a file with the filename + an appropriate
-suffix, like "Image.jpg".
+     * suffix, like "Image.jpg".
      * The suffix is automatically set by the
      * @param file the file
-     * @throws IOException When somethings wrong with the corresponding
-file.
+     * @throws IOException When somethings wrong with the corresponding file.
      */
     public void write2file(File file) throws IOException
     {
@@ -223,7 +222,7 @@ file.
      */
     public int getBitsPerComponent()
     {
-        return getCOSStream().getInt( new String[] { "BPC", "BitsPerComponent"}, -1 );
+        return getCOSStream().getInt( COSName.BITS_PER_COMPONENT, COSName.BPC, -1 );
     }
 
     /**
@@ -233,7 +232,7 @@ file.
      */
     public void setBitsPerComponent( int bpc )
     {
-        getCOSStream().setInt( "BitsPerComponent", bpc );
+        getCOSStream().setInt( COSName.BITS_PER_COMPONENT, bpc );
     }
 
     /**
@@ -245,49 +244,38 @@ file.
      */
     public PDColorSpace getColorSpace() throws IOException
     {
-        COSBase cs = getCOSStream().getDictionaryObject( new String[]{ "CS", "ColorSpace" } );
+        COSBase cs = getCOSStream().getDictionaryObject( COSName.COLORSPACE, COSName.CS );
         PDColorSpace retval = null;
         if( cs != null )
         {
             retval = PDColorSpaceFactory.createColorSpace( cs );
             if (retval == null)
-                {
-                    log.info("About to return NULL from createColorSpace branch");
-                }
+            {
+                LOG.info("About to return NULL from createColorSpace branch");
+            }
         }
         else
         {
             //there are some cases where the 'required' CS value is not present
             //but we know that it will be grayscale for a CCITT filter.
-            COSBase filter = getCOSStream().getDictionaryObject( "Filter" );
+            COSBase filter = getCOSStream().getDictionaryObject( COSName.FILTER );
             if( COSName.CCITTFAX_DECODE.equals( filter ) ||
                 COSName.CCITTFAX_DECODE_ABBREVIATION.equals( filter ) )
             {
                 retval = new PDDeviceGray();
-                if (retval == null)
-                    {
-                        log.info("About to return NULL from CCITT branch");
-                    }
             }
             else if( COSName.JBIG2_DECODE.equals( filter ) )
             {
                 retval = new PDDeviceGray();
-                if (retval == null)
-                {
-                    log.info("About to return NULL from JBIG2 branch");
-                }
             }
             else if (getImageMask())
             {
-                //Stencil Mask branch.  Section 4.8.5 of the reference, page 350 in version 1.7.
-                retval = graphicsState.getNonStrokingColor().getColorSpace();
-                log.info("Stencil Mask branch returning " + retval.toString());
-                //throw new IOException("Trace the Stencil Mask!!!!");
-
+                // image is a stencil mask -> use DeviceGray
+                retval = new PDDeviceGray();
             }
             else
             {
-                log.info("About to return NULL from unhandled branch."
+                LOG.info("About to return NULL from unhandled branch."
                         + " filter = " + filter);
             }
         }
@@ -330,13 +318,23 @@ file.
     }
 
     /**
-     * Allow the Invoke operator to set the graphics state so that,
-     * in the case of an Image Mask, we can get to the current nonstroking colorspace.
-     * @param newGS The new graphicstate
+     * Set the current non stroking colorstate. It'll be used to create stencil masked images.
+     * 
+     * @param stencilColorValue The non stroking colorstate
+     */
+    public void setStencilColor(PDColorState stencilColorValue)
+    {
+        stencilColor = stencilColorValue;
+    }
+
+    /**
+     * Returns the non stroking colorstate to be used to create stencil makes images.
+     * 
+     * @return The current non stroking colorstate.
      */
-    public void setGraphicsState(PDGraphicsState newGS)
+    public PDColorState getStencilColor()
     {
-        graphicsState = newGS;
+        return stencilColor;
     }
 
     /**

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java?rev=1182494&r1=1182493&r2=1182494&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/util/operator/pagedrawer/Invoke.java Wed Oct 12 17:53:11 2011
@@ -50,7 +50,7 @@ public class Invoke extends OperatorProc
     /**
      * Log instance.
      */
-    private static final Log log = LogFactory.getLog(Invoke.class);
+    private static final Log LOG = LogFactory.getLog(Invoke.class);
 
     /**
      * process : Do : Paint the specified XObject (section 4.7).
@@ -63,35 +63,42 @@ public class Invoke extends OperatorProc
         PageDrawer drawer = (PageDrawer)context;
         PDPage page = drawer.getPage();
         COSName objectName = (COSName)arguments.get( 0 );
-        Map xobjects = drawer.getResources().getXObjects();
+        Map<String, PDXObject> xobjects = drawer.getResources().getXObjects();
         PDXObject xobject = (PDXObject)xobjects.get( objectName.getName() );
         if ( xobject == null )
         {
-            log.warn("Can't find the XObject for '"+objectName.getName()+"'");
+            LOG.warn("Can't find the XObject for '"+objectName.getName()+"'");
         }
         else if( xobject instanceof PDXObjectImage )
         {
             PDXObjectImage image = (PDXObjectImage)xobject;
             try
             {
-                image.setGraphicsState(drawer.getGraphicsState());
+                if (image.getImageMask())
+                {
+                    // set the current non stroking colorstate, so that it can
+                    // be used to create a stencil masked image
+                    image.setStencilColor(drawer.getGraphicsState().getNonStrokingColor());
+                }
                 BufferedImage awtImage = image.getRGBImage();
                 if (awtImage == null) 
                 {
-                    log.warn("getRGBImage returned NULL");
+                    LOG.warn("getRGBImage returned NULL");
                     return;//TODO PKOCH
                 }
                 int imageWidth = awtImage.getWidth();
                 int imageHeight = awtImage.getHeight();
                 double pageHeight = drawer.getPageSize().getHeight();
 
-                log.debug("imageWidth: " + imageWidth + "\t\timageHeight: " + imageHeight);
+                LOG.debug("imageWidth: " + imageWidth + "\t\timageHeight: " + imageHeight);
         
                 Matrix ctm = drawer.getGraphicsState().getCurrentTransformationMatrix();
                 float yScaling = ctm.getYScale();
                 float angle = (float)Math.acos(ctm.getValue(0, 0)/ctm.getXScale());
                 if (ctm.getValue(0, 1) < 0 && ctm.getValue(1, 0) > 0)
+                {
                     angle = (-1)*angle;
+                }
                 ctm.setValue(2, 1, (float)(pageHeight - ctm.getYPosition() - Math.cos(angle)*yScaling));
                 ctm.setValue(2, 0, (float)(ctm.getXPosition() - Math.sin(angle)*yScaling));
                 // because of the moved 0,0-reference, we have to shear in the opposite direction
@@ -104,7 +111,7 @@ public class Invoke extends OperatorProc
             catch( Exception e )
             {
                 e.printStackTrace();
-                log.error(e, e);
+                LOG.error(e, e);
             }
         }
         else if(xobject instanceof PDXObjectForm)