]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Bugzilla #31512:
authorJeremias Maerki <jeremias@apache.org>
Mon, 11 Oct 2004 21:06:14 +0000 (21:06 +0000)
committerJeremias Maerki <jeremias@apache.org>
Mon, 11 Oct 2004 21:06:14 +0000 (21:06 +0000)
Fop should use Batik's Image readers when possible.
Submitted by: Thomas Deweese <deweese.at.apache.org>

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198036 13f79535-47bb-0310-9956-ffa450edef68

examples/fo/basic/images.fo
examples/fo/graphics/asf-logo.png [new file with mode: 0644]
examples/fo/graphics/asf-logo.tif [new file with mode: 0644]
src/java/org/apache/fop/image/ImageFactory.java
src/java/org/apache/fop/image/PNGImage.java [new file with mode: 0644]
src/java/org/apache/fop/image/TIFFImage.java [new file with mode: 0644]
src/java/org/apache/fop/render/pdf/FopPDFImage.java
src/java/org/apache/fop/svg/PDFTranscoder.java

index 12db1237f75c8da0b8ba47f4256a3736db643dde..282f2050a4dbca08e090335bbcf2547557768316 100644 (file)
     <fo:external-graphic src="file:../graphics/linux.bmp"/>
   </fo:block>
 </fo:block>
+<fo:block id="N2555">
+  <!--fox:destination internal-destination="N2555"/-->
+  <fo:block font-size="16pt" font-weight="bold" space-before.minimum="1em" space-before.optimum="1.5em" space-before.maximum="2em">A PNG image in FOP</fo:block>
+  <fo:block>
+    <fo:external-graphic src="file:../graphics/asf-logo.png"/>
+  </fo:block>
+</fo:block>
+<fo:block id="N2556">
+  <!--fox:destination internal-destination="N2556"/-->
+  <fo:block font-size="16pt" font-weight="bold" space-before.minimum="1em" space-before.optimum="1.5em" space-before.maximum="2em">A TIFF image in FOP</fo:block>
+  <fo:block>
+    <fo:external-graphic src="file:../graphics/asf-logo.tif"/>
+  </fo:block>
+</fo:block>
 <fo:block id="N2559">
   <!--fox:destination internal-destination="N2559"/-->
   <fo:block font-size="16pt" font-weight="bold" space-before.minimum="1em" space-before.optimum="1.5em" space-before.maximum="2em"/>
