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