001: /*
002: * $RCSfile: TIFFCodecLibFaxDecompressor.java,v $
003: *
004: *
005: * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * - Redistribution of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * - Redistribution in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * Neither the name of Sun Microsystems, Inc. or the names of
020: * contributors may be used to endorse or promote products derived
021: * from this software without specific prior written permission.
022: *
023: * This software is provided "AS IS," without a warranty of any
024: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
025: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
026: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
027: * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
028: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
029: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
030: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
031: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
032: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
033: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
034: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
035: * POSSIBILITY OF SUCH DAMAGES.
036: *
037: * You acknowledge that this software is not designed or intended for
038: * use in the design, construction, operation or maintenance of any
039: * nuclear facility.
040: *
041: * $Revision: 1.1 $
042: * $Date: 2005/02/11 05:01:44 $
043: * $State: Exp $
044: */
045: package com.sun.media.imageioimpl.plugins.tiff;
046:
047: import java.io.IOException;
048: import com.sun.media.imageio.plugins.tiff.BaselineTIFFTagSet;
049: import com.sun.media.imageio.plugins.tiff.TIFFDecompressor;
050:
051: public class TIFFCodecLibFaxDecompressor extends TIFFFaxDecompressor {
052:
053: private static final boolean DEBUG = false; // XXX 'false' for release!!!
054:
055: /**
056: * com.sun.medialib.codec.g3fax.Decoder for T.4 or
057: * com.sun.medialib.codec.g4fax.Decoder for T.6.
058: */
059: private Object decoder = null;
060:
061: /**
062: * Constructor which initializes the internal codecLib decoder.
063: *
064: * @throws RuntimeException if <code>bilevelCompression</code> is
065: * not T.4 or T.6 compression or if codecLib is not available.
066: */
067: public TIFFCodecLibFaxDecompressor(int bilevelCompression) {
068: super ();
069:
070: try {
071: // 'compression' is set in the superclass method.
072: if (bilevelCompression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_4) {
073: com.sun.medialib.codec.g3fax.Decoder decoder = new com.sun.medialib.codec.g3fax.Decoder();
074: this .decoder = decoder;
075: } else if (bilevelCompression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_6) {
076: com.sun.medialib.codec.g4fax.Decoder decoder = new com.sun.medialib.codec.g4fax.Decoder();
077: this .decoder = decoder;
078: } else {
079: throw new RuntimeException("Unknown compression = "
080: + bilevelCompression);
081: }
082: } catch (Throwable e) {
083: throw new RuntimeException("CodecLib not available");
084: }
085: }
086:
087: public synchronized final void decodeRaw(byte[] b, int dstOffset,
088: int pixelBitStride, // always 1
089: int scanlineStride) throws IOException {
090:
091: int bytesPerRow = (srcWidth + 7) / 8;
092: byte[] image = null;
093: byte[] code = new byte[byteCount];
094: stream.seek(offset);
095: stream.readFully(code, 0, byteCount);
096:
097: // Flip the bytes if fill order is LSB-to-MSB.
098: if (fillOrder == 2) {
099: for (int i = 0; i < byteCount; i++) {
100: code[i] = flipTable[code[i] & 0xff];
101: }
102: }
103:
104: if (dstOffset == 0 && bytesPerRow == scanlineStride) {
105: image = b;
106: } else {
107: image = new byte[srcWidth * srcHeight];
108: }
109:
110: if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_6) {
111: com.sun.medialib.codec.g4fax.Decoder decoder = (com.sun.medialib.codec.g4fax.Decoder) this .decoder;
112:
113: if (DEBUG) {
114: System.out.println("Using MediaLib G4 decoder");
115: }
116:
117: int result = com.sun.medialib.codec.g4fax.Constants.G4FAX_FAILURE;
118: try {
119: result = decoder.decode(image, code, srcWidth,
120: srcHeight, 0);
121: } catch (Throwable t) {
122: ((TIFFImageReader) reader)
123: .forwardWarningMessage("codecLib T.6 decompressor failed; falling back to Java.");
124: result = com.sun.medialib.codec.g4fax.Constants.G4FAX_FAILURE;
125: }
126:
127: if (result == com.sun.medialib.codec.g4fax.Constants.G4FAX_FAILURE) {
128: // Fall back to Java decoder.
129: if (DEBUG) {
130: System.out
131: .println("Falling back to Java G4 decoder");
132: }
133: super .decodeRaw(b, dstOffset, pixelBitStride,
134: scanlineStride);
135: return;
136: }
137: } else {
138: com.sun.medialib.codec.g3fax.Decoder decoder = (com.sun.medialib.codec.g3fax.Decoder) this .decoder;
139: if (DEBUG) {
140: System.out.println("Using MediaLib G3 decoder");
141: }
142:
143: int decodingFlags = 0;
144: if (oneD == 1) {
145: decodingFlags = decoder.G3FAX_VERTICAL_CODING
146: | decoder.G3FAX_NORTC;
147: if (DEBUG) {
148: System.out.print("G3FAX_VERTICAL_CODING"
149: + " | G3FAX_NORTC");
150: }
151: } else {
152: decodingFlags = decoder.G3FAX_HORIZONTAL_CODING
153: | decoder.G3FAX_NORTC;
154: if (DEBUG) {
155: System.out.print("G3FAX_HORIZONTAL_CODING"
156: + " | G3FAX_NORTC");
157: }
158: }
159:
160: if (fillBits == 1) {
161: if (DEBUG) {
162: System.out.print(" | G3FAX_EOLPADDING_CODING");
163: }
164: decodingFlags |= decoder.G3FAX_EOLPADDING;
165: }
166:
167: if (DEBUG) {
168: System.out.println("");
169: }
170:
171: int result = com.sun.medialib.codec.g3fax.Constants.G3FAX_FAILURE;
172: try {
173: result = decoder.decode(image, code, srcWidth,
174: srcHeight, decodingFlags);
175: } catch (Throwable t) {
176: ((TIFFImageReader) reader)
177: .forwardWarningMessage("codecLib T.4 decompressor failed; falling back to Java.");
178: result = com.sun.medialib.codec.g3fax.Constants.G3FAX_FAILURE;
179: }
180:
181: if (result == com.sun.medialib.codec.g3fax.Constants.G3FAX_FAILURE) {
182: // Fall back to Java decoder.
183: if (DEBUG) {
184: System.out
185: .println("Falling back to Java G3 decoder");
186: }
187: super .decodeRaw(b, dstOffset, pixelBitStride,
188: scanlineStride);
189: return;
190: }
191: }
192:
193: if (image != b) {
194: int srcOffset = 0;
195: for (int row = 0; row < srcHeight; row++) {
196: System.arraycopy(image, srcOffset, b, dstOffset,
197: bytesPerRow);
198: srcOffset += bytesPerRow;
199: dstOffset += scanlineStride;
200: }
201: }
202: }
203: }
|