Author: lehmi
Date: Wed Sep 28 18:40:44 2011
New Revision: 1177010

URL: http://svn.apache.org/viewvc?rev=1177010&view=rev
Log:
PDFBOX-1095: fixed the rendering of images  using a separation colorspace

Modified:
    
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/graphics/xobject/PDPixelMap.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=1177010&r1=1177009&r2=1177010&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 Sep 28 18:40:44 2011
@@ -33,13 +33,17 @@ import org.apache.commons.logging.LogFac
 import org.apache.pdfbox.cos.COSArray;
 import org.apache.pdfbox.cos.COSBase;
 import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSInteger;
 import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSNumber;
 import org.apache.pdfbox.pdmodel.common.PDStream;
+import org.apache.pdfbox.pdmodel.common.function.PDFunction;
 
 import org.apache.pdfbox.pdmodel.graphics.color.PDColorSpace;
 import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceGray;
 import org.apache.pdfbox.pdmodel.graphics.color.PDICCBased;
 import org.apache.pdfbox.pdmodel.graphics.color.PDIndexed;
+import org.apache.pdfbox.pdmodel.graphics.color.PDSeparation;
 
 
 
@@ -54,7 +58,7 @@ public class PDPixelMap extends PDXObjec
     /**
      * Log instance.
      */
-    private static final Log log = LogFactory.getLog(PDPixelMap.class);
+    private static final Log LOG = LogFactory.getLog(PDPixelMap.class);
 
     private BufferedImage image = null;
 
@@ -137,14 +141,14 @@ public class PDPixelMap extends PDXObjec
             byte[] array = getPDStream().getByteArray();
             if (array.length == 0)
             {
-                log.error("Something went wrong ... the pixelmap doesn't 
contain any data.");
+                LOG.error("Something went wrong ... the pixelmap doesn't 
contain any data.");
                 return null;
             }
             // Get the ColorModel right
             PDColorSpace colorspace = getColorSpace();
             if (colorspace == null)
             {
-                log.error("getColorSpace() returned NULL.  Predictor = " + 
getPredictor());
+                LOG.error("getColorSpace() returned NULL.  Predictor = " + 
getPredictor());
                 return null;
             }
 
@@ -193,6 +197,50 @@ public class PDPixelMap extends PDXObjec
                     }
                 }
             }
+            else if (colorspace instanceof PDSeparation)
+            {
+                PDSeparation csSeparation = (PDSeparation)colorspace;
+                int numberOfComponents = 
csSeparation.getAlternateColorSpace().getNumberOfComponents();
+                PDFunction tintTransformFunc = csSeparation.getTintTransform();
+                COSArray decode = getDecode();
+                // we have to invert the tint-values,
+                // if the Decode array exists and consists of (1,0)
+                boolean invert = decode != null && decode.getInt(0) == 1;
+                // TODO add interpolation for other decode values then 1,0
+                int maxValue = (int)Math.pow(2,bpc) - 1;
+                // destination array
+                byte[] mappedData = new byte[width*height*numberOfComponents];
+                int rowLength = width*numberOfComponents;
+                COSArray input = new COSArray();
+                input.add(COSInteger.ZERO);
+                for ( int i = 0; i < height; i++ )
+                {
+                    int rowOffset = i * rowLength; 
+                    for (int j = 0; j < width; j++)
+                    {
+                        // scale tint values to a range of 0...1
+                        int value = (array[ i * width + j ] + 256) % 256;
+                        if (invert)
+                        {
+                            input.set(0, 1-(value / maxValue) );
+                        }
+                        else
+                        {
+                            input.set(0, value / maxValue);
+                        }
+                        COSArray mappedColor = tintTransformFunc.eval(input);
+                        int columnOffset = j * numberOfComponents;
+                        for ( int k = 0; k < numberOfComponents; k++ ) 
+                        {
+                            // redo scaling for every single color value 
+                            float mappedValue = 
((COSNumber)mappedColor.get(k)).floatValue();
+                            mappedData[ rowOffset + columnOffset + k] = 
(byte)(mappedValue * maxValue);
+                        }
+                    }
+                }
+                array = mappedData;
+                cm = colorspace.createColorModel( bpc );
+            }
             else if (bpc == 1)
             {
                 byte[] map = null;
@@ -247,7 +295,7 @@ public class PDPixelMap extends PDXObjec
                 }
             }
 
-            log.debug("ColorModel: " + cm.toString());
+            LOG.debug("ColorModel: " + cm.toString());
             WritableRaster raster = cm.createCompatibleWritableRaster( width, 
height );
             DataBufferByte buffer = (DataBufferByte)raster.getDataBuffer();
             byte[] bufferData = buffer.getData();
@@ -277,7 +325,7 @@ public class PDPixelMap extends PDXObjec
         }
         catch (Exception exception)
         {
-            log.error(exception, exception);
+            LOG.error(exception, exception);
             //A NULL return is caught in pagedrawer.Invoke.process() so don't 
re-throw.
             //Returning the NULL falls through to Phillip Koch's TODO section.
             return null;


Reply via email to