Submitted by: Eric Dalquist ebdalqui@mtu.edu Reviewed by: Keiron git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194467 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_20_3
@@ -21,6 +21,7 @@ import org.apache.fop.image.analyser.ImageReader; | |||
/** | |||
* 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 { | |||
@@ -75,6 +76,12 @@ 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: | |||
@@ -250,7 +257,16 @@ public abstract class AbstractFopImage implements FopImage { | |||
* @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; | |||
} | |||
/** |
@@ -118,10 +118,10 @@ public class FopImageFactory { | |||
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"; |
@@ -19,17 +19,18 @@ import org.apache.fop.pdf.PDFColor; | |||
import org.apache.fop.image.analyser.ImageReader; | |||
/** | |||
* FopImage object for GIF or JPEG images, using Java native classes. | |||
* 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 GifJpegImage extends AbstractFopImage { | |||
public GifJpegImage(URL href) throws FopImageException { | |||
public class GifImage extends AbstractFopImage { | |||
public GifImage(URL href) throws FopImageException { | |||
super(href); | |||
} | |||
public GifJpegImage(URL href, | |||
public GifImage(URL href, | |||
ImageReader imgReader) throws FopImageException { | |||
super(href, imgReader); | |||
} | |||
@@ -41,9 +42,12 @@ public class GifJpegImage extends AbstractFopImage { | |||
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(); | |||
@@ -118,7 +122,6 @@ public class GifJpegImage extends AbstractFopImage { | |||
+ 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]; |
@@ -0,0 +1,136 @@ | |||
/* | |||
* $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; | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,35 @@ | |||
/* | |||
* $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; | |||
} | |||
} | |||
@@ -65,7 +65,15 @@ public class PDFXObject extends PDFObject { | |||
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 @@ public class PDFXObject extends PDFObject { | |||
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"; |