xmlgraphics-fop-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jerem...@apache.org
Subject svn commit: r617512 - in /xmlgraphics/fop/trunk/src/java/org/apache/fop: pdf/AlphaRasterImage.java render/pdf/AbstractImageAdapter.java svg/PDFGraphics2D.java svg/PDFImageElementBridge.java
Date Fri, 01 Feb 2008 14:58:39 GMT
Author: jeremias
Date: Fri Feb  1 06:58:30 2008
New Revision: 617512

URL: http://svn.apache.org/viewvc?rev=617512&view=rev
Log:
AlphaRasterImage now knows how to deal with TYPE_INT Rasters.
Streamlined image handling in Graphics2D.
Support natively handling CCITT images in SVG images.
Add fallback to device RGB if sRGB isn't set up as the default color space in PDF.

Modified:
    xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/AlphaRasterImage.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java
    xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFImageElementBridge.java

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/AlphaRasterImage.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/AlphaRasterImage.java?rev=617512&r1=617511&r2=617512&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/AlphaRasterImage.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/pdf/AlphaRasterImage.java Fri Feb  1 06:58:30
2008
@@ -22,6 +22,8 @@
 import java.awt.image.DataBuffer;
 import java.awt.image.Raster;
 import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.SinglePixelPackedSampleModel;
 import java.io.IOException;
 import java.io.OutputStream;
 
@@ -137,18 +139,37 @@
             throw new UnsupportedOperationException(
                     "Expected only one band/component for the alpha channel");
         }
+
+        //...and write the Raster line by line with a reusable buffer
         int dataType = alpha.getDataBuffer().getDataType();
-        if (dataType != DataBuffer.TYPE_BYTE) {
+        if (dataType == DataBuffer.TYPE_BYTE) {
+            byte[] line = new byte[nbands * w];
+            for (int y = 0; y < h; y++) {
+                alpha.getDataElements(0, y, w, 1, line);
+                out.write(line);
+            }
+        } else if (dataType == DataBuffer.TYPE_INT) {
+            //Is there an better way to get a 8bit raster from a TYPE_INT raster?
+            int shift = 24;
+            SampleModel sampleModel = alpha.getSampleModel();
+            if (sampleModel instanceof SinglePixelPackedSampleModel) {
+                SinglePixelPackedSampleModel m = (SinglePixelPackedSampleModel)sampleModel;
+                shift = m.getBitOffsets()[0];
+            }
+            int[] iline = new int[nbands * w];
+            byte[] line = new byte[nbands * w];
+            for (int y = 0; y < h; y++) {
+                alpha.getDataElements(0, y, w, 1, iline);
+                for (int i = 0; i < w; i++) {
+                    line[i] = (byte)(iline[i] >> shift);
+                }
+                out.write(line);
+            }
+        } else {
             throw new UnsupportedOperationException("Unsupported DataBuffer type: "
                     + alpha.getDataBuffer().getClass().getName());
         }
 
-        //...and write the Raster line by line with a reusable buffer
-        byte[] line = new byte[nbands * w];
-        for (int y = 0; y < h; y++) {
-            alpha.getDataElements(0, y, w, 1, line);
-            out.write(line);
-        }
     }
     
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java?rev=617512&r1=617511&r2=617512&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/render/pdf/AbstractImageAdapter.java Fri
Feb  1 06:58:30 2008
@@ -59,6 +59,9 @@
     public AbstractImageAdapter(Image image, String key) {
         this.image = image;
         this.key = key;
+        if (log.isDebugEnabled()) {
+            log.debug("New ImageAdapter created for key: " + key);
+        }
     }
 
     /** {@inheritDoc} */
