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