/grib/src/main/java/ucar/jpeg/jj2000/j2k/fileformat/reader/FileFormatReader.java
Java | 392 lines | 171 code | 60 blank | 161 comment | 33 complexity | 35c3deac38f61b2c39f111a4934433d4 MD5 | raw file
1/*
2 * cvs identifier:
3 *
4 * $Id: FileFormatReader.java,v 1.16 2002/07/25 14:04:08 grosbois Exp $
5 *
6 * Class: FileFormatReader
7 *
8 * Description: Reads the file format
9 *
10 *
11 *
12 * COPYRIGHT:
13 *
14 * This software module was originally developed by Rapha?l Grosbois and
15 * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
16 * Askel?f (Ericsson Radio Systems AB); and Bertrand Berthelot, David
17 * Bouchard, F?lix Henry, Gerard Mozelle and Patrice Onno (Canon Research
18 * Centre France S.A) in the course of development of the JPEG2000
19 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
20 * software module is an implementation of a part of the JPEG 2000
21 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
22 * Systems AB and Canon Research Centre France S.A (collectively JJ2000
23 * Partners) agree not to assert against ISO/IEC and users of the JPEG
24 * 2000 Standard (Users) any of their rights under the copyright, not
25 * including other intellectual property rights, for this software module
26 * with respect to the usage by ISO/IEC and Users of this software module
27 * or modifications thereof for use in hardware or software products
28 * claiming conformance to the JPEG 2000 Standard. Those intending to use
29 * this software module in hardware or software products are advised that
30 * their use may infringe existing patents. The original developers of
31 * this software module, JJ2000 Partners and ISO/IEC assume no liability
32 * for use of this software module or modifications thereof. No license
33 * or right to this software module is granted for non JPEG 2000 Standard
34 * conforming products. JJ2000 Partners have full right to use this
35 * software module for his/her own purpose, assign or donate this
36 * software module to any third party and to inhibit third parties from
37 * using this software module for non JPEG 2000 Standard conforming
38 * products. This copyright notice must be included in all copies or
39 * derivative works of this software module.
40 *
41 * Copyright (c) 1999/2000 JJ2000 Partners.
42 * */
43package ucar.jpeg.jj2000.j2k.fileformat.reader;
44
45import ucar.jpeg.jj2000.j2k.codestream.*;
46import ucar.jpeg.jj2000.j2k.fileformat.*;
47import ucar.jpeg.jj2000.j2k.util.*;
48import ucar.jpeg.jj2000.j2k.io.*;
49
50import java.util.*;
51import java.io.*;
52
53/**
54 * This class reads the file format wrapper that may or may not exist around a
55 * valid JPEG 2000 codestream. Since no information from the file format is
56 * used in the actual decoding, this class simply goes through the file and
57 * finds the first valid codestream.
58 *
59 * @see jj2000.j2k.fileformat.writer.FileFormatWriter
60 * */
61public class FileFormatReader implements FileFormatBoxes {
62
63 /** The random access from which the file format boxes are read */
64 private RandomAccessIO in;
65
66 /** The positions of the codestreams in the fileformat*/
67 private Vector codeStreamPos;
68
69 /** The lengths of the codestreams in the fileformat*/
70 private Vector codeStreamLength;
71
72 /** Flag indicating whether or not the JP2 file format is used */
73 public boolean JP2FFUsed;
74
75 /**
76 * The constructor of the FileFormatReader
77 *
78 * @param in The RandomAccessIO from which to read the file format
79 * */
80 public FileFormatReader(RandomAccessIO in) {
81 this.in = in;
82 }
83
84 /**
85 * This method checks whether the given RandomAccessIO is a valid JP2 file
86 * and if so finds the first codestream in the file. Currently, the
87 * information in the codestream is not used
88 *
89 * @param in The RandomAccessIO from which to read the file format
90 *
91 * @exception java.io.IOException If an I/O error ocurred.
92 *
93 * @exception java.io.EOFException If end of file is reached
94 * */
95 public void readFileFormat() throws IOException, EOFException {
96
97 int foundCodeStreamBoxes=0;
98 int box;
99 int length;
100 long longLength=0;
101 int pos;
102 short marker;
103 boolean jp2HeaderBoxFound=false;
104 boolean lastBoxFound = false;
105
106 try {
107
108 // Go through the randomaccessio and find the first contiguous
109 // codestream box. Check also that the File Format is correct
110
111 // Make sure that the first 12 bytes is the JP2_SIGNATURE_BOX or
112 // if not that the first 2 bytes is the SOC marker
113 if(in.readInt() != 0x0000000c ||
114 in.readInt() != JP2_SIGNATURE_BOX ||
115 in.readInt() != 0x0d0a870a) { // Not a JP2 file
116 in.seek(0);
117
118 marker = (short)in.readShort();
119 if(marker != Markers.SOC) //Standard syntax marker found
120 throw new Error("File is neither valid JP2 file nor "+
121 "valid JPEG 2000 codestream");
122 JP2FFUsed = false;
123 in.seek(0);
124 return;
125 }
126
127 // The JP2 File format is being used
128 JP2FFUsed = true;
129
130 // Read File Type box
131 if(!readFileTypeBox()) {
132 // Not a valid JP2 file or codestream
133 throw new Error("Invalid JP2 file: File Type box missing");
134 }
135
136 // Read all remaining boxes
137 while(!lastBoxFound) {
138 pos = in.getPos();
139 length = in.readInt();
140 if((pos+length) == in.length())
141 lastBoxFound = true;
142
143 box = in.readInt();
144 if(length == 0){
145 lastBoxFound = true;
146 length = in.length()-in.getPos();
147 } else if(length == 1) {
148 longLength = in.readLong();
149 throw new IOException("File too long.");
150 } else longLength = (long) 0;
151
152 switch(box) {
153 case CONTIGUOUS_CODESTREAM_BOX:
154 if(!jp2HeaderBoxFound) {
155 throw new Error("Invalid JP2 file: JP2Header box not "+
156 "found before Contiguous codestream "+
157 "box ");
158 }
159 readContiguousCodeStreamBox(pos, length, longLength);
160 break;
161 case JP2_HEADER_BOX:
162 if(jp2HeaderBoxFound)
163 throw new Error("Invalid JP2 file: Multiple "+
164 "JP2Header boxes found");
165 readJP2HeaderBox(pos, length, longLength);
166 jp2HeaderBoxFound = true;
167 break;
168 case INTELLECTUAL_PROPERTY_BOX:
169 readIntPropertyBox(length);
170 break;
171 case XML_BOX:
172 readXMLBox(length);
173 break;
174 case UUID_BOX:
175 readUUIDBox(length);
176 break;
177 case UUID_INFO_BOX:
178 readUUIDInfoBox(length);
179 break;
180 default:
181 FacilityManager.getMsgLogger().
182 printmsg(MsgLogger.WARNING,"Unknown box-type: 0x"+
183 Integer.toHexString(box));
184 }
185 if(!lastBoxFound)
186 in.seek(pos+length);
187 }
188 } catch(EOFException e) {
189 throw new Error("EOF reached before finding Contiguous "+
190 "Codestream Box");
191 }
192
193 if(codeStreamPos.size()==0) {
194 // Not a valid JP2 file or codestream
195 throw new Error("Invalid JP2 file: Contiguous codestream box "+
196 "missing");
197 }
198
199 return;
200
201 }
202
203 /**
204 * This method reads the File Type box.
205 *
206 * @return false if the File Type box was not found or invalid else true
207 *
208 * @exception java.io.IOException If an I/O error ocurred.
209 * @exception java.io.EOFException If the end of file was reached
210 * */
211 public boolean readFileTypeBox()throws IOException, EOFException {
212 int length;
213 long longLength=0;
214 int pos;
215 int nComp;
216 boolean foundComp=false;
217
218 // Get current position in file
219 pos = in.getPos();
220
221 // Read box length (LBox)
222 length = in.readInt();
223 if(length==0) { // This can not be last box
224 throw new Error("Zero-length of Profile Box");
225 }
226
227 // Check that this is a File Type box (TBox)
228 if(in.readInt() != FILE_TYPE_BOX) {
229 return false;
230 }
231
232 // Check for XLBox
233 if(length==1) { // Box has 8 byte length;
234 longLength = in.readLong();
235 throw new IOException("File too long.");
236 }
237
238 // Read Brand field
239 in.readInt();
240
241 // Read MinV field
242 in.readInt();
243
244 // Check that there is at least one FT_BR entry in in
245 // compatibility list
246 nComp = (length - 16)/4; // Number of compatibilities.
247 for(int i=nComp; i>0; i--){
248 if(in.readInt() == FT_BR)
249 foundComp = true;
250 }
251 if(!foundComp) {
252 return false;
253 }
254
255 return true;
256 }
257
258 /**
259 * This method reads the JP2Header box
260 *
261 * @param pos The position in the file
262 *
263 * @param length The length of the JP2Header box
264 *
265 * @param long length The length of the JP2Header box if greater than
266 * 1<<32
267 *
268 * @return false if the JP2Header box was not found or invalid else true
269 *
270 * @exception java.io.IOException If an I/O error ocurred.
271 *
272 * @exception java.io.EOFException If the end of file was reached
273 * */
274 public boolean readJP2HeaderBox(long pos, int length, long longLength)
275 throws IOException, EOFException {
276
277 if(length==0) { // This can not be last box
278 throw new Error("Zero-length of JP2Header Box");
279 }
280
281 // Here the JP2Header data (DBox) would be read if we were to use it
282
283 return true;
284 }
285
286 /**
287 * This method skips the Contiguous codestream box and adds position
288 * of contiguous codestream to a vector
289 *
290 * @param pos The position in the file
291 *
292 * @param length The length of the JP2Header box
293 *
294 * @param long length The length of the JP2Header box if greater than 1<<32
295 *
296 * @return false if the Contiguous codestream box was not found or invalid
297 * else true
298 *
299 * @exception java.io.IOException If an I/O error ocurred.
300 *
301 * @exception java.io.EOFException If the end of file was reached
302 * */
303 public boolean readContiguousCodeStreamBox(long pos, int length,
304 long longLength)
305 throws IOException, EOFException {
306
307 // Add new codestream position to position vector
308 int ccpos = in.getPos();
309
310 if(codeStreamPos == null)
311 codeStreamPos = new Vector();
312 codeStreamPos.addElement(new Integer(ccpos));
313
314 // Add new codestream length to length vector
315 if(codeStreamLength == null)
316 codeStreamLength = new Vector();
317 codeStreamLength.addElement(new Integer(length));
318
319 return true;
320 }
321
322 /**
323 * This method reads the contents of the Intellectual property box
324 * */
325 public void readIntPropertyBox(int length){
326 }
327
328 /**
329 * This method reads the contents of the XML box
330 * */
331 public void readXMLBox(int length){
332 }
333
334 /**
335 * This method reads the contents of the Intellectual property box
336 * */
337 public void readUUIDBox(int length){
338 }
339
340 /**
341 * This method reads the contents of the Intellectual property box
342 * */
343 public void readUUIDInfoBox(int length){
344 }
345
346 /**
347 * This method creates and returns an array of positions to contiguous
348 * codestreams in the file
349 *
350 * @return The positions of the contiguous codestreams in the file
351 * */
352 public long[] getCodeStreamPos(){
353 int size = codeStreamPos.size();
354 long[] pos = new long[size];
355 for(int i=0 ; i<size ; i++)
356 pos[i]=((Integer)(codeStreamPos.elementAt(i))).longValue();
357 return pos;
358 }
359
360 /**
361 * This method returns the position of the first contiguous codestreams in
362 * the file
363 *
364 * @return The position of the first contiguous codestream in the file
365 * */
366 public int getFirstCodeStreamPos(){
367 return ((Integer)(codeStreamPos.elementAt(0))).intValue();
368 }
369
370 /**
371 * This method returns the length of the first contiguous codestreams in
372 * the file
373 *
374 * @return The length of the first contiguous codestream in the file
375 * */
376 public int getFirstCodeStreamLength(){
377 return ((Integer)(codeStreamLength.elementAt(0))).intValue();
378 }
379
380}
381
382
383
384
385
386
387
388
389
390
391
392