/**
* Base class to implement the FopImage interface.
* @author Eric SCHAEFFER
+ * @author Modified by Eric Dalquist - 9/14/2001 - ebdalqui@mtu.edu
* @see FopImage
*/
public abstract class AbstractFopImage implements FopImage {
*/
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:
* @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;
}
/**
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";
--- /dev/null
+/*
+ * $Id$
+ * 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 - ebdalqui@mtu.edu
+ * @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);
+ }
+ }
+ }
+
+}
+
+++ /dev/null
-/*
- * $Id$
- * 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 or JPEG images, using Java native classes.
- * @author Eric SCHAEFFER
- * @see AbstractFopImage
- * @see FopImage
- */
-public class GifJpegImage extends AbstractFopImage {
- public GifJpegImage(URL href) throws FopImageException {
- super(href);
- }
-
- public GifJpegImage(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);
-
- 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);
- }
- }
- }
-
-}
-
--- /dev/null
+/*
+ * $Id$
+ * 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;
+ }
+ }
+}
+
+
--- /dev/null
+/*
+ * $Id$
+ * 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;
+ }
+}
+
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();
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";