PageRenderTime 27ms CodeModel.GetById 15ms RepoModel.GetById 0ms 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. * */
  43. package ucar.jpeg.jj2000.j2k.fileformat.reader;
  44. import ucar.jpeg.jj2000.j2k.codestream.*;
  45. import ucar.jpeg.jj2000.j2k.fileformat.*;
  46. import ucar.jpeg.jj2000.j2k.util.*;
  47. import ucar.jpeg.jj2000.j2k.io.*;
  48. import java.util.*;
  49. import java.io.*;
  50. /**
  51. * This class reads the file format wrapper that may or may not exist around a
  52. * valid JPEG 2000 codestream. Since no information from the file format is
  53. * used in the actual decoding, this class simply goes through the file and
  54. * finds the first valid codestream.
  55. *
  56. * @see jj2000.j2k.fileformat.writer.FileFormatWriter
  57. * */
  58. public class FileFormatReader implements FileFormatBoxes {
  59. /** The random access from which the file format boxes are read */
  60. private RandomAccessIO in;
  61. /** The positions of the codestreams in the fileformat*/
  62. private Vector codeStreamPos;
  63. /** The lengths of the codestreams in the fileformat*/
  64. private Vector codeStreamLength;
  65. /** Flag indicating whether or not the JP2 file format is used */
  66. public boolean JP2FFUsed;
  67. /**
  68. * The constructor of the FileFormatReader
  69. *
  70. * @param in The RandomAccessIO from which to read the file format
  71. * */
  72. public FileFormatReader(RandomAccessIO in) {
  73. this.in = in;
  74. }
  75. /**
  76. * This method checks whether the given RandomAccessIO is a valid JP2 file
  77. * and if so finds the first codestream in the file. Currently, the
  78. * information in the codestream is not used
  79. *
  80. * @param in The RandomAccessIO from which to read the file format
  81. *
  82. * @exception java.io.IOException If an I/O error ocurred.
  83. *
  84. * @exception java.io.EOFException If end of file is reached
  85. * */
  86. public void readFileFormat() throws IOException, EOFException {
  87. int foundCodeStreamBoxes=0;
  88. int box;
  89. int length;
  90. long longLength=0;
  91. int pos;
  92. short marker;
  93. boolean jp2HeaderBoxFound=false;
  94. boolean lastBoxFound = false;
  95. try {
  96. // Go through the randomaccessio and find the first contiguous
  97. // codestream box. Check also that the File Format is correct
  98. // Make sure that the first 12 bytes is the JP2_SIGNATURE_BOX or
  99. // if not that the first 2 bytes is the SOC marker
  100. if(in.readInt() != 0x0000000c ||
  101. in.readInt() != JP2_SIGNATURE_BOX ||
  102. in.readInt() != 0x0d0a870a) { // Not a JP2 file
  103. in.seek(0);
  104. marker = (short)in.readShort();
  105. if(marker != Markers.SOC) //Standard syntax marker found
  106. throw new Error("File is neither valid JP2 file nor "+
  107. "valid JPEG 2000 codestream");
  108. JP2FFUsed = false;
  109. in.seek(0);
  110. return;
  111. }
  112. // The JP2 File format is being used
  113. JP2FFUsed = true;
  114. // Read File Type box
  115. if(!readFileTypeBox()) {
  116. // Not a valid JP2 file or codestream
  117. throw new Error("Invalid JP2 file: File Type box missing");
  118. }
  119. // Read all remaining boxes
  120. while(!lastBoxFound) {
  121. pos = in.getPos();
  122. length = in.readInt();
  123. if((pos+length) == in.length())
  124. lastBoxFound = true;
  125. box = in.readInt();
  126. if(length == 0){
  127. lastBoxFound = true;
  128. length = in.length()-in.getPos();
  129. } else if(length == 1) {
  130. longLength = in.readLong();
  131. throw new IOException("File too long.");
  132. } else longLength = (long) 0;
  133. switch(box) {
  134. case CONTIGUOUS_CODESTREAM_BOX:
  135. if(!jp2HeaderBoxFound) {
  136. throw new Error("Invalid JP2 file: JP2Header box not "+
  137. "found before Contiguous codestream "+
  138. "box ");
  139. }
  140. readContiguousCodeStreamBox(pos, length, longLength);
  141. break;
  142. case JP2_HEADER_BOX:
  143. if(jp2HeaderBoxFound)
  144. throw new Error("Invalid JP2 file: Multiple "+
  145. "JP2Header boxes found");
  146. readJP2HeaderBox(pos, length, longLength);
  147. jp2HeaderBoxFound = true;
  148. break;
  149. case INTELLECTUAL_PROPERTY_BOX:
  150. readIntPropertyBox(length);
  151. break;
  152. case XML_BOX:
  153. readXMLBox(length);
  154. break;
  155. case UUID_BOX:
  156. readUUIDBox(length);
  157. break;
  158. case UUID_INFO_BOX:
  159. readUUIDInfoBox(length);
  160. break;
  161. default:
  162. FacilityManager.getMsgLogger().
  163. printmsg(MsgLogger.WARNING,"Unknown box-type: 0x"+
  164. Integer.toHexString(box));
  165. }
  166. if(!lastBoxFound)
  167. in.seek(pos+length);
  168. }
  169. } catch(EOFException e) {
  170. throw new Error("EOF reached before finding Contiguous "+
  171. "Codestream Box");
  172. }
  173. if(codeStreamPos.size()==0) {
  174. // Not a valid JP2 file or codestream
  175. throw new Error("Invalid JP2 file: Contiguous codestream box "+
  176. "missing");
  177. }
  178. return;
  179. }
  180. /**
  181. * This method reads the File Type box.
  182. *
  183. * @return false if the File Type box was not found or invalid else true
  184. *
  185. * @exception java.io.IOException If an I/O error ocurred.
  186. * @exception java.io.EOFException If the end of file was reached
  187. * */
  188. public boolean readFileTypeBox()throws IOException, EOFException {
  189. int length;
  190. long longLength=0;
  191. int pos;
  192. int nComp;
  193. boolean foundComp=false;
  194. // Get current position in file
  195. pos = in.getPos();
  196. // Read box length (LBox)
  197. length = in.readInt();
  198. if(length==0) { // This can not be last box
  199. throw new Error("Zero-length of Profile Box");
  200. }
  201. // Check that this is a File Type box (TBox)
  202. if(in.readInt() != FILE_TYPE_BOX) {
  203. return false;
  204. }
  205. // Check for XLBox
  206. if(length==1) { // Box has 8 byte length;
  207. longLength = in.readLong();
  208. throw new IOException("File too long.");
  209. }
  210. // Read Brand field
  211. in.readInt();
  212. // Read MinV field
  213. in.readInt();
  214. // Check that there is at least one FT_BR entry in in
  215. // compatibility list
  216. nComp = (length - 16)/4; // Number of compatibilities.
  217. for(int i=nComp; i>0; i--){
  218. if(in.readInt() == FT_BR)
  219. foundComp = true;
  220. }
  221. if(!foundComp) {
  222. return false;
  223. }
  224. return true;
  225. }
  226. /**
  227. * This method reads the JP2Header box
  228. *
  229. * @param pos The position in the file
  230. *
  231. * @param length The length of the JP2Header box
  232. *
  233. * @param long length The length of the JP2Header box if greater than
  234. * 1<<32
  235. *
  236. * @return false if the JP2Header box was not found or invalid else true
  237. *
  238. * @exception java.io.IOException If an I/O error ocurred.
  239. *
  240. * @exception java.io.EOFException If the end of file was reached
  241. * */
  242. public boolean readJP2HeaderBox(long pos, int length, long longLength)
  243. throws IOException, EOFException {
  244. if(length==0) { // This can not be last box
  245. throw new Error("Zero-length of JP2Header Box");
  246. }
  247. // Here the JP2Header data (DBox) would be read if we were to use it
  248. return true;
  249. }
  250. /**
  251. * This method skips the Contiguous codestream box and adds position
  252. * of contiguous codestream to a vector
  253. *
  254. * @param pos The position in the file
  255. *
  256. * @param length The length of the JP2Header box
  257. *
  258. * @param long length The length of the JP2Header box if greater than 1<<32
  259. *
  260. * @return false if the Contiguous codestream box was not found or invalid
  261. * else true
  262. *
  263. * @exception java.io.IOException If an I/O error ocurred.
  264. *
  265. * @exception java.io.EOFException If the end of file was reached
  266. * */
  267. public boolean readContiguousCodeStreamBox(long pos, int length,
  268. long longLength)
  269. throws IOException, EOFException {
  270. // Add new codestream position to position vector
  271. int ccpos = in.getPos();
  272. if(codeStreamPos == null)
  273. codeStreamPos = new Vector();
  274. codeStreamPos.addElement(new Integer(ccpos));
  275. // Add new codestream length to length vector
  276. if(codeStreamLength == null)
  277. codeStreamLength = new Vector();
  278. codeStreamLength.addElement(new Integer(length));
  279. return true;
  280. }
  281. /**
  282. * This method reads the contents of the Intellectual property box
  283. * */
  284. public void readIntPropertyBox(int length){
  285. }
  286. /**
  287. * This method reads the contents of the XML box
  288. * */
  289. public void readXMLBox(int length){
  290. }
  291. /**
  292. * This method reads the contents of the Intellectual property box
  293. * */
  294. public void readUUIDBox(int length){
  295. }
  296. /**
  297. * This method reads the contents of the Intellectual property box
  298. * */
  299. public void readUUIDInfoBox(int length){
  300. }
  301. /**
  302. * This method creates and returns an array of positions to contiguous
  303. * codestreams in the file
  304. *
  305. * @return The positions of the contiguous codestreams in the file
  306. * */
  307. public long[] getCodeStreamPos(){
  308. int size = codeStreamPos.size();
  309. long[] pos = new long[size];
  310. for(int i=0 ; i<size ; i++)
  311. pos[i]=((Integer)(codeStreamPos.elementAt(i))).longValue();
  312. return pos;
  313. }
  314. /**
  315. * This method returns the position of the first contiguous codestreams in
  316. * the file
  317. *
  318. * @return The position of the first contiguous codestream in the file
  319. * */
  320. public int getFirstCodeStreamPos(){
  321. return ((Integer)(codeStreamPos.elementAt(0))).intValue();
  322. }
  323. /**
  324. * This method returns the length of the first contiguous codestreams in
  325. * the file
  326. *
  327. * @return The length of the first contiguous codestream in the file
  328. * */
  329. public int getFirstCodeStreamLength(){
  330. return ((Integer)(codeStreamLength.elementAt(0))).intValue();
  331. }
  332. }