Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2007, Digital Signal Processing Laboratory, Università degli studi di Perugia (UPG), Italy
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  *
  14.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
  15.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  18.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  19.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  20.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  21.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  22.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  23.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  24.  * POSSIBILITY OF SUCH DAMAGE.
  25.  */
  26. #include "OPJViewer.h"
  27.  
  28. /* defines */
  29. #define SHORT_DESCR_LEN        32
  30. #define LONG_DESCR_LEN         256
  31.  
  32. /* enumeration for file formats */
  33. #define J2FILENUM              4
  34. typedef enum {
  35.  
  36.         JP2_FILE,
  37.         J2K_FILE,
  38.                 MJ2_FILE,
  39.                 UNK_FILE
  40.  
  41. } j2filetype;
  42.  
  43. /* enumeration for the box types */
  44. #define j22boxNUM                23
  45. typedef enum {
  46.  
  47.                         FILE_BOX,
  48.                         JP_BOX,
  49.                         FTYP_BOX,
  50.                         JP2H_BOX,
  51.                         IHDR_BOX,
  52.                         COLR_BOX,
  53.                         JP2C_BOX,
  54.                         JP2I_BOX,
  55.                         XML_BOX,
  56.                         UUID_BOX,
  57.                         UINF_BOX,
  58.                         MOOV_BOX,
  59.                         MVHD_BOX,
  60.                         TRAK_BOX,
  61.                         TKHD_BOX,
  62.                         MDIA_BOX,
  63.                         MDHD_BOX,
  64.                         HDLR_BOX,
  65.                         MINF_BOX,
  66.                         VMHD_BOX,
  67.                         STBL_BOX,
  68.                         STSD_BOX,
  69.                         STSZ_BOX,
  70.                         MJP2_BOX,
  71.                         MDAT_BOX,
  72.                         ANY_BOX,
  73.                         UNK_BOX
  74.  
  75. } j22boxtype;
  76.  
  77. /* the box structure itself */
  78. struct boxdef {
  79.  
  80.         char                  value[5];                 /* hexadecimal value/string*/
  81.                 char                  name[SHORT_DESCR_LEN];    /* short description       */
  82.                 char                  descr[LONG_DESCR_LEN];    /* long  description       */
  83.                 int                   sbox;                     /* is it a superbox?       */
  84.                 int                   req[J2FILENUM];           /* mandatory box           */
  85.                 j22boxtype             ins;                      /* contained in box...     */
  86.  
  87. };
  88.  
  89.  
  90. /* jp2 family box signatures */
  91. #define FILE_SIGN           ""
  92. #define JP_SIGN             "jP\040\040"
  93. #define FTYP_SIGN           "ftyp"
  94. #define JP2H_SIGN           "jp2h"
  95. #define IHDR_SIGN           "ihdr"
  96. #define COLR_SIGN           "colr"
  97. #define JP2C_SIGN           "jp2c"
  98. #define JP2I_SIGN           "jp2i"
  99. #define XML_SIGN            "xml\040"
  100. #define UUID_SIGN           "uuid"
  101. #define UINF_SIGN           "uinf"
  102. #define MOOV_SIGN           "moov"
  103. #define MVHD_SIGN           "mvhd"
  104. #define TRAK_SIGN           "trak"
  105. #define TKHD_SIGN           "tkhd"
  106. #define MDIA_SIGN           "mdia"
  107. #define MDHD_SIGN           "mdhd"
  108. #define HDLR_SIGN           "hdlr"
  109. #define MINF_SIGN           "minf"
  110. #define VMHD_SIGN           "vmhd"
  111. #define STBL_SIGN           "stbl"
  112. #define STSD_SIGN           "stsd"
  113. #define STSZ_SIGN           "stsz"
  114. #define MJP2_SIGN           "mjp2"
  115. #define MDAT_SIGN           "mdat"
  116. #define ANY_SIGN                        ""
  117. #define UNK_SIGN            ""
  118.  
  119. /* the possible boxes */
  120. struct boxdef j22box[] =
  121. {
  122. /* sign */      {FILE_SIGN,
  123. /* short */     "placeholder for nothing",
  124. /* long */      "Nothing to say",
  125. /* sbox */      0,
  126. /* req */       {1, 1, 1},
  127. /* ins */       FILE_BOX},
  128.  
  129. /* sign */      {JP_SIGN,
  130. /* short */     "JPEG 2000 Signature box",
  131. /* long */      "This box uniquely identifies the file as being part of the JPEG 2000 family of files",
  132. /* sbox */      0,
  133. /* req */       {1, 1, 1},
  134. /* ins */       FILE_BOX},
  135.  
  136. /* sign */      {FTYP_SIGN,
  137. /* short */     "File Type box",
  138. /* long */      "This box specifies file type, version and compatibility information, including specifying if this file "
  139.                         "is a conforming JP2 file or if it can be read by a conforming JP2 reader",
  140. /* sbox */      0,
  141. /* req */       {1, 1, 1},
  142. /* ins */       FILE_BOX},
  143.  
  144. /* sign */      {JP2H_SIGN,
  145. /* short */     "JP2 Header box",
  146. /* long */      "This box contains a series of boxes that contain header-type information about the file",
  147. /* sbox */      1,
  148. /* req */       {1, 1, 1},
  149. /* ins */       FILE_BOX},
  150.  
  151. /* sign */      {IHDR_SIGN,
  152. /* short */     "Image Header box",
  153. /* long */      "This box specifies the size of the image and other related fields",
  154. /* sbox */      0,
  155. /* req */       {1, 1, 1},
  156. /* ins */       JP2H_BOX},
  157.  
  158. /* sign */      {COLR_SIGN,
  159. /* short */     "Colour Specification box",
  160. /* long */      "This box specifies the colourspace of the image",
  161. /* sbox */      0,
  162. /* req */       {1, 1, 1},
  163. /* ins */       JP2H_BOX},
  164.  
  165. /* sign */      {JP2C_SIGN,
  166. /* short */     "Contiguous Codestream box",
  167. /* long */      "This box contains the codestream as defined by Annex A",
  168. /* sbox */      0,
  169. /* req */       {1, 1, 1},
  170. /* ins */       FILE_BOX},
  171.  
  172. /* sign */      {JP2I_SIGN,
  173. /* short */     "Intellectual Property box",
  174. /* long */      "This box contains intellectual property information about the image",
  175. /* sbox */      0,
  176. /* req */       {0, 0, 0},
  177. /* ins */       FILE_BOX},
  178.  
  179. /* sign */      {XML_SIGN,
  180. /* short */     "XML box",
  181. /* long */      "This box provides a tool by which vendors can add XML formatted information to a JP2 file",
  182. /* sbox */      0,
  183. /* req */       {0, 0, 0},
  184. /* ins */       FILE_BOX},
  185.  
  186. /* sign */      {UUID_SIGN,
  187. /* short */     "UUID box",
  188. /* long */      "This box provides a tool by which vendors can add additional information to a file "
  189.                         "without risking conflict with other vendors",
  190. /* sbox */      0,
  191. /* req */       {0, 0, 0},
  192. /* ins */       FILE_BOX},
  193.  
  194. /* sign */      {UINF_SIGN,
  195. /* short */     "UUID Info box",
  196. /* long */      "This box provides a tool by which a vendor may provide access to additional information associated with a UUID",
  197. /* sbox */      0,
  198. /* req */       {0, 0, 0},
  199. /* ins */       FILE_BOX},
  200.  
  201. /* sign */      {MOOV_SIGN,
  202. /* short */     "Movie box",
  203. /* long */      "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames",
  204. /* sbox */      1,
  205. /* req */       {1, 1, 1},
  206. /* ins */       FILE_BOX},
  207.  
  208. /* sign */      {MVHD_SIGN,
  209. /* short */     "Movie Header box",
  210. /* long */      "This box defines overall information which is media-independent, and relevant to the entire presentation "
  211.                         "considered as a whole",
  212. /* sbox */      0,
  213. /* req */       {1, 1, 1},
  214. /* ins */       MOOV_BOX},
  215.  
  216. /* sign */      {TRAK_SIGN,
  217. /* short */     "Track box",
  218. /* long */      "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks",
  219. /* sbox */      1,
  220. /* req */       {1, 1, 1},
  221. /* ins */       MOOV_BOX},
  222.  
  223. /* sign */      {TKHD_SIGN,
  224. /* short */     "Track Header box",
  225. /* long */      "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track",
  226. /* sbox */      0,
  227. /* req */       {1, 1, 1},
  228. /* ins */       TRAK_BOX},
  229.  
  230. /* sign */      {MDIA_SIGN,
  231. /* short */     "Media box",
  232. /* long */      "The media declaration container contains all the objects which declare information about the media data "
  233.                         "within a track",
  234. /* sbox */      1,
  235. /* req */       {1, 1, 1},
  236. /* ins */       TRAK_BOX},
  237.  
  238. /* sign */      {MDHD_SIGN,
  239. /* short */     "Media Header box",
  240. /* long */      "The media header declares overall information which is media-independent, and relevant to characteristics "
  241.                         "of the media in a track",
  242. /* sbox */      0,
  243. /* req */       {1, 1, 1},
  244. /* ins */       MDIA_BOX},
  245.  
  246. /* sign */      {HDLR_SIGN,
  247. /* short */     "Handler Reference box",
  248. /* long */      "This box within a Media Box declares the process by which the media-data in the track may be presented, "
  249.                         "and thus, the nature of the media in a track",
  250. /* sbox */      0,
  251. /* req */       {1, 1, 1},
  252. /* ins */       MDIA_BOX},
  253.  
  254. /* sign */      {MINF_SIGN,
  255. /* short */     "Media Information box",
  256. /* long */      "This box contains all the objects which declare characteristic information of the media in the track",
  257. /* sbox */      1,
  258. /* req */       {1, 1, 1},
  259. /* ins */       MDIA_BOX},
  260.  
  261. /* sign */      {VMHD_SIGN,
  262. /* short */     "Video Media Header box",
  263. /* long */      "The video media header contains general presentation information, independent of the coding, for video media",
  264. /* sbox */      0,
  265. /* req */       {1, 1, 1},
  266. /* ins */       MINF_BOX},
  267.  
  268. /* sign */      {STBL_SIGN,
  269. /* short */     "Sample Table box",
  270. /* long */      "The sample table contains all the time and data indexing of the media samples in a track",
  271. /* sbox */      1,
  272. /* req */       {1, 1, 1},
  273. /* ins */       MINF_BOX},
  274.  
  275. /* sign */      {STSD_SIGN,
  276. /* short */     "STSD Sample Description box",
  277. /* long */      "The sample description table gives detailed information about the coding type used, and any initialization "
  278.                         "information needed for that coding",
  279. /* sbox */      0,
  280. /* req */       {1, 1, 1},
  281. /* ins */       MINF_BOX},
  282.  
  283. /* sign */      {STSZ_SIGN,
  284. /* short */     "Sample Size box",
  285. /* long */      "This box contains the sample count and a table giving the size of each sample",
  286. /* sbox */      0,
  287. /* req */       {1, 1, 1},
  288. /* ins */       STBL_BOX},
  289.  
  290. /* sign */      {MJP2_SIGN,
  291. /* short */     "MJP2 Sample Description box",
  292. /* long */      "The MJP2 sample description table gives detailed information about the coding type used, and any initialization "
  293.                         "information needed for that coding",
  294. /* sbox */      0,
  295. /* req */       {1, 1, 1},
  296. /* ins */       MINF_BOX},
  297.  
  298. /* sign */      {MDAT_SIGN,
  299. /* short */     "Media Data box",
  300. /* long */      "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file",
  301. /* sbox */      1,
  302. /* req */       {1, 1, 1},
  303. /* ins */       FILE_BOX},
  304.  
  305. /* sign */      {ANY_SIGN,
  306. /* short */     "Any box",
  307. /* long */      "All the existing boxes",
  308. /* sbox */      0,
  309. /* req */       {0, 0, 0},
  310. /* ins */       FILE_BOX},
  311.  
  312. /* sign */      {UNK_SIGN,
  313. /* short */     "Unknown Type box",
  314. /* long */      "The signature is not recognised to be that of an existing box",
  315. /* sbox */      0,
  316. /* req */       {0, 0, 0},
  317. /* ins */       ANY_BOX}
  318.  
  319. };
  320.  
  321.  
  322. /* macro functions */
  323. /* From little endian to big endian, 2 and 4 bytes */
  324. #define BYTE_SWAP2(X)   ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8)
  325. #define BYTE_SWAP4(X)   ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24)
  326.  
  327. #ifdef __WXGTK__
  328. #define BYTE_SWAP8(X)   ((X & 0x00000000000000FFULL) << 56) | ((X & 0x000000000000FF00ULL) << 40) | \
  329.                         ((X & 0x0000000000FF0000ULL) << 24) | ((X & 0x00000000FF000000ULL) << 8) | \
  330.                                                 ((X & 0x000000FF00000000ULL) >> 8)  | ((X & 0x0000FF0000000000ULL) >> 24) | \
  331.                                                 ((X & 0x00FF000000000000ULL) >> 40) | ((X & 0xFF00000000000000ULL) >> 56)
  332. #else
  333. #define BYTE_SWAP8(X)   ((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \
  334.                         ((X & 0x0000000000FF0000) << 24) | ((X & 0x00000000FF000000) << 8) | \
  335.                                                 ((X & 0x000000FF00000000) >> 8)  | ((X & 0x0000FF0000000000) >> 24) | \
  336.                                                 ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56)
  337. #endif
  338.  
  339. /* From codestream to int values */
  340. #define STREAM_TO_UINT32(C, P)  (((unsigned long int) (C)[(P) + 0] << 24) + \
  341.                                                                 ((unsigned long int) (C)[(P) + 1] << 16) + \
  342.                                                                 ((unsigned long int) (C)[(P) + 2] << 8) + \
  343.                                                                 ((unsigned long int) (C)[(P) + 3] << 0))
  344.  
  345. #define STREAM_TO_UINT16(C, P)  (((unsigned long int) (C)[(P) + 0] << 8) + \
  346.                                                                 ((unsigned long int) (C)[(P) + 1] << 0))
  347.  
  348. #define OPJREAD_LONG(F,L,N) { \
  349.                                                         if (F->Read(fourbytes, 4) < 4) { \
  350.                                                                 wxLogMessage(wxT("Problem reading " N " from the file (file ended?)")); \
  351.                                                                 return -1; \
  352.                                                         }; \
  353.                                                         L = STREAM_TO_UINT32(fourbytes, 0); \
  354.                                                         }
  355.  
  356. /* handling functions */
  357. #define ITEM_PER_ROW    10
  358.  
  359. //#define indprint      if (0) printf("%.*s", 2 * level + 9, indent), printf
  360. char    indent[] =  "                                                                   "
  361.                                         "                                                                   "
  362.                                         "                                                                   "
  363.                                         "                                                                   ";
  364.  
  365. void indprint(wxString printout, int level)
  366. {
  367.         wxLogMessage(/*wxString::Format(wxT("%.*s"), 2 * level + 9, indent) + */printout);
  368. }
  369.  
  370. /* Box handler function */
  371. int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit,
  372.                                                  wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint)
  373. {
  374.         switch ((j22boxtype) boxtype) {
  375.  
  376.  
  377.         /* JPEG 2000 Signature box */
  378.         case (JP_BOX): {
  379.  
  380.                         unsigned long int checkdata = 0;
  381.                         fileid->Read(&checkdata, sizeof(unsigned long int));
  382.                         checkdata = BYTE_SWAP4(checkdata);
  383.  
  384.                         // add info
  385.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  386.                                 wxString::Format(wxT("Check data: %X -> %s"), checkdata, (checkdata == 0x0D0A870A) ? wxT("OK") : wxT("KO")),
  387.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  388.                                 new OPJMarkerData(wxT("INFO"))
  389.                                 );
  390.  
  391.                 };
  392.                 break;
  393.  
  394.  
  395.         /* JPEG 2000 codestream box */
  396.         case (JP2C_BOX): {
  397.  
  398.                         // add info
  399.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  400.                                 wxString(wxT("Codestream")),
  401.                                 m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,
  402.                                 new OPJMarkerData(wxT("INFO-CSTREAM"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
  403.                                 );
  404.  
  405.                         m_tree->SetItemHasChildren(currid);
  406.  
  407.                         // parse the file
  408.                         //ParseJ2KFile(fileid, filepoint, filelimit, currid);
  409.  
  410.                 };
  411.                 break;
  412.  
  413.  
  414.  
  415.  
  416.  
  417.         /* File Type box */
  418.         case (FTYP_BOX): {
  419.  
  420.                         char BR[4], CL[4];
  421.                         unsigned long int MinV, numCL, i;
  422.                         fileid->Read(BR, sizeof(char) * 4);
  423.                         fileid->Read(&MinV, sizeof(unsigned long int));
  424.                         MinV = BYTE_SWAP4(MinV);
  425.                         numCL = (filelimit - fileid->Tell()) / 4;                              
  426.  
  427.                         // add info
  428.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  429.                                 wxT("Brand/Minor version: ") +
  430.                                 wxString::FromAscii(BR).Truncate(4) +
  431.                                 wxString::Format(wxT("/%d"), MinV),
  432.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  433.                                 new OPJMarkerData(wxT("INFO"))
  434.                                 );
  435.  
  436.                         currid = m_tree->AppendItem(parentid,
  437.                                 wxString::Format(wxT("Compatibility list")),
  438.                                 m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,
  439.                                 new OPJMarkerData(wxT("INFO"))
  440.                                 );
  441.  
  442.                         for (i = 0; i < numCL; i++) {
  443.                                 fileid->Read(CL, sizeof(char) * 4);
  444.                                 m_tree->AppendItem(currid,
  445.                                         wxString::FromAscii(CL).Truncate(4),
  446.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  447.                                         new OPJMarkerData(wxT("INFO"))
  448.                                         );
  449.                         };
  450.                        
  451.                 };
  452.                 break;
  453.  
  454.  
  455.  
  456.         /* JP2 Header box */
  457.         case (IHDR_BOX): {
  458.  
  459.                         unsigned long int height, width;
  460.                         unsigned short int nc;
  461.                         unsigned char bpc, C, UnkC, IPR;
  462.                         fileid->Read(&height, sizeof(unsigned long int));
  463.                         height = BYTE_SWAP4(height);
  464.                         fileid->Read(&width, sizeof(unsigned long int));
  465.                         width = BYTE_SWAP4(width);
  466.                         fileid->Read(&nc, sizeof(unsigned short int));
  467.                         nc = BYTE_SWAP2(nc);
  468.                         fileid->Read(&bpc, sizeof(unsigned char));
  469.                         fileid->Read(&C, sizeof(unsigned char));
  470.                         fileid->Read(&UnkC, sizeof(unsigned char));
  471.                         fileid->Read(&IPR, sizeof(unsigned char));
  472.                        
  473.                         // add info
  474.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  475.                                 wxString::Format(wxT("Dimensions: %d x %d x %d @ %d bpc"), width, height, nc, bpc + 1),
  476.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  477.                                 new OPJMarkerData(wxT("INFO"))
  478.                                 );
  479.  
  480.                         currid = m_tree->AppendItem(parentid,
  481.                                 wxString::Format(wxT("Compression type: %d"), C),
  482.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  483.                                 new OPJMarkerData(wxT("INFO"))
  484.                                 );
  485.  
  486.                         currid = m_tree->AppendItem(parentid,
  487.                                 wxString::Format(wxT("Colourspace unknown: %d"), UnkC),
  488.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  489.                                 new OPJMarkerData(wxT("INFO"))
  490.                                 );
  491.  
  492.                         currid = m_tree->AppendItem(parentid,
  493.                                 wxString::Format(wxT("Intellectual Property Rights: %d"), IPR),
  494.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  495.                                 new OPJMarkerData(wxT("INFO"))
  496.                                 );
  497.                        
  498.                 };
  499.                 break;
  500.  
  501.  
  502.  
  503.         /* Colour Specification box */
  504.         case (COLR_BOX): {
  505.  
  506.                         unsigned char METH, PREC, APPROX;
  507.                         char methdescr[80], enumcsdescr[80];
  508.                         unsigned long int EnumCS;
  509.                         fileid->Read(&METH, sizeof(unsigned char));
  510.                         switch (METH) {
  511.                         case 1:
  512.                                 strcpy(methdescr, "Enumerated Colourspace");
  513.                                 break;
  514.                         case 2:
  515.                                 strcpy(methdescr, "Restricted ICC profile");
  516.                                 break;
  517.                         default:
  518.                                 strcpy(methdescr, "Unknown");
  519.                                 break;
  520.                         };
  521.                         fileid->Read(&PREC, sizeof(unsigned char));
  522.                         fileid->Read(&APPROX, sizeof(unsigned char));
  523.                         if (METH != 2) {
  524.                                 fileid->Read(&EnumCS, sizeof(unsigned long int));
  525.                                 EnumCS = BYTE_SWAP4(EnumCS);
  526.                                 switch (EnumCS) {
  527.                                 case 16:
  528.                                         strcpy(enumcsdescr, "sRGB");
  529.                                         break;
  530.                                 case 17:
  531.                                         strcpy(enumcsdescr, "greyscale");
  532.                                         break;
  533.                                 case 18:
  534.                                         strcpy(enumcsdescr, "sYCC");
  535.                                         break;
  536.                                 default:
  537.                                         strcpy(enumcsdescr, "Unknown");
  538.                                         break;
  539.                                 };
  540.                         };
  541.  
  542.                         // add info
  543.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  544.                                 wxString::Format(wxT("Specification method: %d ("), METH) +
  545.                                 wxString::FromAscii(methdescr) +
  546.                                 wxT(")"),
  547.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  548.                                 new OPJMarkerData(wxT("INFO"))
  549.                                 );
  550.  
  551.                         currid = m_tree->AppendItem(parentid,
  552.                                 wxString::Format(wxT("Precedence: %d"), PREC),
  553.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  554.                                 new OPJMarkerData(wxT("INFO"))
  555.                                 );
  556.  
  557.                         currid = m_tree->AppendItem(parentid,
  558.                                 wxString::Format(wxT("Colourspace approximation: %d"), APPROX),
  559.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  560.                                 new OPJMarkerData(wxT("INFO"))
  561.                                 );
  562.  
  563.                         if (METH != 2)
  564.                                 currid = m_tree->AppendItem(parentid,
  565.                                         wxString::Format(wxT("Enumerated colourspace: %d ("), EnumCS) +
  566.                                         wxString::FromAscii(enumcsdescr) +
  567.                                         wxT(")"),
  568.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  569.                                         new OPJMarkerData(wxT("INFO"))
  570.                                         );
  571.  
  572.                         if (METH != 1)
  573.                                 currid = m_tree->AppendItem(parentid,
  574.                                         wxString::Format(wxT("ICC profile: there is one")),
  575.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  576.                                         new OPJMarkerData(wxT("INFO"))
  577.                                         );
  578.  
  579.  
  580.                 };
  581.                 break;
  582.  
  583.  
  584.  
  585.  
  586.                
  587.  
  588.         /* Movie Header Box */
  589.         case (MVHD_BOX): {
  590.  
  591.                         unsigned long int version, rate, matrix[9], next_track_ID;
  592.                         unsigned short int volume;
  593.                         fileid->Read(&version, sizeof(unsigned long int));
  594.                         version = BYTE_SWAP4(version);
  595.                         if (version == 0) {
  596.                                 unsigned long int creation_time, modification_time, timescale, duration;
  597.                                 fileid->Read(&creation_time, sizeof(unsigned long int));
  598.                                 creation_time = BYTE_SWAP4(creation_time);
  599.                                 fileid->Read(&modification_time, sizeof(unsigned long int));
  600.                                 modification_time = BYTE_SWAP4(modification_time);
  601.                                 fileid->Read(&timescale, sizeof(unsigned long int));
  602.                                 timescale = BYTE_SWAP4(timescale);
  603.                                 fileid->Read(&duration, sizeof(unsigned long int));
  604.                                 duration = BYTE_SWAP4(duration);
  605.                                 const long unix_time = creation_time - 2082844800L;
  606.                                 wxTreeItemId currid = m_tree->AppendItem(parentid,
  607.                                         wxString::Format(wxT("Creation time: %u (%.24s)"), creation_time, ctime(&unix_time)),
  608.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  609.                                         new OPJMarkerData(wxT("INFO"))
  610.                                         );
  611.                                 const long unix_time1 = modification_time - 2082844800L;
  612.                                 currid = m_tree->AppendItem(parentid,
  613.                                         wxString::Format(wxT("Modification time: %u (%.24s)"), modification_time, ctime(&unix_time1)),
  614.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  615.                                         new OPJMarkerData(wxT("INFO"))
  616.                                         );
  617.                                 currid = m_tree->AppendItem(parentid,
  618.                                         wxString::Format(wxT("Timescale: %u (%.6fs)"), timescale, 1.0 / (float) timescale),
  619.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  620.                                         new OPJMarkerData(wxT("INFO"))
  621.                                         );
  622.                                 currid = m_tree->AppendItem(parentid,
  623.                                         wxString::Format(wxT("Duration: %u (%.3fs)"), duration, (float) duration / (float) timescale),
  624.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  625.                                         new OPJMarkerData(wxT("INFO"))
  626.                                         );
  627.                         } else {
  628.                                 int8byte creation_time, modification_time, duration;
  629.                                 unsigned long int timescale;
  630.                                 fileid->Read(&creation_time, sizeof(int8byte));
  631.                                 creation_time = BYTE_SWAP8(creation_time);
  632.                                 fileid->Read(&modification_time, sizeof(int8byte));
  633.                                 modification_time = BYTE_SWAP8(modification_time);
  634.                                 fileid->Read(&timescale, sizeof(unsigned long int));
  635.                                 timescale = BYTE_SWAP4(timescale);
  636.                                 fileid->Read(&duration, sizeof(int8byte));
  637.                                 duration = BYTE_SWAP8(duration);
  638.                                 wxTreeItemId currid = m_tree->AppendItem(parentid,
  639.                                         wxString::Format(wxT("Creation time: %u"), creation_time),
  640.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  641.                                         new OPJMarkerData(wxT("INFO"))
  642.                                         );
  643.                                 currid = m_tree->AppendItem(parentid,
  644.                                         wxString::Format(wxT("Modification time: %u"), modification_time),
  645.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  646.                                         new OPJMarkerData(wxT("INFO"))
  647.                                         );
  648.                                 currid = m_tree->AppendItem(parentid,
  649.                                         wxString::Format(wxT("Timescale: %u"), timescale),
  650.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  651.                                         new OPJMarkerData(wxT("INFO"))
  652.                                         );
  653.                                 currid = m_tree->AppendItem(parentid,
  654.                                         wxString::Format(wxT("Duration: %u"), duration),
  655.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  656.                                         new OPJMarkerData(wxT("INFO"))
  657.                                         );
  658.                         };
  659.                         fileid->Read(&rate, sizeof(unsigned long int));
  660.                         rate = BYTE_SWAP4(rate);
  661.                         fileid->Read(&volume, sizeof(unsigned short int));
  662.                         volume = BYTE_SWAP2(volume);
  663.                         fileid->Seek(6, wxFromCurrent);
  664.                         fileid->Read(&matrix, sizeof(unsigned char) * 9);
  665.                         fileid->Seek(4, wxFromCurrent);
  666.                         fileid->Read(&next_track_ID, sizeof(unsigned long int));
  667.                         next_track_ID = BYTE_SWAP4(next_track_ID);
  668.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  669.                                 wxString::Format(wxT("Rate: %d (%d.%d)"), rate, rate >> 16, rate & 0x0000FFFF),
  670.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  671.                                 new OPJMarkerData(wxT("INFO"))
  672.                                 );
  673.                         currid = m_tree->AppendItem(parentid,
  674.                                 wxString::Format(wxT("Volume: %d (%d.%d)"), volume, volume >> 8, volume & 0x00FF),
  675.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  676.                                 new OPJMarkerData(wxT("INFO"))
  677.                                 );
  678.                         currid = m_tree->AppendItem(parentid,
  679.                                 wxString::Format(wxT("Next track ID: %d"), next_track_ID),
  680.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  681.                                 new OPJMarkerData(wxT("INFO"))
  682.                                 );
  683.                 };
  684.                 break;
  685.  
  686.  
  687.                         /* Sample Description box */
  688.         case (STSD_BOX): {
  689.  
  690.                         unsigned long int version, entry_count;
  691.                         fileid->Read(&version, sizeof(unsigned long int));
  692.                         version = BYTE_SWAP4(version);
  693.                         fileid->Read(&entry_count, sizeof(unsigned long int));
  694.                         entry_count = BYTE_SWAP4(entry_count);
  695.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  696.                                 wxString::Format(wxT("Entry count: %d"), entry_count),
  697.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  698.                                 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
  699.                                 );
  700.                         jpeg2000parse(fileid, filepoint + 8, filelimit, parentid, level + 1, scansign, scanpoint);
  701.                 };
  702.                 break;
  703.  
  704.  
  705.                         /* Sample Size box */
  706.         case (STSZ_BOX): {
  707.  
  708.                         unsigned long int version, sample_size, sample_count, entry_size;
  709.                        
  710.                         fileid->Read(&version, sizeof(unsigned long int));
  711.                         version = BYTE_SWAP4(version);
  712.                        
  713.                         fileid->Read(&sample_size, sizeof(unsigned long int));
  714.                         sample_size = BYTE_SWAP4(sample_size);
  715.  
  716.                         if (sample_size == 0) {
  717.                                 fileid->Read(&sample_count, sizeof(unsigned long int));
  718.                                 sample_count = BYTE_SWAP4(sample_count);
  719.  
  720.                                 wxTreeItemId currid = m_tree->AppendItem(parentid,
  721.                                         wxString::Format(wxT("Sample count: %d"), sample_count),
  722.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  723.                                         new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
  724.                                         );
  725.  
  726.                                 currid = m_tree->AppendItem(parentid,
  727.                                         wxT("Entries size (bytes)"),
  728.                                         m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,
  729.                                         new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
  730.                                         );
  731.  
  732.                                 wxString text;
  733.                                 for (unsigned int s = 0; s < sample_count; s++) {
  734.                                         fileid->Read(&entry_size, sizeof(unsigned long int));
  735.                                         entry_size = BYTE_SWAP4(entry_size);
  736.                                        
  737.                                         text << wxString::Format(wxT("%d, "), entry_size);
  738.  
  739.                                         if (((s % 10) == (ITEM_PER_ROW - 1)) || (s == (sample_count - 1))) {
  740.                                                 m_tree->AppendItem(currid,
  741.                                                         text,
  742.                                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  743.                                                         new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
  744.                                                         );
  745.                                                 text = wxT("");
  746.                                         }
  747.  
  748.                                 }
  749.                                
  750.                         }
  751.  
  752.                 };
  753.                 break;
  754.  
  755.  
  756.                         /* Video Media Header box */
  757.         case (VMHD_BOX): {
  758.  
  759.                         unsigned long int version;
  760.                         unsigned short int graphicsmode, opcolor[3];
  761.                         char graphicsdescr[100];
  762.  
  763.                         fileid->Read(&version, sizeof(unsigned long int));
  764.                         version = BYTE_SWAP4(version);
  765.  
  766.                         fileid->Read(&graphicsmode, sizeof(unsigned short int));
  767.                         graphicsmode = BYTE_SWAP2(graphicsmode);
  768.                         switch (graphicsmode) {
  769.                         case (0x00):
  770.                                         strcpy(graphicsdescr, "copy");
  771.                                         break;
  772.                         case (0x24):
  773.                                         strcpy(graphicsdescr, "transparent");
  774.                                         break;
  775.                         case (0x0100):
  776.                                         strcpy(graphicsdescr, "alpha");
  777.                                         break;
  778.                         case (0x0101):
  779.                                         strcpy(graphicsdescr, "whitealpha");
  780.                                         break;
  781.                         case (0x0102):
  782.                                         strcpy(graphicsdescr, "blackalpha");
  783.                                         break;
  784.                         default:
  785.                                         strcpy(graphicsdescr, "unknown");
  786.                                         break;
  787.                         };
  788.  
  789.                         fileid->Read(opcolor, 3 * sizeof(unsigned short int));
  790.                         opcolor[0] = BYTE_SWAP2(opcolor[0]);
  791.                         opcolor[1] = BYTE_SWAP2(opcolor[1]);
  792.                         opcolor[2] = BYTE_SWAP2(opcolor[2]);
  793.  
  794.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  795.                                 wxString::Format(wxT("Composition mode: %d (")) +
  796.                                 wxString::FromAscii(graphicsdescr) +
  797.                                 wxT(")"),
  798.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  799.                                 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
  800.                                 );
  801.  
  802.                         currid = m_tree->AppendItem(parentid,
  803.                                 wxString::Format(wxT("OP color: %d %d %d"), opcolor[0], opcolor[1], opcolor[2]),
  804.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  805.                                 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
  806.                                 );
  807.                 };
  808.                 break;
  809.  
  810.  
  811.  
  812.                         /* MJP2 Sample Description box */
  813.         case (MJP2_BOX): {
  814.  
  815.                         unsigned short int height, width, depth;
  816.                         unsigned long int horizresolution, vertresolution;
  817.                         char compressor_name[32];
  818.                         fileid->Seek(24, wxFromCurrent);
  819.                         fileid->Read(&width, sizeof(unsigned short int));
  820.                         width = BYTE_SWAP2(width);
  821.                         fileid->Read(&height, sizeof(unsigned short int));
  822.                         height = BYTE_SWAP2(height);
  823.                         fileid->Read(&horizresolution, sizeof(unsigned long int));
  824.                         horizresolution = BYTE_SWAP4(horizresolution);
  825.                         fileid->Read(&vertresolution, sizeof(unsigned long int));
  826.                         vertresolution = BYTE_SWAP4(vertresolution);
  827.                         fileid->Seek(6, wxFromCurrent);
  828.                         fileid->Read(compressor_name, sizeof(char) * 32);
  829.                         fileid->Read(&depth, sizeof(unsigned short int));
  830.                         depth = BYTE_SWAP2(depth);
  831.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  832.                                 wxString::Format(wxT("Dimensions: %d x %d @ %d bpp"), width, height, depth),
  833.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  834.                                 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
  835.                                 );
  836.                         currid = m_tree->AppendItem(parentid,
  837.                                 wxString::Format(wxT("Resolution: %d.%d x %d.%d"), horizresolution >> 16, horizresolution & 0x0000FFFF,
  838.                                 vertresolution >> 16, vertresolution & 0x0000FFFF),
  839.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  840.                                 new OPJMarkerData(wxT("INFO"))
  841.                                 );
  842.                         currid = m_tree->AppendItem(parentid,
  843.                                 wxString::Format(wxT("Compressor: %.32s"), compressor_name),
  844.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  845.                                 new OPJMarkerData(wxT("INFO"))
  846.                                 );
  847.                         jpeg2000parse(fileid, filepoint + 78, filelimit, parentid, level + 1, scansign, scanpoint);
  848.  
  849.                 };
  850.                 break;
  851.  
  852.                 /* Media Header box */
  853.         case (MDHD_BOX): {
  854.                         unsigned long int version;
  855.                         unsigned short int language;
  856.                         fileid->Read(&version, sizeof(unsigned long int));
  857.                         version = BYTE_SWAP4(version);
  858.                         if (version == 0) {
  859.                                 unsigned long int creation_time, modification_time, timescale, duration;
  860.                                 fileid->Read(&creation_time, sizeof(unsigned long int));
  861.                                 creation_time = BYTE_SWAP4(creation_time);
  862.                                 fileid->Read(&modification_time, sizeof(unsigned long int));
  863.                                 modification_time = BYTE_SWAP4(modification_time);
  864.                                 fileid->Read(&timescale, sizeof(unsigned long int));
  865.                                 timescale = BYTE_SWAP4(timescale);
  866.                                 fileid->Read(&duration, sizeof(unsigned long int));
  867.                                 duration = BYTE_SWAP4(duration);
  868.                                 const long unix_time = creation_time - 2082844800L;
  869.                                 wxTreeItemId currid = m_tree->AppendItem(parentid,
  870.                                         wxString::Format(wxT("Creation time: %u (%.24s)"), creation_time, ctime(&unix_time)),
  871.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  872.                                         new OPJMarkerData(wxT("INFO"))
  873.                                         );
  874.                                 const long unix_time1 = modification_time - 2082844800L;
  875.                                 currid = m_tree->AppendItem(parentid,
  876.                                         wxString::Format(wxT("Modification time: %u (%.24s)"), modification_time, ctime(&unix_time1)),
  877.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  878.                                         new OPJMarkerData(wxT("INFO"))
  879.                                         );
  880.                                 currid = m_tree->AppendItem(parentid,
  881.                                         wxString::Format(wxT("Timescale: %u (%.6fs)"), timescale, 1.0 / (float) timescale),
  882.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  883.                                         new OPJMarkerData(wxT("INFO"))
  884.                                         );
  885.                                 currid = m_tree->AppendItem(parentid,
  886.                                         wxString::Format(wxT("Duration: %u (%.3fs)"), duration, (float) duration / (float) timescale),
  887.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  888.                                         new OPJMarkerData(wxT("INFO"))
  889.                                         );
  890.                         } else {
  891.                                 int8byte creation_time, modification_time, duration;
  892.                                 unsigned long int timescale;
  893.                                 fileid->Read(&creation_time, sizeof(int8byte));
  894.                                 creation_time = BYTE_SWAP8(creation_time);
  895.                                 fileid->Read(&modification_time, sizeof(int8byte));
  896.                                 modification_time = BYTE_SWAP8(modification_time);
  897.                                 fileid->Read(&timescale, sizeof(unsigned long int));
  898.                                 timescale = BYTE_SWAP4(timescale);
  899.                                 fileid->Read(&duration, sizeof(int8byte));
  900.                                 duration = BYTE_SWAP8(duration);
  901.                                 wxTreeItemId currid = m_tree->AppendItem(parentid,
  902.                                         wxString::Format(wxT("Creation time: %u"), creation_time),
  903.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  904.                                         new OPJMarkerData(wxT("INFO"))
  905.                                         );
  906.                                 currid = m_tree->AppendItem(parentid,
  907.                                         wxString::Format(wxT("Modification time: %u"), modification_time),
  908.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  909.                                         new OPJMarkerData(wxT("INFO"))
  910.                                         );
  911.                                 currid = m_tree->AppendItem(parentid,
  912.                                         wxString::Format(wxT("Timescale: %u"), timescale),
  913.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  914.                                         new OPJMarkerData(wxT("INFO"))
  915.                                         );
  916.                                 currid = m_tree->AppendItem(parentid,
  917.                                         wxString::Format(wxT("Duration: %u"), duration),
  918.                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  919.                                         new OPJMarkerData(wxT("INFO"))
  920.                                         );
  921.                         }
  922.                         fileid->Read(&language, sizeof(unsigned short int));
  923.  
  924.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  925.                                 wxString::Format(wxT("Language: %d (%c%c%c)"), language & 0xEFFF,
  926.                                 0x60 + (char) ((language >> 10) & 0x001F), 0x60 + (char) ((language >> 5) & 0x001F), 0x60 + (char) ((language >> 0) & 0x001F)),
  927.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  928.                                 new OPJMarkerData(wxT("INFO"))
  929.                                 );
  930.                 };
  931.                 break;
  932.                
  933.                 /* Media Handler box */
  934.         case (HDLR_BOX): {
  935.                         unsigned long int version, predefined, temp[3];
  936.                         char handler[4], name[256];
  937.                         int namelen = wxMin(256, (filelimit - filepoint - 24));
  938.                         fileid->Read(&version, sizeof(unsigned long int));
  939.                         version = BYTE_SWAP4(version);
  940.                         fileid->Read(&predefined, sizeof(unsigned long int));
  941.                         fileid->Read(handler, 4 * sizeof(char));
  942.                         fileid->Read(&temp, 3 * sizeof(unsigned long int));
  943.                         fileid->Read(name, namelen * sizeof(char));
  944.  
  945.                         wxTreeItemId currid = m_tree->AppendItem(parentid,
  946.                                 wxString::Format(wxT("Handler: %.4s"), handler),
  947.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  948.                                 new OPJMarkerData(wxT("INFO"))
  949.                                 );
  950.                                          
  951.                         currid = m_tree->AppendItem(parentid,
  952.                                 wxString::Format(wxT("Name: %.255s"), name),
  953.                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
  954.                                 new OPJMarkerData(wxT("INFO"))
  955.                                 );
  956.                                                                          
  957.                 }
  958.                 break;
  959.  
  960.         /* not yet implemented */
  961.         default:
  962.                 break;
  963.  
  964.         };
  965.  
  966.         return (0);
  967. }
  968.  
  969.  
  970. void OPJParseThread::ParseJP2File(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, wxTreeItemId parentid)
  971. {
  972.         unsigned long int scanpoint;
  973.  
  974.         jpeg2000parse(fileid, filepoint, filelimit, parentid, 0, NULL, &scanpoint);
  975. }
  976.  
  977. /* the parsing function itself */
  978. /*
  979.   fileid    = fid of the file to scan (you should open it by yourself)
  980.   filepoint = first byte where to start to scan from (usually 0)
  981.   filelimit = first byte where to stop to scan from (usually the file size)
  982.   level     = set this to 0
  983.   scansign  = signature to scan for (NULL avoids search, returns "    " if successful)
  984.   scanpoint = point where the scan signature lies
  985. */
  986. int OPJParseThread::jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit,
  987.                                                                   wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint)
  988. {
  989.         unsigned long int       LBox = 0x00000000;
  990.         //int                     LBox_read;
  991.         char                    TBox[5] = "\0\0\0\0";
  992.         //int                     TBox_read;
  993.         int8byte                                XLBox = 0x0000000000000000;
  994.         //int                     XLBox_read;
  995.         unsigned long int       box_length = 0;
  996.         int                     last_box = 0, box_num = 0;
  997.         int                     box_type = ANY_BOX;
  998.         unsigned char           /*onebyte[1], twobytes[2],*/ fourbytes[4];
  999.  
  1000.         /* cycle all over the file */
  1001.         box_num = 0;
  1002.         last_box = 0;
  1003.         while (!last_box) {
  1004.  
  1005.                 /* do not exceed file limit */
  1006.                 if (filepoint >= filelimit)
  1007.                         return (0);
  1008.  
  1009.                 /* seek on file */
  1010.                 if (fileid->Seek(filepoint, wxFromStart) == wxInvalidOffset)
  1011.                         return (-1);
  1012.  
  1013.                 /* read the mandatory LBox, 4 bytes */
  1014.                 if (fileid->Read(fourbytes, 4) < 4) {
  1015.                         WriteText(wxT("Problem reading LBox from the file (file ended?)"));
  1016.                         return -1;
  1017.                 };
  1018.                 LBox = STREAM_TO_UINT32(fourbytes, 0);
  1019.  
  1020.                 /* read the mandatory TBox, 4 bytes */
  1021.                 if (fileid->Read(TBox, 4) < 4) {
  1022.                         WriteText(wxT("Problem reading TBox from the file (file ended?)"));
  1023.                         return -1;
  1024.                 };
  1025.  
  1026.                 /* look if scansign is got */
  1027.                 if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) {
  1028.                         memcpy(scansign, "    ", 4);
  1029.                         *scanpoint = filepoint;
  1030.  
  1031.                         /* hack/exploit */
  1032.                         // stop as soon as you find the codebox
  1033.                         return (0);
  1034.  
  1035.                 };
  1036.  
  1037.                 /* determine the box type */
  1038.                 for (box_type = JP_BOX; box_type < UNK_BOX; box_type++)
  1039.                         if (memcmp(TBox, j22box[box_type].value, 4) == 0)
  1040.                                 break; 
  1041.  
  1042.                 /* read the optional XLBox, 8 bytes */
  1043.                 if (LBox == 1) {
  1044.  
  1045.                         if (fileid->Read(&XLBox, 8) < 8) {
  1046.                                 WriteText(wxT("Problem reading XLBox from the file (file ended?)"));
  1047.                                 return -1;
  1048.                         };
  1049.                         box_length = (unsigned long int) BYTE_SWAP8(XLBox);
  1050.  
  1051.                 } else if (LBox == 0x00000000) {
  1052.  
  1053.                         /* last box in file */
  1054.                         last_box = 1;
  1055.                         box_length = filelimit - filepoint;
  1056.  
  1057.                 } else
  1058.  
  1059.                         box_length = LBox;
  1060.  
  1061.                 /* show box info */
  1062.  
  1063.                 // append the marker
  1064.                 int image, imageSel;
  1065.                 image = m_tree->TreeCtrlIcon_Folder;
  1066.                 imageSel = image + 1;
  1067.                 wxTreeItemId currid = m_tree->AppendItem(parentid,
  1068.                         wxString::Format(wxT("%03d: "), box_num) +
  1069.                         wxString::FromAscii(TBox) +
  1070.                         wxString::Format(wxT(" (0x%04X)"),
  1071.                                 ((unsigned long int) TBox[3]) + ((unsigned long int) TBox[2] << 8) +
  1072.                                 ((unsigned long int) TBox[1] << 16) + ((unsigned long int) TBox[0] << 24)
  1073.                         ),
  1074.                         image, imageSel,
  1075.                         new OPJMarkerData(wxT("BOX"), m_tree->m_fname.GetFullPath(), filepoint, filepoint + box_length)
  1076.                         );
  1077.  
  1078.                 // append some info
  1079.                 image = m_tree->TreeCtrlIcon_File;
  1080.                 imageSel = image + 1;
  1081.  
  1082.                 // box name
  1083.                 wxTreeItemId subcurrid1 = m_tree->AppendItem(currid,
  1084.                         wxT("*** ") + wxString::FromAscii(j22box[box_type].name) + wxT(" ***"),
  1085.                         image, imageSel,
  1086.                         new OPJMarkerData(wxT("INFO"))
  1087.                         );
  1088.                 m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT);
  1089.  
  1090.                 // position and length
  1091.                 wxTreeItemId subcurrid2 = m_tree->AppendItem(currid,
  1092.                         wxLongLong(filepoint).ToString() + wxT(" > ") + wxLongLong(filepoint + box_length - 1).ToString() +
  1093.                         wxT(", ") + wxString::Format(wxT("%d + 8 (%d)"), box_length, box_length + 8),
  1094.                         image, imageSel,
  1095.                         new OPJMarkerData(wxT("INFO"))
  1096.                         );
  1097.  
  1098.                 /* go deep in the box */
  1099.                 box_handler_function((int) box_type, fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length,
  1100.                         currid, level, scansign, scanpoint);
  1101.  
  1102.                 /* if it's a superbox go inside it */
  1103.                 if (j22box[box_type].sbox)
  1104.                         jpeg2000parse(fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length,
  1105.                                 currid, level + 1, scansign, scanpoint);
  1106.  
  1107.                 /* increment box number and filepoint*/
  1108.                 box_num++;
  1109.                 filepoint += box_length;
  1110.  
  1111.         };
  1112.  
  1113.         /* all good */
  1114.         return (0);
  1115. }
  1116.  
  1117.