KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > imageio > plugins > jpeg > MarkerSegment


1 /*
2  * @(#)MarkerSegment.java 1.7 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package com.sun.imageio.plugins.jpeg;
9
10 import javax.imageio.metadata.IIOInvalidTreeException JavaDoc;
11 import javax.imageio.metadata.IIOMetadataNode JavaDoc;
12 import javax.imageio.stream.ImageOutputStream JavaDoc;
13
14 import java.io.IOException JavaDoc;
15
16 import org.w3c.dom.Node JavaDoc;
17 import org.w3c.dom.NamedNodeMap JavaDoc;
18
19 /**
20  * All metadata is stored in MarkerSegments. Marker segments
21  * that we know about are stored in subclasses of this
22  * basic class, which used for unrecognized APPn marker
23  * segments. XXX break out UnknownMarkerSegment as a subclass
24  * and make this abstract, avoiding unused data field.
25  */

26 class MarkerSegment implements Cloneable JavaDoc {
27     protected static final int LENGTH_SIZE = 2; // length is 2 bytes
28
int tag; // See JPEG.java
29
int length; /* Sometimes needed by subclasses; doesn't include
30                       itself. Meaningful only if constructed from a stream */

31     byte [] data = null; // Raw segment data, used for unrecognized segments
32
boolean unknown = false; // Set to true if the tag is not recognized
33

34     /**
35      * Constructor for creating <code>MarkerSegment</code>s by reading
36      * from an <code>ImageInputStream</code>.
37      */

38     MarkerSegment(JPEGBuffer buffer) throws IOException JavaDoc {
39
40         buffer.loadBuf(3); // tag plus length
41
tag = buffer.buf[buffer.bufPtr++] & 0xff;
42         length = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
43         length |= buffer.buf[buffer.bufPtr++] & 0xff;
44         length -= 2; // JPEG length includes itself, we don't
45
buffer.bufAvail -= 3;
46         // Now that we know the true length, ensure that we've got it,
47
// or at least a bufferful if length is too big.
48
buffer.loadBuf(length);
49     }
50
51     /**
52      * Constructor used when creating segments other than by
53      * reading them from a stream.
54      */

55     MarkerSegment(int tag) {
56         this.tag = tag;
57         length = 0;
58     }
59
60     /**
61      * Construct a MarkerSegment from an "unknown" DOM Node.
62      */

63     MarkerSegment(Node JavaDoc node) throws IIOInvalidTreeException JavaDoc {
64         // The type of node should have been verified already.
65
// get the attribute and assign it to the tag
66
tag = getAttributeValue(node,
67                                 null,
68                                 "MarkerTag",
69                                 0, 255,
70                                 true);
71         length = 0;
72         // get the user object and clone it to the data
73
if (node instanceof IIOMetadataNode JavaDoc) {
74             IIOMetadataNode JavaDoc iioNode = (IIOMetadataNode JavaDoc) node;
75             try {
76                 data = (byte []) iioNode.getUserObject();
77             } catch (Exception JavaDoc e) {
78                 IIOInvalidTreeException JavaDoc newGuy =
79                     new IIOInvalidTreeException JavaDoc
80                     ("Can't get User Object", node);
81                 newGuy.initCause(e);
82                 throw newGuy;
83             }
84         } else {
85             throw new IIOInvalidTreeException JavaDoc
86                 ("Node must have User Object", node);
87         }
88     }
89
90     /**
91      * Deep copy of data array.
92      */

93     protected Object JavaDoc clone() {
94         MarkerSegment newGuy = null;
95         try {
96             newGuy = (MarkerSegment) super.clone();
97         } catch (CloneNotSupportedException JavaDoc e) {} // won't happen
98
if (this.data != null) {
99             newGuy.data = (byte[]) data.clone();
100         }
101         return newGuy;
102     }
103
104     /**
105      * We have determined that we don't know the type, so load
106      * the data using the length parameter.
107      */

108     void loadData(JPEGBuffer buffer) throws IOException JavaDoc {
109         data = new byte[length];
110         buffer.readData(data);
111     }
112
113     IIOMetadataNode JavaDoc getNativeNode() {
114         IIOMetadataNode JavaDoc node = new IIOMetadataNode JavaDoc("unknown");
115         node.setAttribute("MarkerTag", Integer.toString(tag));
116         node.setUserObject(data);
117         
118         return node;
119     }
120
121     static int getAttributeValue(Node JavaDoc node,
122                                  NamedNodeMap JavaDoc attrs,
123                                  String JavaDoc name,
124                                  int min,
125                                  int max,
126                                  boolean required)
127         throws IIOInvalidTreeException JavaDoc {
128         if (attrs == null) {
129             attrs = node.getAttributes();
130         }
131         String JavaDoc valueString = attrs.getNamedItem(name).getNodeValue();
132         int value = -1;
133         if (valueString == null) {
134             if (required) {
135                 throw new IIOInvalidTreeException JavaDoc
136                     (name + " attribute not found", node);
137             }
138         } else {
139               value = Integer.parseInt(valueString);
140               if ((value < min) || (value > max)) {
141                   throw new IIOInvalidTreeException JavaDoc
142                       (name + " attribute out of range", node);
143               }
144         }
145         return value;
146     }
147
148     /**
149      * Writes the marker, tag, and length. Note that length
150      * should be verified by the caller as a correct JPEG
151      * length, i.e it includes itself.
152      */

153     void writeTag(ImageOutputStream JavaDoc ios) throws IOException JavaDoc {
154         ios.write(0xff);
155         ios.write(tag);
156         write2bytes(ios, length);
157     }
158
159     /**
160      * Writes the data for this segment to the stream in
161      * valid JPEG format.
162      */

163     void write(ImageOutputStream JavaDoc ios) throws IOException JavaDoc {
164         length = 2 + ((data != null) ? data.length : 0);
165         writeTag(ios);
166         if (data != null) {
167             ios.write(data);
168         }
169     }
170
171     static void write2bytes(ImageOutputStream JavaDoc ios,
172                             int value) throws IOException JavaDoc {
173         ios.write((value >> 8) & 0xff);
174         ios.write(value & 0xff);
175             
176     }
177
178     void printTag(String JavaDoc prefix) {
179         System.out.println(prefix + " marker segment - marker = 0x"
180                            + Integer.toHexString(tag));
181         System.out.println("length: " + length);
182     }
183
184     void print() {
185         printTag("Unknown");
186         if (length > 10) {
187             System.out.print("First 5 bytes:");
188             for (int i=0;i<5;i++) {
189                 System.out.print(" Ox"
190                                  + Integer.toHexString((int)data[i]));
191             }
192             System.out.print("\nLast 5 bytes:");
193             for (int i=data.length-5;i<data.length;i++) {
194                 System.out.print(" Ox"
195                                  + Integer.toHexString((int)data[i]));
196             }
197         } else {
198             System.out.print("Data:");
199             for (int i=0;i<data.length;i++) {
200                 System.out.print(" Ox"
201                                  + Integer.toHexString((int)data[i]));
202             }
203         }
204         System.out.println();
205     }
206 }
207     
208
Popular Tags