001/* 002 * $RCSfile: TIFFCompressor.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:18 $ 043 * $State: Exp $ 044 */ 045package com.github.jaiimageio.plugins.tiff; 046 047import java.io.IOException; 048 049import javax.imageio.ImageWriter; 050import javax.imageio.metadata.IIOMetadata; 051import javax.imageio.stream.ImageOutputStream; 052 053import com.github.jaiimageio.impl.plugins.tiff.TIFFImageWriter; 054 055/** 056 * An abstract superclass for pluggable TIFF compressors. 057 */ 058public abstract class TIFFCompressor { 059 060 /** 061 * The <code>ImageWriter</code> calling this 062 * <code>TIFFCompressor</code>. 063 */ 064 protected ImageWriter writer; 065 066 /** 067 * The <code>IIOMetadata</code> object containing metadata for the 068 * current image. 069 */ 070 protected IIOMetadata metadata; 071 072 /** 073 * The name of the compression type supported by this compressor. 074 */ 075 protected String compressionType; 076 077 /** 078 * The value to be assigned to the TIFF <i>Compression</i> tag in the 079 * TIFF image metadata. 080 */ 081 protected int compressionTagValue; 082 083 /** 084 * Whether the compression is lossless. 085 */ 086 protected boolean isCompressionLossless; 087 088 /** 089 * The <code>ImageOutputStream</code> to be written. 090 */ 091 protected ImageOutputStream stream; 092 093 /** 094 * Creates a compressor object for use in compressing TIFF data. This 095 * object may be passed to the 096 * {@link TIFFImageWriteParam#setTIFFCompressor(TIFFCompressor)} 097 * method to override the compressor of a supported compression type or 098 * to provide the implementation of the compression algorithm of an 099 * unsupported compression type. 100 * 101 * <p>The parameters <code>compressionTagValue</code> and 102 * <code>isCompressionLossless</code> are provided to accomodate 103 * compression types which are unknown. A compression type is 104 * "known" if it is either among those already supported by the 105 * TIFF writer (see {@link TIFFImageWriteParam}), or is listed in 106 * the TIFF 6.0 specification but not supported. If the compression 107 * type is unknown, the <code>compressionTagValue</code> and 108 * <code>isCompressionLossless</code> parameters are ignored.</p> 109 * 110 * @param compressionType The name of the compression type. 111 * @param compressionTagValue The value to be assigned to the TIFF 112 * <i>Compression</i> tag in the TIFF image metadata; ignored if 113 * <code>compressionType</code> is a known type. 114 * @param isCompressionLossless Whether the compression is lossless; 115 * ignored if <code>compressionType</code> is a known type. 116 * 117 * @throws IllegalArgumentException if <code>compressionType</code> is 118 * <code>null</code> or <code>compressionTagValue</code> is less than 119 * <code>1</code>. 120 */ 121 public TIFFCompressor(String compressionType, 122 int compressionTagValue, 123 boolean isCompressionLossless) { 124 if(compressionType == null) { 125 throw new IllegalArgumentException("compressionType == null"); 126 } else if(compressionTagValue < 1) { 127 throw new IllegalArgumentException("compressionTagValue < 1"); 128 } 129 130 // Set the compression type. 131 this.compressionType = compressionType; 132 133 // Determine whether this type is either defined in the TIFF 6.0 134 // specification or is already supported. 135 int compressionIndex = -1; 136 String[] compressionTypes = TIFFImageWriter.compressionTypes; 137 int len = compressionTypes.length; 138 for(int i = 0; i < len; i++) { 139 if(compressionTypes[i].equals(compressionType)) { 140 // Save the index of the supported type. 141 compressionIndex = i; 142 break; 143 } 144 } 145 146 if(compressionIndex != -1) { 147 // Known compression type. 148 this.compressionTagValue = 149 TIFFImageWriter.compressionNumbers[compressionIndex]; 150 this.isCompressionLossless = 151 TIFFImageWriter.isCompressionLossless[compressionIndex]; 152 } else { 153 // Unknown compression type. 154 this.compressionTagValue = compressionTagValue; 155 this.isCompressionLossless = isCompressionLossless; 156 } 157 } 158 159 /** 160 * Retrieve the name of the compression type supported by this compressor. 161 * 162 * @return The compression type name. 163 */ 164 public String getCompressionType() { 165 return compressionType; 166 } 167 168 /** 169 * Retrieve the value to be assigned to the TIFF <i>Compression</i> tag 170 * in the TIFF image metadata. 171 * 172 * @return The <i>Compression</i> tag value. 173 */ 174 public int getCompressionTagValue() { 175 return compressionTagValue; 176 } 177 178 /** 179 * Retrieves a value indicating whether the compression is lossless. 180 * 181 * @return Whether the compression is lossless. 182 */ 183 public boolean isCompressionLossless() { 184 return isCompressionLossless; 185 } 186 187 /** 188 * Sets the <code>ImageOutputStream</code> to be written. 189 * 190 * @param stream an <code>ImageOutputStream</code> to be written. 191 * 192 * @see #getStream 193 */ 194 public void setStream(ImageOutputStream stream) { 195 this.stream = stream; 196 } 197 198 /** 199 * Returns the <code>ImageOutputStream</code> that will be written. 200 * 201 * @return an <code>ImageOutputStream</code>. 202 * 203 * @see #setStream(ImageOutputStream) 204 */ 205 public ImageOutputStream getStream() { 206 return stream; 207 } 208 209 /** 210 * Sets the value of the <code>writer</code> field. 211 * 212 * @param writer the current <code>ImageWriter</code>. 213 * 214 * @see #getWriter() 215 */ 216 public void setWriter(ImageWriter writer) { 217 this.writer = writer; 218 } 219 220 /** 221 * Returns the current <code>ImageWriter</code>. 222 * 223 * @return an <code>ImageWriter</code>. 224 * 225 * @see #setWriter(ImageWriter) 226 */ 227 public ImageWriter getWriter() { 228 return this.writer; 229 } 230 231 /** 232 * Sets the value of the <code>metadata</code> field. 233 * 234 * @param metadata the <code>IIOMetadata</code> object for the 235 * image being written. 236 * 237 * @see #getMetadata() 238 */ 239 public void setMetadata(IIOMetadata metadata) { 240 this.metadata = metadata; 241 } 242 243 /** 244 * Returns the current <code>IIOMetadata</code> object. 245 * 246 * @return the <code>IIOMetadata</code> object for the image being 247 * written. 248 * 249 * @see #setMetadata(IIOMetadata) 250 */ 251 public IIOMetadata getMetadata() { 252 return this.metadata; 253 } 254 255 /** 256 * Encodes the supplied image data, writing to the currently set 257 * <code>ImageOutputStream</code>. 258 * 259 * @param b an array of <code>byte</code>s containing the packed 260 * but uncompressed image data. 261 * @param off the starting offset of the data to be written in the 262 * array <code>b</code>. 263 * @param width the width of the rectangle of pixels to be written. 264 * @param height the height of the rectangle of pixels to be written. 265 * @param bitsPerSample an array of <code>int</code>s indicting 266 * the number of bits used to represent each image sample within 267 * a pixel. 268 * @param scanlineStride the number of bytes separating each 269 * row of the input data. 270 * 271 * @return the number of bytes written. 272 * 273 * @throws IOException if the supplied data cannot be encoded by 274 * this <code>TIFFCompressor</code>, or if any I/O error occurs 275 * during writing. 276 */ 277 public abstract int encode(byte[] b, int off, 278 int width, int height, 279 int[] bitsPerSample, 280 int scanlineStride) throws IOException; 281 282 /** 283 * Allows any resources held by this object to be released. The 284 * result of calling any other method (other than 285 * <code>finalize</code>) subsequent to a call to this method 286 * is undefined. 287 * 288 * <p>It is important for applications to call this method when they 289 * know they will no longer be using this <code>TIFFCompressor</code>. 290 * Otherwise, the writer may continue to hold on to resources 291 * indefinitely. 292 * 293 * <p>The default implementation of this method in the superclass does 294 * nothing. Subclass implementations should ensure that all resources, 295 * especially native resources, are released. 296 */ 297 public void dispose() { 298 } 299 300}