1 /* 2 * $RCSfile: TIFFDescriptor.java,v $ 3 * 4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 5 * 6 * Use is subject to license terms. 7 * 8 * $Revision: 1.1 $ 9 * $Date: 2005/02/11 04:57:45 $ 10 * $State: Exp $ 11 */ 12 package com.lightcrafts.mediax.jai.operator; 13 import com.lightcrafts.media.jai.codec.SeekableStream; 14 import com.lightcrafts.media.jai.codec.TIFFDecodeParam; 15 import java.awt.RenderingHints; 16 import java.awt.image.renderable.ParameterBlock; 17 import com.lightcrafts.mediax.jai.JAI; 18 import com.lightcrafts.mediax.jai.OperationDescriptorImpl; 19 import com.lightcrafts.mediax.jai.ParameterBlockJAI; 20 import com.lightcrafts.mediax.jai.RenderedOp; 21 import com.lightcrafts.mediax.jai.registry.RenderedRegistryMode; 22 23 /** 24 * An <code>OperationDescriptor</code> describing the "TIFF" operation. 25 * 26 * <p> The "TIFF" operation reads TIFF data from a <code>SeekableStream</code>. 27 * 28 * <p><a href="http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf"> 29 * TIFF version 6.0</a> was finalized in June, 1992. Since that time 30 * there have been two technical notes extending the specification. 31 * There are also a number of 32 * <a href="http://home.earthlink.net/~ritter/tiff/#extensions"> 33 * TIFF Extensions</a> including 34 * <a href="http://www.remotesensing.org/geotiff/geotiff.html"> 35 * GeoTIFF</a>. 36 * 37 * <p> The TIFF format consists of a short header that points to a 38 * linked list of Image File Directories (IFDs). An IFD is 39 * essentially a list of fields. The <code>TIFFDirectory</code> class 40 * encapsulates a set of common operations performed on an IFD; an instance 41 * of the <code>TIFFField</code> class corresponds to a field in an IFD. 42 * Each field has numeric value or <i>tag</i>, a data type, and a byte offset 43 * at which the field's data may be found. This mechanism allows TIFF 44 * files to contain multiple images, each with its own IFD, and to order 45 * its contents flexibly since (apart from the header) nothing is required to 46 * appear at a fixed offset. 47 * 48 * <p> An image generated by the "TIFF" operation will have a property 49 * named "tiff_directory" the value of which will be a <code>TIFFDirectory</code> 50 * corresponding to the IFD of the image. JAI's property inheritance mechanism 51 * provides a mechanism by which the field information of the IFD may be 52 * made available to applications in a straightforward way. This mechanism 53 * may be utilized by setting a <code>PropertyGenerator</code> on this 54 * <code>OperationDescriptor</code> which extracts <code>TIFFField</code>s 55 * from the <code>TIFFDirectory</code>-valued property and returns them either 56 * as <code>TIFFField</code> instances or as some user-defined object 57 * initialized from a <code>TIFFField</code>. In the latter case application 58 * code would be insulated from the uncommitted <code>TIFFField</code> class. 59 * 60 * <p> The second parameter contains an instance of 61 * <code>TIFFDecodeParam</code> to be used during the decoding. 62 * It may be set to <code>null</code> in order to perform default 63 * decoding, or equivalently may be omitted. 64 * 65 * <p> Some TIFF extensions make use of a mechanism known as "private 66 * IFDs." A private IFD is one that is not referenced by the standard 67 * linked list of IFDs that starts in the file header. To a standard 68 * TIFF reader, it appears as an unreferenced area in the file. 69 * However, the byte offset of the private IFD is stored as the value 70 * of a private tag, allowing readers that understand the tag to 71 * locate and interpret the IFD. The "TIFF" operation may read the data 72 * at an arbitrary IFD by supplying the offset of the IFD via the 73 * <code>setIFDOffset()</code> method of the <code>TIFFDecodeParam</code> 74 * parameter. 75 * 76 * <p> The third parameter specifies which page of the TIFF data to 77 * read. This permits loading of multi-page TIFF files. The value 78 * provided is zero-relative and so may be interpreted as the index 79 * of the IFD after the first IFD in the stream with zero of course 80 * indicating the first IFD. The default value is zero. 81 * 82 * <p> All pages of a multi-page TIFF stream may also be read by doing the 83 * following: 84 * <pre> 85 * SeekableStream s; // initialization omitted 86 * ParameterBlock pb = new ParameterBlock(); 87 * pb.add(s); 88 * 89 * TIFFDecodeParam param = new TIFFDecodeParam(); 90 * pb.add(param); 91 * 92 * java.util.ArrayList images = new ArrayList(); 93 * long nextOffset = 0; 94 * do { 95 * RenderedOp op = JAI.create("tiff", pb); 96 * images.add(op); 97 * TIFFDirectory dir = (TIFFDirectory)op.getProperty("tiff_directory"); 98 * nextOffset = dir.getNextIFDOffset(); 99 * if(nextOffset != 0) { 100 * param.setIFDOffset(nextOffset); 101 * } 102 * } while(nextOffset != 0); 103 * </pre> 104 * 105 * <p><b> The classes in the <code>com.lightcrafts.media.jai.codec</code> 106 * package are not a committed part of the JAI API. Future releases 107 * of JAI will make use of new classes in their place. This 108 * class will change accordingly.</b> 109 * 110 * <p><table border=1> 111 * <caption>Resource List</caption> 112 * <tr><th>Name</th> <th>Value</th></tr> 113 * <tr><td>GlobalName</td> <td>TIFF</td></tr> 114 * <tr><td>LocalName</td> <td>TIFF</td></tr> 115 * <tr><td>Vendor</td> <td>com.lightcrafts.media.jai</td></tr> 116 * <tr><td>Description</td> <td>Reads a TIFF 6.0 file.</td></tr> 117 * <tr><td>DocURL</td> <td>http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/TIFFDescriptor.html</td></tr> 118 * <tr><td>Version</td> <td>1.0</td></tr> 119 * <tr><td>arg0Desc</td> <td>The SeekableStream to read from.</td></tr> 120 * <tr><td>arg1Desc</td> <td>The TIFFDecodeParam to use.</td></tr> 121 * <tr><td>arg2Desc</td> <td>The page to be decoded.</td></tr> 122 * </table></p> 123 * <p><table border=1> 124 * <caption>Parameter List</caption> 125 * <tr><th>Name</th> <th>Class Type</th> 126 * <th>Default Value</th></tr> 127 * <tr><td>stream</td> <td>com.lightcrafts.media.jai.codec.SeekableStream</td> 128 * <td>NO_PARAMETER_DEFAULT</td> 129 * <tr><td>param</td> <td>com.lightcrafts.media.jai.codec.TIFFDecodeParam</td> 130 * <td>null</td> 131 * <tr><td>page</td> <td>java.lang.Integer</td> 132 * <td>0</td> 133 * </table></p> 134 * 135 * @see com.lightcrafts.media.jai.codec.SeekableStream 136 * @see com.lightcrafts.media.jai.codec.TIFFDecodeParam 137 * @see com.lightcrafts.media.jai.codec.TIFFDirectory 138 * @see com.lightcrafts.media.jai.codec.TIFFEncodeParam 139 * @see com.lightcrafts.media.jai.codec.TIFFField 140 * @see com.lightcrafts.mediax.jai.OperationDescriptor 141 * @see com.lightcrafts.mediax.jai.operator.EncodeDescriptor 142 */ 143 public class TIFFDescriptor extends OperationDescriptorImpl { 144 145 /** 146 * The resource strings that provide the general documentation and 147 * specify the parameter list for the "TIFF" operation. 148 */ 149 private static final String[][] resources = { 150 {"GlobalName", "TIFF"}, 151 {"LocalName", "TIFF"}, 152 {"Vendor", "com.lightcrafts.media.jai"}, 153 {"Description", JaiI18N.getString("TIFFDescriptor0")}, 154 {"DocURL", "http://java.sun.com/products/java-media/jai/forDevelopers/jai-apidocs/javax/media/jai/operator/TIFFDescriptor.html"}, 155 {"Version", JaiI18N.getString("DescriptorVersion")}, 156 {"arg0Desc", JaiI18N.getString("TIFFDescriptor1")}, 157 {"arg1Desc", JaiI18N.getString("TIFFDescriptor2")}, 158 {"arg2Desc", JaiI18N.getString("TIFFDescriptor3")} 159 }; 160 161 /** The parameter names for the "TIFF" operation. */ 162 private static final String[] paramNames = { 163 "stream", "param", "page" 164 }; 165 166 /** The parameter class types for the "TIFF" operation. */ 167 private static final Class[] paramClasses = { 168 com.lightcrafts.media.jai.codec.SeekableStream.class, 169 com.lightcrafts.media.jai.codec.TIFFDecodeParam.class, 170 java.lang.Integer.class 171 }; 172 173 /** The parameter default values for the "TIFF" operation. */ 174 private static final Object[] paramDefaults = { 175 NO_PARAMETER_DEFAULT, null, new Integer(0) 176 }; 177 178 /** Constructor. */ TIFFDescriptor()179 public TIFFDescriptor() { 180 super(resources, 0, paramClasses, paramNames, paramDefaults); 181 } 182 183 184 /** 185 * Reads TIFF 6.0 data from an SeekableStream. 186 * 187 * <p>Creates a <code>ParameterBlockJAI</code> from all 188 * supplied arguments except <code>hints</code> and invokes 189 * {@link JAI#create(String,ParameterBlock,RenderingHints)}. 190 * 191 * @see JAI 192 * @see ParameterBlockJAI 193 * @see RenderedOp 194 * 195 * @param stream The SeekableStream to read from. 196 * @param param The TIFFDecodeParam to use. 197 * May be <code>null</code>. 198 * @param page The page to be decoded. 199 * May be <code>null</code>. 200 * @param hints The <code>RenderingHints</code> to use. 201 * May be <code>null</code>. 202 * @return The <code>RenderedOp</code> destination. 203 * @throws IllegalArgumentException if <code>stream</code> is <code>null</code>. 204 */ create(SeekableStream stream, TIFFDecodeParam param, Integer page, RenderingHints hints)205 public static RenderedOp create(SeekableStream stream, 206 TIFFDecodeParam param, 207 Integer page, 208 RenderingHints hints) { 209 ParameterBlockJAI pb = 210 new ParameterBlockJAI("TIFF", 211 RenderedRegistryMode.MODE_NAME); 212 213 pb.setParameter("stream", stream); 214 pb.setParameter("param", param); 215 pb.setParameter("page", page); 216 217 return JAI.create("TIFF", pb, hints); 218 } 219 } 220