001: /*
002: * $RCSfile: TIFFRLECompressor.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:49 $
043: * $State: Exp $
044: */
045: package com.sun.media.imageioimpl.plugins.tiff;
046:
047: import com.sun.media.imageio.plugins.tiff.BaselineTIFFTagSet;
048: import com.sun.media.imageio.plugins.tiff.TIFFCompressor;
049: import java.io.IOException;
050: import javax.imageio.IIOException;
051:
052: /**
053: *
054: */
055: public class TIFFRLECompressor extends TIFFFaxCompressor {
056:
057: public TIFFRLECompressor() {
058: super ("CCITT RLE", BaselineTIFFTagSet.COMPRESSION_CCITT_RLE,
059: true);
060: }
061:
062: /**
063: * Encode a row of data using Modified Huffman Compression also known as
064: * CCITT RLE (Run Lenth Encoding).
065: *
066: * @param data The row of data to compress.
067: * @param rowOffset Starting index in <code>data</code>.
068: * @param colOffset Bit offset within first <code>data[rowOffset]</code>.
069: * @param rowLength Number of bits in the row.
070: * @param compData The compressed data.
071: *
072: * @return The number of bytes saved in the compressed data array.
073: */
074: public int encodeRLE(byte[] data, int rowOffset, int colOffset,
075: int rowLength, byte[] compData) {
076: //
077: // Initialize bit buffer machinery.
078: //
079: initBitBuf();
080:
081: //
082: // Run-length encode line.
083: //
084: int outIndex = encode1D(data, rowOffset, colOffset, rowLength,
085: compData, 0);
086:
087: //
088: // Flush pending bits
089: //
090: while (ndex > 0) {
091: compData[outIndex++] = (byte) (bits >>> 24);
092: bits <<= 8;
093: ndex -= 8;
094: }
095:
096: //
097: // Flip the bytes if inverse fill was requested.
098: //
099: if (inverseFill) {
100: byte[] flipTable = TIFFFaxDecompressor.flipTable;
101: for (int i = 0; i < outIndex; i++) {
102: compData[i] = flipTable[compData[i] & 0xff];
103: }
104: }
105:
106: return outIndex;
107: }
108:
109: public int encode(byte[] b, int off, int width, int height,
110: int[] bitsPerSample, int scanlineStride) throws IOException {
111: if (bitsPerSample.length != 1 || bitsPerSample[0] != 1) {
112: throw new IIOException(
113: "Bits per sample must be 1 for RLE compression!");
114: }
115:
116: // In the worst case, 2 bits of input will result in 9 bits of output,
117: // plus 2 extra bits if the row starts with black.
118: int maxBits = 9 * ((width + 1) / 2) + 2;
119: byte[] compData = new byte[(maxBits + 7) / 8];
120:
121: int bytes = 0;
122: int rowOffset = off;
123:
124: for (int i = 0; i < height; i++) {
125: int rowBytes = encodeRLE(b, rowOffset, 0, width, compData);
126: stream.write(compData, 0, rowBytes);
127:
128: rowOffset += scanlineStride;
129: bytes += rowBytes;
130: }
131:
132: return bytes;
133: }
134: }
|