PageRenderTime 57ms CodeModel.GetById 29ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/grib/src/main/java/ucar/jpeg/jj2000/j2k/fileformat/reader/FileFormatReader.java

https://github.com/blazetopher/THREDDS
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