@@ -96,11 +99,16 @@
                     pdfICCStream = cs.getICCStream();
                 }
             } else {
-                if (cs == null && "sRGB".equals(desc)) {
+                if (cs == null && desc.startsWith("sRGB")) {
                     //It's the default sRGB profile which we mapped to DefaultRGB in PDFRenderer
                     cs = doc.getResources().getColorSpace("DefaultRGB");
                 }
-                pdfICCStream = cs.getICCStream();
+                if (cs != null) {
+                    pdfICCStream = cs.getICCStream();
+                } else {
+                    //DefaultRGB hasn't been mapped to sRGB
+                    //(that's the case with a plain PDFGraphics2D)
+                }
             }
         }
         if (doc.getProfile().getPDFAMode().isPDFA1LevelB()) {

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java?rev=617512&r1=617511&r2=617512&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFGraphics2D.java Fri Feb  1 06:58:30
2008
@@ -41,7 +41,6 @@
 import java.awt.image.BufferedImage;
 import java.awt.image.ColorModel;
 import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferInt;
 import java.awt.image.DirectColorModel;
 import java.awt.image.ImageObserver;
 import java.awt.image.Raster;
@@ -65,6 +64,7 @@
 
 import org.apache.xmlgraphics.image.loader.ImageInfo;
 import org.apache.xmlgraphics.image.loader.ImageSize;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
 import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
 import org.apache.xmlgraphics.image.loader.impl.ImageRendered;
 import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
@@ -86,7 +86,6 @@
 import org.apache.fop.pdf.PDFImage;
 import org.apache.fop.pdf.PDFImageXObject;
 import org.apache.fop.pdf.PDFLink;
-import org.apache.fop.pdf.PDFName;
 import org.apache.fop.pdf.PDFNumber;
 import org.apache.fop.pdf.PDFPattern;
 import org.apache.fop.pdf.PDFResourceContext;
@@ -94,6 +93,7 @@
 import org.apache.fop.pdf.PDFState;
 import org.apache.fop.pdf.PDFText;
 import org.apache.fop.pdf.PDFXObject;
+import org.apache.fop.render.pdf.ImageRawCCITTFaxAdapter;
 import org.apache.fop.render.pdf.ImageRawJPEGAdapter;
 import org.apache.fop.render.pdf.ImageRenderedAdapter;
 import org.apache.fop.util.ColorExt;
@@ -143,10 +143,10 @@
     protected int baseLevel = 0;
 
     /**
-     * The count of JPEG images added to document so they recieve
+     * The count of natively handled images added to document so they receive
      * unique keys.
      */
-    protected int[] jpegCount = {0};
+    protected int nativeCount = 0;
 
     /**
      * The current font information.
@@ -232,7 +232,7 @@
         this.pageRef = g.pageRef;
         this.graphicsState = g.graphicsState;
         this.currentStream = g.currentStream;
-        this.jpegCount = g.jpegCount;
+        this.nativeCount = g.nativeCount;
         this.outputStream = g.outputStream;
         this.ovFontState = g.ovFontState;
     }
@@ -401,44 +401,41 @@
     }
 
     /**
-     * Add a JPEG image directly to the PDF document.
-     * This is used by the PDFImageElementBridge to draw a JPEG
-     * directly into the pdf document rather than converting the image into
+     * Add a natively handled image directly to the PDF document.
+     * This is used by the PDFImageElementBridge to draw a natively handled image
+     * (like JPEG or CCITT images)
+     * directly into the PDF document rather than converting the image into
      * a bitmap and increasing the size.
      *
-     * @param jpeg the jpeg image to draw
+     * @param image the image to draw
      * @param x the x position
      * @param y the y position
      * @param width the width to draw the image
      * @param height the height to draw the image
      */
-    public void addJpegImage(ImageRawJPEG jpeg, float x, float y, 
+    void addNativeImage(org.apache.xmlgraphics.image.loader.Image image, float x, float y,

                              float width, float height) {
         preparePainting();
-        // Need to include hash code as when invoked from FO you
-        // may have several 'independent' PDFGraphics2D so the
-        // count is not enough.
-        String key = "__AddJPEG_" + hashCode() + "_" + jpegCount[0];
-        jpegCount[0]++;
-        PDFImage pdfimage = new ImageRawJPEGAdapter(jpeg, key);
-        PDFName imageName = this.pdfDoc.addImage(resourceContext, 
-                                              pdfimage).getName();
-        AffineTransform at = getTransform();
-        double[] matrix = new double[6];
-        at.getMatrix(matrix);
-        currentStream.write("q\n");
-        if (!at.isIdentity()) {
-            concatMatrix(matrix);
+        String key = image.getInfo().getOriginalURI();
+        if (key == null) {
+            // Need to include hash code as when invoked from FO you
+            // may have several 'independent' PDFGraphics2D so the
+            // count is not enough.
+            key = "__AddNative_" + hashCode() + "_" + nativeCount; 
+            nativeCount++;
         }
-        Shape imclip = getClip();
-        writeClip(imclip);
-
-        currentStream.write("" + width + " 0 0 "
-                          + (-height) + " "
-                          + x + " "
-                          + (y + height) + " cm\n"
-                          + imageName + " Do\nQ\n");
-
+        
+        PDFImage pdfImage;
+        if (image instanceof ImageRawJPEG) {
+            pdfImage = new ImageRawJPEGAdapter((ImageRawJPEG)image, key);
+        } else if (image instanceof ImageRawCCITTFax) {
+            pdfImage = new ImageRawCCITTFaxAdapter((ImageRawCCITTFax)image, key);
+        } else {
+            throw new IllegalArgumentException(
+                    "Unsupported Image subclass: " + image.getClass().getName());
+        }
+        
+        PDFXObject xObject = this.pdfDoc.addImage(resourceContext, pdfImage);
         if (outputStream != null) {
             try {
                 this.pdfDoc.output(outputStream);
@@ -446,6 +443,10 @@
                 // ignore exception, will be thrown again later
             }
         }
+
+        AffineTransform at = new AffineTransform();
+        at.translate(x, y);
+        useXObject(xObject, at, width, height);
     }
 
     /**
@@ -492,40 +493,7 @@
                                  BufferedImage.TYPE_INT_ARGB);
     }
 
-    /**
-     * Draws as much of the specified image as has already been scaled
-     * to fit inside the specified rectangle.
-     * <p>
-     * The image is drawn inside the specified rectangle of this
-     * graphics context's coordinate space, and is scaled if
-     * necessary. Transparent pixels do not affect whatever pixels
-     * are already there.
-     * <p>
-     * This method returns immediately in all cases, even if the
-     * entire image has not yet been scaled, dithered, and converted
-     * for the current output device.
-     * If the current output representation is not yet complete, then
-     * <code>drawImage</code> returns <code>false</code>. As more
of
-     * the image becomes available, the process that draws the image notifies
-     * the image observer by calling its <code>imageUpdate</code> method.
-     * <p>
-     * A scaled version of an image will not necessarily be
-     * available immediately just because an unscaled version of the
-     * image has been constructed for this output device.  Each size of
-     * the image may be cached separately and generated from the original
-     * data in a separate image production sequence.
-     * @param    img    the specified image to be drawn.
-     * @param    x      the <i>x</i> coordinate.
-     * @param    y      the <i>y</i> coordinate.
-     * @param    width  the width of the rectangle.
-     * @param    height the height of the rectangle.
-     * @param    observer    object to be notified as more of
-     * the image is converted.
-     * @return true if the image was drawn
-     * @see      java.awt.Image
-     * @see      java.awt.image.ImageObserver
-     * @see      java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int,
int, int)
-     */
+    /** {@inheritDoc} */
     public boolean drawImage(Image img, int x, int y, int width, int height,
                                ImageObserver observer) {
         preparePainting();
@@ -533,8 +501,9 @@
         // the pdf document. If so, we just reuse the reference;
         // otherwise we have to build a FopImage and add it to the pdf
         // document
-        PDFXObject imageInfo = pdfDoc.getXObject("TempImage:" + img.toString());
-        if (imageInfo == null) {
+        String key = "TempImage:" + img.toString();
+        PDFXObject xObject = pdfDoc.getXObject(key);
+        if (xObject == null) {
             // OK, have to build and add a PDF image
 
             Dimension size = new Dimension(width, height);
@@ -553,92 +522,14 @@
             }
             g.dispose();
 
-            final byte[] result = new byte[buf.getWidth() * buf.getHeight() * 3 /*for RGB*/];
-            byte[] mask = new byte[buf.getWidth() * buf.getHeight()];
-            boolean hasMask = false;
-            //boolean binaryMask = true;
-
-            Raster raster = buf.getData();
-            DataBuffer bd = raster.getDataBuffer();
-
-            int count = 0;
-            int maskpos = 0;
-            int[] iarray;
-            int i, j, val, alpha;
-            switch (bd.getDataType()) {
-                case DataBuffer.TYPE_INT:
-                int[][] idata = ((DataBufferInt)bd).getBankData();
-                for (i = 0; i < idata.length; i++) {
-                    iarray = idata[i];
-                    for (j = 0; j < iarray.length; j++) {
-                        val = iarray[j];
-                        alpha = val >>> 24;
-                        mask[maskpos++] = (byte)(alpha & 0xFF);
-                        if (alpha != 255) {
-                            hasMask = true;
-                        }
-                        result[count++] = (byte)((val >> 16) & 0xFF);
-                        result[count++] = (byte)((val >> 8) & 0xFF);
-                        result[count++] = (byte)((val) & 0xFF);
-                    }
-                }
-                break;
-                default:
-                // error
-                break;
-            }
-            String ref = null;
-            if (hasMask) {
-                // if the mask is binary then we could convert it into a bitmask
-                BitmapImage fopimg = new BitmapImage("TempImageMask:"
-                                             + img.toString(), buf.getWidth(),
-                                             buf.getHeight(), mask, null);
-                fopimg.setColorSpace(new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY));
-                PDFImageXObject xobj = pdfDoc.addImage(resourceContext, fopimg);
-                ref = xobj.referencePDF();
-
-                if (outputStream != null) {
-                    try {
-                        this.pdfDoc.output(outputStream);
-                    } catch (IOException ioe) {
-                        // ignore exception, will be thrown again later
-                    }
-                }
-            } else {
-                mask = null;
-            }
-
-            BitmapImage fopimg = new BitmapImage("TempImage:"
-                                          + img.toString(), buf.getWidth(),
-                                          buf.getHeight(), result, ref);
-            imageInfo = pdfDoc.addImage(resourceContext, fopimg);
-            //int xObjectNum = imageInfo.getXNumber();
-
-            if (outputStream != null) {
-                try {
-                    this.pdfDoc.output(outputStream);
-                } catch (IOException ioe) {
-                    // ignore exception, will be thrown again later
-                }
-            }
+            xObject = addRenderedImage(key, buf);
         } else {
-            resourceContext.getPDFResources().addXObject(imageInfo);
+            resourceContext.getPDFResources().addXObject(xObject);
         }
 
-        // now do any transformation required and add the actual image
-        // placement instance
-        AffineTransform at = getTransform();
-        double[] matrix = new double[6];
-        at.getMatrix(matrix);
-        currentStream.write("q\n");
-        if (!at.isIdentity()) {
-            concatMatrix(matrix);
-        }
-        Shape imclip = getClip();
-        writeClip(imclip);
-        currentStream.write("" + width + " 0 0 " + (-height) + " " + x
-                            + " " + (y + height) + " cm\n"
-                            + imageInfo.getName() + " Do\nQ\n");
+        AffineTransform at = new AffineTransform();
+        at.translate(x, y);
+        useXObject(xObject, at, width, height);
         return true;
     }
 
@@ -1342,18 +1233,24 @@
 
     /** {@inheritDoc} */
     public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
-        preparePainting();
         String key = "TempImage:" + img.toString();
+        drawInnerRenderedImage(key, img, xform);
+    }
+
+    /** {@inheritDoc} */
+    public void drawInnerRenderedImage(String key, RenderedImage img, AffineTransform xform)
{
+        preparePainting();
         PDFXObject xObject = pdfDoc.getXObject(key);
         if (xObject == null) {
-            ImageInfo info = new ImageInfo(null, "image/unknown");
-            ImageSize size = new ImageSize(img.getWidth(), img.getHeight(), 72);
-            info.setSize(size);
-            ImageRendered imgRend = new ImageRendered(info, img, null);
-            ImageRenderedAdapter adapter = new ImageRenderedAdapter(imgRend, key);
-            xObject = pdfDoc.addImage(resourceContext, adapter);
+            xObject = addRenderedImage(key, img);
+        } else {
+            resourceContext.getPDFResources().addXObject(xObject);
         }
 
+        useXObject(xObject, xform, img.getWidth(), img.getHeight());
+    }
+
+    private void useXObject(PDFXObject xObject, AffineTransform xform, float width, float
height) {
         // now do any transformation required and add the actual image
         // placement instance
         currentStream.write("q\n");
@@ -1361,9 +1258,27 @@
         Shape imclip = getClip();
         writeClip(imclip);
         concatMatrix(xform);
-        currentStream.write("" + img.getWidth() + " 0 0 " + (-img.getHeight()) + " 0"
-                + " " + (img.getHeight()) + " cm\n"
+        String w = PDFNumber.doubleOut(width, DEC);
+        String h = PDFNumber.doubleOut(height, DEC);
+        currentStream.write("" + w + " 0 0 -" + h + " 0 " + h + " cm\n"
                 + xObject.getName() + " Do\nQ\n");
+    }
+
+    private PDFXObject addRenderedImage(String key, RenderedImage img) {
+        ImageInfo info = new ImageInfo(null, "image/unknown");
+        ImageSize size = new ImageSize(img.getWidth(), img.getHeight(), 72);
+        info.setSize(size);
+        ImageRendered imgRend = new ImageRendered(info, img, null);
+        ImageRenderedAdapter adapter = new ImageRenderedAdapter(imgRend, key);
+        PDFXObject xObject = pdfDoc.addImage(resourceContext, adapter);
+        if (outputStream != null) {
+            try {
+                this.pdfDoc.output(outputStream);
+            } catch (IOException ioe) {
+                // ignore exception, will be thrown again later
+            }
+        }
+        return xObject;
     }
 
     /** {@inheritDoc} */

Modified: xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFImageElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFImageElementBridge.java?rev=617512&r1=617511&r2=617512&view=diff
==============================================================================
--- xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFImageElementBridge.java (original)
+++ xmlgraphics/fop/trunk/src/java/org/apache/fop/svg/PDFImageElementBridge.java Fri Feb 
1 06:58:30 2008
@@ -39,6 +39,7 @@
 import org.apache.xmlgraphics.image.loader.ImageManager;
 import org.apache.xmlgraphics.image.loader.ImageSessionContext;
 import org.apache.xmlgraphics.image.loader.impl.ImageGraphics2D;
+import org.apache.xmlgraphics.image.loader.impl.ImageRawCCITTFax;
 import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
 import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM;
 
@@ -56,6 +57,7 @@
 
     private final ImageFlavor[] supportedFlavors = new ImageFlavor[]
                                                {ImageFlavor.RAW_JPEG,
+                                                ImageFlavor.RAW_CCITTFAX,
                                                 ImageFlavor.GRAPHICS2D,
                                                 ImageFlavor.XML_DOM};
     /**
@@ -90,9 +92,9 @@
                 }
             }
             if (image instanceof ImageRawJPEG) {
-                ImageRawJPEG jpegImage = (ImageRawJPEG)image;
-                specializedNode = new PDFJpegNode(jpegImage, ctx, imageElement, purl);
-                
+                specializedNode = new LoaderImageNode(image, ctx, imageElement, purl);
+            } else if (image instanceof ImageRawCCITTFax) {
+                specializedNode = new LoaderImageNode(image, ctx, imageElement, purl);
             } else if (image instanceof ImageGraphics2D) {
                 ImageGraphics2D g2dImage = (ImageGraphics2D)image;
                 specializedNode = new Graphics2DNode(g2dImage);
@@ -135,29 +137,29 @@
 
 
     /**
-     * A PDF jpeg node.
-     * This holds a jpeg image so that it can be drawn into
+     * An image node for natively handled Image instance.
+     * This holds a natively handled image so that it can be drawn into
      * the PDFGraphics2D.
      */
-    public class PDFJpegNode extends AbstractGraphicsNode {
+    public class LoaderImageNode extends AbstractGraphicsNode {
         
-        private ImageRawJPEG jpeg;
+        private Image image;
         private BridgeContext ctx;
         private Element imageElement;
         private ParsedURL purl;
         private GraphicsNode origGraphicsNode = null;
         
         /**
-         * Create a new PDF JPEG node for drawing JPEG images
-         * into pdf graphics.
-         * @param j the JPEG image
+         * Create a new image node for drawing natively handled images
+         * into PDF graphics.
+         * @param image the JPEG image
          * @param ctx the bridge context
          * @param imageElement the SVG image element
          * @param purl the URL to the image
          */
-        public PDFJpegNode(ImageRawJPEG j, BridgeContext ctx, 
+        public LoaderImageNode(Image image, BridgeContext ctx, 
                            Element imageElement, ParsedURL purl) {
-            this.jpeg = j;
+            this.image = image;
             this.ctx  = ctx;
             this.imageElement = imageElement;
             this.purl = purl;
@@ -175,9 +177,9 @@
                 float x = 0;
                 float y = 0;
                 try {
-                    float width = jpeg.getSize().getWidthPx();
-                    float height = jpeg.getSize().getHeightPx();
-                    pdfg.addJpegImage(jpeg, x, y, width, height);
+                    float width = image.getSize().getWidthPx();
+                    float height = image.getSize().getHeightPx();
+                    pdfg.addNativeImage(image, x, y, width, height);
                 } catch (Exception e) {
                     ctx.getUserAgent().displayError(e);
                 }
@@ -203,8 +205,8 @@
         /** {@inheritDoc} */
         public Rectangle2D getPrimitiveBounds() {
             return new Rectangle2D.Double(0, 0,
-                       jpeg.getSize().getWidthPx(),
-                       jpeg.getSize().getHeightPx());
+                       image.getSize().getWidthPx(),
+                       image.getSize().getHeightPx());
         }
 
         /** {@inheritDoc} */



---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org


Mime
View raw message