diff --git a/examples/fo/graphics/asf-logo.png b/examples/fo/graphics/asf-logo.png
new file mode 100644 (file)
index 0000000..b831a2d
Binary files /dev/null and b/examples/fo/graphics/asf-logo.png differ
diff --git a/examples/fo/graphics/asf-logo.tif b/examples/fo/graphics/asf-logo.tif
new file mode 100644 (file)
index 0000000..dc420f2
Binary files /dev/null and b/examples/fo/graphics/asf-logo.tif differ
index 935662a67d375eecbfc98409e182f11d82f9b833..10b14895e5625fba3f4fe15103f686c602cc60de 100644 (file)
@@ -300,13 +300,13 @@ public class ImageFactory {
         } else if ("image/eps".equals(imgMimeType)) {
             imgClassName = "org.apache.fop.image.EPSImage";
         } else if ("image/png".equals(imgMimeType)) {
-            imgClassName = "org.apache.fop.image.JimiImage";
+            imgClassName = "org.apache.fop.image.PNGImage";
             // imgClassName = "org.apache.fop.image.JAIImage";
         } else if ("image/tga".equals(imgMimeType)) {
             imgClassName = "org.apache.fop.image.JimiImage";
             // imgClassName = "org.apache.fop.image.JAIImage";
         } else if ("image/tiff".equals(imgMimeType)) {
-            imgClassName = "org.apache.fop.image.JimiImage";
+            imgClassName = "org.apache.fop.image.TIFFImage";
             // imgClassName = "org.apache.fop.image.JAIImage";
         } else if ("image/svg+xml".equals(imgMimeType)) {
             imgClassName = "org.apache.fop.image.XMLImage";
diff --git a/src/java/org/apache/fop/image/PNGImage.java b/src/java/org/apache/fop/image/PNGImage.java
new file mode 100644 (file)
index 0000000..4d7cef5
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ *  Copyright 2004 The Apache Software Foundation 
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.fop.image;
+
+import java.awt.Color;
+import java.awt.Transparency;
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.WritableRaster;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+import org.apache.batik.ext.awt.image.codec.PNGRed;
+import org.apache.batik.ext.awt.image.codec.PNGDecodeParam;
+import org.apache.batik.ext.awt.image.codec.SeekableStream;
+import org.apache.batik.ext.awt.image.codec.MemoryCacheSeekableStream;
+import org.apache.batik.ext.awt.image.codec.FileCacheSeekableStream;
+import org.apache.batik.ext.awt.image.rendered.Any2sRGBRed;
+import org.apache.batik.ext.awt.image.rendered.CachableRed;
+
+/**
+ * FopImage object using PNG
+ * @author Eric SCHAEFFER
+ * @see AbstractFopImage
+ * @see FopImage
+ */
+public class PNGImage extends AbstractFopImage {
+
+    private byte[] softMask = null;
+
+    public PNGImage(FopImage.ImageInfo imgReader) {
+        super(imgReader);
+    }
+
+    protected boolean loadDimensions() {
+        if (this.bitmaps == null) {
+            loadImage();
+        }
+
+        return this.bitmaps != null;
+    }
+
+    /**
+     * @see org.apache.fop.image.AbstractFopImage#loadBitmap()
+     */
+    protected boolean loadBitmap() {
+        if (this.bitmaps == null) {
+            loadImage();
+        }
+
+        return this.bitmaps != null;
+    }
+
+    public boolean hasSoftMask() {
+        if (this.bitmaps == null) {
+            loadImage();
+        }
+
+        return (this.softMask != null);
+    }
+
+    public byte[] getSoftMask() {
+        if (this.bitmaps == null) {
+            loadImage();
+        }
+
+        return this.softMask;
+    }
+
+    protected void loadImage() {
+        try {
+            SeekableStream seekableInput;
+            try { seekableInput = new FileCacheSeekableStream(inputStream);
+            } catch (IOException ioe) {
+                seekableInput = new MemoryCacheSeekableStream(inputStream);
+            }
+
+            PNGDecodeParam param = new PNGDecodeParam();
+            param.setPerformGammaCorrection(true);
+            param.setDisplayExponent(2.2f); // sRGB gamma
+            CachableRed cr = new PNGRed(seekableInput, param);
+            ColorModel cm = cr.getColorModel();
+
+            this.height = cr.getHeight();
+            this.width  = cr.getWidth();
+
+            cr = new Any2sRGBRed(cr);
+
+            this.isTransparent = false;
+            this.softMask = null;
+            int transparencyType = cm.getTransparency();
+            if ((transparencyType == Transparency.BITMASK) 
+                    && (cm instanceof IndexColorModel)) {
+                // Currently only supports 'transparent color'(?)
+                IndexColorModel icm = (IndexColorModel)cm;
+                int numColor = icm.getMapSize();
+                byte [] alpha = new byte[numColor];
+                icm.getAlphas(alpha);
+                for (int i = 0; i < numColor; i++) {
+                    if ((alpha[i] & 0xFF) == 0) {
+                        this.isTransparent = true;
+                        int red = (icm.getRed  (i)) & 0xFF;
+                        int grn = (icm.getGreen(i)) & 0xFF;
+                        int blu = (icm.getBlue (i)) & 0xFF;
+                        this.transparentColor = new Color(red, grn, blu);
+                        break;
+                    }
+                }
+            }
+
+            cm = cr.getColorModel();
+            if ((!this.isTransparent) && cm.hasAlpha()) {
+                this.softMask = new byte[this.width * this.height];
+            }
+
+            this.bitsPerPixel = 8;
+            this.bitmapsSize = this.width * this.height * 3;
+            this.bitmaps = new byte[this.bitmapsSize];
+            this.colorSpace = cm.getColorSpace();
+
+            WritableRaster wr = (WritableRaster)cr.getData();
+            BufferedImage bi = new BufferedImage
+                (cm, wr.createWritableTranslatedChild(0, 0), 
+                 cm.isAlphaPremultiplied(), null);
+            int [] tmpMap = new int[this.width];
+            int idx = 0;
+            int sfIdx = 0;
+            for (int y = 0; y < this.height; y++) {
+                tmpMap = bi.getRGB(0, y, this.width, 1, tmpMap, 0, this.width);
+                if (softMask != null) {
+                    for (int x = 0; x < this.width; x++) {
+                        int pix = tmpMap[x];
+                        this.softMask[sfIdx++] = (byte)(pix >>> 24);
+                        this.bitmaps[idx++]    = (byte)((pix >>> 16) & 0xFF);
+                        this.bitmaps[idx++]    = (byte)((pix >>> 8)  & 0xFF);
+                        this.bitmaps[idx++]    = (byte)((pix)        & 0xFF);
+                    }
+                } else {
+                    for (int x = 0; x < this.width; x++) {
+                        int pix = tmpMap[x];
+                        this.bitmaps[idx++] = (byte)((pix >> 16) & 0xFF);
+                        this.bitmaps[idx++] = (byte)((pix >> 8)  & 0xFF);
+                        this.bitmaps[idx++] = (byte)((pix)       & 0xFF);
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            /*throw new FopImageException("Error while loading image "
+                                         + "" + " : "
+                                         + ex.getClass() + " - "
+                                         + ex.getMessage());
+            */
+        }
+    }
+};
diff --git a/src/java/org/apache/fop/image/TIFFImage.java b/src/java/org/apache/fop/image/TIFFImage.java
new file mode 100644 (file)
index 0000000..d4359d8
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ *  Copyright 2004 The Apache Software Foundation 
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+package org.apache.fop.image;
+
+import java.awt.Color;
+import java.awt.Transparency;
+import java.awt.image.ColorModel;
+import java.awt.image.IndexColorModel;
+import java.awt.image.WritableRaster;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+import org.apache.batik.ext.awt.image.codec.SeekableStream;
+import org.apache.batik.ext.awt.image.codec.MemoryCacheSeekableStream;
+import org.apache.batik.ext.awt.image.codec.FileCacheSeekableStream;
+import org.apache.batik.ext.awt.image.rendered.Any2sRGBRed;
+import org.apache.batik.ext.awt.image.rendered.CachableRed;
+
+/**
+ * FopImage object using TIFF
+ * @author Eric SCHAEFFER
+ * @see AbstractFopImage
+ * @see FopImage
+ */
+public class TIFFImage extends AbstractFopImage {
+
+    private byte[] softMask = null;
+
+    /**
+     * Constructs a new TIFFImage instance.
+     * @param imgReader basic metadata for the image
+     */
+    public TIFFImage(FopImage.ImageInfo imgReader) {
+        super(imgReader);
+    }
+
+    /**
+     * @see org.apache.fop.image.AbstractFopImage#loadDimensions()
+     */
+    protected boolean loadDimensions() {
+        if (this.bitmaps == null) {
+            loadImage();
+        }
+
+        return this.bitmaps != null;
+    }
+
+    /**
+     * @see org.apache.fop.image.AbstractFopImage#loadBitmap()
+     */
+    protected boolean loadBitmap() {
+        if (this.bitmaps == null) {
+            loadImage();
+        }
+
+        return this.bitmaps != null;
+    }
+
+    /**
+     * @see org.apache.fop.image.FopImage#hasSoftMask()
+     */
+    public boolean hasSoftMask() {
+        if (this.bitmaps == null) {
+            loadImage();
+        }
+
+        return (this.softMask != null);
+    }
+
+    /**
+     * @see org.apache.fop.image.FopImage#getSoftMask()
+     */
+    public byte[] getSoftMask() {
+        if (this.bitmaps == null) {
+            loadImage();
+        }
+
+        return this.softMask;
+    }
+
+    /**
+     * Loads the image from the InputStream.
+     */
+    protected void loadImage() {
+        try {
+            SeekableStream seekableInput;
+            try { seekableInput = new FileCacheSeekableStream(inputStream);
+            } catch (IOException ioe) {
+                seekableInput = new MemoryCacheSeekableStream(inputStream);
+            }
+
+            CachableRed cr;
+            cr = new org.apache.batik.ext.awt.image.codec.tiff.TIFFImage
+                (seekableInput, null, 0);
+            ColorModel cm = cr.getColorModel();
+
+            this.height = cr.getHeight();
+            this.width  = cr.getWidth();
+
+            cr = new Any2sRGBRed(cr);
+
+            this.isTransparent = false;
+            this.softMask = null;
+            int transparencyType = cm.getTransparency();
+            if ((transparencyType == Transparency.BITMASK) 
+                    && (cm instanceof IndexColorModel)) {
+                // Use 'transparent color'.
+                IndexColorModel icm = (IndexColorModel)cm;
+                int numColor = icm.getMapSize();
+                byte [] alpha = new byte[numColor];
+                icm.getAlphas(alpha);
+                for (int i = 0; i < numColor; i++) {
+                    if ((alpha[i] & 0xFF) == 0) {
+                        this.isTransparent = true;
+                        int red = (icm.getRed  (i)) & 0xFF;
+                        int grn = (icm.getGreen(i)) & 0xFF;
+                        int blu = (icm.getBlue (i)) & 0xFF;
+                        this.transparentColor = new Color(red, grn, blu);
+                        break;
+                    }
+                }
+            }
+
+            // Get our current ColorModel
+            cm = cr.getColorModel();
+
+            // It has an alpha channel so generate a soft mask.
+            if ((!this.isTransparent) && cm.hasAlpha()) {
+                this.softMask = new byte[this.width * this.height];
+            }
+
+            this.bitsPerPixel = 8;
+            this.bitmapsSize = this.width * this.height * 3;
+            this.bitmaps = new byte[this.bitmapsSize];
+            this.colorSpace = cm.getColorSpace();
+
+            WritableRaster wr = (WritableRaster)cr.getData();
+            BufferedImage bi = new BufferedImage
+                (cm, wr.createWritableTranslatedChild(0, 0), 
+                 cm.isAlphaPremultiplied(), null);
+            int [] tmpMap = new int[this.width];
+            int idx = 0;
+            int sfIdx = 0;
+            for (int y = 0; y < this.height; y++) {
+                tmpMap = bi.getRGB(0, y, this.width, 1, tmpMap, 0, this.width);
+                if (softMask != null) {
+                    for (int x = 0; x < this.width; x++) {
+                        int pix = tmpMap[x];
+                        this.softMask[sfIdx++] = (byte)(pix >>> 24);
+                        this.bitmaps[idx++]    = (byte)((pix >>> 16) & 0xFF);
+                        this.bitmaps[idx++]    = (byte)((pix >>> 8)  & 0xFF);
+                        this.bitmaps[idx++]    = (byte)((pix)        & 0xFF);
+                    }
+                } else {
+                    for (int x = 0; x < this.width; x++) {
+                        int pix = tmpMap[x];
+                        this.bitmaps[idx++] = (byte)((pix >> 16) & 0xFF);
+                        this.bitmaps[idx++] = (byte)((pix >> 8)  & 0xFF);
+                        this.bitmaps[idx++] = (byte)((pix)       & 0xFF);
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            /*throw new FopImageException("Error while loading image "
+                                         + "" + " : "
+                                         + ex.getClass() + " - "
+                                         + ex.getMessage());
+            */
+        }
+    }
+};
index 1e2881fc655c5aa3a775af302bc1ef6f6ff02480..3e964c11142de626f4d0c6328bd221fb3038ec85 100644 (file)
@@ -26,6 +26,8 @@ import org.apache.fop.pdf.PDFColor;
 import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.DCTFilter;
 import org.apache.fop.pdf.PDFColorSpace;
+import org.apache.fop.pdf.PDFXObject;
+import org.apache.fop.pdf.BitmapImage;
 
 import org.apache.fop.image.FopImage;
 import org.apache.fop.image.JpegImage;
@@ -84,6 +86,17 @@ public class FopPDFImage implements PDFImage {
                 pdfICCStream.setColorSpace(prof, pdfCS);
             }
         }
+
+        if (fopImage.hasSoftMask()) {
+            byte [] softMask = fopImage.getSoftMask();
+            if (softMask == null) return;
+            BitmapImage fopimg = new BitmapImage
+                ("Mask:" + key, fopImage.getWidth(), fopImage.getHeight(), 
+                 softMask, null);
+            fopimg.setColorSpace(new PDFColorSpace(PDFColorSpace.DEVICE_GRAY));
+            PDFXObject xobj = doc.addImage(null, fopimg);
+            softMaskRef = xobj.referencePDF();
+        }
     }
 
     /**
@@ -156,6 +169,7 @@ public class FopPDFImage implements PDFImage {
      * @see org.apache.fop.pdf.PDFImage#getSoftMask()
      */
     public String getSoftMask() {
+
         return softMaskRef;
     }
 
index 2ac0153ac671f372c633b7640718bd67597901b0..839cd46a5f82a192dff2e24b3e6388b5993328fe 100644 (file)
@@ -29,6 +29,7 @@ import org.apache.avalon.framework.container.ContainerUtil;
 import org.apache.batik.bridge.BridgeContext;
 import org.apache.batik.bridge.UnitProcessor;
 import org.apache.batik.bridge.UserAgent;
+import org.apache.batik.ext.awt.RenderingHintsKeyExt;
 import org.apache.batik.gvt.TextPainter;
 import org.apache.batik.gvt.renderer.StrokingTextPainter;
 import org.apache.batik.transcoder.TranscoderException;
@@ -153,6 +154,9 @@ public class PDFTranscoder extends AbstractFOPTranscoder
             graphics.setGraphicContext
                 (new org.apache.batik.ext.awt.g2d.GraphicContext());
             graphics.setTransform(curTxf);
+            graphics.setRenderingHint
+                (RenderingHintsKeyExt.KEY_TRANSCODING,
+                 RenderingHintsKeyExt.VALUE_TRANSCODING_VECTOR);
 
             this.root.paint(graphics);