keiron 01/09/18 01:17:08 Modified: src/org/apache/fop/image AbstractFopImage.java FopImageFactory.java src/org/apache/fop/pdf PDFXObject.java Added: src/org/apache/fop/image GifImage.java JpegImage.java src/org/apache/fop/pdf DCTFilter.java Removed: src/org/apache/fop/image GifJpegImage.java Log: Patch to handle direct embedding of jpeg images into pdf Submitted by: Eric Dalquist [EMAIL PROTECTED] Reviewed by: Keiron Revision Changes Path 1.5 +18 -2 xml-fop/src/org/apache/fop/image/AbstractFopImage.java Index: AbstractFopImage.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/image/AbstractFopImage.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- AbstractFopImage.java 2001/07/30 20:29:26 1.4 +++ AbstractFopImage.java 2001/09/18 08:17:07 1.5 @@ -1,5 +1,5 @@ /* - * $Id: AbstractFopImage.java,v 1.4 2001/07/30 20:29:26 tore Exp $ + * $Id: AbstractFopImage.java,v 1.5 2001/09/18 08:17:07 keiron Exp $ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. @@ -21,6 +21,7 @@ /** * Base class to implement the FopImage interface. * @author Eric SCHAEFFER + * @author Modified by Eric Dalquist - 9/14/2001 - [EMAIL PROTECTED] * @see FopImage */ public abstract class AbstractFopImage implements FopImage { @@ -76,6 +77,12 @@ protected PDFColor m_transparentColor = null; /** + * Image compression type. + * Added by Eric Dalquist + */ + protected PDFFilter m_compressionType = null; + + /** * Constructor. * Construct a new FopImage object and initialize its default properties: * <UL> @@ -250,7 +257,16 @@ * @exception FopImageException an error occured during loading */ public PDFFilter getPDFFilter() throws FopImageException { - return null; + + /* + * Added by Eric Dalquist + * Using the bitsPerPixel var as our flag since many imges will + * have a null m_compressionType even after being loaded + */ + if (this.m_bitsPerPixel == 0) + this.loadImage(); + + return m_compressionType; } /** 1.24 +3 -3 xml-fop/src/org/apache/fop/image/FopImageFactory.java Index: FopImageFactory.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/image/FopImageFactory.java,v retrieving revision 1.23 retrieving revision 1.24 diff -u -r1.23 -r1.24 --- FopImageFactory.java 2001/09/07 14:10:07 1.23 +++ FopImageFactory.java 2001/09/18 08:17:07 1.24 @@ -1,5 +1,5 @@ /* - * $Id: FopImageFactory.java,v 1.23 2001/09/07 14:10:07 keiron Exp $ + * $Id: FopImageFactory.java,v 1.24 2001/09/18 08:17:07 keiron Exp $ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. @@ -118,10 +118,10 @@ String imgMimeType = imgReader.getMimeType(); String imgClassName = null; if ("image/gif".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.GifJpegImage"; + imgClassName = "org.apache.fop.image.GifImage"; // imgClassName = "org.apache.fop.image.JAIImage"; } else if ("image/jpeg".equals(imgMimeType)) { - imgClassName = "org.apache.fop.image.GifJpegImage"; + imgClassName = "org.apache.fop.image.JpegImage"; // imgClassName = "org.apache.fop.image.JAIImage"; } else if ("image/bmp".equals(imgMimeType)) { imgClassName = "org.apache.fop.image.BmpImage"; 1.1 xml-fop/src/org/apache/fop/image/GifImage.java Index: GifImage.java =================================================================== /* * $Id: GifImage.java,v 1.1 2001/09/18 08:17:07 keiron Exp $ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. */ package org.apache.fop.image; // Java import java.net.URL; import java.awt.image.ImageProducer; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; // FOP import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.image.analyser.ImageReader; /** * FopImage object for GIF images, using Java native classes. * @author Eric SCHAEFFER * @author Modified by Eric Dalquist - 9/14/2001 - [EMAIL PROTECTED] * @see AbstractFopImage * @see FopImage */ public class GifImage extends AbstractFopImage { public GifImage(URL href) throws FopImageException { super(href); } public GifImage(URL href, ImageReader imgReader) throws FopImageException { super(href, imgReader); } protected void loadImage() throws FopImageException { int[] tmpMap = null; try { ImageProducer ip = (ImageProducer)this.m_href.getContent(); FopImageConsumer consumer = new FopImageConsumer(ip); ip.startProduction(consumer); //Load the image into memory while (!consumer.isImageReady()) { Thread.sleep(500); } this.m_height = consumer.getHeight(); this.m_width = consumer.getWidth(); try { tmpMap = consumer.getImage(); } catch (Exception ex) { throw new FopImageException("Image grabbing interrupted : " + ex.getMessage()); } ColorModel cm = consumer.getColorModel(); this.m_bitsPerPixel = 8; // this.m_bitsPerPixel = cm.getPixelSize(); this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); if (cm.hasAlpha()) { int transparencyType = cm.getTransparency(); // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT if (transparencyType == java.awt.Transparency.OPAQUE) { this.m_isTransparent = false; } else if (transparencyType == java.awt.Transparency.BITMASK) { if (cm instanceof IndexColorModel) { this.m_isTransparent = false; byte[] alphas = new byte[((IndexColorModel)cm).getMapSize()]; byte[] reds = new byte[((IndexColorModel)cm).getMapSize()]; byte[] greens = new byte[((IndexColorModel)cm).getMapSize()]; byte[] blues = new byte[((IndexColorModel)cm).getMapSize()]; ((IndexColorModel)cm).getAlphas(alphas); ((IndexColorModel)cm).getReds(reds); ((IndexColorModel)cm).getGreens(greens); ((IndexColorModel)cm).getBlues(blues); for (int i = 0; i < ((IndexColorModel)cm).getMapSize(); i++) { if ((alphas[i] & 0xFF) == 0) { this.m_isTransparent = true; this.m_transparentColor = new PDFColor((int)(reds[i] & 0xFF), (int)(greens[i] & 0xFF), (int)(blues[i] & 0xFF)); break; } } } else { // TRANSLUCENT /* * this.m_isTransparent = false; * for (int i = 0; i < this.m_width * this.m_height; i++) { * if (cm.getAlpha(tmpMap[i]) == 0) { * this.m_isTransparent = true; * this.m_transparentColor = new PDFColor(cm.getRed(tmpMap[i]), cm.getGreen(tmpMap[i]), cm.getBlue(tmpMap[i])); * break; * } * } */ // use special API... this.m_isTransparent = false; } } else { this.m_isTransparent = false; } } else { this.m_isTransparent = false; } } catch (Exception ex) { throw new FopImageException("Error while loading image " + this.m_href.toString() + " : " + ex.getClass() + " - " + ex.getMessage()); } // Should take care of the ColorSpace and bitsPerPixel this.m_bitmapsSize = this.m_width * this.m_height * 3; this.m_bitmaps = new byte[this.m_bitmapsSize]; for (int i = 0; i < this.m_height; i++) { for (int j = 0; j < this.m_width; j++) { int p = tmpMap[i * this.m_width + j]; int r = (p >> 16) & 0xFF; int g = (p >> 8) & 0xFF; int b = (p) & 0xFF; this.m_bitmaps[3 * (i * this.m_width + j)] = (byte)(r & 0xFF); this.m_bitmaps[3 * (i * this.m_width + j) + 1] = (byte)(g & 0xFF); this.m_bitmaps[3 * (i * this.m_width + j) + 2] = (byte)(b & 0xFF); } } } } 1.1 xml-fop/src/org/apache/fop/image/JpegImage.java Index: JpegImage.java =================================================================== /* * $Id: JpegImage.java,v 1.1 2001/09/18 08:17:07 keiron Exp $ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. */ package org.apache.fop.image; // Java import java.net.URL; import java.awt.image.ImageProducer; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.io.ByteArrayOutputStream; import java.io.InputStream; // FOP import org.apache.fop.datatypes.ColorSpace; import org.apache.fop.pdf.PDFColor; import org.apache.fop.pdf.DCTFilter; import org.apache.fop.image.analyser.ImageReader; /** * FopImage object for JPEG images, Using Java native classes. * @author Eric Dalquist * @see AbstractFopImage * @see FopImage */ public class JpegImage extends AbstractFopImage { public JpegImage(URL href) throws FopImageException { super(href); } public JpegImage(URL href, ImageReader imgReader) throws FopImageException { super(href, imgReader); } protected void loadImage() throws FopImageException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); InputStream inStream; byte[] readBuf = new byte[4096]; int bytes_read; int index = 0; boolean cont = true; this.m_compressionType = new DCTFilter(); this.m_compressionType.setApplied(true); try { inStream = this.m_href.openStream(); while ((bytes_read = inStream.read(readBuf)) != -1) { baos.write(readBuf, 0, bytes_read); } } catch (java.io.IOException ex) { throw new FopImageException("Error while loading image " + this.m_href.toString() + " : " + ex.getClass() + " - " + ex.getMessage()); } this.m_bitmaps = baos.toByteArray(); this.m_bitsPerPixel = 8; this.m_isTransparent = false; if (this.m_bitmaps.length > (index + 2) && uByte(this.m_bitmaps[index]) == 255 && uByte(this.m_bitmaps[index + 1]) == 216) { index += 2; while (index < this.m_bitmaps.length && cont) { //check to be sure this is the begining of a header if (this.m_bitmaps.length > (index + 2) && uByte(this.m_bitmaps[index]) == 255) { //192 or 194 are the header bytes that contain the jpeg width height and color depth. if (uByte(this.m_bitmaps[index + 1]) == 192 || uByte(this.m_bitmaps[index + 1]) == 194) { this.m_height = calcBytes(this.m_bitmaps[index + 5], this.m_bitmaps[index + 6]); this.m_width = calcBytes(this.m_bitmaps[index + 7], this.m_bitmaps[index + 8]); if (this.m_bitmaps[index + 9] == 1) { this.m_colorSpace = new ColorSpace( ColorSpace.DEVICE_GRAY); } else if (this.m_bitmaps[index + 9] == 3) { this.m_colorSpace = new ColorSpace(ColorSpace.DEVICE_RGB); } else { cont = false; throw new FopImageException( "\n2 Error while loading image " + this.m_href.toString() + " : JpegImage - Invalid JPEG Header (bad color space " + this.m_bitmaps[index + 9] + ")."); } cont = false; break; } else { // if (uByte(this.m_bitmaps[index + 1]) == headers[headerIndex]) { index += calcBytes(this.m_bitmaps[index + 2], this.m_bitmaps[index + 3]) + 2; } } else { cont = false; throw new FopImageException( "\n2 Error while loading image " + this.m_href.toString() + " : JpegImage - Invalid JPEG Header (bad header byte)."); } } } else { throw new FopImageException( "\n1 Error while loading image " + this.m_href.toString() + " : JpegImage - Invalid JPEG Header."); } } private int calcBytes(byte bOne, byte bTwo) { return (uByte(bOne) * 256) + uByte(bTwo); } private int uByte(byte bIn) { if (bIn < 0) { return 256 + bIn; } else { return bIn; } } } 1.14 +11 -3 xml-fop/src/org/apache/fop/pdf/PDFXObject.java Index: PDFXObject.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/pdf/PDFXObject.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- PDFXObject.java 2001/07/30 20:29:30 1.13 +++ PDFXObject.java 2001/09/18 08:17:08 1.14 @@ -1,5 +1,5 @@ /* - * $Id: PDFXObject.java,v 1.13 2001/07/30 20:29:30 tore Exp $ + * $Id: PDFXObject.java,v 1.14 2001/09/18 08:17:08 keiron Exp $ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. @@ -65,7 +65,15 @@ PDFStream imgStream = new PDFStream(0); imgStream.setData(fopimage.getBitmaps()); - // imgStream.addFilter(new FlateFilter()); + + /* + * Added by Eric Dalquist + * If the DCT filter hasn't been added to the object we add it here + */ + if (fopimage.getPDFFilter() != null) { + imgStream.addFilter(fopimage.getPDFFilter()); + } + imgStream.addDefaultFilters(); String dictEntries = imgStream.applyFilters(); @@ -74,7 +82,7 @@ p = p + "<</Type /XObject\n"; p = p + "/Subtype /Image\n"; p = p + "/Name /Im" + Xnum + "\n"; - p = p + "/Length " + imgStream.getDataLength(); + p = p + "/Length " + imgStream.getDataLength() + "\n"; p = p + "/Width " + fopimage.getWidth() + "\n"; p = p + "/Height " + fopimage.getHeight() + "\n"; p = p + "/BitsPerComponent " + fopimage.getBitsPerPixel() + "\n"; 1.1 xml-fop/src/org/apache/fop/pdf/DCTFilter.java Index: DCTFilter.java =================================================================== /* * $Id: DCTFilter.java,v 1.1 2001/09/18 08:17:08 keiron Exp $ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. */ package org.apache.fop.pdf; import java.io.ByteArrayOutputStream; import java.io.IOException; /** * DCT Filter class. Right now it is just used as a dummy filter flag so * we can write JPG images to the PDF. The encode method just returns the * data passed to it. In the future an actual JPEG compression should be * added to the encode method so other images can be compressed. * * @author Eric Dalquist */ public class DCTFilter extends PDFFilter { public String getName() { return "/DCTDecode"; } public String getDecodeParms() { return null; } public byte[] encode(byte[] data) { return data; } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]