001/*
002 * $RCSfile: TIFFDeflateDecompressor.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:45 $
043 * $State: Exp $
044 */
045package com.github.jaiimageio.impl.plugins.tiff;
046
047import java.io.IOException;
048import java.util.zip.DataFormatException;
049import java.util.zip.Inflater;
050
051import javax.imageio.IIOException;
052
053import com.github.jaiimageio.plugins.tiff.BaselineTIFFTagSet;
054import com.github.jaiimageio.plugins.tiff.TIFFDecompressor;
055
056public class TIFFDeflateDecompressor extends TIFFDecompressor {
057
058    private static final boolean DEBUG = false;
059
060    Inflater inflater = null;
061    int predictor;
062
063    public TIFFDeflateDecompressor(int predictor) throws IIOException {
064        inflater = new Inflater();
065
066        if (predictor != BaselineTIFFTagSet.PREDICTOR_NONE && 
067            predictor != 
068            BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING) {
069            throw new IIOException("Illegal value for Predictor in " +
070                                   "TIFF file");
071        }
072
073        if(DEBUG) {
074            System.out.println("Using horizontal differencing predictor");
075        }
076
077        this.predictor = predictor;
078    }
079
080    public synchronized void decodeRaw(byte[] b,
081                                       int dstOffset,
082                                       int bitsPerPixel,
083                                       int scanlineStride) throws IOException {
084
085        // Check bitsPerSample.
086        if (predictor == 
087            BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING) {
088            int len = bitsPerSample.length;
089            for(int i = 0; i < len; i++) {
090                if(bitsPerSample[i] != 8) {
091                    throw new IIOException
092                        (bitsPerSample[i] + "-bit samples "+
093                         "are not supported for Horizontal "+
094                         "differencing Predictor");
095                }
096            }
097        }
098
099        // Seek to current tile data offset.
100        stream.seek(offset);
101
102        // Read the deflated data.
103        byte[] srcData = new byte[byteCount];
104        stream.readFully(srcData);
105
106        int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8;
107        byte[] buf;
108        int bufOffset;
109        if(bytesPerRow == scanlineStride) {
110            buf = b;
111            bufOffset = dstOffset;
112        } else {
113            buf = new byte[bytesPerRow*srcHeight];
114            bufOffset = 0;
115        }
116
117        // Set the input to the Inflater.
118        inflater.setInput(srcData);
119
120        // Inflate the data.
121        try {
122            inflater.inflate(buf, bufOffset, bytesPerRow*srcHeight);
123        } catch(DataFormatException dfe) {
124            throw new IIOException(I18N.getString("TIFFDeflateDecompressor0"),
125                                   dfe);
126        }
127
128        // Reset the Inflater.
129        inflater.reset();
130
131        if (predictor ==
132            BaselineTIFFTagSet.PREDICTOR_HORIZONTAL_DIFFERENCING) {
133            
134            for (int j = 0; j < srcHeight; j++) {
135                int count = bufOffset + samplesPerPixel * (j * srcWidth + 1);
136                for (int i=samplesPerPixel; i<srcWidth*samplesPerPixel; i++) {
137                    buf[count] += buf[count - samplesPerPixel];
138                    count++;
139                }
140            }
141        }
142
143        if(bytesPerRow != scanlineStride) {
144            if(DEBUG) {
145                System.out.println("bytesPerRow != scanlineStride");
146            }
147            int off = 0;
148            for (int y = 0; y < srcHeight; y++) {
149                System.arraycopy(buf, off, b, dstOffset, bytesPerRow);
150                off += bytesPerRow;
151                dstOffset += scanlineStride;
152            }
153        }
154    }
155}