Author: damjan Date: Sat Mar 17 09:42:36 2012 New Revision: 1301903 URL: http://svn.apache.org/viewvc?rev=1301903&view=rev Log: Make BitInputStream sensitive to byte order. Allows 48 BPP TIFF files to load.
Jira issue key: SANSELAN-66 Submitted by: Piyush Kapoor <pkapoor at adobe dot com> Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/BinaryFileParser.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/BitInputStream.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageData.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageParser.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/datareaders/DataReaderStrips.java commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/datareaders/DataReaderTiled.java Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java?rev=1301903&r1=1301902&r2=1301903&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/SanselanConstants.java Sat Mar 17 09:42:36 2012 @@ -123,4 +123,12 @@ public interface SanselanConstants * Valid values: PixelDensity */ public static final String PARAM_KEY_PIXEL_DENSITY = "PIXEL_DENSITY"; + + /** + * Parameter key. Used in Tiff operations to use the byte order + * of the Tiff image. + * <p> + * Valid values: any Integer + */ + public static final String BYTE_ORDER = "BYTE_ORDER"; } Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/BinaryFileParser.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/BinaryFileParser.java?rev=1301903&r1=1301902&r2=1301903&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/BinaryFileParser.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/BinaryFileParser.java Sat Mar 17 09:42:36 2012 @@ -57,7 +57,7 @@ public class BinaryFileParser extends Bi this.byteOrder = byteOrder; } - protected int getByteOrder() + public int getByteOrder() { return byteOrder; } Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/BitInputStream.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/BitInputStream.java?rev=1301903&r1=1301902&r2=1301903&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/BitInputStream.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/common/BitInputStream.java Sat Mar 17 09:42:36 2012 @@ -21,13 +21,14 @@ import java.io.InputStream; public class BitInputStream extends InputStream implements BinaryConstants { - // TODO should be byte order conscious, ie TIFF for reading - // samples size<8 - shuoldn't that effect their order within byte? + private final InputStream is; + private final int byteOrder; - public BitInputStream(InputStream is) + public BitInputStream(InputStream is, int byteOrder) { this.is = is; + this.byteOrder = byteOrder; // super(is); } @@ -88,25 +89,53 @@ public class BitInputStream extends Inpu bytes_read++; return is.read(); } + + /** + * Taking default order of the Tiff to be + * Little Endian and reversing the bytes in the end + * if its Big Endian.This is done because majority (may be all) + * of the files will be of Little Endian. + */ + if(byteOrder == BYTE_ORDER_BIG_ENDIAN) { + if (count == 16) + { + bytes_read += 2; + return (is.read() << 8) | (is.read() << 0); + } - if (count == 16) - { - bytes_read += 2; - return (is.read() << 8) | (is.read() << 0); - } - - if (count == 24) - { - bytes_read += 3; - return (is.read() << 16) | (is.read() << 8) | (is.read() << 0); - } + if (count == 24) + { + bytes_read += 3; + return (is.read() << 16) | (is.read() << 8) | (is.read() << 0); + } - if (count == 32) + if (count == 32) + { + bytes_read += 4; + return (is.read() << 24) | (is.read() << 16) | (is.read() << 8) + | (is.read() << 0); + } + } + else { - bytes_read += 4; - return (is.read() << 24) | (is.read() << 16) | (is.read() << 8) - | (is.read() << 0); - } + if(count == 16) + { + bytes_read +=2; + return ((is.read() << 0) | (is.read() << 8)); + } + + if(count == 24) + { + bytes_read += 3; + return ((is.read() << 0) | (is.read() << 8) | (is.read() << 16)); + } + + if(count == 32) + { + bytes_read += 4; + return ((is.read() << 0) | (is.read() << 8) | (is.read() << 16) | (is.read() << 24)); + } + } throw new IOException("BitInputStream: unknown error"); } Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageData.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageData.java?rev=1301903&r1=1301902&r2=1301903&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageData.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageData.java Sat Mar 17 09:42:36 2012 @@ -55,12 +55,12 @@ public abstract class TiffImageData public DataReader getDataReader(TiffDirectory directory, PhotometricInterpreter photometricInterpreter, int bitsPerPixel, int bitsPerSample[], int predictor, - int samplesPerPixel, int width, int height, int compression) + int samplesPerPixel, int width, int height, int compression, int byteOrder) throws IOException, ImageReadException { return new DataReaderTiled(directory, photometricInterpreter, tileWidth, tileLength, bitsPerPixel, bitsPerSample, - predictor, samplesPerPixel, width, height, compression, this); + predictor, samplesPerPixel, width, height, compression, byteOrder, this); } // public TiffElement[] getElements() @@ -95,12 +95,12 @@ public abstract class TiffImageData public DataReader getDataReader(TiffDirectory directory, PhotometricInterpreter photometricInterpreter, int bitsPerPixel, int bitsPerSample[], int predictor, - int samplesPerPixel, int width, int height, int compression) + int samplesPerPixel, int width, int height, int compression, int byteorder) throws IOException, ImageReadException { return new DataReaderStrips(directory, photometricInterpreter, bitsPerPixel, bitsPerSample, predictor, samplesPerPixel, - width, height, compression, rowsPerStrip, this); + width, height, compression,byteorder, rowsPerStrip, this); } // public TiffElement[] getElements() @@ -119,7 +119,7 @@ public abstract class TiffImageData public abstract DataReader getDataReader(TiffDirectory directory, PhotometricInterpreter photometricInterpreter, int bitsPerPixel, int bitsPerSample[], int predictor, int samplesPerPixel, int width, - int height, int compression) throws IOException, ImageReadException; + int height, int compression, int byteOrder) throws IOException, ImageReadException; public static class Data extends TiffElement.DataElement { Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageParser.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageParser.java?rev=1301903&r1=1301902&r2=1301903&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageParser.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/TiffImageParser.java Sat Mar 17 09:42:36 2012 @@ -24,6 +24,7 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -441,9 +442,14 @@ public class TiffImageParser extends Ima throws ImageReadException, IOException { FormatCompliance formatCompliance = FormatCompliance.getDefault(); - TiffContents contents = new TiffReader(isStrict(params)) - .readFirstDirectory(byteSource, params, true, formatCompliance); + TiffReader reader = new TiffReader(isStrict(params)); + int byteOrder = reader.getByteOrder(); + TiffContents contents = reader.readFirstDirectory(byteSource, params, true, formatCompliance); TiffDirectory directory = contents.directories.get(0); + if(params == null) { + params = new HashMap<String, Integer>(); + } + params.put(BYTE_ORDER, byteOrder); BufferedImage result = directory.getTiffImage(params); if (null == result) throw new ImageReadException("TIFF does not contain an image."); @@ -472,7 +478,17 @@ public class TiffImageParser extends Ima throws ImageReadException, IOException { List<TiffField> entries = directory.entries; - + + int byteOrder = BYTE_ORDER_LITTLE_ENDIAN; //taking little endian to be default + if(params != null){ + if(params.containsKey(BYTE_ORDER)) { + Object obj = params.get(BYTE_ORDER); + if(obj instanceof Integer) { + Integer a = (Integer)obj; + byteOrder = a.intValue(); + } + } + } if (entries == null) throw new ImageReadException("TIFF missing entries"); @@ -528,7 +544,7 @@ public class TiffImageParser extends Ima DataReader dataReader = imageData.getDataReader(directory, photometricInterpreter, bitsPerPixel, bitsPerSample, predictor, - samplesPerPixel, width, height, compression); + samplesPerPixel, width, height, compression, byteOrder); dataReader.readImageData(imageBuilder); Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/datareaders/DataReaderStrips.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/datareaders/DataReaderStrips.java?rev=1301903&r1=1301902&r2=1301903&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/datareaders/DataReaderStrips.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/datareaders/DataReaderStrips.java Sat Mar 17 09:42:36 2012 @@ -32,6 +32,7 @@ public final class DataReaderStrips exte private final int bitsPerPixel; private final int compression; private final int rowsPerStrip; + private final int byteOrder; private final TiffImageData.Strips imageData; @@ -39,7 +40,7 @@ public final class DataReaderStrips exte PhotometricInterpreter photometricInterpreter, int bitsPerPixel, int bitsPerSample[], int predictor, int samplesPerPixel, int width, int height, int compression, - int rowsPerStrip, TiffImageData.Strips imageData) + int byteOrder, int rowsPerStrip, TiffImageData.Strips imageData) { super(directory, photometricInterpreter, bitsPerSample, predictor, samplesPerPixel, width, height); @@ -47,13 +48,14 @@ public final class DataReaderStrips exte this.compression = compression; this.rowsPerStrip = rowsPerStrip; this.imageData = imageData; + this.byteOrder = byteOrder; } private void interpretStrip(ImageBuilder imageBuilder, byte bytes[], int pixels_per_strip) throws ImageReadException, IOException { ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - BitInputStream bis = new BitInputStream(bais); + BitInputStream bis = new BitInputStream(bais, byteOrder); if (y >= height) { return; Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/datareaders/DataReaderTiled.java URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/datareaders/DataReaderTiled.java?rev=1301903&r1=1301902&r2=1301903&view=diff ============================================================================== --- commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/datareaders/DataReaderTiled.java (original) +++ commons/proper/sanselan/trunk/src/main/java/org/apache/commons/sanselan/formats/tiff/datareaders/DataReaderTiled.java Sat Mar 17 09:42:36 2012 @@ -35,6 +35,7 @@ public final class DataReaderTiled exten private final int bitsPerPixel; private final int compression; + private final int byteOrder; private final TiffImageData.Tiles imageData; @@ -42,7 +43,7 @@ public final class DataReaderTiled exten PhotometricInterpreter photometricInterpreter, int tileWidth, int tileLength, int bitsPerPixel, int bitsPerSample[], int predictor, int samplesPerPixel, int width, - int height, int compression, TiffImageData.Tiles imageData) + int height, int compression, int byteOrder, TiffImageData.Tiles imageData) { super(directory, photometricInterpreter, bitsPerSample, predictor, samplesPerPixel, width, height); @@ -53,13 +54,14 @@ public final class DataReaderTiled exten this.compression = compression; this.imageData = imageData; + this.byteOrder = byteOrder; } private void interpretTile(ImageBuilder imageBuilder, byte bytes[], int startX, int startY) throws ImageReadException, IOException { ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - BitInputStream bis = new BitInputStream(bais); + BitInputStream bis = new BitInputStream(bais, byteOrder); int pixelsPerTile = tileWidth * tileLength;