2 * Copyright (c) 2007, Digital Signal Processing Laboratory, Universit� degli studi di Perugia (UPG), Italy
\r
3 * All rights reserved.
\r
5 * Redistribution and use in source and binary forms, with or without
\r
6 * modification, are permitted provided that the following conditions
\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
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
26 #include "OPJViewer.h"
\r
29 #define SHORT_DESCR_LEN 32
\r
30 #define LONG_DESCR_LEN 256
\r
32 /* enumeration for file formats */
\r
43 /* enumeration for the box types */
\r
44 #define j22boxNUM 23
\r
77 /* the box structure itself */
\r
80 char value[5]; /* hexadecimal value/string*/
\r
81 char name[SHORT_DESCR_LEN]; /* short description */
\r
82 char descr[LONG_DESCR_LEN]; /* long description */
\r
83 int sbox; /* is it a superbox? */
\r
84 int req[J2FILENUM]; /* mandatory box */
\r
85 j22boxtype ins; /* contained in box... */
\r
90 /* jp2 family box signatures */
\r
91 #define FILE_SIGN ""
\r
92 #define JP_SIGN "jP\040\040"
\r
93 #define FTYP_SIGN "ftyp"
\r
94 #define JP2H_SIGN "jp2h"
\r
95 #define IHDR_SIGN "ihdr"
\r
96 #define COLR_SIGN "colr"
\r
97 #define JP2C_SIGN "jp2c"
\r
98 #define JP2I_SIGN "jp2i"
\r
99 #define XML_SIGN "xml\040"
\r
100 #define UUID_SIGN "uuid"
\r
101 #define UINF_SIGN "uinf"
\r
102 #define MOOV_SIGN "moov"
\r
103 #define MVHD_SIGN "mvhd"
\r
104 #define TRAK_SIGN "trak"
\r
105 #define TKHD_SIGN "tkhd"
\r
106 #define MDIA_SIGN "mdia"
\r
107 #define MDHD_SIGN "mdhd"
\r
108 #define HDLR_SIGN "hdlr"
\r
109 #define MINF_SIGN "minf"
\r
110 #define VMHD_SIGN "vmhd"
\r
111 #define STBL_SIGN "stbl"
\r
112 #define STSD_SIGN "stsd"
\r
113 #define STSZ_SIGN "stsz"
\r
114 #define MJP2_SIGN "mjp2"
\r
115 #define MDAT_SIGN "mdat"
\r
116 #define ANY_SIGN ""
\r
117 #define UNK_SIGN ""
\r
119 /* the possible boxes */
\r
120 struct boxdef j22box[] =
\r
122 /* sign */ {FILE_SIGN,
\r
123 /* short */ "placeholder for nothing",
\r
124 /* long */ "Nothing to say",
\r
126 /* req */ {1, 1, 1},
\r
127 /* ins */ FILE_BOX},
\r
129 /* sign */ {JP_SIGN,
\r
130 /* short */ "JPEG 2000 Signature box",
\r
131 /* long */ "This box uniquely identifies the file as being part of the JPEG 2000 family of files",
\r
133 /* req */ {1, 1, 1},
\r
134 /* ins */ FILE_BOX},
\r
136 /* sign */ {FTYP_SIGN,
\r
137 /* short */ "File Type box",
\r
138 /* long */ "This box specifies file type, version and compatibility information, including specifying if this file "
\r
139 "is a conforming JP2 file or if it can be read by a conforming JP2 reader",
\r
141 /* req */ {1, 1, 1},
\r
142 /* ins */ FILE_BOX},
\r
144 /* sign */ {JP2H_SIGN,
\r
145 /* short */ "JP2 Header box",
\r
146 /* long */ "This box contains a series of boxes that contain header-type information about the file",
\r
148 /* req */ {1, 1, 1},
\r
149 /* ins */ FILE_BOX},
\r
151 /* sign */ {IHDR_SIGN,
\r
152 /* short */ "Image Header box",
\r
153 /* long */ "This box specifies the size of the image and other related fields",
\r
155 /* req */ {1, 1, 1},
\r
156 /* ins */ JP2H_BOX},
\r
158 /* sign */ {COLR_SIGN,
\r
159 /* short */ "Colour Specification box",
\r
160 /* long */ "This box specifies the colourspace of the image",
\r
162 /* req */ {1, 1, 1},
\r
163 /* ins */ JP2H_BOX},
\r
165 /* sign */ {JP2C_SIGN,
\r
166 /* short */ "Contiguous Codestream box",
\r
167 /* long */ "This box contains the codestream as defined by Annex A",
\r
169 /* req */ {1, 1, 1},
\r
170 /* ins */ FILE_BOX},
\r
172 /* sign */ {JP2I_SIGN,
\r
173 /* short */ "Intellectual Property box",
\r
174 /* long */ "This box contains intellectual property information about the image",
\r
176 /* req */ {0, 0, 0},
\r
177 /* ins */ FILE_BOX},
\r
179 /* sign */ {XML_SIGN,
\r
180 /* short */ "XML box",
\r
181 /* long */ "This box provides a tool by which vendors can add XML formatted information to a JP2 file",
\r
183 /* req */ {0, 0, 0},
\r
184 /* ins */ FILE_BOX},
\r
186 /* sign */ {UUID_SIGN,
\r
187 /* short */ "UUID box",
\r
188 /* long */ "This box provides a tool by which vendors can add additional information to a file "
\r
189 "without risking conflict with other vendors",
\r
191 /* req */ {0, 0, 0},
\r
192 /* ins */ FILE_BOX},
\r
194 /* sign */ {UINF_SIGN,
\r
195 /* short */ "UUID Info box",
\r
196 /* long */ "This box provides a tool by which a vendor may provide access to additional information associated with a UUID",
\r
198 /* req */ {0, 0, 0},
\r
199 /* ins */ FILE_BOX},
\r
201 /* sign */ {MOOV_SIGN,
\r
202 /* short */ "Movie box",
\r
203 /* long */ "This box contains the media data. In video tracks, this box would contain JPEG2000 video frames",
\r
205 /* req */ {1, 1, 1},
\r
206 /* ins */ FILE_BOX},
\r
208 /* sign */ {MVHD_SIGN,
\r
209 /* short */ "Movie Header box",
\r
210 /* long */ "This box defines overall information which is media-independent, and relevant to the entire presentation "
\r
211 "considered as a whole",
\r
213 /* req */ {1, 1, 1},
\r
214 /* ins */ MOOV_BOX},
\r
216 /* sign */ {TRAK_SIGN,
\r
217 /* short */ "Track box",
\r
218 /* long */ "This is a container box for a single track of a presentation. A presentation may consist of one or more tracks",
\r
220 /* req */ {1, 1, 1},
\r
221 /* ins */ MOOV_BOX},
\r
223 /* sign */ {TKHD_SIGN,
\r
224 /* short */ "Track Header box",
\r
225 /* long */ "This box specifies the characteristics of a single track. Exactly one Track Header Box is contained in a track",
\r
227 /* req */ {1, 1, 1},
\r
228 /* ins */ TRAK_BOX},
\r
230 /* sign */ {MDIA_SIGN,
\r
231 /* short */ "Media box",
\r
232 /* long */ "The media declaration container contains all the objects which declare information about the media data "
\r
235 /* req */ {1, 1, 1},
\r
236 /* ins */ TRAK_BOX},
\r
238 /* sign */ {MDHD_SIGN,
\r
239 /* short */ "Media Header box",
\r
240 /* long */ "The media header declares overall information which is media-independent, and relevant to characteristics "
\r
241 "of the media in a track",
\r
243 /* req */ {1, 1, 1},
\r
244 /* ins */ MDIA_BOX},
\r
246 /* sign */ {HDLR_SIGN,
\r
247 /* short */ "Handler Reference box",
\r
248 /* long */ "This box within a Media Box declares the process by which the media-data in the track may be presented, "
\r
249 "and thus, the nature of the media in a track",
\r
251 /* req */ {1, 1, 1},
\r
252 /* ins */ MDIA_BOX},
\r
254 /* sign */ {MINF_SIGN,
\r
255 /* short */ "Media Information box",
\r
256 /* long */ "This box contains all the objects which declare characteristic information of the media in the track",
\r
258 /* req */ {1, 1, 1},
\r
259 /* ins */ MDIA_BOX},
\r
261 /* sign */ {VMHD_SIGN,
\r
262 /* short */ "Video Media Header box",
\r
263 /* long */ "The video media header contains general presentation information, independent of the coding, for video media",
\r
265 /* req */ {1, 1, 1},
\r
266 /* ins */ MINF_BOX},
\r
268 /* sign */ {STBL_SIGN,
\r
269 /* short */ "Sample Table box",
\r
270 /* long */ "The sample table contains all the time and data indexing of the media samples in a track",
\r
272 /* req */ {1, 1, 1},
\r
273 /* ins */ MINF_BOX},
\r
275 /* sign */ {STSD_SIGN,
\r
276 /* short */ "STSD Sample Description box",
\r
277 /* long */ "The sample description table gives detailed information about the coding type used, and any initialization "
\r
278 "information needed for that coding",
\r
280 /* req */ {1, 1, 1},
\r
281 /* ins */ MINF_BOX},
\r
283 /* sign */ {STSZ_SIGN,
\r
284 /* short */ "Sample Size box",
\r
285 /* long */ "This box contains the sample count and a table giving the size of each sample",
\r
287 /* req */ {1, 1, 1},
\r
288 /* ins */ STBL_BOX},
\r
290 /* sign */ {MJP2_SIGN,
\r
291 /* short */ "MJP2 Sample Description box",
\r
292 /* long */ "The MJP2 sample description table gives detailed information about the coding type used, and any initialization "
\r
293 "information needed for that coding",
\r
295 /* req */ {1, 1, 1},
\r
296 /* ins */ MINF_BOX},
\r
298 /* sign */ {MDAT_SIGN,
\r
299 /* short */ "Media Data box",
\r
300 /* long */ "The meta-data for a presentation is stored in the single Movie Box which occurs at the top-level of a file",
\r
302 /* req */ {1, 1, 1},
\r
303 /* ins */ FILE_BOX},
\r
305 /* sign */ {ANY_SIGN,
\r
306 /* short */ "Any box",
\r
307 /* long */ "All the existing boxes",
\r
309 /* req */ {0, 0, 0},
\r
310 /* ins */ FILE_BOX},
\r
312 /* sign */ {UNK_SIGN,
\r
313 /* short */ "Unknown Type box",
\r
314 /* long */ "The signature is not recognised to be that of an existing box",
\r
316 /* req */ {0, 0, 0},
\r
322 /* macro functions */
\r
323 /* From little endian to big endian, 2 and 4 bytes */
\r
324 #define BYTE_SWAP2(X) ((X & 0x00FF) << 8) | ((X & 0xFF00) >> 8)
\r
325 #define BYTE_SWAP4(X) ((X & 0x000000FF) << 24) | ((X & 0x0000FF00) << 8) | ((X & 0x00FF0000) >> 8) | ((X & 0xFF000000) >> 24)
\r
328 #define BYTE_SWAP8(X) ((X & 0x00000000000000FFULL) << 56) | ((X & 0x000000000000FF00ULL) << 40) | \
\r
329 ((X & 0x0000000000FF0000ULL) << 24) | ((X & 0x00000000FF000000ULL) << 8) | \
\r
330 ((X & 0x000000FF00000000ULL) >> 8) | ((X & 0x0000FF0000000000ULL) >> 24) | \
\r
331 ((X & 0x00FF000000000000ULL) >> 40) | ((X & 0xFF00000000000000ULL) >> 56)
\r
333 #define BYTE_SWAP8(X) ((X & 0x00000000000000FF) << 56) | ((X & 0x000000000000FF00) << 40) | \
\r
334 ((X & 0x0000000000FF0000) << 24) | ((X & 0x00000000FF000000) << 8) | \
\r
335 ((X & 0x000000FF00000000) >> 8) | ((X & 0x0000FF0000000000) >> 24) | \
\r
336 ((X & 0x00FF000000000000) >> 40) | ((X & 0xFF00000000000000) >> 56)
\r
339 /* From codestream to int values */
\r
340 #define STREAM_TO_UINT32(C, P) (((unsigned long int) (C)[(P) + 0] << 24) + \
\r
341 ((unsigned long int) (C)[(P) + 1] << 16) + \
\r
342 ((unsigned long int) (C)[(P) + 2] << 8) + \
\r
343 ((unsigned long int) (C)[(P) + 3] << 0))
\r
345 #define STREAM_TO_UINT16(C, P) (((unsigned long int) (C)[(P) + 0] << 8) + \
\r
346 ((unsigned long int) (C)[(P) + 1] << 0))
\r
348 #define OPJREAD_LONG(F,L,N) { \
\r
349 if (F->Read(fourbytes, 4) < 4) { \
\r
350 wxLogMessage(wxT("Problem reading " N " from the file (file ended?)")); \
\r
353 L = STREAM_TO_UINT32(fourbytes, 0); \
\r
356 /* handling functions */
\r
357 #define ITEM_PER_ROW 10
\r
359 //#define indprint if (0) printf("%.*s", 2 * level + 9, indent), printf
\r
360 char indent[] = " "
\r
365 void indprint(wxString printout, int level)
\r
367 wxLogMessage(/*wxString::Format(wxT("%.*s"), 2 * level + 9, indent) + */printout);
\r
370 /* Box handler function */
\r
371 int OPJParseThread::box_handler_function(int boxtype, wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit,
\r
372 wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint)
\r
374 switch ((j22boxtype) boxtype) {
\r
377 /* JPEG 2000 Signature box */
\r
380 unsigned long int checkdata = 0;
\r
381 fileid->Read(&checkdata, sizeof(unsigned long int));
\r
382 checkdata = BYTE_SWAP4(checkdata);
\r
385 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
386 wxString::Format(wxT("Check data: %X -> %s"), checkdata, (checkdata == 0x0D0A870A) ? wxT("OK") : wxT("KO")),
\r
387 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
388 new OPJMarkerData(wxT("INFO"))
\r
395 /* JPEG 2000 codestream box */
\r
399 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
400 wxString(wxT("Codestream")),
\r
401 m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,
\r
402 new OPJMarkerData(wxT("INFO-CSTREAM"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
\r
405 m_tree->SetItemHasChildren(currid);
\r
408 //ParseJ2KFile(fileid, filepoint, filelimit, currid);
\r
417 /* File Type box */
\r
421 unsigned long int MinV, numCL, i;
\r
422 fileid->Read(BR, sizeof(char) * 4);
\r
423 fileid->Read(&MinV, sizeof(unsigned long int));
\r
424 MinV = BYTE_SWAP4(MinV);
\r
425 numCL = (filelimit - fileid->Tell()) / 4;
\r
428 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
429 wxT("Brand/Minor version: ") +
\r
430 wxString::FromAscii(BR).Truncate(4) +
\r
431 wxString::Format(wxT("/%d"), MinV),
\r
432 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
433 new OPJMarkerData(wxT("INFO"))
\r
436 currid = m_tree->AppendItem(parentid,
\r
437 wxString::Format(wxT("Compatibility list")),
\r
438 m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,
\r
439 new OPJMarkerData(wxT("INFO"))
\r
442 for (i = 0; i < numCL; i++) {
\r
443 fileid->Read(CL, sizeof(char) * 4);
\r
444 m_tree->AppendItem(currid,
\r
445 wxString::FromAscii(CL).Truncate(4),
\r
446 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
447 new OPJMarkerData(wxT("INFO"))
\r
456 /* JP2 Header box */
\r
459 unsigned long int height, width;
\r
460 unsigned short int nc;
\r
461 unsigned char bpc, C, UnkC, IPR;
\r
462 fileid->Read(&height, sizeof(unsigned long int));
\r
463 height = BYTE_SWAP4(height);
\r
464 fileid->Read(&width, sizeof(unsigned long int));
\r
465 width = BYTE_SWAP4(width);
\r
466 fileid->Read(&nc, sizeof(unsigned short int));
\r
467 nc = BYTE_SWAP2(nc);
\r
468 fileid->Read(&bpc, sizeof(unsigned char));
\r
469 fileid->Read(&C, sizeof(unsigned char));
\r
470 fileid->Read(&UnkC, sizeof(unsigned char));
\r
471 fileid->Read(&IPR, sizeof(unsigned char));
\r
474 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
475 wxString::Format(wxT("Dimensions: %d x %d x %d @ %d bpc"), width, height, nc, bpc + 1),
\r
476 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
477 new OPJMarkerData(wxT("INFO"))
\r
480 currid = m_tree->AppendItem(parentid,
\r
481 wxString::Format(wxT("Compression type: %d"), C),
\r
482 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
483 new OPJMarkerData(wxT("INFO"))
\r
486 currid = m_tree->AppendItem(parentid,
\r
487 wxString::Format(wxT("Colourspace unknown: %d"), UnkC),
\r
488 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
489 new OPJMarkerData(wxT("INFO"))
\r
492 currid = m_tree->AppendItem(parentid,
\r
493 wxString::Format(wxT("Intellectual Property Rights: %d"), IPR),
\r
494 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
495 new OPJMarkerData(wxT("INFO"))
\r
503 /* Colour Specification box */
\r
506 unsigned char METH, PREC, APPROX;
\r
507 char methdescr[80], enumcsdescr[80];
\r
508 unsigned long int EnumCS;
\r
509 fileid->Read(&METH, sizeof(unsigned char));
\r
512 strcpy(methdescr, "Enumerated Colourspace");
\r
515 strcpy(methdescr, "Restricted ICC profile");
\r
518 strcpy(methdescr, "Unknown");
\r
521 fileid->Read(&PREC, sizeof(unsigned char));
\r
522 fileid->Read(&APPROX, sizeof(unsigned char));
\r
524 fileid->Read(&EnumCS, sizeof(unsigned long int));
\r
525 EnumCS = BYTE_SWAP4(EnumCS);
\r
528 strcpy(enumcsdescr, "sRGB");
\r
531 strcpy(enumcsdescr, "greyscale");
\r
534 strcpy(enumcsdescr, "sYCC");
\r
537 strcpy(enumcsdescr, "Unknown");
\r
543 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
544 wxString::Format(wxT("Specification method: %d ("), METH) +
\r
545 wxString::FromAscii(methdescr) +
\r
547 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
548 new OPJMarkerData(wxT("INFO"))
\r
551 currid = m_tree->AppendItem(parentid,
\r
552 wxString::Format(wxT("Precedence: %d"), PREC),
\r
553 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
554 new OPJMarkerData(wxT("INFO"))
\r
557 currid = m_tree->AppendItem(parentid,
\r
558 wxString::Format(wxT("Colourspace approximation: %d"), APPROX),
\r
559 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
560 new OPJMarkerData(wxT("INFO"))
\r
564 currid = m_tree->AppendItem(parentid,
\r
565 wxString::Format(wxT("Enumerated colourspace: %d ("), EnumCS) +
\r
566 wxString::FromAscii(enumcsdescr) +
\r
568 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
569 new OPJMarkerData(wxT("INFO"))
\r
573 currid = m_tree->AppendItem(parentid,
\r
574 wxString::Format(wxT("ICC profile: there is one")),
\r
575 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
576 new OPJMarkerData(wxT("INFO"))
\r
588 /* Movie Header Box */
\r
591 unsigned long int version, rate, matrix[9], next_track_ID;
\r
592 unsigned short int volume;
\r
593 fileid->Read(&version, sizeof(unsigned long int));
\r
594 version = BYTE_SWAP4(version);
\r
595 if (version == 0) {
\r
596 unsigned long int creation_time, modification_time, timescale, duration;
\r
597 fileid->Read(&creation_time, sizeof(unsigned long int));
\r
598 creation_time = BYTE_SWAP4(creation_time);
\r
599 fileid->Read(&modification_time, sizeof(unsigned long int));
\r
600 modification_time = BYTE_SWAP4(modification_time);
\r
601 fileid->Read(×cale, sizeof(unsigned long int));
\r
602 timescale = BYTE_SWAP4(timescale);
\r
603 fileid->Read(&duration, sizeof(unsigned long int));
\r
604 duration = BYTE_SWAP4(duration);
\r
605 const long unix_time = creation_time - 2082844800L;
\r
606 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
607 wxString::Format(wxT("Creation time: %u (%.24s)"), creation_time, ctime(&unix_time)),
\r
608 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
609 new OPJMarkerData(wxT("INFO"))
\r
611 const long unix_time1 = modification_time - 2082844800L;
\r
612 currid = m_tree->AppendItem(parentid,
\r
613 wxString::Format(wxT("Modification time: %u (%.24s)"), modification_time, ctime(&unix_time1)),
\r
614 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
615 new OPJMarkerData(wxT("INFO"))
\r
617 currid = m_tree->AppendItem(parentid,
\r
618 wxString::Format(wxT("Timescale: %u (%.6fs)"), timescale, 1.0 / (float) timescale),
\r
619 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
620 new OPJMarkerData(wxT("INFO"))
\r
622 currid = m_tree->AppendItem(parentid,
\r
623 wxString::Format(wxT("Duration: %u (%.3fs)"), duration, (float) duration / (float) timescale),
\r
624 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
625 new OPJMarkerData(wxT("INFO"))
\r
628 int8byte creation_time, modification_time, duration;
\r
629 unsigned long int timescale;
\r
630 fileid->Read(&creation_time, sizeof(int8byte));
\r
631 creation_time = BYTE_SWAP8(creation_time);
\r
632 fileid->Read(&modification_time, sizeof(int8byte));
\r
633 modification_time = BYTE_SWAP8(modification_time);
\r
634 fileid->Read(×cale, sizeof(unsigned long int));
\r
635 timescale = BYTE_SWAP4(timescale);
\r
636 fileid->Read(&duration, sizeof(int8byte));
\r
637 duration = BYTE_SWAP8(duration);
\r
638 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
639 wxString::Format(wxT("Creation time: %u"), creation_time),
\r
640 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
641 new OPJMarkerData(wxT("INFO"))
\r
643 currid = m_tree->AppendItem(parentid,
\r
644 wxString::Format(wxT("Modification time: %u"), modification_time),
\r
645 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
646 new OPJMarkerData(wxT("INFO"))
\r
648 currid = m_tree->AppendItem(parentid,
\r
649 wxString::Format(wxT("Timescale: %u"), timescale),
\r
650 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
651 new OPJMarkerData(wxT("INFO"))
\r
653 currid = m_tree->AppendItem(parentid,
\r
654 wxString::Format(wxT("Duration: %u"), duration),
\r
655 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
656 new OPJMarkerData(wxT("INFO"))
\r
659 fileid->Read(&rate, sizeof(unsigned long int));
\r
660 rate = BYTE_SWAP4(rate);
\r
661 fileid->Read(&volume, sizeof(unsigned short int));
\r
662 volume = BYTE_SWAP2(volume);
\r
663 fileid->Seek(6, wxFromCurrent);
\r
664 fileid->Read(&matrix, sizeof(unsigned char) * 9);
\r
665 fileid->Seek(4, wxFromCurrent);
\r
666 fileid->Read(&next_track_ID, sizeof(unsigned long int));
\r
667 next_track_ID = BYTE_SWAP4(next_track_ID);
\r
668 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
669 wxString::Format(wxT("Rate: %d (%d.%d)"), rate, rate >> 16, rate & 0x0000FFFF),
\r
670 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
671 new OPJMarkerData(wxT("INFO"))
\r
673 currid = m_tree->AppendItem(parentid,
\r
674 wxString::Format(wxT("Volume: %d (%d.%d)"), volume, volume >> 8, volume & 0x00FF),
\r
675 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
676 new OPJMarkerData(wxT("INFO"))
\r
678 currid = m_tree->AppendItem(parentid,
\r
679 wxString::Format(wxT("Next track ID: %d"), next_track_ID),
\r
680 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
681 new OPJMarkerData(wxT("INFO"))
\r
687 /* Sample Description box */
\r
690 unsigned long int version, entry_count;
\r
691 fileid->Read(&version, sizeof(unsigned long int));
\r
692 version = BYTE_SWAP4(version);
\r
693 fileid->Read(&entry_count, sizeof(unsigned long int));
\r
694 entry_count = BYTE_SWAP4(entry_count);
\r
695 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
696 wxString::Format(wxT("Entry count: %d"), entry_count),
\r
697 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
698 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
\r
700 jpeg2000parse(fileid, filepoint + 8, filelimit, parentid, level + 1, scansign, scanpoint);
\r
705 /* Sample Size box */
\r
708 unsigned long int version, sample_size, sample_count, entry_size;
\r
710 fileid->Read(&version, sizeof(unsigned long int));
\r
711 version = BYTE_SWAP4(version);
\r
713 fileid->Read(&sample_size, sizeof(unsigned long int));
\r
714 sample_size = BYTE_SWAP4(sample_size);
\r
716 if (sample_size == 0) {
\r
717 fileid->Read(&sample_count, sizeof(unsigned long int));
\r
718 sample_count = BYTE_SWAP4(sample_count);
\r
720 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
721 wxString::Format(wxT("Sample count: %d"), sample_count),
\r
722 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
723 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
\r
726 currid = m_tree->AppendItem(parentid,
\r
727 wxT("Entries size (bytes)"),
\r
728 m_tree->TreeCtrlIcon_Folder, m_tree->TreeCtrlIcon_Folder + 1,
\r
729 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
\r
733 for (unsigned int s = 0; s < sample_count; s++) {
\r
734 fileid->Read(&entry_size, sizeof(unsigned long int));
\r
735 entry_size = BYTE_SWAP4(entry_size);
\r
737 text << wxString::Format(wxT("%d, "), entry_size);
\r
739 if (((s % 10) == (ITEM_PER_ROW - 1)) || (s == (sample_count - 1))) {
\r
740 m_tree->AppendItem(currid,
\r
742 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
743 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
\r
756 /* Video Media Header box */
\r
759 unsigned long int version;
\r
760 unsigned short int graphicsmode, opcolor[3];
\r
761 char graphicsdescr[100];
\r
763 fileid->Read(&version, sizeof(unsigned long int));
\r
764 version = BYTE_SWAP4(version);
\r
766 fileid->Read(&graphicsmode, sizeof(unsigned short int));
\r
767 graphicsmode = BYTE_SWAP2(graphicsmode);
\r
768 switch (graphicsmode) {
\r
770 strcpy(graphicsdescr, "copy");
\r
773 strcpy(graphicsdescr, "transparent");
\r
776 strcpy(graphicsdescr, "alpha");
\r
779 strcpy(graphicsdescr, "whitealpha");
\r
782 strcpy(graphicsdescr, "blackalpha");
\r
785 strcpy(graphicsdescr, "unknown");
\r
789 fileid->Read(opcolor, 3 * sizeof(unsigned short int));
\r
790 opcolor[0] = BYTE_SWAP2(opcolor[0]);
\r
791 opcolor[1] = BYTE_SWAP2(opcolor[1]);
\r
792 opcolor[2] = BYTE_SWAP2(opcolor[2]);
\r
794 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
795 wxString::Format(wxT("Composition mode: %d (")) +
\r
796 wxString::FromAscii(graphicsdescr) +
\r
798 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
799 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
\r
802 currid = m_tree->AppendItem(parentid,
\r
803 wxString::Format(wxT("OP color: %d %d %d"), opcolor[0], opcolor[1], opcolor[2]),
\r
804 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
805 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
\r
812 /* MJP2 Sample Description box */
\r
815 unsigned short int height, width, depth;
\r
816 unsigned long int horizresolution, vertresolution;
\r
817 char compressor_name[32];
\r
818 fileid->Seek(24, wxFromCurrent);
\r
819 fileid->Read(&width, sizeof(unsigned short int));
\r
820 width = BYTE_SWAP2(width);
\r
821 fileid->Read(&height, sizeof(unsigned short int));
\r
822 height = BYTE_SWAP2(height);
\r
823 fileid->Read(&horizresolution, sizeof(unsigned long int));
\r
824 horizresolution = BYTE_SWAP4(horizresolution);
\r
825 fileid->Read(&vertresolution, sizeof(unsigned long int));
\r
826 vertresolution = BYTE_SWAP4(vertresolution);
\r
827 fileid->Seek(6, wxFromCurrent);
\r
828 fileid->Read(compressor_name, sizeof(char) * 32);
\r
829 fileid->Read(&depth, sizeof(unsigned short int));
\r
830 depth = BYTE_SWAP2(depth);
\r
831 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
832 wxString::Format(wxT("Dimensions: %d x %d @ %d bpp"), width, height, depth),
\r
833 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
834 new OPJMarkerData(wxT("INFO"), m_tree->m_fname.GetFullPath(), filepoint, filelimit)
\r
836 currid = m_tree->AppendItem(parentid,
\r
837 wxString::Format(wxT("Resolution: %d.%d x %d.%d"), horizresolution >> 16, horizresolution & 0x0000FFFF,
\r
838 vertresolution >> 16, vertresolution & 0x0000FFFF),
\r
839 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
840 new OPJMarkerData(wxT("INFO"))
\r
842 currid = m_tree->AppendItem(parentid,
\r
843 wxString::Format(wxT("Compressor: %.32s"), compressor_name),
\r
844 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
845 new OPJMarkerData(wxT("INFO"))
\r
847 jpeg2000parse(fileid, filepoint + 78, filelimit, parentid, level + 1, scansign, scanpoint);
\r
852 /* Media Header box */
\r
854 unsigned long int version;
\r
855 unsigned short int language;
\r
856 fileid->Read(&version, sizeof(unsigned long int));
\r
857 version = BYTE_SWAP4(version);
\r
858 if (version == 0) {
\r
859 unsigned long int creation_time, modification_time, timescale, duration;
\r
860 fileid->Read(&creation_time, sizeof(unsigned long int));
\r
861 creation_time = BYTE_SWAP4(creation_time);
\r
862 fileid->Read(&modification_time, sizeof(unsigned long int));
\r
863 modification_time = BYTE_SWAP4(modification_time);
\r
864 fileid->Read(×cale, sizeof(unsigned long int));
\r
865 timescale = BYTE_SWAP4(timescale);
\r
866 fileid->Read(&duration, sizeof(unsigned long int));
\r
867 duration = BYTE_SWAP4(duration);
\r
868 const long unix_time = creation_time - 2082844800L;
\r
869 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
870 wxString::Format(wxT("Creation time: %u (%.24s)"), creation_time, ctime(&unix_time)),
\r
871 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
872 new OPJMarkerData(wxT("INFO"))
\r
874 const long unix_time1 = modification_time - 2082844800L;
\r
875 currid = m_tree->AppendItem(parentid,
\r
876 wxString::Format(wxT("Modification time: %u (%.24s)"), modification_time, ctime(&unix_time1)),
\r
877 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
878 new OPJMarkerData(wxT("INFO"))
\r
880 currid = m_tree->AppendItem(parentid,
\r
881 wxString::Format(wxT("Timescale: %u (%.6fs)"), timescale, 1.0 / (float) timescale),
\r
882 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
883 new OPJMarkerData(wxT("INFO"))
\r
885 currid = m_tree->AppendItem(parentid,
\r
886 wxString::Format(wxT("Duration: %u (%.3fs)"), duration, (float) duration / (float) timescale),
\r
887 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
888 new OPJMarkerData(wxT("INFO"))
\r
891 int8byte creation_time, modification_time, duration;
\r
892 unsigned long int timescale;
\r
893 fileid->Read(&creation_time, sizeof(int8byte));
\r
894 creation_time = BYTE_SWAP8(creation_time);
\r
895 fileid->Read(&modification_time, sizeof(int8byte));
\r
896 modification_time = BYTE_SWAP8(modification_time);
\r
897 fileid->Read(×cale, sizeof(unsigned long int));
\r
898 timescale = BYTE_SWAP4(timescale);
\r
899 fileid->Read(&duration, sizeof(int8byte));
\r
900 duration = BYTE_SWAP8(duration);
\r
901 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
902 wxString::Format(wxT("Creation time: %u"), creation_time),
\r
903 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
904 new OPJMarkerData(wxT("INFO"))
\r
906 currid = m_tree->AppendItem(parentid,
\r
907 wxString::Format(wxT("Modification time: %u"), modification_time),
\r
908 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
909 new OPJMarkerData(wxT("INFO"))
\r
911 currid = m_tree->AppendItem(parentid,
\r
912 wxString::Format(wxT("Timescale: %u"), timescale),
\r
913 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
914 new OPJMarkerData(wxT("INFO"))
\r
916 currid = m_tree->AppendItem(parentid,
\r
917 wxString::Format(wxT("Duration: %u"), duration),
\r
918 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
919 new OPJMarkerData(wxT("INFO"))
\r
922 fileid->Read(&language, sizeof(unsigned short int));
\r
924 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
925 wxString::Format(wxT("Language: %d (%c%c%c)"), language & 0xEFFF,
\r
926 0x60 + (char) ((language >> 10) & 0x001F), 0x60 + (char) ((language >> 5) & 0x001F), 0x60 + (char) ((language >> 0) & 0x001F)),
\r
927 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
928 new OPJMarkerData(wxT("INFO"))
\r
933 /* Media Handler box */
\r
935 unsigned long int version, predefined, temp[3];
\r
936 char handler[4], name[256];
\r
937 int namelen = wxMin(256, (filelimit - filepoint - 24));
\r
938 fileid->Read(&version, sizeof(unsigned long int));
\r
939 version = BYTE_SWAP4(version);
\r
940 fileid->Read(&predefined, sizeof(unsigned long int));
\r
941 fileid->Read(handler, 4 * sizeof(char));
\r
942 fileid->Read(&temp, 3 * sizeof(unsigned long int));
\r
943 fileid->Read(name, namelen * sizeof(char));
\r
945 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
946 wxString::Format(wxT("Handler: %.4s"), handler),
\r
947 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
948 new OPJMarkerData(wxT("INFO"))
\r
951 currid = m_tree->AppendItem(parentid,
\r
952 wxString::Format(wxT("Name: %.255s"), name),
\r
953 m_tree->TreeCtrlIcon_File, m_tree->TreeCtrlIcon_File + 1,
\r
954 new OPJMarkerData(wxT("INFO"))
\r
960 /* not yet implemented */
\r
970 void OPJParseThread::ParseJP2File(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit, wxTreeItemId parentid)
\r
972 unsigned long int scanpoint;
\r
974 jpeg2000parse(fileid, filepoint, filelimit, parentid, 0, NULL, &scanpoint);
\r
977 /* the parsing function itself */
\r
979 fileid = fid of the file to scan (you should open it by yourself)
\r
980 filepoint = first byte where to start to scan from (usually 0)
\r
981 filelimit = first byte where to stop to scan from (usually the file size)
\r
982 level = set this to 0
\r
983 scansign = signature to scan for (NULL avoids search, returns " " if successful)
\r
984 scanpoint = point where the scan signature lies
\r
986 int OPJParseThread::jpeg2000parse(wxFile *fileid, wxFileOffset filepoint, wxFileOffset filelimit,
\r
987 wxTreeItemId parentid, int level, char *scansign, unsigned long int *scanpoint)
\r
989 unsigned long int LBox = 0x00000000;
\r
991 char TBox[5] = "\0\0\0\0";
\r
993 int8byte XLBox = 0x0000000000000000;
\r
995 unsigned long int box_length = 0;
\r
996 int last_box = 0, box_num = 0;
\r
997 int box_type = ANY_BOX;
\r
998 unsigned char /*onebyte[1], twobytes[2],*/ fourbytes[4];
\r
1000 /* cycle all over the file */
\r
1003 while (!last_box) {
\r
1005 /* do not exceed file limit */
\r
1006 if (filepoint >= filelimit)
\r
1009 /* seek on file */
\r
1010 if (fileid->Seek(filepoint, wxFromStart) == wxInvalidOffset)
\r
1013 /* read the mandatory LBox, 4 bytes */
\r
1014 if (fileid->Read(fourbytes, 4) < 4) {
\r
1015 WriteText(wxT("Problem reading LBox from the file (file ended?)"));
\r
1018 LBox = STREAM_TO_UINT32(fourbytes, 0);
\r
1020 /* read the mandatory TBox, 4 bytes */
\r
1021 if (fileid->Read(TBox, 4) < 4) {
\r
1022 WriteText(wxT("Problem reading TBox from the file (file ended?)"));
\r
1026 /* look if scansign is got */
\r
1027 if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) {
\r
1028 memcpy(scansign, " ", 4);
\r
1029 *scanpoint = filepoint;
\r
1031 /* hack/exploit */
\r
1032 // stop as soon as you find the codebox
\r
1037 /* determine the box type */
\r
1038 for (box_type = JP_BOX; box_type < UNK_BOX; box_type++)
\r
1039 if (memcmp(TBox, j22box[box_type].value, 4) == 0)
\r
1042 /* read the optional XLBox, 8 bytes */
\r
1045 if (fileid->Read(&XLBox, 8) < 8) {
\r
1046 WriteText(wxT("Problem reading XLBox from the file (file ended?)"));
\r
1049 box_length = (unsigned long int) BYTE_SWAP8(XLBox);
\r
1051 } else if (LBox == 0x00000000) {
\r
1053 /* last box in file */
\r
1055 box_length = filelimit - filepoint;
\r
1059 box_length = LBox;
\r
1061 /* show box info */
\r
1063 // append the marker
\r
1064 int image, imageSel;
\r
1065 image = m_tree->TreeCtrlIcon_Folder;
\r
1066 imageSel = image + 1;
\r
1067 wxTreeItemId currid = m_tree->AppendItem(parentid,
\r
1068 wxString::Format(wxT("%03d: "), box_num) +
\r
1069 wxString::FromAscii(TBox) +
\r
1070 wxString::Format(wxT(" (0x%04X)"),
\r
1071 ((unsigned long int) TBox[3]) + ((unsigned long int) TBox[2] << 8) +
\r
1072 ((unsigned long int) TBox[1] << 16) + ((unsigned long int) TBox[0] << 24)
\r
1075 new OPJMarkerData(wxT("BOX"), m_tree->m_fname.GetFullPath(), filepoint, filepoint + box_length)
\r
1078 // append some info
\r
1079 image = m_tree->TreeCtrlIcon_File;
\r
1080 imageSel = image + 1;
\r
1083 wxTreeItemId subcurrid1 = m_tree->AppendItem(currid,
\r
1084 wxT("*** ") + wxString::FromAscii(j22box[box_type].name) + wxT(" ***"),
\r
1086 new OPJMarkerData(wxT("INFO"))
\r
1088 m_tree->SetItemFont(subcurrid1, *wxITALIC_FONT);
\r
1090 // position and length
\r
1091 wxTreeItemId subcurrid2 = m_tree->AppendItem(currid,
\r
1092 wxLongLong(filepoint).ToString() + wxT(" > ") + wxLongLong(filepoint + box_length - 1).ToString() +
\r
1093 wxT(", ") + wxString::Format(wxT("%d + 8 (%d)"), box_length, box_length + 8),
\r
1095 new OPJMarkerData(wxT("INFO"))
\r
1098 /* go deep in the box */
\r
1099 box_handler_function((int) box_type, fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length,
\r
1100 currid, level, scansign, scanpoint);
\r
1102 /* if it's a superbox go inside it */
\r
1103 if (j22box[box_type].sbox)
\r
1104 jpeg2000parse(fileid, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length,
\r
1105 currid, level + 1, scansign, scanpoint);
\r
1107 /* increment box number and filepoint*/
\r
1109 filepoint += box_length;
\r