Source Code Cross Referenced for XTIFFDirectory.java in  » GIS » openjump » org » libtiff » jai » codec » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » openjump » org.libtiff.jai.codec 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.libtiff.jai.codec;
002:
003:        /*
004:         * XTIFF: eXtensible TIFF libraries for JAI.
005:         * 
006:         * The contents of this file are subject to the  JAVA ADVANCED IMAGING
007:         * SAMPLE INPUT-OUTPUT CODECS AND WIDGET HANDLING SOURCE CODE  License
008:         * Version 1.0 (the "License"); You may not use this file except in
009:         * compliance with the License. You may obtain a copy of the License at
010:         * http://www.sun.com/software/imaging/JAI/index.html
011:         *
012:         * Software distributed under the License is distributed on an "AS IS"
013:         * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
014:         * the License for the specific language governing rights and limitations
015:         * under the License. 
016:         *
017:         * The Original Code is JAVA ADVANCED IMAGING SAMPLE INPUT-OUTPUT CODECS
018:         * AND WIDGET HANDLING SOURCE CODE. 
019:         * The Initial Developer of the Original Code is: Sun Microsystems, Inc..
020:         * Portions created by: Niles Ritter 
021:         * are Copyright (C): Niles Ritter, GeoTIFF.org, 1999,2000.
022:         * All Rights Reserved.
023:         * Contributor(s): Niles Ritter
024:         */
025:
026:        import java.io.IOException;
027:        import java.util.Enumeration;
028:        import java.util.Hashtable;
029:        import java.util.Vector;
030:        import java.util.TreeMap;
031:        import java.util.Iterator;
032:        import org.libtiff.jai.util.JaiI18N;
033:
034:        // Warning: media libraries subject to change
035:        import com.sun.media.jai.codec.SeekableStream;
036:
037:        /**
038:         * XTIFFDirectory is an extensible TIFF directory object. This
039:         * class may be extended without changing the XTIFF codec by
040:         * overriding the XTIFFFactory instance registered in this
041:         * class. In addition, this class is the repository of all
042:         * XTIFFTileCodec's which may be augmented with new codecs,
043:         * again without overriding the ImageCodec. If the jai "tiff"
044:         * codec has been overridden through the
045:         * <code>XTIFFDescriptor.register()</code> method, each XTIFF image will
046:         * possess a property called "tiff.directory" which will be
047:         * an object of the type created by the factory. The class is
048:         * declared as serializable to permit its transmission to remote
049:         * images as a set of parameters to the codec, and to be able
050:         * to survive as an instantiated property of the RenderedImage.
051:         * 
052:         *
053:         * @serializable
054:         * @author Niles Ritter
055:         * @see XTIFFDescriptor
056:         * @see XTIFFField
057:         * @see XTIFFTileCodec
058:         * @see XTIFFFactory
059:         */
060:        public class XTIFFDirectory extends Object implements 
061:                java.io.Serializable {
062:            private int imageType;
063:
064:            /** default directory factory */
065:            protected static XTIFFFactory factory = new XTIFFFactory();
066:
067:            protected static Hashtable tileCodecs = new Hashtable();
068:
069:            /** The stream being read. Not persisted */
070:            transient protected SeekableStream stream;
071:
072:            /** A boolean storing the endianness of the stream. */
073:            boolean isBigEndian;
074:
075:            /** A boolean indicating tiled tagset  */
076:            boolean _isTiled = false;
077:
078:            /** for dynamically adding fields in sorted order*/
079:            TreeMap fieldIndex = new TreeMap();
080:
081:            /** The default constructor. Publicized for Serializability */
082:            public XTIFFDirectory() {
083:            }
084:
085:            private static boolean isValidEndianTag(int endian) {
086:                return ((endian == 0x4949) || (endian == 0x4d4d));
087:            }
088:
089:            /**
090:             * If true this image uses TIFF 6.0 tiling
091:             */
092:            public boolean isTiled() {
093:                return _isTiled;
094:            }
095:
096:            /**
097:             * reads the TIFF header. Not likely to be overridden.
098:             */
099:            protected void readHeader() throws IOException {
100:
101:                // Read the TIFF header
102:                stream.seek(0L);
103:                int endian = stream.readUnsignedShort();
104:                if (!isValidEndianTag(endian)) {
105:                    throw new IllegalArgumentException(JaiI18N
106:                            .getString("XTIFFDirectory1"));
107:                }
108:                isBigEndian = (endian == 0x4d4d);
109:
110:                // Verify that Douglas Addams still has influence in software:
111:                int magic = readUnsignedShort(stream);
112:                if (magic != 42) {
113:                    throw new IllegalArgumentException(JaiI18N
114:                            .getString("XTIFFDirectory2"));
115:                }
116:
117:            }
118:
119:            /**
120:             * Constructs a XTIFFDirectory from a SeekableStream.
121:             * The directory parameter specifies which directory to read from
122:             * the linked list present in the stream; directory 0 is normally
123:             * read but it is possible to store multiple images in a single
124:             * TIFF file by maintaing multiple directories.
125:             *
126:             * @param stream a SeekableStream to read from.
127:             * @param directory the index of the directory to read.
128:             */
129:            protected XTIFFDirectory(SeekableStream stream, int directory)
130:                    throws IOException {
131:
132:                this .stream = stream;
133:                long global_save_offset = stream.getFilePointer();
134:                long ifd_offset;
135:
136:                readHeader();
137:
138:                // Get the initial ifd offset as an unsigned int (using a long)
139:                ifd_offset = readUnsignedInt(stream);
140:
141:                for (int i = 0; i < directory; i++) {
142:                    if (ifd_offset == 0L) {
143:                        throw new IllegalArgumentException(JaiI18N
144:                                .getString("XTIFFDirectory3"));
145:                    }
146:
147:                    stream.seek(ifd_offset);
148:                    int entries = readUnsignedShort(stream);
149:                    stream.skip(12 * entries);
150:
151:                    ifd_offset = readUnsignedInt(stream);
152:                }
153:
154:                stream.seek(ifd_offset);
155:                initialize();
156:                stream.seek(global_save_offset);
157:            }
158:
159:            /**
160:             * Constructs a XTIFFDirectory by reading a SeekableStream.
161:             * The ifd_offset parameter specifies the stream offset from which
162:             * to begin reading; this mechanism is sometimes used to store
163:             * private IFDs within a TIFF file that are not part of the normal
164:             * sequence of IFDs.
165:             *
166:             * @param stream a SeekableStream to read from.
167:             * @param ifd_offset the long byte offset of the directory.
168:             */
169:            protected XTIFFDirectory(SeekableStream stream, long ifd_offset)
170:                    throws IOException {
171:                this .stream = stream;
172:                long global_save_offset = stream.getFilePointer();
173:
174:                readHeader();
175:
176:                stream.seek(ifd_offset);
177:                initialize();
178:                stream.seek(global_save_offset);
179:            }
180:
181:            private static final int[] _sizeOfType = { 0, //  0 = n/a
182:                    1, //  1 = byte
183:                    1, //  2 = ascii
184:                    2, //  3 = short
185:                    4, //  4 = long
186:                    8, //  5 = rational
187:                    1, //  6 = sbyte
188:                    1, //  7 = undefined
189:                    2, //  8 = sshort
190:                    4, //  9 = slong
191:                    8, // 10 = srational
192:                    4, // 11 = float
193:                    8 // 12 = double 
194:            };
195:
196:            /**
197:             * Return the size of a data type. Extend if you
198:             * need to define new TIFF field types. Also override
199:             * the createField() method of the XTIFFFactory, the
200:             * XTIFFField class, and the readFieldValue() method here.
201:             * @param type the XTIFFField type code
202:             * @see XTIFFField
203:             * @see XTIFFFactory
204:             */
205:            public int sizeOfType(int type)
206:                    throws ArrayIndexOutOfBoundsException {
207:                return _sizeOfType[type];
208:            }
209:
210:            /**
211:             * Create and add a TIFF field to this directory.
212:             * @param tag the TIFF tag listed in XTIFF
213:             * @param type the TIFF field type listed in XTIFFField
214:             * @param count the number of values in array obj
215:             * @param obj the array of values
216:             * @see XTIFFField
217:             * @see XTIFF
218:             */
219:            public void addField(int tag, int type, int count, Object obj) {
220:                addField(factory.createField(tag, type, count, obj));
221:            }
222:
223:            /**
224:             * Create a TIFF field 
225:             * @param tag the TIFF tag listed in XTIFF
226:             * @param type the TIFF field type listed in XTIFFField
227:             * @param count the number of values in array obj
228:             * @param obj the array of values
229:             * @see XTIFFField
230:             * @see XTIFF
231:             */
232:            public static XTIFFField createField(int tag, int type, int count,
233:                    Object obj) {
234:                return factory.createField(tag, type, count, obj);
235:            }
236:
237:            /**
238:             * Add an existing TIFF field to this directory.
239:             * @param type the XTIFFField type code
240:             * @see XTIFFField
241:             */
242:            public void addField(XTIFFField field) {
243:                fieldIndex.put(new Integer(field.tag), field);
244:            }
245:
246:            /**
247:             * Initialize the directory from a stream
248:             */
249:            protected void initialize() throws IOException {
250:                XTIFFField field;
251:                long nextTagOffset;
252:
253:                int numEntries = readUnsignedShort(stream);
254:
255:                for (int i = 0; i < numEntries; i++) {
256:
257:                    try {
258:                        field = readField();
259:                    } catch (ArrayIndexOutOfBoundsException ae) {
260:                        // if the data type is unknown we should skip this TIFF Field
261:                        continue;
262:                    }
263:                    addField(field);
264:                }
265:            }
266:
267:            /** Returns the number of directory entries. */
268:            public int getNumEntries() {
269:                return fieldIndex.size();
270:            }
271:
272:            /**
273:             * Returns the value of a given tag as a XTIFFField,
274:             * or null if the tag is not present.
275:             */
276:            public XTIFFField getField(int tag) {
277:                return (XTIFFField) fieldIndex.get(new Integer(tag));
278:            }
279:
280:            /**
281:             * Returns true if a tag appears in the directory. 
282:             */
283:            public boolean isTagPresent(int tag) {
284:                return fieldIndex.containsKey(new Integer(tag));
285:            }
286:
287:            /**
288:             * Returns an ordered array of ints indicating the tag
289:             * values.
290:             */
291:            public int[] getTags() {
292:                int[] tags = new int[fieldIndex.size()];
293:                Iterator iter = fieldIndex.keySet().iterator();
294:                int i = 0;
295:                while (iter.hasNext()) {
296:                    tags[i++] = ((Integer) iter.next()).intValue();
297:                }
298:                return tags;
299:            }
300:
301:            /**
302:             * Returns an array of XTIFFFields containing all the fields
303:             * in this directory.
304:             */
305:            public XTIFFField[] getFields() {
306:                XTIFFField[] fields = new XTIFFField[fieldIndex.size()];
307:                Iterator iter = fieldIndex.values().iterator();
308:                int i = 0;
309:                while (iter.hasNext()) {
310:                    fields[i++] = (XTIFFField) iter.next();
311:                }
312:                return fields;
313:            }
314:
315:            /**
316:             * Returns the value of a particular index of a given tag as a
317:             * byte.  The caller is responsible for ensuring that the tag is
318:             * present and has type XTIFFField.TIFF_SBYTE, TIFF_BYTE, or
319:             * TIFF_UNDEFINED.
320:             */
321:            public byte getFieldAsByte(int tag, int index) {
322:                return (getField(tag).getAsBytes())[index];
323:            }
324:
325:            /**
326:             * Returns the value of index 0 of a given tag as a
327:             * byte.  The caller is responsible for ensuring that the tag is
328:             * present and has  type XTIFFField.TIFF_SBYTE, TIFF_BYTE, or
329:             * TIFF_UNDEFINED.
330:             */
331:            public byte getFieldAsByte(int tag) {
332:                return getFieldAsByte(tag, 0);
333:            }
334:
335:            /**
336:             * Returns the value of a particular index of a given tag as a
337:             * long.  The caller is responsible for ensuring that the tag is
338:             * present and has type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED,
339:             * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG.
340:             */
341:            public long getFieldAsLong(int tag, int index) {
342:                return getField(tag).getAsLong(index);
343:            }
344:
345:            /**
346:             * Returns the value of index 0 of a given tag as a
347:             * long.  The caller is responsible for ensuring that the tag is
348:             * present and has type TIFF_BYTE, TIFF_SBYTE, TIFF_UNDEFINED,
349:             * TIFF_SHORT, TIFF_SSHORT, TIFF_SLONG or TIFF_LONG.
350:             */
351:            public long getFieldAsLong(int tag) {
352:                return getFieldAsLong(tag, 0);
353:            }
354:
355:            /**
356:             * Returns the value of a particular index of a given tag as a
357:             * float.  The caller is responsible for ensuring that the tag is
358:             * present and has numeric type (all but TIFF_UNDEFINED and
359:             * TIFF_ASCII).
360:             */
361:            public float getFieldAsFloat(int tag, int index) {
362:                return getField(tag).getAsFloat(index);
363:            }
364:
365:            /**
366:             * Returns the value of index 0 of a given tag as a float.  The
367:             * caller is responsible for ensuring that the tag is present and
368:             * has numeric type (all but TIFF_UNDEFINED and TIFF_ASCII).
369:             */
370:            public float getFieldAsFloat(int tag) {
371:                return getFieldAsFloat(tag, 0);
372:            }
373:
374:            /**
375:             * Returns the value of a particular index of a given tag as a
376:             * double.  The caller is responsible for ensuring that the tag is
377:             * present and has numeric type (all but TIFF_UNDEFINED and
378:             * TIFF_ASCII).
379:             */
380:            public double getFieldAsDouble(int tag, int index) {
381:                return getField(tag).getAsDouble(index);
382:            }
383:
384:            /**
385:             * Returns the value of index 0 of a given tag as a double.  The
386:             * caller is responsible for ensuring that the tag is present and
387:             * has numeric type (all but TIFF_UNDEFINED and TIFF_ASCII).
388:             */
389:            public double getFieldAsDouble(int tag) {
390:                return getFieldAsDouble(tag, 0);
391:            }
392:
393:            /**
394:             * TIFF field-value reader. Override if there are
395:             * new field types. Also override sizeOfType() and,
396:             * possibly the createField method of the factory,
397:             * if the field needs new accessors.
398:             */
399:            public Object readFieldValue(int tag, int type, int count)
400:                    throws IOException, ArrayIndexOutOfBoundsException {
401:                int j;
402:                Object obj = null;
403:
404:                switch (type) {
405:                case XTIFFField.TIFF_BYTE:
406:                case XTIFFField.TIFF_SBYTE:
407:                case XTIFFField.TIFF_UNDEFINED:
408:                case XTIFFField.TIFF_ASCII:
409:                    byte[] bvalues = new byte[count];
410:                    stream.readFully(bvalues, 0, count);
411:
412:                    if (type == XTIFFField.TIFF_ASCII) {
413:
414:                        // Can be multiple strings
415:                        int index = 0, prevIndex = 0;
416:                        Vector v = new Vector();
417:
418:                        while (index < count) {
419:
420:                            while ((index < count) && (bvalues[index++] != 0))
421:                                ;
422:
423:                            // When we encountered zero, means one string has ended
424:                            v.add(new String(bvalues, prevIndex,
425:                                    (index - prevIndex)));
426:                            prevIndex = index;
427:                        }
428:
429:                        count = v.size();
430:                        String strings[] = new String[count];
431:                        for (int c = 0; c < count; c++) {
432:                            strings[c] = (String) v.elementAt(c);
433:                        }
434:
435:                        obj = strings;
436:                    } else {
437:                        obj = bvalues;
438:                    }
439:
440:                    break;
441:
442:                case XTIFFField.TIFF_SHORT:
443:                    char[] cvalues = new char[count];
444:                    for (j = 0; j < count; j++) {
445:                        cvalues[j] = (char) (readUnsignedShort(stream));
446:                    }
447:                    obj = cvalues;
448:                    break;
449:
450:                case XTIFFField.TIFF_LONG:
451:                    long[] lvalues = new long[count];
452:                    for (j = 0; j < count; j++) {
453:                        lvalues[j] = readUnsignedInt(stream);
454:                    }
455:                    obj = lvalues;
456:                    break;
457:
458:                case XTIFFField.TIFF_RATIONAL:
459:                    long[][] llvalues = new long[count][2];
460:                    for (j = 0; j < count; j++) {
461:                        llvalues[j][0] = readUnsignedInt(stream);
462:                        llvalues[j][1] = readUnsignedInt(stream);
463:                    }
464:                    obj = llvalues;
465:                    break;
466:
467:                case XTIFFField.TIFF_SSHORT:
468:                    short[] svalues = new short[count];
469:                    for (j = 0; j < count; j++) {
470:                        svalues[j] = readShort(stream);
471:                    }
472:                    obj = svalues;
473:                    break;
474:
475:                case XTIFFField.TIFF_SLONG:
476:                    int[] ivalues = new int[count];
477:                    for (j = 0; j < count; j++) {
478:                        ivalues[j] = readInt(stream);
479:                    }
480:                    obj = ivalues;
481:                    break;
482:
483:                case XTIFFField.TIFF_SRATIONAL:
484:                    int[][] iivalues = new int[count][2];
485:                    for (j = 0; j < count; j++) {
486:                        iivalues[j][0] = readInt(stream);
487:                        iivalues[j][1] = readInt(stream);
488:                    }
489:                    obj = iivalues;
490:                    break;
491:
492:                case XTIFFField.TIFF_FLOAT:
493:                    float[] fvalues = new float[count];
494:                    for (j = 0; j < count; j++) {
495:                        fvalues[j] = readFloat(stream);
496:                    }
497:                    obj = fvalues;
498:                    break;
499:
500:                case XTIFFField.TIFF_DOUBLE:
501:                    double[] dvalues = new double[count];
502:                    for (j = 0; j < count; j++) {
503:                        dvalues[j] = readDouble(stream);
504:                    }
505:                    obj = dvalues;
506:                    break;
507:
508:                default:
509:                    System.err.println(JaiI18N.getString("XTIFFDirectory0"));
510:                    break;
511:                }
512:                return obj;
513:            }
514:
515:            /**
516:             * Method for reading a field from stream. Positions
517:             * stream at the next field location.
518:             */
519:            private XTIFFField readField() throws IOException,
520:                    ArrayIndexOutOfBoundsException {
521:                int j;
522:                int tag = readUnsignedShort(stream);
523:                int type = readUnsignedShort(stream);
524:                int count = (int) readUnsignedInt(stream);
525:                int value = 0;
526:
527:                // The place to return to to read the next tag
528:                long nextTagOffset = stream.getFilePointer() + 4;
529:
530:                try {
531:                    // If the tag data can't fit in 4 bytes, the next 4 bytes
532:                    // contain the starting offset of the data
533:                    if (count * sizeOfType(type) > 4) {
534:                        value = (int) (readUnsignedInt(stream));
535:                        stream.seek(value);
536:                    }
537:                } catch (ArrayIndexOutOfBoundsException ae) {
538:                    System.err.println(tag + " "
539:                            + JaiI18N.getString("XTIFFDirectory4"));
540:                    // if the data type is unknown we should skip this TIFF Field
541:                    stream.seek(nextTagOffset);
542:                    throw ae;
543:                }
544:
545:                Object obj = readFieldValue(tag, type, count);
546:
547:                // Position stream at next field and return this one
548:                stream.seek(nextTagOffset);
549:
550:                return createField(tag, type, count, obj);
551:            }
552:
553:            // Methods to read primitive data types from the stream
554:
555:            protected short readShort(SeekableStream stream) throws IOException {
556:                if (isBigEndian) {
557:                    return stream.readShort();
558:                } else {
559:                    return stream.readShortLE();
560:                }
561:            }
562:
563:            protected int readUnsignedShort(SeekableStream stream)
564:                    throws IOException {
565:                if (isBigEndian) {
566:                    int val = stream.readUnsignedShort();
567:                    return val;
568:                } else {
569:                    int val = stream.readUnsignedShortLE();
570:                    return val;
571:                }
572:            }
573:
574:            protected int readInt(SeekableStream stream) throws IOException {
575:                if (isBigEndian) {
576:                    return stream.readInt();
577:                } else {
578:                    return stream.readIntLE();
579:                }
580:            }
581:
582:            protected long readUnsignedInt(SeekableStream stream)
583:                    throws IOException {
584:                if (isBigEndian) {
585:                    return stream.readUnsignedInt();
586:                } else {
587:                    return stream.readUnsignedIntLE();
588:                }
589:            }
590:
591:            protected long readLong(SeekableStream stream) throws IOException {
592:                if (isBigEndian) {
593:                    return stream.readLong();
594:                } else {
595:                    return stream.readLongLE();
596:                }
597:            }
598:
599:            protected float readFloat(SeekableStream stream) throws IOException {
600:                if (isBigEndian) {
601:                    return stream.readFloat();
602:                } else {
603:                    return stream.readFloatLE();
604:                }
605:            }
606:
607:            protected double readDouble(SeekableStream stream)
608:                    throws IOException {
609:                if (isBigEndian) {
610:                    return stream.readDouble();
611:                } else {
612:                    return stream.readDoubleLE();
613:                }
614:            }
615:
616:            // Static methods used by the public static method below
617:
618:            private static int readUnsignedShort(SeekableStream stream,
619:                    boolean isBigEndian) throws IOException {
620:                if (isBigEndian) {
621:                    return stream.readUnsignedShort();
622:                } else {
623:                    return stream.readUnsignedShortLE();
624:                }
625:            }
626:
627:            private static long readUnsignedInt(SeekableStream stream,
628:                    boolean isBigEndian) throws IOException {
629:                if (isBigEndian) {
630:                    return stream.readUnsignedInt();
631:                } else {
632:                    return stream.readUnsignedIntLE();
633:                }
634:            }
635:
636:            // Utilities
637:
638:            /**
639:             * Returns the number of image directories (subimages) stored in a
640:             * given TIFF file, represented by a <code>SeekableStream</code>.
641:             */
642:            public static int getNumDirectories(SeekableStream stream)
643:                    throws IOException {
644:                long pointer = stream.getFilePointer(); // Save stream pointer
645:
646:                stream.seek(0L);
647:                int endian = stream.readUnsignedShort();
648:                if (!isValidEndianTag(endian)) {
649:                    throw new IllegalArgumentException(JaiI18N
650:                            .getString("XTIFFDirectory1"));
651:                }
652:                boolean isBigEndian = (endian == 0x4d4d);
653:                int magic = readUnsignedShort(stream, isBigEndian);
654:                if (magic != 42) {
655:                    throw new IllegalArgumentException(JaiI18N
656:                            .getString("XTIFFDirectory2"));
657:                }
658:
659:                stream.seek(4L);
660:                long offset = readUnsignedInt(stream, isBigEndian);
661:
662:                int numDirectories = 0;
663:                while (offset != 0L) {
664:                    ++numDirectories;
665:
666:                    stream.seek(offset);
667:                    int entries = readUnsignedShort(stream, isBigEndian);
668:                    stream.skip(12 * entries);
669:                    offset = readUnsignedInt(stream, isBigEndian);
670:                }
671:
672:                stream.seek(pointer); // Reset stream pointer
673:                return numDirectories;
674:            }
675:
676:            /**
677:             * Returns a boolean indicating whether the byte order used in the
678:             * the TIFF file is big-endian (i.e. whether the byte order is from  
679:             * the most significant to the least significant)
680:             */
681:            public boolean isBigEndian() {
682:                return isBigEndian;
683:            }
684:
685:            /**
686:             * Specifies the type of compression to be used. The compression type
687:             * specified will be honored only if it is compatible with the image
688:             * being written out. 
689:             *
690:             * @param compression    The compression type.
691:             */
692:            public void setCompression(int compression) {
693:                //this.compression = compression;
694:                // Check to see if compression supported
695:                // Add Field
696:                addField(XTIFF.TIFFTAG_COMPRESSION, XTIFFField.TIFF_SHORT, 1,
697:                        new char[] { (char) compression });
698:            }
699:
700:            /**
701:             * Return the type of compression indicated in the
702:             * TIFF fields, or XTIFF.COMPRESSION_NON if not
703:             * specified.
704:             */
705:            public int getCompression() {
706:                if (getField(XTIFF.TIFFTAG_COMPRESSION) == null)
707:                    return XTIFF.COMPRESSION_NONE;
708:                return (int) getFieldAsLong(XTIFF.TIFFTAG_COMPRESSION);
709:            }
710:
711:            /**
712:             * If set, the data will be written out in tiled format, instead of
713:             * in strips.
714:             *
715:             * @param isTiled     Specifies whether the image data should be 
716:             *                       wriiten out in tiled format.
717:             */
718:            public void setIsTiled(boolean isTiled) {
719:                this ._isTiled = isTiled;
720:            }
721:
722:            /**
723:             * Constructs a tile codec for decoding data, using the
724:             * compression defined in the current directory.
725:             * @param param the encoding param
726:             * @see XTIFFTileCodec
727:             */
728:            public XTIFFTileCodec createTileCodec(XTIFFDecodeParam param)
729:                    throws IOException {
730:                int compression = getCompression();
731:                XTIFFTileCodec codec = getTileCodec(compression);
732:                if (codec == null)
733:                    throw new IOException("Compression type (" + compression
734:                            + ") not supported");
735:                return codec.create(param);
736:            }
737:
738:            /**
739:             * Constructs a tile codec for encoding data, using the
740:             * compression defined in the current directory.
741:             * @param param the encoding param
742:             * @see XTIFFTileCodec
743:             */
744:            public XTIFFTileCodec createTileCodec(XTIFFEncodeParam param)
745:                    throws IOException {
746:                int compression = getCompression();
747:                XTIFFTileCodec codec = getTileCodec(compression);
748:                if (codec == null)
749:                    throw new IOException("Compression type (" + compression
750:                            + ") not supported");
751:                return codec.create(param);
752:            }
753:
754:            /**
755:             * Set the XTIFFFactory, which is used to
756:             * construct the XTIFFDirectory object assigned as a
757:             * "tiff.directory" property in the resulting jai image.
758:             *
759:             * @param fact the factory to register. The factory is 
760:             * guaranteed to always be non-null; if a null is passed
761:             * in then the default XTIFFFactory is used.
762:             * a null object is passed in
763:             * @see XTIFFFactory
764:             */
765:            public static void setFactory(XTIFFFactory fact) {
766:                if (fact == null)
767:                    factory = new XTIFFFactory();
768:                else
769:                    factory = fact;
770:            }
771:
772:            /**
773:             * Constructs a XTIFFDirectory from a SeekableStream.
774:             * The directory parameter specifies which directory to read from
775:             * the linked list present in the stream; directory 0 is normally
776:             * read but it is possible to store multiple images in a single
777:             * TIFF file by maintaing multiple directories.
778:             *
779:             * @param stream a SeekableStream to read from.
780:             * @param directory the index of the directory to read.
781:             * @see XTIFFFactory
782:             */
783:            public static XTIFFDirectory create(SeekableStream stream,
784:                    int directory) throws IOException {
785:                return factory.createDirectory(stream, directory);
786:            }
787:
788:            /**
789:             * Constructs a TIFFDirectory by reading a SeekableStream.
790:             * The ifd_offset parameter specifies the stream offset from which
791:             * to begin reading; this mechanism is sometimes used to store
792:             * private IFDs within a TIFF file that are not part of the normal
793:             * sequence of IFDs. Uses the XTIFFFactory to do this, so
794:             * to extend the directory class, the factory method should be
795:             * extended and registered instead of this one.
796:             *
797:             * @param stream a SeekableStream to read from.
798:             * @param ifd_offset the long byte offset of the directory.
799:             * @see XTIFFFactory
800:             */
801:            public static XTIFFDirectory create(SeekableStream stream,
802:                    long ifd_offset) throws IOException {
803:                return factory.createDirectory(stream, ifd_offset);
804:            }
805:
806:            /**
807:             * Constructs an XTIFFDirectory from the currently.
808:             * registered XTIFFDirectory factory.
809:             * @see XTIFFFactory
810:             */
811:            public static XTIFFDirectory create() {
812:                return factory.createDirectory();
813:            }
814:
815:            /**
816:             * Return the currently registered XTIFFTileCodec
817:             * for this compression type. Used by the XTIFFImage
818:             * to decode the compression data.
819:             * @see XTIFFTileCodec
820:             */
821:            public static XTIFFTileCodec getTileCodec(int comp) {
822:                return (XTIFFTileCodec) tileCodecs.get(new Integer(comp));
823:            }
824:
825:            /**
826:             * UnRegister the XTIFFTileCodec corresponding to the 
827:             * TIFF compression type.
828:             * @param comp The TIFF compression code indicated 
829:             */
830:            public static void unRegisterTileCodec(int comp) {
831:                XTIFFTileCodec cod = getTileCodec(comp);
832:                tileCodecs.remove(cod);
833:            }
834:
835:            /**
836:             * Register a new XTIFFTileCodec for encoding and decoding
837:             * compressed TIFF image data. This overrides any existing
838:             * codec previously registered.
839:             * @param comp The TIFF compression code indicated by the
840:             * @param codec The codec to register.
841:             *    XTIFF.TIFFTAG_COMPRESSION field.
842:             * @see XTIFFTileCodec
843:             */
844:            public static void registerTileCodec(int comp, XTIFFTileCodec codec) {
845:                tileCodecs.put(new Integer(comp), codec);
846:            }
847:
848:            /**
849:             * Get the JAI Image decoded type. This method is
850:             * called by the XTIFFTileCodeImpl object during the
851:             * decode() method to determine what type of colorspace
852:             * and sample model to use.
853:             */
854:            public int getImageType() {
855:                return imageType;
856:            }
857:
858:            /**
859:             * Set the JAI Image decoded type. This method is
860:             * called by the XTIFFImage constructor to indicate
861:             * to the XTIFFTileCodec what type of colorspace and
862:             * sample model to use. The types are enumerated in
863:             * the XTIFF class.
864:             * @see XTIFF
865:             * @see XTIFFImage
866:             * @see XTIFFTileCodec
867:             */
868:            public void setImageType(int image_type) {
869:                imageType = image_type;
870:            }
871:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.