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