Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4758 | right-hear | 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 | |||
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 */ |
||
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(×cale, 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(×cale, 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(×cale, 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(×cale, 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 | |||
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 | */ |
||
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 |