Source Code Cross Referenced for FileFormatReader.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » jj2000 » j2k » fileformat » reader » 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 » 6.0 JDK Modules » Java Advanced Imaging » jj2000.j2k.fileformat.reader 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: FileFormatReader.java,v $
003:         * $Revision: 1.2 $
004:         * $Date: 2005/04/28 01:25:38 $
005:         * $State: Exp $
006:         *
007:         * Class:                   FileFormatReader
008:         *
009:         * Description:             Read J2K file stream
010:         *
011:         * COPYRIGHT:
012:         *
013:         * This software module was originally developed by Raphaël Grosbois and
014:         * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
015:         * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
016:         * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
017:         * Centre France S.A) in the course of development of the JPEG2000
018:         * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
019:         * software module is an implementation of a part of the JPEG 2000
020:         * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
021:         * Systems AB and Canon Research Centre France S.A (collectively JJ2000
022:         * Partners) agree not to assert against ISO/IEC and users of the JPEG
023:         * 2000 Standard (Users) any of their rights under the copyright, not
024:         * including other intellectual property rights, for this software module
025:         * with respect to the usage by ISO/IEC and Users of this software module
026:         * or modifications thereof for use in hardware or software products
027:         * claiming conformance to the JPEG 2000 Standard. Those intending to use
028:         * this software module in hardware or software products are advised that
029:         * their use may infringe existing patents. The original developers of
030:         * this software module, JJ2000 Partners and ISO/IEC assume no liability
031:         * for use of this software module or modifications thereof. No license
032:         * or right to this software module is granted for non JPEG 2000 Standard
033:         * conforming products. JJ2000 Partners have full right to use this
034:         * software module for his/her own purpose, assign or donate this
035:         * software module to any third party and to inhibit third parties from
036:         * using this software module for non JPEG 2000 Standard conforming
037:         * products. This copyright notice must be included in all copies or
038:         * derivative works of this software module.
039:         *
040:         * Copyright (c) 1999/2000 JJ2000 Partners.
041:         * */
042:        package jj2000.j2k.fileformat.reader;
043:
044:        import java.awt.Transparency;
045:        import java.awt.color.ICC_Profile;
046:        import java.awt.color.ColorSpace;
047:        import java.awt.color.ICC_ColorSpace;
048:        import java.awt.image.ColorModel;
049:        import java.awt.image.ComponentColorModel;
050:        import java.awt.image.DataBuffer;
051:        import java.awt.image.IndexColorModel;
052:
053:        import jj2000.j2k.codestream.*;
054:        import jj2000.j2k.fileformat.*;
055:        import jj2000.j2k.io.*;
056:
057:        import java.util.*;
058:        import java.io.*;
059:        import com.sun.media.imageioimpl.plugins.jpeg2000.Box;
060:        import com.sun.media.imageioimpl.plugins.jpeg2000.BitsPerComponentBox;
061:        import com.sun.media.imageioimpl.plugins.jpeg2000.ChannelDefinitionBox;
062:        import com.sun.media.imageioimpl.plugins.jpeg2000.ColorSpecificationBox;
063:        import com.sun.media.imageioimpl.plugins.jpeg2000.ComponentMappingBox;
064:        import com.sun.media.imageioimpl.plugins.jpeg2000.DataEntryURLBox;
065:        import com.sun.media.imageioimpl.plugins.jpeg2000.FileTypeBox;
066:        import com.sun.media.imageioimpl.plugins.jpeg2000.HeaderBox;
067:        import com.sun.media.imageioimpl.plugins.jpeg2000.J2KMetadata;
068:        import com.sun.media.imageioimpl.plugins.jpeg2000.ResolutionBox;
069:        import com.sun.media.imageioimpl.plugins.jpeg2000.PaletteBox;
070:        import com.sun.media.imageioimpl.plugins.jpeg2000.UUIDBox;
071:        import com.sun.media.imageioimpl.plugins.jpeg2000.UUIDListBox;
072:        import com.sun.media.imageioimpl.plugins.jpeg2000.XMLBox;
073:        import com.sun.media.imageioimpl.plugins.jpeg2000.SignatureBox;
074:
075:        /**
076:         * This class reads the file format wrapper that may or may not exist around a
077:         * valid JPEG 2000 codestream. Since no information from the file format is
078:         * used in the actual decoding, this class simply goes through the file and
079:         * finds the first valid codestream.
080:         *
081:         * @see jj2000.j2k.fileformat.writer.FileFormatWriter
082:         * */
083:        public class FileFormatReader implements  FileFormatBoxes {
084:
085:            /** The random access from which the file format boxes are read */
086:            private RandomAccessIO in;
087:
088:            /** The positions of the codestreams in the fileformat*/
089:            private Vector codeStreamPos;
090:
091:            /** The lengths of the codestreams in the fileformat*/
092:            private Vector codeStreamLength;
093:
094:            /** Create a IndexColorModel from the palette box if there is one */
095:            private ColorModel colorModel = null;
096:
097:            /** The meta data */
098:            private J2KMetadata metadata;
099:
100:            /** Parameters in header box */
101:            private int width;
102:            private int height;
103:            private int numComp;
104:            private int bitDepth;
105:            private int compressionType;
106:            private int unknownColor;
107:            private int intelProp;
108:
109:            /** Various bit depth */
110:            private byte[] bitDepths;
111:
112:            /** The lut in the palette box */
113:            private byte[][] lut;
114:            private byte[] compSize;
115:
116:            /** Component mapping */
117:            private short[] comps;
118:            private byte[] type;
119:            private byte[] maps;
120:
121:            /** Channel definitions */
122:            private short[] channels;
123:            private short[] cType;
124:            private short[] associations;
125:
126:            /** Color specification */
127:            private int colorSpaceType;
128:
129:            /** ICC profile */
130:            private ICC_Profile profile;
131:
132:            /**
133:             * The constructor of the FileFormatReader
134:             *
135:             * @param in The RandomAccessIO from which to read the file format
136:             * */
137:            public FileFormatReader(RandomAccessIO in, J2KMetadata metadata) {
138:                this .in = in;
139:                this .metadata = metadata;
140:            }
141:
142:            /**
143:             * This method checks whether the given RandomAccessIO is a valid JP2 file
144:             * and if so finds the first codestream in the file. Currently, the
145:             * information in the codestream is not used
146:             *
147:             * @param in The RandomAccessIO from which to read the file format
148:             *
149:             * @exception java.io.IOException If an I/O error ocurred.
150:             *
151:             * @exception java.io.EOFException If end of file is reached
152:             * */
153:            public void readFileFormat() throws IOException, EOFException {
154:
155:                int foundCodeStreamBoxes = 0;
156:                int box;
157:                int length;
158:                long longLength = 0;
159:                int pos;
160:                short marker;
161:                boolean jp2HeaderBoxFound = false;
162:                boolean lastBoxFound = false;
163:
164:                try {
165:
166:                    // Go through the randomaccessio and find the first
167:                    // contiguous codestream box. Check also that the File Format is
168:                    // correct
169:
170:                    pos = in.getPos();
171:
172:                    // Make sure that the first 12 bytes is the JP2_SIGNATURE_BOX
173:                    // or if not that the first 2 bytes is the SOC marker
174:                    if (in.readInt() != 0x0000000c
175:                            || in.readInt() != JP2_SIGNATURE_BOX
176:                            || in.readInt() != 0x0d0a870a) { // Not a JP2 file
177:                        in.seek(pos);
178:
179:                        marker = (short) in.readShort();
180:                        if (marker != Markers.SOC) //Standard syntax marker found
181:                            throw new Error(
182:                                    "File is neither valid JP2 file nor "
183:                                            + "valid JPEG 2000 codestream");
184:                        in.seek(pos);
185:                        if (codeStreamPos == null)
186:                            codeStreamPos = new Vector();
187:                        codeStreamPos.addElement(new Integer(pos));
188:                        return;
189:                    }
190:
191:                    if (metadata != null)
192:                        metadata.addNode(new SignatureBox());
193:
194:                    // Read all remaining boxes
195:                    while (!lastBoxFound) {
196:                        pos = in.getPos();
197:                        length = in.readInt();
198:                        if ((pos + length) == in.length())
199:                            lastBoxFound = true;
200:
201:                        box = in.readInt();
202:                        if (length == 0) {
203:                            lastBoxFound = true;
204:                            length = in.length() - in.getPos();
205:                        } else if (length == 1) {
206:                            longLength = in.readLong();
207:                            throw new IOException("File too long.");
208:                        } else
209:                            longLength = (long) 0;
210:
211:                        pos = in.getPos();
212:                        length -= 8;
213:
214:                        switch (box) {
215:                        case FILE_TYPE_BOX:
216:                            readFileTypeBox(length + 8, longLength);
217:                            break;
218:                        case CONTIGUOUS_CODESTREAM_BOX:
219:                            if (!jp2HeaderBoxFound)
220:                                throw new Error(
221:                                        "Invalid JP2 file: JP2Header box not "
222:                                                + "found before Contiguous codestream "
223:                                                + "box ");
224:                            readContiguousCodeStreamBox(length + 8, longLength);
225:                            break;
226:                        case JP2_HEADER_BOX:
227:                            if (jp2HeaderBoxFound)
228:                                throw new Error("Invalid JP2 file: Multiple "
229:                                        + "JP2Header boxes found");
230:                            readJP2HeaderBox(length + 8);
231:                            jp2HeaderBoxFound = true;
232:                            length = 0;
233:                            break;
234:                        case IMAGE_HEADER_BOX:
235:                            readImageHeaderBox(length);
236:                            break;
237:                        case INTELLECTUAL_PROPERTY_BOX:
238:                            readIntPropertyBox(length);
239:                            break;
240:                        case XML_BOX:
241:                            readXMLBox(length);
242:                            break;
243:                        case UUID_INFO_BOX:
244:                            length = 0;
245:                            break;
246:                        case UUID_BOX:
247:                            readUUIDBox(length);
248:                            break;
249:                        case UUID_LIST_BOX:
250:                            readUUIDListBox(length);
251:                            break;
252:                        case URL_BOX:
253:                            readURLBox(length);
254:                            break;
255:                        case PALETTE_BOX:
256:                            readPaletteBox(length + 8);
257:                            break;
258:                        case BITS_PER_COMPONENT_BOX:
259:                            readBitsPerComponentBox(length);
260:                            break;
261:                        case COMPONENT_MAPPING_BOX:
262:                            readComponentMappingBox(length);
263:                            break;
264:                        case COLOUR_SPECIFICATION_BOX:
265:                            readColourSpecificationBox(length);
266:                            break;
267:                        case CHANNEL_DEFINITION_BOX:
268:                            readChannelDefinitionBox(length);
269:                            break;
270:                        case RESOLUTION_BOX:
271:                            length = 0;
272:                            break;
273:                        case CAPTURE_RESOLUTION_BOX:
274:                        case DEFAULT_DISPLAY_RESOLUTION_BOX:
275:                            readResolutionBox(box, length);
276:                            break;
277:                        default:
278:                            if (metadata != null) {
279:                                byte[] data = new byte[length];
280:                                in.readFully(data, 0, length);
281:                                metadata.addNode(new Box(length + 8, box,
282:                                        longLength, data));
283:                            }
284:                        }
285:                        if (!lastBoxFound)
286:                            in.seek(pos + length);
287:                    }
288:                } catch (EOFException e) {
289:                    throw new Error("EOF reached before finding Contiguous "
290:                            + "Codestream Box");
291:                }
292:
293:                if (codeStreamPos.size() == 0) {
294:                    // Not a valid JP2 file or codestream
295:                    throw new Error(
296:                            "Invalid JP2 file: Contiguous codestream box "
297:                                    + "missing");
298:                }
299:
300:                return;
301:            }
302:
303:            /**
304:             * This method reads the File Type box
305:             *
306:             * @return false if the File Type box was not found or invalid else true
307:             *
308:             * @exception java.io.IOException If an I/O error ocurred.
309:             *
310:             * @exception java.io.EOFException If the end of file was reached
311:             * */
312:            public boolean readFileTypeBox(int length, long longLength)
313:                    throws IOException, EOFException {
314:                int nComp;
315:                boolean foundComp = false;
316:
317:                // Check for XLBox
318:                if (length == 1) { // Box has 8 byte length;
319:                    longLength = in.readLong();
320:                    throw new IOException("File too long.");
321:                }
322:
323:                // Check that this is a correct DBox value
324:                // Read Brand field
325:                if (in.readInt() != FT_BR)
326:                    return false;
327:
328:                // Read MinV field
329:                int minorVersion = in.readInt();
330:
331:                // Check that there is at least one FT_BR entry in in
332:                // compatibility list
333:                nComp = (length - 16) / 4; // Number of compatibilities.
334:                int[] comp = new int[nComp];
335:                for (int i = 0; i < nComp; i++) {
336:                    if ((comp[i] = in.readInt()) == FT_BR)
337:                        foundComp = true;
338:                }
339:                if (!foundComp)
340:                    return false;
341:
342:                if (metadata != null)
343:                    metadata
344:                            .addNode(new FileTypeBox(FT_BR, minorVersion, comp));
345:
346:                return true;
347:            }
348:
349:            /**
350:             * This method reads the JP2Header box
351:             *
352:             * @param pos The position in the file
353:             *
354:             * @param length The length of the JP2Header box
355:             *
356:             * @param long length The length of the JP2Header box if greater than
357:             * 1<<32
358:             *
359:             * @return false if the JP2Header box was not found or invalid else true
360:             *
361:             * @exception java.io.IOException If an I/O error ocurred.
362:             *
363:             * @exception java.io.EOFException If the end of file was reached
364:             * */
365:            public boolean readJP2HeaderBox(int length) throws IOException,
366:                    EOFException {
367:
368:                if (length == 0) // This can not be last box
369:                    throw new Error("Zero-length of JP2Header Box");
370:
371:                // Here the JP2Header data (DBox) would be read if we were to use it
372:                return true;
373:            }
374:
375:            /**
376:             * This method reads the Image Header box
377:             * @param length The length of the JP2Header box
378:             *
379:             * @return false if the JP2Header box was not found or invalid else true
380:             *
381:             * @exception java.io.IOException If an I/O error ocurred.
382:             *
383:             * @exception java.io.EOFException If the end of file was reached
384:             * */
385:            public boolean readImageHeaderBox(int length) throws IOException,
386:                    EOFException {
387:
388:                if (length == 0) // This can not be last box
389:                    throw new Error("Zero-length of JP2Header Box");
390:
391:                // Here the JP2Header data (DBox) would be read if we were to use it
392:
393:                height = in.readInt();
394:                width = in.readInt();
395:                numComp = in.readShort();
396:                bitDepth = in.readByte();
397:
398:                compressionType = in.readByte();
399:                unknownColor = in.readByte();
400:                intelProp = in.readByte();
401:
402:                if (metadata != null) {
403:
404:                    metadata
405:                            .addNode(new HeaderBox(height, width, numComp,
406:                                    bitDepth, compressionType, unknownColor,
407:                                    intelProp));
408:                }
409:                return true;
410:            }
411:
412:            /**
413:             * This method skips the Contiguous codestream box and adds position
414:             * of contiguous codestream to a vector
415:             *
416:             * @param pos The position in the file
417:             *
418:             * @param length The length of the JP2Header box
419:             *
420:             * @param long length The length of the JP2Header box if greater than 1<<32
421:             *
422:             * @return false if the Contiguous codestream box was not found or invalid
423:             * else true
424:             *
425:             * @exception java.io.IOException If an I/O error ocurred.
426:             *
427:             * @exception java.io.EOFException If the end of file was reached
428:             * */
429:            public boolean readContiguousCodeStreamBox(int length,
430:                    long longLength) throws IOException, EOFException {
431:
432:                // Add new codestream position to position vector
433:                int ccpos = in.getPos();
434:
435:                if (codeStreamPos == null)
436:                    codeStreamPos = new Vector();
437:                codeStreamPos.addElement(new Integer(ccpos));
438:
439:                // Add new codestream length to length vector
440:                if (codeStreamLength == null)
441:                    codeStreamLength = new Vector();
442:                codeStreamLength.addElement(new Integer(length));
443:
444:                return true;
445:            }
446:
447:            /**
448:             * This method reads the contents of the Intellectual property box
449:             * */
450:            public void readIntPropertyBox(int length) throws IOException {
451:                if (metadata != null) {
452:                    byte[] data = new byte[length];
453:                    in.readFully(data, 0, length);
454:                    metadata.addNode(new Box(length + 8, 0x6A703269, data));
455:                }
456:            }
457:
458:            /**
459:             * This method reads the contents of the XML box
460:             */
461:            public void readXMLBox(int length) throws IOException {
462:                if (metadata != null) {
463:                    byte[] data = new byte[length];
464:                    in.readFully(data, 0, length);
465:                    metadata.addNode(new XMLBox(data));
466:                }
467:            }
468:
469:            /**
470:             * This method reads the contents of the XML box
471:             */
472:            public void readURLBox(int length) throws IOException {
473:                if (metadata != null) {
474:                    byte[] data = new byte[length];
475:                    in.readFully(data, 0, length);
476:                    metadata.addNode(new DataEntryURLBox(data));
477:                }
478:            }
479:
480:            /**
481:             * This method reads the contents of the Intellectual property box
482:             */
483:            public void readUUIDBox(int length) throws IOException {
484:                if (metadata != null) {
485:                    byte[] data = new byte[length];
486:                    in.readFully(data, 0, length);
487:                    metadata.addNode(new UUIDBox(data));
488:                }
489:            }
490:
491:            /**
492:             * This method reads the contents of the UUID List box
493:             * */
494:            public void readUUIDListBox(int length) throws IOException {
495:                if (metadata != null) {
496:                    byte[] data = new byte[length];
497:                    in.readFully(data, 0, length);
498:                    metadata.addNode(new UUIDListBox(data));
499:                }
500:            }
501:
502:            /** This method reads the content of the palette box */
503:            public void readPaletteBox(int length) throws IOException {
504:                // Get current position in file
505:                int pos = in.getPos();
506:
507:                int lutSize = in.readShort();
508:                int numComp = in.readByte();
509:                compSize = new byte[numComp];
510:
511:                for (int i = 0; i < numComp; i++) {
512:                    compSize[i] = (byte) in.readByte();
513:                }
514:
515:                lut = new byte[numComp][lutSize];
516:
517:                for (int n = 0; n < lutSize; n++) {
518:                    for (int c = 0; c < numComp; c++) {
519:                        int depth = 1 + (compSize[c] & 0x7F);
520:                        if (depth > 32)
521:                            depth = 32;
522:                        int numBytes = (depth + 7) >> 3;
523:                        int mask = (1 << depth) - 1;
524:                        byte[] buf = new byte[numBytes];
525:                        in.readFully(buf, 0, numBytes);
526:
527:                        int val = 0;
528:
529:                        for (int k = 0; k < numBytes; k++) {
530:                            val = buf[k] + (val << 8);
531:                        }
532:                        lut[c][n] = (byte) val;
533:                    }
534:                }
535:                if (metadata != null) {
536:                    metadata.addNode(new PaletteBox(length, compSize, lut));
537:                }
538:            }
539:
540:            /** Read the component mapping channel.
541:             */
542:            public void readComponentMappingBox(int length) throws IOException {
543:                int num = length / 4;
544:
545:                comps = new short[num];
546:                type = new byte[num];
547:                maps = new byte[num];
548:
549:                for (int i = 0; i < num; i++) {
550:                    comps[i] = in.readShort();
551:                    type[i] = in.readByte();
552:                    maps[i] = in.readByte();
553:                }
554:
555:                if (metadata != null) {
556:                    metadata
557:                            .addNode(new ComponentMappingBox(comps, type, maps));
558:                }
559:            }
560:
561:            /**
562:             * This method reads the Channel Definition box
563:             *
564:             * @exception java.io.IOException If an I/O error ocurred.
565:             *
566:             */
567:            public void readChannelDefinitionBox(int length) throws IOException {
568:                int num = in.readShort();
569:                channels = new short[num];
570:                cType = new short[num];
571:                associations = new short[num];
572:
573:                for (int i = 0; i < num; i++) {
574:                    channels[i] = in.readShort();
575:                    cType[i] = in.readShort();
576:                    associations[i] = in.readShort();
577:                }
578:                if (metadata != null) {
579:                    metadata.addNode(new ChannelDefinitionBox(channels, cType,
580:                            associations));
581:                }
582:            }
583:
584:            /** Read the bits per component.
585:             */
586:            public void readBitsPerComponentBox(int length) throws IOException {
587:                bitDepths = new byte[length];
588:                in.readFully(bitDepths, 0, length);
589:
590:                if (metadata != null) {
591:                    metadata.addNode(new BitsPerComponentBox(bitDepths));
592:                }
593:            }
594:
595:            /** Read the color specifications.
596:             */
597:            public void readColourSpecificationBox(int length)
598:                    throws IOException {
599:                // read METHOD field
600:                byte method = (byte) in.readByte();
601:
602:                // read PREC field
603:                byte prec = (byte) in.readByte();
604:
605:                // read APPROX field
606:                byte approx = (byte) in.readByte();
607:
608:                if (method == 2) {
609:                    byte[] data = new byte[length - 3];
610:                    in.readFully(data, 0, data.length);
611:                    profile = ICC_Profile.getInstance(data);
612:                } else
613:                    // read EnumCS field
614:                    colorSpaceType = in.readInt();
615:
616:                if (metadata != null) {
617:                    metadata.addNode(new ColorSpecificationBox(method, prec,
618:                            approx, colorSpaceType, profile));
619:                }
620:            }
621:
622:            /** Read the resolution.
623:             */
624:            public void readResolutionBox(int type, int length)
625:                    throws IOException {
626:                byte[] data = new byte[length];
627:                in.readFully(data, 0, length);
628:                if (metadata != null) {
629:                    metadata.addNode(new ResolutionBox(type, data));
630:                }
631:            }
632:
633:            /**
634:             * This method creates and returns an array of positions to contiguous
635:             * codestreams in the file
636:             *
637:             * @return The positions of the contiguous codestreams in the file
638:             * */
639:            public long[] getCodeStreamPos() {
640:                int size = codeStreamPos.size();
641:                long[] pos = new long[size];
642:                for (int i = 0; i < size; i++)
643:                    pos[i] = ((Integer) (codeStreamPos.elementAt(i)))
644:                            .longValue();
645:                return pos;
646:            }
647:
648:            /**
649:             * This method returns the position of the first contiguous codestreams in
650:             * the file
651:             *
652:             * @return The position of the first contiguous codestream in the file
653:             * */
654:            public int getFirstCodeStreamPos() {
655:                return ((Integer) (codeStreamPos.elementAt(0))).intValue();
656:            }
657:
658:            /**
659:             * This method returns the length of the first contiguous codestreams in
660:             * the file
661:             *
662:             * @return The length of the first contiguous codestream in the file
663:             * */
664:            public int getFirstCodeStreamLength() {
665:                return ((Integer) (codeStreamLength.elementAt(0))).intValue();
666:            }
667:
668:            /**
669:             * Returns the color model created from the palette box.
670:             */
671:            public ColorModel getColorModel() {
672:                // Check 'numComp' instance variable here in case there is an
673:                // embedded palette such as in the pngsuite images pp0n2c16.png
674:                // and pp0n6a08.png.
675:                if (lut != null && numComp == 1) {
676:                    int numComp = lut.length;
677:
678:                    int maxDepth = 1 + (bitDepth & 0x7F);
679:
680:                    if (maps == null) {
681:                        maps = new byte[numComp];
682:                        for (int i = 0; i < numComp; i++)
683:                            maps[i] = (byte) i;
684:                    }
685:                    if (numComp == 3)
686:                        colorModel = new IndexColorModel(maxDepth,
687:                                lut[0].length, lut[maps[0]], lut[maps[1]],
688:                                lut[maps[2]]);
689:                    else if (numComp == 4)
690:                        colorModel = new IndexColorModel(maxDepth,
691:                                lut[0].length, lut[maps[0]], lut[maps[1]],
692:                                lut[maps[2]], lut[maps[3]]);
693:                } else if (channels != null) {
694:                    boolean hasAlpha = false;
695:                    int alphaChannel = numComp - 1;
696:
697:                    for (int i = 0; i < channels.length; i++) {
698:                        if (cType[i] == 1 && channels[i] == alphaChannel)
699:                            hasAlpha = true;
700:                    }
701:
702:                    boolean[] isPremultiplied = new boolean[] { false };
703:
704:                    if (hasAlpha) {
705:                        isPremultiplied = new boolean[alphaChannel];
706:
707:                        for (int i = 0; i < alphaChannel; i++)
708:                            isPremultiplied[i] = false;
709:
710:                        for (int i = 0; i < channels.length; i++) {
711:                            if (cType[i] == 2)
712:                                isPremultiplied[associations[i] - 1] = true;
713:                        }
714:
715:                        for (int i = 1; i < alphaChannel; i++)
716:                            isPremultiplied[0] &= isPremultiplied[i];
717:                    }
718:
719:                    ColorSpace cs = null;
720:                    if (profile != null)
721:                        cs = new ICC_ColorSpace(profile);
722:                    else if (colorSpaceType == CSB_ENUM_SRGB)
723:                        cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
724:                    else if (colorSpaceType == CSB_ENUM_GREY)
725:                        cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
726:                    else if (colorSpaceType == CSB_ENUM_YCC)
727:                        cs = ColorSpace.getInstance(ColorSpace.CS_PYCC);
728:
729:                    int[] bits = new int[numComp];
730:                    for (int i = 0; i < numComp; i++)
731:                        if (bitDepths != null)
732:                            bits[i] = (bitDepths[i] & 0x7F) + 1;
733:                        else
734:                            bits[i] = (bitDepth & 0x7F) + 1;
735:
736:                    int maxBitDepth = 1 + (bitDepth & 0x7F);
737:                    boolean isSigned = (bitDepth & 0x80) == 0x80;
738:                    if (bitDepths != null)
739:                        isSigned = (bitDepths[0] & 0x80) == 0x80;
740:
741:                    if (bitDepths != null)
742:                        for (int i = 0; i < numComp; i++)
743:                            if (bits[i] > maxBitDepth)
744:                                maxBitDepth = bits[i];
745:
746:                    int type = -1;
747:
748:                    if (maxBitDepth <= 8)
749:                        type = DataBuffer.TYPE_BYTE;
750:                    else if (maxBitDepth <= 16)
751:                        type = isSigned ? DataBuffer.TYPE_SHORT
752:                                : DataBuffer.TYPE_USHORT;
753:                    else if (maxBitDepth <= 32)
754:                        type = DataBuffer.TYPE_INT;
755:
756:                    if (type == -1)
757:                        return null;
758:
759:                    if (cs != null) {
760:                        colorModel = new ComponentColorModel(cs, bits,
761:                                hasAlpha, isPremultiplied[0],
762:                                hasAlpha ? Transparency.TRANSLUCENT
763:                                        : Transparency.OPAQUE, type);
764:                    }
765:                }
766:                return colorModel;
767:            }
768:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.