Some coding style adaptations for compiling the OPJViewer GUI under Linux. It compile...
[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                         MINF_BOX,\r
64                         VMHD_BOX,\r
65                         STBL_BOX,\r
66                         STSD_BOX,\r
67                         STSZ_BOX,\r
68                         MJP2_BOX,\r
69                         MDAT_BOX,\r
70                         ANY_BOX,\r
71                         UNK_BOX\r
72 \r
73 } j22boxtype;\r
74 \r
75 /* the box structure itself */\r
76 struct boxdef {\r
77 \r
78         char                  value[5];                 /* hexadecimal value/string*/\r
79                 char                  name[SHORT_DESCR_LEN];    /* short description       */\r
80                 char                  descr[LONG_DESCR_LEN];    /* long  description       */\r
81                 int                   sbox;                     /* is it a superbox?       */\r
82                 int                   req[J2FILENUM];           /* mandatory box           */\r
83                 j22boxtype             ins;                      /* contained in box...     */\r
84 \r
85 };\r
86 \r
87 \r
88 /* jp2 family box signatures */\r
89 #define FILE_SIGN           ""\r
90 #define JP_SIGN             "jP\040\040"\r
91 #define FTYP_SIGN           "ftyp"\r
92 #define JP2H_SIGN           "jp2h"\r
93 #define IHDR_SIGN           "ihdr"\r
94 #define COLR_SIGN           "colr"\r
95 #define JP2C_SIGN           "jp2c"\r
96 #define JP2I_SIGN           "jp2i"\r
97 #define XML_SIGN            "xml\040"\r
98 #define UUID_SIGN           "uuid"\r
99 #define UINF_SIGN           "uinf"\r
100 #define MOOV_SIGN           "moov"\r
101 #define MVHD_SIGN           "mvhd"\r
102 #define TRAK_SIGN           "trak"\r
103 #define TKHD_SIGN           "tkhd"\r
104 #define MDIA_SIGN           "mdia"\r
105 #define MINF_SIGN           "minf"\r
106 #define VMHD_SIGN           "vmhd"\r
107 #define STBL_SIGN           "stbl"\r
108 #define STSD_SIGN           "stsd"\r
109 #define STSZ_SIGN           "stsz"\r
110 #define MJP2_SIGN           "mjp2"\r
111 #define MDAT_SIGN           "mdat"\r
112 #define ANY_SIGN                        ""\r
113 #define UNK_SIGN            ""\r
114 \r
115 /* the possible boxes */\r
116 struct boxdef j22box[] =\r
117 {\r
118 /* sign */      {FILE_SIGN,\r
119 /* short */     "placeholder for nothing",\r
120 /* long */      "Nothing to say",\r
121 /* sbox */      0,\r
122 /* req */       {1, 1, 1},\r
123 /* ins */       FILE_BOX},\r
124 \r
125 /* sign */      {JP_SIGN,\r
126 /* short */     "JPEG 2000 Signature box",\r
127 /* long */      "This box uniquely identifies the file as being part of the JPEG 2000 family of files",\r
128 /* sbox */      0,\r
129 /* req */       {1, 1, 1},\r
130 /* ins */       FILE_BOX},\r
131 \r
132 /* sign */      {FTYP_SIGN,\r
133 /* short */     "File Type box",\r
134 /* long */      "This box specifies file type, version and compatibility information, including specifying if this file "\r
135                         "is a conforming JP2 file or if it can be read by a conforming JP2 reader",\r
136 /* sbox */      0,\r
137 /* req */       {1, 1, 1},\r
138 /* ins */       FILE_BOX},\r
139 \r
140 /* sign */      {JP2H_SIGN,\r
141 /* short */     "JP2 Header box",\r
142 /* long */      "This box contains a series of boxes that contain header-type information about the file",\r
143 /* sbox */      1,\r
144 /* req */       {1, 1, 1},\r
145 /* ins */       FILE_BOX},\r
146 \r
147 /* sign */      {IHDR_SIGN,\r
148 /* short */     "Image Header box",\r
149 /* long */      "This box specifies the size of the image and other related fields",\r
150 /* sbox */      0,\r
151 /* req */       {1, 1, 1},\r
152 /* ins */       JP2H_BOX},\r
153 \r
154 /* sign */      {COLR_SIGN,\r
155 /* short */     "Colour Specification box",\r
156 /* long */      "This box specifies the colourspace of the image",\r
157 /* sbox */      0,\r
158 /* req */       {1, 1, 1},\r
159 /* ins */       JP2H_BOX},\r
160 \r
161 /* sign */      {JP2C_SIGN,\r
162 /* short */     "Contiguous Codestream box",\r
163 /* long */      "This box contains the codestream as defined by Annex A",\r
164 /* sbox */      0,\r
165 /* req */       {1, 1, 1},\r
166 /* ins */       FILE_BOX},\r
167 \r
168 /* sign */      {JP2I_SIGN,\r
169 /* short */     "Intellectual Property box",\r
170 /* long */      "This box contains intellectual property information about the image",\r
171 /* sbox */      0,\r
172 /* req */       {0, 0, 0},\r
173 /* ins */       FILE_BOX},\r
174 \r
175 /* sign */      {XML_SIGN,\r
176 /* short */     "XML box",\r
177 /* long */      "This box provides a tool by which vendors can add XML formatted information to a JP2 file",\r
178 /* sbox */      0,\r
179 /* req */       {0, 0, 0},\r
180 /* ins */       FILE_BOX},\r
181 \r
182 /* sign */      {UUID_SIGN,\r
183 /* short */     "UUID box",\r
184 /* long */      "This box provides a tool by which vendors can add additional information to a file "\r
185                         "without risking conflict with other vendors",\r
186 /* sbox */      0,\r
187 /* req */       {0, 0, 0},\r
188 /* ins */       FILE_BOX},\r
189 \r
190 /* sign */      {UINF_SIGN,\r
191 /* short */     "UUID Info box",\r
192 /* long */      "This box provides a tool by which a vendor may provide access to additional information associated with a UUID",\r
193 /* sbox */      0,\r
194 /* req */       {0, 0, 0},\r
195 /* ins */       FILE_BOX},\r
196 \r
197 /* sign */      {MOOV_SIGN,\r
198 /* short */     "Movie box",\r
199 /* long */      "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames",\r
200 /* sbox */      1,\r
201 /* req */       {1, 1, 1},\r
202 /* ins */       FILE_BOX},\r
203 \r
204 /* sign */      {MVHD_SIGN,\r
205 /* short */     "Movie Header box",\r
206 /* long */      "This box defines overall information which is media-independent, and relevant to the entire presentation "\r
207                         "considered as a whole",\r
208 /* sbox */      0,\r
209 /* req */       {1, 1, 1},\r
210 /* ins */       MOOV_BOX},\r
211 \r
212 /* sign */      {TRAK_SIGN,\r
213 /* short */     "Track box",\r
214 /* long */      "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks",\r
215 /* sbox */      1,\r
216 /* req */       {1, 1, 1},\r
217 /* ins */       MOOV_BOX},\r
218 \r
219 /* sign */      {TKHD_SIGN,\r
220 /* short */     "Track Header box",\r
221 /* long */      "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track",\r
222 /* sbox */      0,\r
223 /* req */       {1, 1, 1},\r
224 /* ins */       TRAK_BOX},\r
225 \r
226 /* sign */      {MDIA_SIGN,\r
227 /* short */     "Media box",\r
228 /* long */      "The media declaration container contains all the objects which declare information about the media data "\r
229                         "within a track",\r
230 /* sbox */      1,\r
231 /* req */       {1, 1, 1},\r
232 /* ins */       TRAK_BOX},\r
233 \r
234 /* sign */      {MINF_SIGN,\r
235 /* short */     "Media Information box",\r
236 /* long */      "This box contains all the objects which declare characteristic information of the media in the track",\r
237 /* sbox */      1,\r
238 /* req */       {1, 1, 1},\r
239 /* ins */       MDIA_BOX},\r
240 \r
241 /* sign */      {VMHD_SIGN,\r
242 /* short */     "Video Media Header box",\r
243 /* long */      "The video media header contains general presentation information, independent of the coding, for video media",\r
244 /* sbox */      0,\r
245 /* req */       {1, 1, 1},\r
246 /* ins */       MINF_BOX},\r
247 \r
248 /* sign */      {STBL_SIGN,\r
249 /* short */     "Sample Table box",\r
250 /* long */      "The sample table contains all the time and data indexing of the media samples in a track",\r
251 /* sbox */      1,\r
252 /* req */       {1, 1, 1},\r
253 /* ins */       MINF_BOX},\r
254 \r
255 /* sign */      {STSD_SIGN,\r
256 /* short */     "STSD Sample Description box",\r
257 /* long */      "The sample description table gives detailed information about the coding type used, and any initialization "\r
258                         "information needed for that coding",\r
259 /* sbox */      0,\r
260 /* req */       {1, 1, 1},\r
261 /* ins */       MINF_BOX},\r
262 \r
263 /* sign */      {STSZ_SIGN,\r
264 /* short */     "Sample Size box",\r
265 /* long */      "This box contains the sample count and a table giving the size of each sample",\r
266 /* sbox */      0,\r
267 /* req */       {1, 1, 1},\r
268 /* ins */       STBL_BOX},\r
269 \r
270 /* sign */      {MJP2_SIGN,\r
271 /* short */     "MJP2 Sample Description box",\r
272 /* long */      "The MJP2 sample description table gives detailed information about the coding type used, and any initialization "\r
273                         "information needed for that coding",\r
274 /* sbox */      0,\r
275 /* req */       {1, 1, 1},\r
276 /* ins */       MINF_BOX},\r
277 \r
278 /* sign */      {MDAT_SIGN,\r
279 /* short */     "Media Data box",\r
280 /* long */      "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file",\r
281 /* sbox */      1,\r
282 /* req */       {1, 1, 1},\r
283 /* ins */       FILE_BOX},\r
284 \r
285 /* sign */      {ANY_SIGN,\r
286 /* short */     "Any box",\r
287 /* long */      "All the existing boxes",\r
288 /* sbox */      0,\r
289 /* req */       {0, 0, 0},\r
290 /* ins */       FILE_BOX},\r
291 \r
292 /* sign */      {UNK_SIGN,\r
293 /* short */     "Unknown Type box",\r
294 /* long */      "The signature is not recognised to be that of an existing box",\r
295 /* sbox */      0,\r
296 /* req */       {0, 0, 0},\r
297 /* ins */       ANY_BOX}\r
298 \r
299 };\r
300 \r
301 \r
302 /* macro functions */\r
303 /* From little endian to big endian, 2 and 4 bytes */\r
304 #define BYTE_SWAP2(X)   ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8)\r
305 #define BYTE_SWAP4(X)   ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24)\r
306 #define BYTE_SWAP8(X)   (((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \\r
307                         ((X & 0x0000000000FF0000) << 24) | ((X & 0x00000000FF000000) << 8) | \\r
308                                                 ((X & 0x000000FF00000000) >> 8)  | ((X & 0x0000FF0000000000) >> 24) | \\r
309                                                 ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56))\r
310 \r
311 /* From codestream to int values */\r
312 #define STREAM_TO_UINT32(C, P)  (((unsigned long int) (C)[(P) + 0] << 24) + \\r
313                                                                 ((unsigned long int) (C)[(P) + 1] << 16) + \\r
314                                                                 ((unsigned long int) (C)[(P) + 2] << 8) + \\r
315                                                                 ((unsigned long int) (C)[(P) + 3] << 0))\r
316 \r
317 #define STREAM_TO_UINT16(C, P)  (((unsigned long int) (C)[(P) + 0] << 8) + \\r
318                                                                 ((unsigned long int) (C)[(P) + 1] << 0))\r
319 \r
320 #define OPJREAD_LONG(F,L,N) { \\r
321                                                         if (F->Read(fourbytes, 4) < 4) { \\r
322                                                                 wxLogMessage(wxT("Problem reading " N " from the file (file ended?)")); \\r
323                                                                 return -1; \\r
324                                                         }; \\r
325                                                         L = STREAM_TO_UINT32(fourbytes, 0); \\r
326                                                         }\r
327 \r
328 /* handling functions */\r
329 #define ITEM_PER_ROW    10\r
330 \r
331 //#define indprint      if (0) printf("%.*s", 2 * level + 9, indent), printf\r
332 char    indent[] =  "                                                                   "\r
333                                         "                                                                   "\r
334                                         "                                                                   "\r
335                                         "                                                                   ";\r
336 \r
337 void indprint(wxString printout, int level)\r
338 {\r
339         wxLogMessage(/*wxString::Format(wxT("%.*s"), 2 * level + 9, indent) + */printout);\r
340 }\r
341 \r
342 /* Box handler function */\r
343 int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit,\r
344                                                  wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint)\r
345 {\r
346         switch ((j22boxtype) boxtype) {\r
347 \r
348 \r
349         /* JPEG 2000 Signature box */\r
350         case (JP_BOX): {\r
351 \r
352                         unsigned long int checkdata = 0;\r
353                         fileid->Read(&checkdata, sizeof(unsigned long int));\r
354                         checkdata = BYTE_SWAP4(checkdata);\r
355 \r
356                         // add info\r
357                         wxTreeItemId currid = m_tree->AppendItem(parentid,\r
358                                 wxString::Format(wxT("Check data: %X -> %s"), checkdata, (checkdata == 0x0D0A870A) ? wxT("OK") : wxT("KO")),\r
359                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
360                                 new OPJMarkerData(wxT("INFO"))\r
361                                 );\r
362 \r
363                 };\r
364                 break;\r
365 \r
366 \r
367         /* JPEG 2000 codestream box */\r
368         case (JP2C_BOX): {\r
369 \r
370                         // add info\r
371                         wxTreeItemId currid = m_tree->AppendItem(parentid,\r
372                                 wxString(wxT("Codestream")),\r
373                                 m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,\r
374                                 new OPJMarkerData(wxT("INFO-CSTREAM"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
375                                 );\r
376 \r
377                         m_tree->SetItemHasChildren(currid);\r
378 \r
379                         // parse the file\r
380                         //ParseJ2KFile(fileid, filepoint, filelimit, currid);\r
381 \r
382                 };\r
383                 break;\r
384 \r
385 \r
386 \r
387 \r
388 \r
389         /* File Type box */\r
390         case (FTYP_BOX): {\r
391 \r
392                         char BR[4], CL[4];\r
393                         unsigned long int MinV, numCL, i;\r
394                         fileid->Read(BR, sizeof(char) * 4);\r
395                         fileid->Read(&MinV, sizeof(unsigned long int));\r
396                         MinV = BYTE_SWAP4(MinV);\r
397                         numCL = (filelimit - fileid->Tell()) / 4;                               \r
398 \r
399                         // add info\r
400                         wxTreeItemId currid = m_tree->AppendItem(parentid,\r
401                                 wxString::Format(wxT("Brand/Minor version: %.4s/%d"), BR, MinV),\r
402                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
403                                 new OPJMarkerData(wxT("INFO"))\r
404                                 );\r
405 \r
406                         currid = m_tree->AppendItem(parentid,\r
407                                 wxString::Format(wxT("Compatibility list")),\r
408                                 m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,\r
409                                 new OPJMarkerData(wxT("INFO"))\r
410                                 );\r
411 \r
412                         for (i = 0; i < numCL; i++) {\r
413                                 fileid->Read(CL, sizeof(char) * 4);\r
414                                 m_tree->AppendItem(currid,\r
415                                         wxString::Format(wxT("%.4s"), CL),\r
416                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
417                                         new OPJMarkerData(wxT("INFO"))\r
418                                         );\r
419                         };\r
420                         \r
421                 };\r
422                 break;\r
423 \r
424 \r
425 \r
426         /* JP2 Header box */\r
427         case (IHDR_BOX): {\r
428 \r
429                         unsigned long int height, width;\r
430                         unsigned short int nc;\r
431                         unsigned char bpc, C, UnkC, IPR;\r
432                         fileid->Read(&height, sizeof(unsigned long int));\r
433                         height = BYTE_SWAP4(height);\r
434                         fileid->Read(&width, sizeof(unsigned long int));\r
435                         width = BYTE_SWAP4(width);\r
436                         fileid->Read(&nc, sizeof(unsigned short int));\r
437                         nc = BYTE_SWAP2(nc);\r
438                         fileid->Read(&bpc, sizeof(unsigned char));\r
439                         fileid->Read(&C, sizeof(unsigned char));\r
440                         fileid->Read(&UnkC, sizeof(unsigned char));\r
441                         fileid->Read(&IPR, sizeof(unsigned char));\r
442                         \r
443                         // add info\r
444                         wxTreeItemId currid = m_tree->AppendItem(parentid,\r
445                                 wxString::Format(wxT("Dimensions: %d x %d x %d @ %d bpc"), width, height, nc, bpc + 1),\r
446                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
447                                 new OPJMarkerData(wxT("INFO"))\r
448                                 );\r
449 \r
450                         currid = m_tree->AppendItem(parentid,\r
451                                 wxString::Format(wxT("Compression type: %d"), C),\r
452                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
453                                 new OPJMarkerData(wxT("INFO"))\r
454                                 );\r
455 \r
456                         currid = m_tree->AppendItem(parentid,\r
457                                 wxString::Format(wxT("Colourspace unknown: %d"), UnkC),\r
458                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
459                                 new OPJMarkerData(wxT("INFO"))\r
460                                 );\r
461 \r
462                         currid = m_tree->AppendItem(parentid,\r
463                                 wxString::Format(wxT("Intellectual Property Rights: %d"), IPR),\r
464                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
465                                 new OPJMarkerData(wxT("INFO"))\r
466                                 );\r
467                         \r
468                 };\r
469                 break;\r
470 \r
471 \r
472 \r
473         /* Colour Specification box */\r
474         case (COLR_BOX): {\r
475 \r
476                         unsigned char METH, PREC, APPROX;\r
477                         char methdescr[80], enumcsdescr[80];\r
478                         unsigned long int EnumCS;\r
479                         fileid->Read(&METH, sizeof(unsigned char));\r
480                         switch (METH) {\r
481                         case 1:\r
482                                 strcpy(methdescr, "Enumerated Colourspace");\r
483                                 break;\r
484                         case 2:\r
485                                 strcpy(methdescr, "Restricted ICC profile");\r
486                                 break;\r
487                         default:\r
488                                 strcpy(methdescr, "Unknown");\r
489                                 break;\r
490                         };\r
491                         fileid->Read(&PREC, sizeof(unsigned char));\r
492                         fileid->Read(&APPROX, sizeof(unsigned char));\r
493                         if (METH != 2) {\r
494                                 fileid->Read(&EnumCS, sizeof(unsigned long int));\r
495                                 EnumCS = BYTE_SWAP4(EnumCS);\r
496                                 switch (EnumCS) {\r
497                                 case 16:\r
498                                         strcpy(enumcsdescr, "sRGB");\r
499                                         break;\r
500                                 case 17:\r
501                                         strcpy(enumcsdescr, "greyscale");\r
502                                         break;\r
503                                 case 18:\r
504                                         strcpy(enumcsdescr, "sYCC");\r
505                                         break;\r
506                                 default:\r
507                                         strcpy(enumcsdescr, "Unknown");\r
508                                         break;\r
509                                 };\r
510                         };\r
511 \r
512                         // add info\r
513                         wxTreeItemId currid = m_tree->AppendItem(parentid,\r
514                                 wxString::Format(wxT("Specification method: %d (%s)"), METH, methdescr),\r
515                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
516                                 new OPJMarkerData(wxT("INFO"))\r
517                                 );\r
518 \r
519                         currid = m_tree->AppendItem(parentid,\r
520                                 wxString::Format(wxT("Precedence: %d"), PREC),\r
521                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
522                                 new OPJMarkerData(wxT("INFO"))\r
523                                 );\r
524 \r
525                         currid = m_tree->AppendItem(parentid,\r
526                                 wxString::Format(wxT("Colourspace approximation: %d"), APPROX),\r
527                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
528                                 new OPJMarkerData(wxT("INFO"))\r
529                                 );\r
530 \r
531                         if (METH != 2)\r
532                                 currid = m_tree->AppendItem(parentid,\r
533                                         wxString::Format(wxT("Enumerated colourspace: %d (%s)"), EnumCS, enumcsdescr),\r
534                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
535                                         new OPJMarkerData(wxT("INFO"))\r
536                                         );\r
537 \r
538                         if (METH != 1)\r
539                                 currid = m_tree->AppendItem(parentid,\r
540                                         wxString::Format(wxT("ICC profile: there is one")),\r
541                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
542                                         new OPJMarkerData(wxT("INFO"))\r
543                                         );\r
544 \r
545 \r
546                 };\r
547                 break;\r
548 \r
549 \r
550 \r
551 \r
552                 \r
553 \r
554         /* Movie Header Box */\r
555         case (MVHD_BOX): {\r
556 \r
557                         unsigned long int version, rate, matrix[9], next_track_ID;\r
558                         unsigned short int volume;\r
559                         fileid->Read(&version, sizeof(unsigned long int));\r
560                         version = BYTE_SWAP4(version);\r
561                         if (version == 0) {\r
562                                 unsigned long int creation_time, modification_time, timescale, duration;\r
563                                 fileid->Read(&creation_time, sizeof(unsigned long int));\r
564                                 creation_time = BYTE_SWAP4(creation_time);\r
565                                 fileid->Read(&modification_time, sizeof(unsigned long int));\r
566                                 modification_time = BYTE_SWAP4(modification_time);\r
567                                 fileid->Read(&timescale, sizeof(unsigned long int));\r
568                                 timescale = BYTE_SWAP4(timescale);\r
569                                 fileid->Read(&duration, sizeof(unsigned long int));\r
570                                 duration = BYTE_SWAP4(duration);\r
571                                 const long unix_time = creation_time - 2082844800L;\r
572                                 wxTreeItemId currid = m_tree->AppendItem(parentid,\r
573                                         wxString::Format(wxT("Creation time: %u (%.24s)"), creation_time, ctime(&unix_time)),\r
574                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
575                                         new OPJMarkerData(wxT("INFO"))\r
576                                         );\r
577                                 const long unix_time1 = modification_time - 2082844800L;\r
578                                 currid = m_tree->AppendItem(parentid,\r
579                                         wxString::Format(wxT("Modification time: %u (%.24s)"), modification_time, ctime(&unix_time1)),\r
580                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
581                                         new OPJMarkerData(wxT("INFO"))\r
582                                         );\r
583                                 currid = m_tree->AppendItem(parentid,\r
584                                         wxString::Format(wxT("Timescale: %u (%.6fs)"), timescale, 1.0 / (float) timescale),\r
585                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
586                                         new OPJMarkerData(wxT("INFO"))\r
587                                         );\r
588                                 currid = m_tree->AppendItem(parentid,\r
589                                         wxString::Format(wxT("Duration: %u (%.3fs)"), duration, (float) duration / (float) timescale),\r
590                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
591                                         new OPJMarkerData(wxT("INFO"))\r
592                                         );\r
593                         } else {\r
594                                 int8byte creation_time, modification_time, duration;\r
595                                 unsigned long int timescale;\r
596                                 fileid->Read(&creation_time, sizeof(int8byte));\r
597                                 creation_time = BYTE_SWAP8(creation_time);\r
598                                 fileid->Read(&modification_time, sizeof(int8byte));\r
599                                 modification_time = BYTE_SWAP8(modification_time);\r
600                                 fileid->Read(&timescale, sizeof(unsigned long int));\r
601                                 timescale = BYTE_SWAP4(timescale);\r
602                                 fileid->Read(&duration, sizeof(int8byte));\r
603                                 duration = BYTE_SWAP8(duration);\r
604                                 wxTreeItemId currid = m_tree->AppendItem(parentid,\r
605                                         wxString::Format(wxT("Creation time: %u"), creation_time),\r
606                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
607                                         new OPJMarkerData(wxT("INFO"))\r
608                                         );\r
609                                 currid = m_tree->AppendItem(parentid,\r
610                                         wxString::Format(wxT("Modification time: %u"), modification_time),\r
611                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
612                                         new OPJMarkerData(wxT("INFO"))\r
613                                         );\r
614                                 currid = m_tree->AppendItem(parentid,\r
615                                         wxString::Format(wxT("Timescale: %u"), timescale),\r
616                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
617                                         new OPJMarkerData(wxT("INFO"))\r
618                                         );\r
619                                 currid = m_tree->AppendItem(parentid,\r
620                                         wxString::Format(wxT("Duration: %u"), duration),\r
621                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
622                                         new OPJMarkerData(wxT("INFO"))\r
623                                         );\r
624                         };\r
625                         fileid->Read(&rate, sizeof(unsigned long int));\r
626                         rate = BYTE_SWAP4(rate);\r
627                         fileid->Read(&volume, sizeof(unsigned short int));\r
628                         volume = BYTE_SWAP2(volume);\r
629                         fileid->Seek(6, wxFromCurrent);\r
630                         fileid->Read(&matrix, sizeof(unsigned char) * 9);\r
631                         fileid->Seek(4, wxFromCurrent);\r
632                         fileid->Read(&next_track_ID, sizeof(unsigned long int));\r
633                         next_track_ID = BYTE_SWAP4(next_track_ID);\r
634                         wxTreeItemId currid = m_tree->AppendItem(parentid,\r
635                                 wxString::Format(wxT("Rate: %d (%d.%d)"), rate, rate >> 16, rate & 0x0000FFFF),\r
636                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
637                                 new OPJMarkerData(wxT("INFO"))\r
638                                 );\r
639                         currid = m_tree->AppendItem(parentid,\r
640                                 wxString::Format(wxT("Volume: %d (%d.%d)"), volume, volume >> 8, volume & 0x00FF),\r
641                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
642                                 new OPJMarkerData(wxT("INFO"))\r
643                                 );\r
644                         currid = m_tree->AppendItem(parentid,\r
645                                 wxString::Format(wxT("Next track ID: %d"), next_track_ID),\r
646                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
647                                 new OPJMarkerData(wxT("INFO"))\r
648                                 );\r
649                 };\r
650                 break;\r
651 \r
652 \r
653                         /* Sample Description box */\r
654         case (STSD_BOX): {\r
655 \r
656                         unsigned long int version, entry_count;\r
657                         fileid->Read(&version, sizeof(unsigned long int));\r
658                         version = BYTE_SWAP4(version);\r
659                         fileid->Read(&entry_count, sizeof(unsigned long int));\r
660                         entry_count = BYTE_SWAP4(entry_count);\r
661                         wxTreeItemId currid = m_tree->AppendItem(parentid,\r
662                                 wxString::Format(wxT("Entry count: %d"), entry_count),\r
663                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
664                                 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
665                                 );\r
666                         jpeg2000parse(fileid, filepoint + 8, filelimit, parentid, level + 1, scansign, scanpoint);\r
667                 };\r
668                 break;\r
669 \r
670 \r
671                         /* Sample Size box */\r
672         case (STSZ_BOX): {\r
673 \r
674                         unsigned long int version, sample_size, sample_count, entry_size;\r
675                         \r
676                         fileid->Read(&version, sizeof(unsigned long int));\r
677                         version = BYTE_SWAP4(version);\r
678                         \r
679                         fileid->Read(&sample_size, sizeof(unsigned long int));\r
680                         sample_size = BYTE_SWAP4(sample_size);\r
681 \r
682                         if (sample_size == 0) {\r
683                                 fileid->Read(&sample_count, sizeof(unsigned long int));\r
684                                 sample_count = BYTE_SWAP4(sample_count);\r
685 \r
686                                 wxTreeItemId currid = m_tree->AppendItem(parentid,\r
687                                         wxString::Format(wxT("Sample count: %d"), sample_count),\r
688                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
689                                         new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
690                                         );\r
691 \r
692                                 currid = m_tree->AppendItem(parentid,\r
693                                         wxT("Entries size (bytes)"),\r
694                                         m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,\r
695                                         new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
696                                         );\r
697 \r
698                                 wxString text;\r
699                                 for (unsigned int s = 0; s < sample_count; s++) {\r
700                                         fileid->Read(&entry_size, sizeof(unsigned long int));\r
701                                         entry_size = BYTE_SWAP4(entry_size);\r
702                                         \r
703                                         text << wxString::Format(wxT("%d, "), entry_size);\r
704 \r
705                                         if (((s % 10) == (ITEM_PER_ROW - 1)) || (s == (sample_count - 1))) {\r
706                                                 m_tree->AppendItem(currid,\r
707                                                         text,\r
708                                                         m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
709                                                         new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
710                                                         );\r
711                                                 text = wxT("");\r
712                                         }\r
713 \r
714                                 }\r
715                                 \r
716                         }\r
717 \r
718                 };\r
719                 break;\r
720 \r
721 \r
722                         /* Video Media Header box */\r
723         case (VMHD_BOX): {\r
724 \r
725                         unsigned long int version;\r
726                         unsigned short int graphicsmode, opcolor[3];\r
727                         char graphicsdescr[100];\r
728 \r
729                         fileid->Read(&version, sizeof(unsigned long int));\r
730                         version = BYTE_SWAP4(version);\r
731 \r
732                         fileid->Read(&graphicsmode, sizeof(unsigned short int));\r
733                         graphicsmode = BYTE_SWAP2(graphicsmode);\r
734                         switch (graphicsmode) {\r
735                         case (0x00):\r
736                                         strcpy(graphicsdescr, "copy");\r
737                                         break;\r
738                         case (0x24):\r
739                                         strcpy(graphicsdescr, "transparent");\r
740                                         break;\r
741                         case (0x0100):\r
742                                         strcpy(graphicsdescr, "alpha");\r
743                                         break;\r
744                         case (0x0101):\r
745                                         strcpy(graphicsdescr, "whitealpha");\r
746                                         break;\r
747                         case (0x0102):\r
748                                         strcpy(graphicsdescr, "blackalpha");\r
749                                         break;\r
750                         default:\r
751                                         strcpy(graphicsdescr, "unknown");\r
752                                         break;\r
753                         };\r
754 \r
755                         fileid->Read(opcolor, 3 * sizeof(unsigned short int));\r
756                         opcolor[0] = BYTE_SWAP2(opcolor[0]);\r
757                         opcolor[1] = BYTE_SWAP2(opcolor[1]);\r
758                         opcolor[2] = BYTE_SWAP2(opcolor[2]);\r
759 \r
760                         wxTreeItemId currid = m_tree->AppendItem(parentid,\r
761                                 wxString::Format(wxT("Composition mode: %d (%s)"), graphicsmode, graphicsdescr),\r
762                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
763                                 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
764                                 );\r
765 \r
766                         currid = m_tree->AppendItem(parentid,\r
767                                 wxString::Format(wxT("OP color: %d %d %d"), opcolor[0], opcolor[1], opcolor[2]),\r
768                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
769                                 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
770                                 );\r
771                 };\r
772                 break;\r
773 \r
774 \r
775 \r
776                         /* MJP2 Sample Description box */\r
777         case (MJP2_BOX): {\r
778 \r
779                         unsigned short int height, width, depth;\r
780                         unsigned long int horizresolution, vertresolution;\r
781                         char compressor_name[32];\r
782                         fileid->Seek(24, wxFromCurrent);\r
783                         fileid->Read(&width, sizeof(unsigned short int));\r
784                         width = BYTE_SWAP2(width);\r
785                         fileid->Read(&height, sizeof(unsigned short int));\r
786                         height = BYTE_SWAP2(height);\r
787                         fileid->Read(&horizresolution, sizeof(unsigned long int));\r
788                         horizresolution = BYTE_SWAP4(horizresolution);\r
789                         fileid->Read(&vertresolution, sizeof(unsigned long int));\r
790                         vertresolution = BYTE_SWAP4(vertresolution);\r
791                         fileid->Seek(6, wxFromCurrent);\r
792                         fileid->Read(compressor_name, sizeof(char) * 32);\r
793                         fileid->Read(&depth, sizeof(unsigned short int));\r
794                         depth = BYTE_SWAP2(depth);\r
795                         wxTreeItemId currid = m_tree->AppendItem(parentid,\r
796                                 wxString::Format(wxT("Dimensions: %d x %d @ %d bpp"), width, height, depth),\r
797                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
798                                 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)\r
799                                 );\r
800                         currid = m_tree->AppendItem(parentid,\r
801                                 wxString::Format(wxT("Resolution: %d.%d x %d.%d"), horizresolution >> 16, horizresolution & 0x0000FFFF,\r
802                                 vertresolution >> 16, vertresolution & 0x0000FFFF),\r
803                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
804                                 new OPJMarkerData(wxT("INFO"))\r
805                                 );\r
806                         currid = m_tree->AppendItem(parentid,\r
807                                 wxString::Format(wxT("Compressor: %.32s"), compressor_name),\r
808                                 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,\r
809                                 new OPJMarkerData(wxT("INFO"))\r
810                                 );\r
811                         jpeg2000parse(fileid, filepoint + 78, filelimit, parentid, level + 1, scansign, scanpoint);\r
812 \r
813                 };\r
814                 break;\r
815 \r
816                 \r
817         /* not yet implemented */\r
818         default:\r
819                 break;\r
820 \r
821         };\r
822 \r
823         return (0);\r
824 }\r
825 \r
826 \r
827 void OPJParseThread::ParseJP2File(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, wxTreeItemId parentid)\r
828 {\r
829         unsigned long int scanpoint;\r
830 \r
831         jpeg2000parse(fileid, filepoint, filelimit, parentid, 0, NULL, &scanpoint);\r
832 }\r
833 \r
834 /* the parsing function itself */\r
835 /*\r
836   fileid    = fid of the file to scan (you should open it by yourself)\r
837   filepoint = first byte where to start to scan from (usually 0)\r
838   filelimit = first byte where to stop to scan from (usually the file size)\r
839   level     = set this to 0\r
840   scansign  = signature to scan for (NULL avoids search, returns "    " if successful)\r
841   scanpoint = point where the scan signature lies\r
842 */\r
843 int OPJParseThread::jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit,\r
844                                                                   wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint)\r
845 {\r
846         unsigned long int       LBox = 0x00000000;\r
847         //int                     LBox_read;\r
848         char                    TBox[5] = "\0\0\0\0";\r
849         //int                     TBox_read;\r
850         int8byte                                XLBox = 0x0000000000000000;\r
851         //int                     XLBox_read;\r
852         unsigned long int       box_length = 0;\r
853         int                     last_box = 0, box_num = 0;\r
854         int                     box_type = ANY_BOX;\r
855         unsigned char           /*onebyte[1], twobytes[2],*/ fourbytes[4];\r
856 \r
857         /* cycle all over the file */\r
858         box_num = 0;\r
859         last_box = 0;\r
860         while (!last_box) {\r
861 \r
862                 /* do not exceed file limit */\r
863                 if (filepoint >= filelimit)\r
864                         return (0);\r
865 \r
866                 /* seek on file */\r
867                 if (fileid->Seek(filepoint, wxFromStart) == wxInvalidOffset)\r
868                         return (-1);\r
869 \r
870                 /* read the mandatory LBox, 4 bytes */\r
871                 if (fileid->Read(fourbytes, 4) < 4) {\r
872                         WriteText(wxT("Problem reading LBox from the file (file ended?)"));\r
873                         return -1;\r
874                 };\r
875                 LBox = STREAM_TO_UINT32(fourbytes, 0);\r
876 \r
877                 /* read the mandatory TBox, 4 bytes */\r
878                 if (fileid->Read(TBox, 4) < 4) {\r
879                         WriteText(wxT("Problem reading TBox from the file (file ended?)"));\r
880                         return -1;\r
881                 };\r
882 \r
883                 /* look if scansign is got */\r
884                 if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) {\r
885                         memcpy(scansign, "    ", 4);\r
886                         *scanpoint = filepoint;\r
887 \r
888                         /* hack/exploit */\r
889                         // stop as soon as you find the codebox\r
890                         return (0);\r
891 \r
892                 };\r
893 \r
894                 /* determine the box type */\r
895                 for (box_type = JP_BOX; box_type < UNK_BOX; box_type++)\r
896                         if (memcmp(TBox, j22box[box_type].value, 4) == 0)\r
897                                 break;  \r
898 \r
899                 /* read the optional XLBox, 8 bytes */\r
900                 if (LBox == 1) {\r
901 \r
902                         if (fileid->Read(&XLBox, 8) < 8) {\r
903                                 WriteText(wxT("Problem reading XLBox from the file (file ended?)"));\r
904                                 return -1;\r
905                         };\r
906                         box_length = (unsigned long int) BYTE_SWAP8(XLBox);\r
907 \r
908                 } else if (LBox == 0x00000000) {\r
909 \r
910                         /* last box in file */\r
911                         last_box = 1; \r
912                         box_length = filelimit - filepoint;\r
913 \r
914                 } else\r
915 \r
916                         box_length = LBox;\r
917 \r
918                 /* show box info */\r
919 \r
920                 // append the marker\r
921                 int image, imageSel;\r
922                 image = m_tree->TreeCtrlIcon_Folder;\r
923                 imageSel = image + 1;\r
924                 wxTreeItemId currid = m_tree->AppendItem(parentid,\r
925                         wxString::Format(wxT("%03d: %s (0x%04X)"), box_num, TBox,\r
926                                 ((unsigned long int) TBox[3]) + ((unsigned long int) TBox[2] << 8) +\r
927                                 ((unsigned long int) TBox[1] << 16) + ((unsigned long int) TBox[0] << 24)\r
928                         ),\r
929                         image, imageSel,\r
930                         new OPJMarkerData(wxT("BOX"), m_tree->m_fname.GetFullPath(), filepoint, filepoint + box_length)\r
931                         );\r
932 \r
933                 // append some info\r
934                 image = m_tree->TreeCtrlIcon_File;\r
935                 imageSel = image + 1;\r
936 \r
937                 // box name\r
938                 wxTreeItemId subcurrid1 = m_tree->AppendItem(currid,\r
939                         wxT("*** ") + wxString::Format(wxT("%s"), j22box[box_type].name) + wxT(" ***"),\r
940                         image, imageSel,\r
941                         new OPJMarkerData(wxT("INFO"))\r
942                         );\r
943                 m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT);\r
944 \r
945                 // position and length\r
946                 wxTreeItemId subcurrid2 = m_tree->AppendItem(currid,\r
947                         wxLongLong(filepoint).ToString() + wxT(" > ") + wxLongLong(filepoint + box_length - 1).ToString() + \r
948                         wxT(", ") + wxString::Format(wxT("%d + 8 (%d)"), box_length, box_length + 8),\r
949                         image, imageSel,\r
950                         new OPJMarkerData(wxT("INFO"))\r
951                         );\r
952 \r
953                 /* go deep in the box */\r
954                 box_handler_function((int) box_type, fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length,\r
955                         currid, level, scansign, scanpoint);\r
956 \r
957                 /* if it's a superbox go inside it */\r
958                 if (j22box[box_type].sbox)\r
959                         jpeg2000parse(fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length,\r
960                                 currid, level + 1, scansign, scanpoint);\r
961 \r
962                 /* increment box number and filepoint*/\r
963                 box_num++;\r
964                 filepoint += box_length;\r
965 \r
966         };\r
967 \r
968         /* all good */\r
969         return (0);\r
970 }\r
971 \r