001    /*
002     * TIFFDecoderPackbits
003     * 
004     * Copyright (c) 2002, 2003 Marco Schmidt.
005     * All rights reserved.
006     */
007    
008    package net.sourceforge.jiu.codecs.tiff;
009    
010    import java.io.DataInput;
011    import java.io.IOException;
012    import net.sourceforge.jiu.codecs.tiff.TIFFDecoder;
013    import net.sourceforge.jiu.codecs.InvalidFileStructureException;
014    
015    /**
016     * A TIFF decoder for files compressed with the <em>Packbits</em> method.
017     * This compression algorithm has the value <code>32773</code> 
018     * in the compression tag of an image file directory.
019     * @author Marco Schmidt
020     * @since 0.9.0
021     */
022    public class TIFFDecoderPackbits extends TIFFDecoder
023    {
024            public void decode() throws 
025                    InvalidFileStructureException,
026                    IOException
027            {
028                    DataInput in = getInput();
029                    byte[] row = new byte[getBytesPerRow()];
030                    for (int y = getY1(); y <= getY2(); y++)
031                    {
032                            int index = 0;
033                            do
034                            {
035                                    byte value = in.readByte();
036                                    if (value >= 0)
037                                    {
038                                            int numSamples = value + 1;
039                                            // copy bytes literally
040                                            in.readFully(row, index, numSamples);
041                                            index += numSamples;
042                                    }
043                                    else
044                                    if (value != (byte)-128)
045                                    {
046                                            int numSamples = - value + 1;
047                                            // write run
048                                            byte sample = in.readByte();
049                                            while (numSamples-- != 0)
050                                            {
051                                                    row[index++] = sample;
052                                            }
053                                    }
054                            }
055                            while (index != row.length);
056                            putBytes(row, 0, row.length);
057                    }
058            }
059    
060    
061            public Integer[] getCompressionTypes()
062            {
063                    return new Integer[] {new Integer(TIFFConstants.COMPRESSION_PACKBITS)};
064            }
065    }