Source Code Cross Referenced for Box.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » com » sun » media » imageioimpl » plugins » jpeg2000 » 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 » com.sun.media.imageioimpl.plugins.jpeg2000 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: Box.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.6 $
042:         * $Date: 2007/09/05 20:03:20 $
043:         * $State: Exp $
044:         */
045:        package com.sun.media.imageioimpl.plugins.jpeg2000;
046:
047:        import java.lang.reflect.Constructor;
048:        import java.lang.reflect.Method;
049:        import java.lang.reflect.InvocationTargetException;
050:        import javax.imageio.metadata.IIOInvalidTreeException;
051:        import javax.imageio.metadata.IIOMetadataNode;
052:
053:        import java.io.EOFException;
054:        import java.io.IOException;
055:        import java.util.Enumeration;
056:        import java.util.Hashtable;
057:        import java.util.StringTokenizer;
058:
059:        import org.w3c.dom.NamedNodeMap;
060:        import org.w3c.dom.Node;
061:        import org.w3c.dom.NodeList;
062:
063:        import javax.imageio.IIOException;
064:        import javax.imageio.stream.ImageOutputStream;
065:        import javax.imageio.stream.ImageInputStream;
066:
067:        import com.sun.media.imageioimpl.common.ImageUtil;
068:
069:        /**
070:         * This class is defined to create the box of JP2 file format.  A box has
071:         *  a length, a type, an optional extra length and its content.  The subclasses
072:         *  should explain the content information.
073:         */
074:        public class Box {
075:            /** The table to link tag names for all the JP2 boxes. */
076:            private static Hashtable names = new Hashtable();
077:
078:            // Initializes the hash table "names".
079:            static {
080:                //children for the root
081:                names.put(new Integer(0x6A502020), "JPEG2000SignatureBox");
082:                names.put(new Integer(0x66747970), "JPEG2000FileTypeBox");
083:
084:                // children for the boxes other than
085:                //JPEG2000SignatureBox/JPEG2000FileTypeBox
086:                names.put(new Integer(0x6A703269),
087:                        "JPEG2000IntellectualPropertyRightsBox");
088:                names.put(new Integer(0x786D6C20), "JPEG2000XMLBox");
089:                names.put(new Integer(0x75756964), "JPEG2000UUIDBox");
090:                names.put(new Integer(0x75696E66), "JPEG2000UUIDInfoBox");
091:
092:                // Children of HeadCStream
093:                names.put(new Integer(0x6a703268), "JPEG2000HeaderSuperBox");
094:                names.put(new Integer(0x6a703263), "JPEG2000CodeStreamBox");
095:
096:                // Children of JPEG2000HeaderSuperBox
097:                names.put(new Integer(0x69686472), "JPEG2000HeaderBox");
098:
099:                // Optional boxes in JPEG2000HeaderSuperBox
100:                names.put(new Integer(0x62706363),
101:                        "JPEG2000BitsPerComponentBox");
102:                names.put(new Integer(0x636f6c72),
103:                        "JPEG2000ColorSpecificationBox");
104:                names.put(new Integer(0x70636c72), "JPEG2000PaletteBox");
105:                names.put(new Integer(0x636d6170),
106:                        "JPEG2000ComponentMappingBox");
107:                names.put(new Integer(0x63646566),
108:                        "JPEG2000ChannelDefinitionBox");
109:                names.put(new Integer(0x72657320), "JPEG2000ResolutionBox");
110:
111:                // Children of JPEG2000ResolutionBox
112:                names.put(new Integer(0x72657363),
113:                        "JPEG2000CaptureResolutionBox");
114:                names.put(new Integer(0x72657364),
115:                        "JPEG2000DefaultDisplayResolutionBox");
116:
117:                // Children of JPEG2000UUIDInfoBox
118:                names.put(new Integer(0x756c7374), "JPEG2000UUIDListBox");
119:                names.put(new Integer(0x75726c20), "JPEG2000DataEntryURLBox");
120:            }
121:
122:            /** A Hashtable contains the class names for each type of the boxes.
123:             *  This table will be used to construct a Box object from a Node object
124:             *  by using reflection.
125:             */
126:            private static Hashtable boxClasses = new Hashtable();
127:
128:            // Initializes the hash table "boxClasses".
129:            static {
130:                //children for the root
131:                boxClasses.put(new Integer(0x6A502020), SignatureBox.class);
132:                boxClasses.put(new Integer(0x66747970), FileTypeBox.class);
133:
134:                // children for the boxes other than
135:                //JPEG2000SignatureBox/JPEG2000FileTypeBox
136:                boxClasses.put(new Integer(0x6A703269), Box.class);
137:                boxClasses.put(new Integer(0x786D6C20), XMLBox.class);
138:                boxClasses.put(new Integer(0x75756964), UUIDBox.class);
139:
140:                // Children of JPEG2000HeaderSuperBox
141:                boxClasses.put(new Integer(0x69686472), HeaderBox.class);
142:
143:                // Optional boxes in JPEG2000HeaderSuperBox
144:                boxClasses.put(new Integer(0x62706363),
145:                        BitsPerComponentBox.class);
146:                boxClasses.put(new Integer(0x636f6c72),
147:                        ColorSpecificationBox.class);
148:                boxClasses.put(new Integer(0x70636c72), PaletteBox.class);
149:                boxClasses.put(new Integer(0x636d6170),
150:                        ComponentMappingBox.class);
151:                boxClasses.put(new Integer(0x63646566),
152:                        ChannelDefinitionBox.class);
153:                boxClasses.put(new Integer(0x72657320), ResolutionBox.class);
154:
155:                // Children of JPEG2000ResolutionBox
156:                boxClasses.put(new Integer(0x72657363), ResolutionBox.class);
157:                boxClasses.put(new Integer(0x72657364), ResolutionBox.class);
158:
159:                // Children of JPEG2000UUIDInfoBox
160:                boxClasses.put(new Integer(0x756c7374), UUIDListBox.class);
161:                boxClasses.put(new Integer(0x75726c20), DataEntryURLBox.class);
162:            }
163:
164:            /** Returns the XML tag name defined in JP2 XML xsd/dtd for the box
165:             *  with the provided <code>type</code>. If the <code>type</code> is
166:             * not known, the string <code>"unknown"</code> is returned.
167:             */
168:            public static String getName(int type) {
169:                String name = (String) names.get(new Integer(type));
170:                return name == null ? "unknown" : name;
171:            }
172:
173:            /** Returns the Box class for the box with the provided <code>type</code>.
174:             */
175:            public static Class getBoxClass(int type) {
176:                if (type == 0x6a703268 || type == 0x72657320)
177:                    return null;
178:                return (Class) boxClasses.get(new Integer(type));
179:            }
180:
181:            /** Returns the type String based on the provided name. */
182:            public static String getTypeByName(String name) {
183:                Enumeration keys = names.keys();
184:                while (keys.hasMoreElements()) {
185:                    Integer i = (Integer) keys.nextElement();
186:                    if (name.equals(names.get(i)))
187:                        return getTypeString(i.intValue());
188:                }
189:                return null;
190:            }
191:
192:            /** Creates a <code>Box</code> object with the provided <code>type</code>
193:             *  based on the provided Node object based on reflection.
194:             */
195:            public static Box createBox(int type, Node node)
196:                    throws IIOInvalidTreeException {
197:                Class boxClass = (Class) boxClasses.get(new Integer(type));
198:
199:                try {
200:                    // gets the constructor with <code>Node</code parameter
201:                    Constructor cons = boxClass
202:                            .getConstructor(new Class[] { Node.class });
203:                    if (cons != null) {
204:                        return (Box) cons.newInstance(new Object[] { node });
205:                    }
206:                } catch (NoSuchMethodException e) {
207:                    // If exception throws, create a <code>Box</code> instance.
208:                    e.printStackTrace();
209:                    return new Box(node);
210:                } catch (InvocationTargetException e) {
211:                    e.printStackTrace();
212:                    return new Box(node);
213:                } catch (IllegalAccessException e) {
214:                    e.printStackTrace();
215:                    return new Box(node);
216:                } catch (InstantiationException e) {
217:                    e.printStackTrace();
218:                    return new Box(node);
219:                }
220:
221:                return null;
222:            }
223:
224:            /** Extracts the value of the attribute from name. */
225:            public static Object getAttribute(Node node, String name) {
226:                NamedNodeMap map = node.getAttributes();
227:                node = map.getNamedItem(name);
228:                return (node != null) ? node.getNodeValue() : null;
229:            }
230:
231:            /** Parses the byte array expressed by a string. */
232:            public static byte[] parseByteArray(String value) {
233:                if (value == null)
234:                    return null;
235:
236:                StringTokenizer token = new StringTokenizer(value);
237:                int count = token.countTokens();
238:
239:                byte[] buf = new byte[count];
240:                int i = 0;
241:                while (token.hasMoreElements()) {
242:                    buf[i++] = new Byte(token.nextToken()).byteValue();
243:                }
244:                return buf;
245:            }
246:
247:            /** Parses the integer array expressed a string. */
248:            protected static int[] parseIntArray(String value) {
249:                if (value == null)
250:                    return null;
251:
252:                StringTokenizer token = new StringTokenizer(value);
253:                int count = token.countTokens();
254:
255:                int[] buf = new int[count];
256:                int i = 0;
257:                while (token.hasMoreElements()) {
258:                    buf[i++] = new Integer(token.nextToken()).intValue();
259:                }
260:                return buf;
261:            }
262:
263:            /** Gets its <code>String</code> value from an <code>IIOMetadataNode</code>.
264:             */
265:            protected static String getStringElementValue(Node node) {
266:
267:                if (node instanceof  IIOMetadataNode) {
268:                    Object obj = ((IIOMetadataNode) node).getUserObject();
269:                    if (obj instanceof  String)
270:                        return (String) obj;
271:                }
272:
273:                return node.getNodeValue();
274:            }
275:
276:            /** Gets its byte value from an <code>IIOMetadataNode</code>. */
277:            protected static byte getByteElementValue(Node node) {
278:                if (node instanceof  IIOMetadataNode) {
279:                    Object obj = ((IIOMetadataNode) node).getUserObject();
280:                    if (obj instanceof  Byte)
281:                        return ((Byte) obj).byteValue();
282:                }
283:
284:                String value = node.getNodeValue();
285:                if (value != null)
286:                    return new Byte(value).byteValue();
287:                return (byte) 0;
288:            }
289:
290:            /** Gets its integer value from an <code>IIOMetadataNode</code>. */
291:            protected static int getIntElementValue(Node node) {
292:                if (node instanceof  IIOMetadataNode) {
293:                    Object obj = ((IIOMetadataNode) node).getUserObject();
294:                    if (obj instanceof  Integer)
295:                        return ((Integer) obj).intValue();
296:                }
297:
298:                String value = node.getNodeValue();
299:                if (value != null)
300:                    return new Integer(value).intValue();
301:                return 0;
302:            }
303:
304:            /** Gets its short value from an <code>IIOMetadataNode</code>. */
305:            protected static short getShortElementValue(Node node) {
306:                if (node instanceof  IIOMetadataNode) {
307:                    Object obj = ((IIOMetadataNode) node).getUserObject();
308:                    if (obj instanceof  Short)
309:                        return ((Short) obj).shortValue();
310:                }
311:                String value = node.getNodeValue();
312:                if (value != null)
313:                    return new Short(value).shortValue();
314:                return (short) 0;
315:            }
316:
317:            /** Gets the byte array from an <code>IIOMetadataNode</code>. */
318:            protected static byte[] getByteArrayElementValue(Node node) {
319:                if (node instanceof  IIOMetadataNode) {
320:                    Object obj = ((IIOMetadataNode) node).getUserObject();
321:                    if (obj instanceof  byte[])
322:                        return (byte[]) obj;
323:                }
324:
325:                return parseByteArray(node.getNodeValue());
326:            }
327:
328:            /** Gets the integer array from an <code>IIOMetadataNode</code>. */
329:            protected static int[] getIntArrayElementValue(Node node) {
330:                if (node instanceof  IIOMetadataNode) {
331:                    Object obj = ((IIOMetadataNode) node).getUserObject();
332:                    if (obj instanceof  int[])
333:                        return (int[]) obj;
334:                }
335:
336:                return parseIntArray(node.getNodeValue());
337:            }
338:
339:            /** Copies that four bytes of an integer into the byte array.  Necessary
340:             *  for the subclasses to compose the content array from the data elements
341:             */
342:            public static void copyInt(byte[] data, int pos, int value) {
343:                data[pos++] = (byte) (value >> 24);
344:                data[pos++] = (byte) (value >> 16);
345:                data[pos++] = (byte) (value >> 8);
346:                data[pos++] = (byte) (value & 0xFF);
347:            }
348:
349:            /** Converts the box type from integer to string. This is necessary because
350:             *  type is defined as String in xsd/dtd and integer in the box classes.
351:             */
352:            public static String getTypeString(int type) {
353:                byte[] buf = new byte[4];
354:                for (int i = 3; i >= 0; i--) {
355:                    buf[i] = (byte) (type & 0xFF);
356:                    type >>>= 8;
357:                }
358:
359:                return new String(buf);
360:            }
361:
362:            /**
363:             * Converts the box type from integer to string.  This is necessary because
364:             *  type is defined as String in xsd/dtd and integer in the box classes.
365:             */
366:            public static int getTypeInt(String s) {
367:                byte[] buf = s.getBytes();
368:                int t = buf[0];
369:                for (int i = 1; i < 4; i++) {
370:                    t = (t << 8) | buf[i];
371:                }
372:
373:                return t;
374:            }
375:
376:            /** Box length, extra length, type and content data array */
377:            protected int length;
378:            protected long extraLength;
379:            protected int type;
380:            protected byte[] data;
381:
382:            /** Constructs a <code>Box</code> instance using the provided
383:             *  the box type and the box content in byte array format.
384:             *
385:             * @param length The provided box length.
386:             * @param type The provided box type.
387:             * @param data The provided box content in a byte array.
388:             *
389:             * @throws IllegalArgumentException If the length of the content byte array
390:             *         is not length - 8.
391:             */
392:            public Box(int length, int type, byte[] data) {
393:                this .type = type;
394:                setLength(length);
395:                setContent(data);
396:            }
397:
398:            /** Constructs a <code>Box</code> instance using the provided
399:             *  the box type, the box extra length, and the box content in byte
400:             *  array format.  In this case, the length of the box is set to 1,
401:             *  which indicates the extra length is meaningful.
402:             *
403:             * @param length The provided box length.
404:             * @param type The provided box type.
405:             * @param extraLength The provided box extra length.
406:             * @param data The provided box content in a byte array.
407:             *
408:             * @throws IllegalArgumentException If the length of the content byte array
409:             *         is not extra length - 16.
410:             */
411:            public Box(int length, int type, long extraLength, byte[] data) {
412:                this .type = type;
413:                setLength(length);
414:                if (length == 1)
415:                    setExtraLength(extraLength);
416:                setContent(data);
417:            }
418:
419:            /** Constructs a <code>Box</code> instance from the provided <code>
420:             *  ImageInputStream</code> at the specified position.
421:             *
422:             * @param iis The <code>ImageInputStream</code> contains the box.
423:             * @param pos The position from where to read the box.
424:             * @throws IOException If any IOException is thrown in the called read
425:             *         methods.
426:             */
427:            public Box(ImageInputStream iis, int pos) throws IOException {
428:                read(iis, pos);
429:            }
430:
431:            /**
432:             * Constructs a Box from an "unknown" Node.  This node has at
433:             * least the attribute "Type", and may have the attribute "Length",
434:             * "ExtraLength" and a child "Content".  The child node content is a
435:             * IIOMetaDataNode with a byte[] user object.
436:             */
437:            public Box(Node node) throws IIOInvalidTreeException {
438:                NodeList children = node.getChildNodes();
439:
440:                String value = (String) Box.getAttribute(node, "Type");
441:                type = getTypeInt(value);
442:                if (value == null || names.get(new Integer(type)) == null)
443:                    throw new IIOInvalidTreeException("Type is not defined",
444:                            node);
445:
446:                value = (String) Box.getAttribute(node, "Length");
447:                if (value != null)
448:                    length = new Integer(value).intValue();
449:
450:                value = (String) Box.getAttribute(node, "ExtraLength");
451:                if (value != null)
452:                    extraLength = new Long(value).longValue();
453:
454:                for (int i = 0; i < children.getLength(); i++) {
455:                    Node child = children.item(i);
456:                    if ("Content".equals(child.getNodeName())) {
457:                        if (child instanceof  IIOMetadataNode) {
458:                            IIOMetadataNode cnode = (IIOMetadataNode) child;
459:                            try {
460:                                data = (byte[]) cnode.getUserObject();
461:                            } catch (Exception e) {
462:                            }
463:                        } else {
464:                            data = getByteArrayElementValue(child);
465:                        }
466:
467:                        if (data == null) {
468:                            value = node.getNodeValue();
469:                            if (value != null)
470:                                data = value.getBytes();
471:                        }
472:                    }
473:                }
474:            }
475:
476:            /** Creates an <code>IIOMetadataNode</code> from this
477:             *  box.  The format of this node is defined in the XML dtd and xsd
478:             *  for the JP2 image file.
479:             */
480:            public IIOMetadataNode getNativeNode() {
481:                String name = Box.getName(getType());
482:                if (name == null)
483:                    name = "unknown";
484:
485:                IIOMetadataNode node = new IIOMetadataNode(name);
486:                setDefaultAttributes(node);
487:                IIOMetadataNode child = new IIOMetadataNode("Content");
488:                child.setUserObject(data);
489:                child.setNodeValue(ImageUtil.convertObjectToString(data));
490:                node.appendChild(child);
491:
492:                return node;
493:            }
494:
495:            /** Creates an <code>IIOMetadataNode</code> from this
496:             *  box.  The format of this node is defined in the XML dtd and xsd
497:             *  for the JP2 image file.
498:             *
499:             *  This method is designed for the types of boxes whose XML tree
500:             *  only has 2 levels.
501:             */
502:            protected IIOMetadataNode getNativeNodeForSimpleBox() {
503:                try {
504:                    Method m = this .getClass().getMethod("getElementNames",
505:                            (Class[]) null);
506:                    String[] elementNames = (String[]) m.invoke(null,
507:                            (Object[]) null);
508:
509:                    IIOMetadataNode node = new IIOMetadataNode(Box
510:                            .getName(getType()));
511:                    setDefaultAttributes(node);
512:                    for (int i = 0; i < elementNames.length; i++) {
513:                        IIOMetadataNode child = new IIOMetadataNode(
514:                                elementNames[i]);
515:                        m = this .getClass().getMethod("get" + elementNames[i],
516:                                (Class[]) null);
517:                        Object obj = m.invoke(this , (Object[]) null);
518:                        child.setUserObject(obj);
519:                        child
520:                                .setNodeValue(ImageUtil
521:                                        .convertObjectToString(obj));
522:                        node.appendChild(child);
523:                    }
524:                    return node;
525:                } catch (Exception e) {
526:                    throw new IllegalArgumentException(I18N.getString("Box0"));
527:                }
528:            }
529:
530:            /** Sets the default attributes, "Length", "Type", and "ExtraLength", to
531:             *  the provided <code>IIOMetadataNode</code>.
532:             */
533:            protected void setDefaultAttributes(IIOMetadataNode node) {
534:                node.setAttribute("Length", Integer.toString(length));
535:                node.setAttribute("Type", getTypeString(type));
536:
537:                if (length == 1) {
538:                    node
539:                            .setAttribute("ExtraLength", Long
540:                                    .toString(extraLength));
541:                }
542:            }
543:
544:            /** Returns the box length. */
545:            public int getLength() {
546:                return length;
547:            }
548:
549:            /** Returns the box type. */
550:            public int getType() {
551:                return type;
552:            }
553:
554:            /** Returns the box extra length. */
555:            public long getExtraLength() {
556:                return extraLength;
557:            }
558:
559:            /** Returns the box content in byte array. */
560:            public byte[] getContent() {
561:                if (data == null)
562:                    compose();
563:                return data;
564:            }
565:
566:            /** Sets the box length to the provided value. */
567:            public void setLength(int length) {
568:                this .length = length;
569:            }
570:
571:            /** Sets the box extra length length to the provided value. */
572:            public void setExtraLength(long extraLength) {
573:                if (length != 1)
574:                    throw new IllegalArgumentException(I18N.getString("Box1"));
575:                this .extraLength = extraLength;
576:            }
577:
578:            /** Sets the box content.  If the content length is not length -8 or
579:             *  extra length - 16, IllegalArgumentException will be thrown.
580:             */
581:            public void setContent(byte[] data) {
582:                if (data != null
583:                        && ((length == 1 && (extraLength - 16 != data.length)) || (length != 1 && length - 8 != data.length)))
584:                    throw new IllegalArgumentException(I18N.getString("Box2"));
585:                this .data = data;
586:                if (data != null)
587:                    parse(data);
588:            }
589:
590:            /** Writes this box instance into a <code>ImageOutputStream</code>. */
591:            public void write(ImageOutputStream ios) throws IOException {
592:                ios.writeInt(length);
593:                ios.writeInt(type);
594:                if (length == 1) {
595:                    ios.writeLong(extraLength);
596:                    ios.write(data, 0, (int) extraLength);
597:                } else if (data != null)
598:                    ios.write(data, 0, length);
599:            }
600:
601:            /** Reads a box from the <code>ImageInputStream</code. at the provided
602:             *  position.
603:             */
604:            public void read(ImageInputStream iis, int pos) throws IOException {
605:                iis.mark();
606:                iis.seek(pos);
607:                length = iis.readInt();
608:                type = iis.readInt();
609:                int dataLength = 0;
610:                if (length == 0) {
611:                    // Length unknown at time of stream creation.
612:                    long streamLength = iis.length();
613:                    if (streamLength != -1)
614:                        // Calculate box length from known stream length.
615:                        dataLength = (int) (streamLength - iis
616:                                .getStreamPosition());
617:                    else {
618:                        // Calculate box length by reading to EOF.
619:                        long dataPos = iis.getStreamPosition();
620:                        int bufLen = 1024;
621:                        byte[] buf = new byte[bufLen];
622:                        long savePos = dataPos;
623:                        try {
624:                            iis.readFully(buf);
625:                            dataLength += bufLen;
626:                            savePos = iis.getStreamPosition();
627:                        } catch (EOFException eofe) {
628:                            iis.seek(savePos);
629:                            while (iis.read() != -1)
630:                                dataLength++;
631:                        }
632:                        iis.seek(dataPos);
633:                    }
634:                } else if (length == 1) {
635:                    // Length given by XL parameter.
636:                    extraLength = iis.readLong();
637:                    dataLength = (int) (extraLength - 16);
638:                } else if (length >= 8 && length < (1 << 32)) {
639:                    // Length given by L parameter.
640:                    dataLength = length - 8;
641:                } else {
642:                    // Illegal value for L parameter.
643:                    throw new IIOException("Illegal value " + length
644:                            + " for box length parameter.");
645:                }
646:                data = new byte[dataLength];
647:                iis.readFully(data);
648:                iis.reset();
649:            }
650:
651:            /** Parses the data elements from the byte array.  The subclasses should
652:             *  override this method.
653:             */
654:            protected void parse(byte[] data) {
655:            }
656:
657:            /** Composes the content byte array from the data elements.
658:             */
659:            protected void compose() {
660:            }
661:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.