From bdda3117d3b3c95fb471587d592c5afd28cb3bec Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 24 Aug 2005 13:43:00 +0000 Subject: [PATCH] Fixes unrecoverable exceptions causing BatchDiffer to fail. Doing a clean separation of encoded and decoded data inside the image implementations. Helps fix a problem with the encoded CCITT TIFF being sent to the PS output even though this is not yet implemented. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@239661 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/image/ImageIOImage.java | 3 +- .../apache/fop/image/AbstractFopImage.java | 16 ++--- src/java/org/apache/fop/image/BatikImage.java | 13 +++-- src/java/org/apache/fop/image/BmpImage.java | 3 +- src/java/org/apache/fop/image/GifImage.java | 3 +- src/java/org/apache/fop/image/JAIImage.java | 4 +- src/java/org/apache/fop/image/JimiImage.java | 6 +- src/java/org/apache/fop/image/JpegImage.java | 58 +++++++++---------- src/java/org/apache/fop/image/TIFFImage.java | 6 +- .../apache/fop/render/pdf/FopPDFImage.java | 6 +- .../apache/fop/render/ps/PSImageUtils.java | 7 ++- 11 files changed, 64 insertions(+), 61 deletions(-) diff --git a/src/java-1.4/org/apache/fop/image/ImageIOImage.java b/src/java-1.4/org/apache/fop/image/ImageIOImage.java index 56bb863b7..111011918 100644 --- a/src/java-1.4/org/apache/fop/image/ImageIOImage.java +++ b/src/java-1.4/org/apache/fop/image/ImageIOImage.java @@ -127,8 +127,7 @@ public class ImageIOImage extends AbstractFopImage { } // Should take care of the ColorSpace and bitsPerPixel - this.bitmapsSize = this.width * this.height * 3; - this.bitmaps = new byte[this.bitmapsSize]; + this.bitmaps = new byte[this.width * this.height * 3]; for (int i = 0; i < this.height; i++) { for (int j = 0; j < this.width; j++) { int p = tmpMap[i * this.width + j]; diff --git a/src/java/org/apache/fop/image/AbstractFopImage.java b/src/java/org/apache/fop/image/AbstractFopImage.java index 2a9136f80..461b474ea 100644 --- a/src/java/org/apache/fop/image/AbstractFopImage.java +++ b/src/java/org/apache/fop/image/AbstractFopImage.java @@ -82,14 +82,14 @@ public abstract class AbstractFopImage implements FopImage { protected int bitsPerPixel = 0; /** - * Image data (uncompressed). + * Image data (pixels, uncompressed). */ protected byte[] bitmaps = null; /** - * Image data size. + * Image data (undecoded, compressed, for image formats that can be embedded without decoding. */ - protected int bitmapsSize = 0; + protected byte[] raw = null; /** * Image transparency. @@ -298,7 +298,7 @@ public abstract class AbstractFopImage implements FopImage { } /** - * Return the image data (uncompressed). + * Return the image data (pixels, uncompressed). * @return the image data */ public byte[] getBitmaps() { @@ -306,11 +306,11 @@ public abstract class AbstractFopImage implements FopImage { } /** - * Return the image data size (uncompressed). + * Return the image data size (number of bytes taken up by the uncompressed pixels). * @return the image data size */ public int getBitmapsSize() { - return this.bitmapsSize; + return (bitmaps != null ? bitmaps.length : 0); } /** @@ -318,7 +318,7 @@ public abstract class AbstractFopImage implements FopImage { * @return the original image data */ public byte[] getRessourceBytes() { - return null; + return raw; } /** @@ -326,7 +326,7 @@ public abstract class AbstractFopImage implements FopImage { * @return the original image data size */ public int getRessourceBytesSize() { - return 0; + return (raw != null ? raw.length : 0); } } diff --git a/src/java/org/apache/fop/image/BatikImage.java b/src/java/org/apache/fop/image/BatikImage.java index 380b21ab6..1f6d7405b 100644 --- a/src/java/org/apache/fop/image/BatikImage.java +++ b/src/java/org/apache/fop/image/BatikImage.java @@ -140,7 +140,7 @@ public abstract class BatikImage extends AbstractFopImage { * @see org.apache.fop.image.FopImage#hasSoftMask() */ public boolean hasSoftMask() { - if (this.bitmaps == null) { + if (this.bitmaps == null && this.raw == null) { loadImage(); } @@ -172,15 +172,20 @@ public abstract class BatikImage extends AbstractFopImage { protected void loadImage() { if (loadDimensions()) { try { + if (cr == null) { + throw new IllegalStateException( + "Can't load the bitmaps data without the CachableRed instance"); + } + // Get our current ColorModel ColorModel cm = cr.getColorModel(); // It has an alpha channel so generate a soft mask. - if (!this.isTransparent && cm.hasAlpha()) + if (!this.isTransparent && cm.hasAlpha()) { this.softMask = new byte[this.width * this.height]; + } - this.bitmapsSize = this.width * this.height * 3; - this.bitmaps = new byte[this.bitmapsSize]; + this.bitmaps = new byte[this.width * this.height * 3]; WritableRaster wr = (WritableRaster)cr.getData(); BufferedImage bi = new BufferedImage diff --git a/src/java/org/apache/fop/image/BmpImage.java b/src/java/org/apache/fop/image/BmpImage.java index 3e256cf77..64c43e8d1 100644 --- a/src/java/org/apache/fop/image/BmpImage.java +++ b/src/java/org/apache/fop/image/BmpImage.java @@ -125,8 +125,7 @@ public class BmpImage extends AbstractFopImage { } // Should take care of the ColorSpace and bitsPerPixel - this.bitmapsSize = this.width * this.height * 3; - this.bitmaps = new byte[this.bitmapsSize]; + this.bitmaps = new byte[this.width * this.height * 3]; int[] temp = new int[bytes * this.height]; try { diff --git a/src/java/org/apache/fop/image/GifImage.java b/src/java/org/apache/fop/image/GifImage.java index 20c24525b..10a3d6328 100644 --- a/src/java/org/apache/fop/image/GifImage.java +++ b/src/java/org/apache/fop/image/GifImage.java @@ -150,8 +150,7 @@ public class GifImage extends AbstractFopImage { } // Should take care of the ColorSpace and bitsPerPixel - this.bitmapsSize = this.width * this.height * 3; - this.bitmaps = new byte[this.bitmapsSize]; + this.bitmaps = new byte[this.width * this.height * 3]; for (int i = 0; i < this.height; i++) { for (int j = 0; j < this.width; j++) { int p = tmpMap[i * this.width + j]; diff --git a/src/java/org/apache/fop/image/JAIImage.java b/src/java/org/apache/fop/image/JAIImage.java index a3e5a533c..c5fcd2304 100644 --- a/src/java/org/apache/fop/image/JAIImage.java +++ b/src/java/org/apache/fop/image/JAIImage.java @@ -22,7 +22,6 @@ package org.apache.fop.image; import java.awt.image.ColorModel; import java.awt.image.IndexColorModel; import java.awt.image.BufferedImage; -import java.awt.color.ColorSpace; import java.awt.Color; // JAI @@ -150,8 +149,7 @@ public class JAIImage extends AbstractFopImage { } // Should take care of the ColorSpace and bitsPerPixel - this.bitmapsSize = this.width * this.height * 3; - this.bitmaps = new byte[this.bitmapsSize]; + this.bitmaps = new byte[this.width * this.height * 3]; for (int i = 0; i < this.height; i++) { for (int j = 0; j < this.width; j++) { int p = tmpMap[i * this.width + j]; diff --git a/src/java/org/apache/fop/image/JimiImage.java b/src/java/org/apache/fop/image/JimiImage.java index 103a067c4..35db0bbc1 100644 --- a/src/java/org/apache/fop/image/JimiImage.java +++ b/src/java/org/apache/fop/image/JimiImage.java @@ -76,8 +76,7 @@ public class JimiImage extends AbstractFopImage { protected void loadImage() { int[] tmpMap = null; try { - ImageProducer ip = - Jimi.getImageProducer(inputStream, + ImageProducer ip = Jimi.getImageProducer(inputStream, Jimi.SYNCHRONOUS | Jimi.IN_MEMORY); FopImageConsumer consumer = new FopImageConsumer(ip); ip.startProduction(consumer); @@ -163,8 +162,7 @@ public class JimiImage extends AbstractFopImage { // Should take care of the ColorSpace and bitsPerPixel - this.bitmapsSize = this.width * this.height * 3; - this.bitmaps = new byte[this.bitmapsSize]; + this.bitmaps = new byte[this.width * this.height * 3]; for (int i = 0; i < this.height; i++) { for (int j = 0; j < this.width; j++) { int p = tmpMap[i * this.width + j]; diff --git a/src/java/org/apache/fop/image/JpegImage.java b/src/java/org/apache/fop/image/JpegImage.java index 6a40e4495..ad4f6fe40 100644 --- a/src/java/org/apache/fop/image/JpegImage.java +++ b/src/java/org/apache/fop/image/JpegImage.java @@ -36,7 +36,6 @@ import org.apache.fop.util.CMYKColorSpace; public class JpegImage extends AbstractFopImage { private ICC_Profile iccProfile = null; private boolean foundICCProfile = false; - private boolean foundDimensions = false; /** * Create a jpeg image with the info. @@ -74,38 +73,38 @@ public class JpegImage extends AbstractFopImage { inputStream = null; } - this.bitmaps = baos.toByteArray(); + this.raw = baos.toByteArray(); this.bitsPerPixel = 8; this.isTransparent = false; //Check for SOI (Start of image) marker (FFD8) - if (this.bitmaps.length > (index + 2) - && uByte(this.bitmaps[index]) == 255 /*0xFF*/ - && uByte(this.bitmaps[index + 1]) == 216 /*0xD8*/) { + if (this.raw.length > (index + 2) + && uByte(this.raw[index]) == 255 /*0xFF*/ + && uByte(this.raw[index + 1]) == 216 /*0xD8*/) { index += 2; - while (index < this.bitmaps.length && cont) { + while (index < this.raw.length && cont) { //check to be sure this is the begining of a header - if (this.bitmaps.length > (index + 2) - && uByte(this.bitmaps[index]) == 255 /*0xFF*/) { + if (this.raw.length > (index + 2) + && uByte(this.raw[index]) == 255 /*0xFF*/) { //192 or 194 are the header bytes that contain // the jpeg width height and color depth. - if (uByte(this.bitmaps[index + 1]) == 192 /*0xC0*/ - || uByte(this.bitmaps[index + 1]) == 194 /*0xC2*/) { + if (uByte(this.raw[index + 1]) == 192 /*0xC0*/ + || uByte(this.raw[index + 1]) == 194 /*0xC2*/) { - this.height = calcBytes(this.bitmaps[index + 5], - this.bitmaps[index + 6]); - this.width = calcBytes(this.bitmaps[index + 7], - this.bitmaps[index + 8]); + this.height = calcBytes(this.raw[index + 5], + this.raw[index + 6]); + this.width = calcBytes(this.raw[index + 7], + this.raw[index + 8]); - if (this.bitmaps[index + 9] == 1) { + if (this.raw[index + 9] == 1) { this.colorSpace = ColorSpace.getInstance( ColorSpace.CS_GRAY); - } else if (this.bitmaps[index + 9] == 3) { + } else if (this.raw[index + 9] == 3) { this.colorSpace = ColorSpace.getInstance( ColorSpace.CS_LINEAR_RGB); - } else if (this.bitmaps[index + 9] == 4) { + } else if (this.raw[index + 9] == 4) { // howto create CMYK color space /* this.colorSpace = ColorSpace.getInstance( @@ -118,36 +117,35 @@ public class JpegImage extends AbstractFopImage { return false; } - foundDimensions = true; if (foundICCProfile) { cont = false; break; } - index += calcBytes(this.bitmaps[index + 2], - this.bitmaps[index + 3]) + 2; + index += calcBytes(this.raw[index + 2], + this.raw[index + 3]) + 2; - } else if (uByte(this.bitmaps[index + 1]) == 226 /*0xE2*/ - && this.bitmaps.length > (index + 60)) { + } else if (uByte(this.raw[index + 1]) == 226 /*0xE2*/ + && this.raw.length > (index + 60)) { // Check if ICC profile byte[] iccString = new byte[11]; - System.arraycopy(this.bitmaps, index + 4, + System.arraycopy(this.raw, index + 4, iccString, 0, 11); if ("ICC_PROFILE".equals(new String(iccString))) { int chunkSize = calcBytes( - this.bitmaps[index + 2], - this.bitmaps[index + 3]) + 2; + this.raw[index + 2], + this.raw[index + 3]) + 2; - iccStream.write(this.bitmaps, + iccStream.write(this.raw, index + 18, chunkSize - 18); } - index += calcBytes(this.bitmaps[index + 2], - this.bitmaps[index + 3]) + 2; + index += calcBytes(this.raw[index + 2], + this.raw[index + 3]) + 2; } else { - index += calcBytes(this.bitmaps[index + 2], - this.bitmaps[index + 3]) + 2; + index += calcBytes(this.raw[index + 2], + this.raw[index + 3]) + 2; } } else { diff --git a/src/java/org/apache/fop/image/TIFFImage.java b/src/java/org/apache/fop/image/TIFFImage.java index 6be59663b..7aa327c99 100644 --- a/src/java/org/apache/fop/image/TIFFImage.java +++ b/src/java/org/apache/fop/image/TIFFImage.java @@ -62,9 +62,7 @@ public class TIFFImage extends BatikImage { return stripCount; } - /** - * @see org.apache.fop.image.BatikImage#decodeImage(org.apache.batik.ext.awt.image.codec.SeekableStream) - */ + /** @see org.apache.fop.image.BatikImage */ protected CachableRed decodeImage(SeekableStream stream) throws IOException { org.apache.batik.ext.awt.image.codec.tiff.TIFFImage img = new org.apache.batik.ext.awt.image.codec.tiff.TIFFImage @@ -135,7 +133,7 @@ public class TIFFImage extends BatikImage { return false; } - this.bitmaps = readBuf; + this.raw = readBuf; return true; } catch (IOException ioe) { log.error("Error while loading image strip 1 (TIFF): ", ioe); diff --git a/src/java/org/apache/fop/render/pdf/FopPDFImage.java b/src/java/org/apache/fop/render/pdf/FopPDFImage.java index e38c9f111..97fee08f9 100644 --- a/src/java/org/apache/fop/render/pdf/FopPDFImage.java +++ b/src/java/org/apache/fop/render/pdf/FopPDFImage.java @@ -213,7 +213,11 @@ public class FopPDFImage implements PDFImage { if (isPS) { outputPostScriptContents(out); } else { - out.write(fopImage.getBitmaps()); + if (fopImage.getBitmapsSize() > 0) { + out.write(fopImage.getBitmaps()); + } else { + out.write(fopImage.getRessourceBytes()); + } } } diff --git a/src/java/org/apache/fop/render/ps/PSImageUtils.java b/src/java/org/apache/fop/render/ps/PSImageUtils.java index 30998d8ca..c620dafb1 100644 --- a/src/java/org/apache/fop/render/ps/PSImageUtils.java +++ b/src/java/org/apache/fop/render/ps/PSImageUtils.java @@ -66,7 +66,12 @@ public class PSImageUtils { } boolean iscolor = img.getColorSpace().getType() != ColorSpace.CS_GRAY; - byte[] imgmap = img.getBitmaps(); + byte[] imgmap; + if (img.getBitmapsSize() > 0) { + imgmap = img.getBitmaps(); + } else { + imgmap = img.getRessourceBytes(); + } gen.saveGraphicsState(); gen.writeln(x + " " + y + " translate"); -- 2.39.5