001/* 002 * Copyright 2003-2008 by Paulo Soares. 003 * 004 * This code was originally released in 2001 by SUN (see class 005 * com.sun.media.imageio.plugins.tiff.TIFFDirectory.java) 006 * using the BSD license in a specific wording. In a mail dating from 007 * January 23, 2008, Brian Burkhalter (@sun.com) gave us permission 008 * to use the code under the following version of the BSD license: 009 * 010 * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved. 011 * 012 * Redistribution and use in source and binary forms, with or without 013 * modification, are permitted provided that the following conditions 014 * are met: 015 * 016 * - Redistribution of source code must retain the above copyright 017 * notice, this list of conditions and the following disclaimer. 018 * 019 * - Redistribution in binary form must reproduce the above copyright 020 * notice, this list of conditions and the following disclaimer in 021 * the documentation and/or other materials provided with the 022 * distribution. 023 * 024 * Neither the name of Sun Microsystems, Inc. or the names of 025 * contributors may be used to endorse or promote products derived 026 * from this software without specific prior written permission. 027 * 028 * This software is provided "AS IS," without a warranty of any 029 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND 030 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, 031 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY 032 * EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL 033 * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF 034 * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS 035 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR 036 * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, 037 * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND 038 * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR 039 * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE 040 * POSSIBILITY OF SUCH DAMAGES. 041 * 042 * You acknowledge that this software is not designed or intended for 043 * use in the design, construction, operation or maintenance of any 044 * nuclear facility. 045 * 046 * $Revision: 4540 $ 047 * $Date: 2010-07-13 05:57:54 -0700 (Tue, 13 Jul 2010) $ 048 * $State: Exp $ 049 */ 050 051package com.itextpdf.text.pdf.codec; 052 053import java.io.IOException; 054import java.io.OutputStream; 055 056/** 057 * Modified from original LZWCompressor to change interface to passing a 058 * buffer of data to be compressed. 059 * @since 5.0.2 060 */ 061public class LZWCompressor 062{ 063 /** base underlying code size of data being compressed 8 for TIFF, 1 to 8 for GIF **/ 064 int codeSize_; 065 066 /** reserved clear code based on code size **/ 067 int clearCode_; 068 069 /** reserved end of data code based on code size **/ 070 int endOfInfo_; 071 072 /** current number bits output for each code **/ 073 int numBits_; 074 075 /** limit at which current number of bits code size has to be increased **/ 076 int limit_; 077 078 /** the prefix code which represents the predecessor string to current input point **/ 079 short prefix_; 080 081 /** output destination for bit codes **/ 082 BitFile bf_; 083 084 /** general purpose LZW string table **/ 085 LZWStringTable lzss_; 086 087 /** modify the limits of the code values in LZW encoding due to TIFF bug / feature **/ 088 boolean tiffFudge_; 089 090 /** 091 * @param out destination for compressed data 092 * @param codeSize the initial code size for the LZW compressor 093 * @param TIFF flag indicating that TIFF lzw fudge needs to be applied 094 * @exception IOException if underlying output stream error 095 **/ 096 public LZWCompressor(OutputStream out, int codeSize, boolean TIFF) throws IOException 097 { 098 bf_ = new BitFile(out, !TIFF); // set flag for GIF as NOT tiff 099 codeSize_ = codeSize; 100 tiffFudge_ = TIFF; 101 clearCode_ = 1 << codeSize_; 102 endOfInfo_ = clearCode_ + 1; 103 numBits_ = codeSize_ + 1; 104 105 limit_ = (1 << numBits_) - 1; 106 if (tiffFudge_) 107 --limit_; 108 109 prefix_ = (short)0xFFFF; 110 lzss_ = new LZWStringTable(); 111 lzss_.ClearTable(codeSize_); 112 bf_.writeBits(clearCode_, numBits_); 113 } 114 115 /** 116 * @param buf data to be compressed to output stream 117 * @exception IOException if underlying output stream error 118 **/ 119 public void compress(byte[] buf, int offset, int length) 120 throws IOException 121 { 122 int idx; 123 byte c; 124 short index; 125 126 int maxOffset = offset + length; 127 for (idx = offset; idx < maxOffset; ++idx) 128 { 129 c = buf[idx]; 130 if ((index = lzss_.FindCharString(prefix_, c)) != -1) 131 prefix_ = index; 132 else 133 { 134 bf_.writeBits(prefix_, numBits_); 135 if (lzss_.AddCharString(prefix_, c) > limit_) 136 { 137 if (numBits_ == 12) 138 { 139 bf_.writeBits(clearCode_, numBits_); 140 lzss_.ClearTable(codeSize_); 141 numBits_ = codeSize_ + 1; 142 } 143 else 144 ++numBits_; 145 146 limit_ = (1 << numBits_) - 1; 147 if (tiffFudge_) 148 --limit_; 149 } 150 prefix_ = (short)((short)c & 0xFF); 151 } 152 } 153 } 154 155 /** 156 * Indicate to compressor that no more data to go so write out 157 * any remaining buffered data. 158 * 159 * @exception IOException if underlying output stream error 160 **/ 161 public void flush() throws IOException 162 { 163 if (prefix_ != -1) 164 bf_.writeBits(prefix_, numBits_); 165 166 bf_.writeBits(endOfInfo_, numBits_); 167 bf_.flush(); 168 } 169}