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]