From: Jeremias Maerki Date: Mon, 11 Oct 2004 21:06:14 +0000 (+0000) Subject: Bugzilla #31512: X-Git-Tag: Root_Temp_KnuthStylePageBreaking~471 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=7b4f481e0cb1c3d0772890210052cb0a200c7eda;p=xmlgraphics-fop.git Bugzilla #31512: Fop should use Batik's Image readers when possible. Submitted by: Thomas Deweese git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@198036 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/examples/fo/basic/images.fo b/examples/fo/basic/images.fo index 12db1237f..282f2050a 100644 --- a/examples/fo/basic/images.fo +++ b/examples/fo/basic/images.fo @@ -75,6 +75,20 @@ + + + A PNG image in FOP + + + + + + + A TIFF image in FOP + + + + diff --git a/examples/fo/graphics/asf-logo.png b/examples/fo/graphics/asf-logo.png new file mode 100644 index 000000000..b831a2d68 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 index 000000000..dc420f20d Binary files /dev/null and b/examples/fo/graphics/asf-logo.tif differ diff --git a/src/java/org/apache/fop/image/ImageFactory.java b/src/java/org/apache/fop/image/ImageFactory.java index 935662a67..10b14895e 100644 --- a/src/java/org/apache/fop/image/ImageFactory.java +++ b/src/java/org/apache/fop/image/ImageFactory.java @@ -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 index 000000000..4d7cef565 --- /dev/null +++ b/src/java/org/apache/fop/image/PNGImage.java @@ -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 index 000000000..d4359d844 --- /dev/null +++ b/src/java/org/apache/fop/image/TIFFImage.java @@ -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()); + */ + } + } +}; diff --git a/src/java/org/apache/fop/render/pdf/FopPDFImage.java b/src/java/org/apache/fop/render/pdf/FopPDFImage.java index 1e2881fc6..3e964c111 100644 --- a/src/java/org/apache/fop/render/pdf/FopPDFImage.java +++ b/src/java/org/apache/fop/render/pdf/FopPDFImage.java @@ -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; } diff --git a/src/java/org/apache/fop/svg/PDFTranscoder.java b/src/java/org/apache/fop/svg/PDFTranscoder.java index 2ac0153ac..839cd46a5 100644 --- a/src/java/org/apache/fop/svg/PDFTranscoder.java +++ b/src/java/org/apache/fop/svg/PDFTranscoder.java @@ -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);