openjp2/j2k: Validate all SGcod/SPcod/SPcoc parameter values.
[openjpeg.git] / src / lib / openmj2 / mj2.c
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) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8  * Copyright (c) 2002-2014, Professor Benoit Macq
9  * Copyright (c) 2003-2007, Francois-Olivier Devaux
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include "opj_includes.h"
35 #include "mj2.h"
36
37 /** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
38 /*@{*/
39
40 /** @name Local static functions */
41 /*@{*/
42
43 /*
44 *
45 * Read box headers
46 *
47 */
48
49 int mj2_read_boxhdr(mj2_box_t * box, opj_cio_t *cio)
50 {
51     box->init_pos = cio_tell(cio);
52     box->length = cio_read(cio, 4);
53     box->type = cio_read(cio, 4);
54     if (box->length == 1) {
55         if (cio_read(cio, 4) != 0) {
56             opj_event_msg(cio->cinfo, EVT_ERROR,
57                           "Error: Cannot handle box sizes higher than 2^32\n");
58             return 1;
59         };
60         box->length = cio_read(cio, 4);
61         if (box->length == 0) {
62             box->length = cio_numbytesleft(cio) + 12;
63         }
64     } else if (box->length == 0) {
65         box->length = cio_numbytesleft(cio) + 8;
66     }
67     return 0;
68 }
69
70 /*
71 *
72 * Initialisation of a Standard Movie, given a simple movie structure defined by the user
73 * The movie will have one sample per chunk
74 *
75 * Arguments: opj_mj2_t * movie
76 * Several variables of "movie" must be defined in order to enable a correct execution of
77 * this function:
78 *   - The number of tracks of each type (movie->num_vtk, movie->num_stk, movie->num_htk)
79 *   - The memory for each must be allocated (movie->tk)
80 *   - For each track:
81 *     The track type (tk->track_type)
82 *     The number of sample (tk->num_samples)
83 *     The sample rate (tk->sample_rate)
84 *
85 */
86
87 int OPJ_CALLCONV mj2_init_stdmovie(opj_mj2_t * movie)
88 {
89     mj2_tk_t *tk0;
90     int i, w, h, prec;
91     unsigned int j;
92     time_t ltime;
93
94     movie->brand = MJ2_MJ2;
95     movie->minversion = 0;
96     movie->num_cl = 2;
97     movie->cl = (unsigned int*) opj_malloc(movie->num_cl * sizeof(unsigned int));
98
99     movie->cl[0] = MJ2_MJ2;
100     movie->cl[1] = MJ2_MJ2S;
101     time(&ltime);         /* Time since 1/1/70 */
102     movie->creation_time = (unsigned int) ltime +
103                            2082844800; /* Seconds between 1/1/04 and 1/1/70 */
104     movie->timescale = 1000;
105
106     movie->rate = 1 <<
107                   16;        /* Rate to play presentation  (default = 0x00010000)          */
108     movie->volume = 1 <<
109                     8;       /* Movie volume (default = 0x0100)                            */
110     movie->trans_matrix[0] =
111         0x00010000;  /* Transformation matrix for video                            */
112     movie->trans_matrix[1] =
113         0;   /* Unity is { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 }  */
114     movie->trans_matrix[2] = 0;
115     movie->trans_matrix[3] = 0;
116     movie->trans_matrix[4] = 0x00010000;
117     movie->trans_matrix[5] = 0;
118     movie->trans_matrix[6] = 0;
119     movie->trans_matrix[7] = 0;
120     movie->trans_matrix[8] = 0x40000000;
121     movie->next_tk_id = 1;
122
123     tk0 = &movie->tk[0];
124     w = tk0->w;
125     h = tk0->h;
126     prec = tk0->depth;
127
128     for (i = 0; i < movie->num_htk + movie->num_stk + movie->num_vtk; i++) {
129         mj2_tk_t *tk = &movie->tk[i];
130
131         movie->next_tk_id++;
132         tk->jp2_struct.comps = NULL;
133         tk->jp2_struct.cl = NULL;
134
135         if (tk->track_type == 0) { /* no sound or hint track */
136             if (tk->num_samples == 0) {
137                 return 1;
138             }
139
140             tk->w = w;
141             tk->h = h;
142             tk->depth = prec;
143             tk->Dim[0] = 0;
144             tk->Dim[1] = 0;
145
146             tk->timescale =
147                 1000; /* Timescale = 1 ms                                          */
148
149             tk->chunk[0].num_samples = 1;
150             tk->chunk[0].sample_descr_idx = 1;
151
152             tk->same_sample_size = 0;
153
154             tk->num_samplestochunk = 1;   /* One sample per chunk  */
155             tk->sampletochunk = (mj2_sampletochunk_t*) opj_malloc(tk->num_samplestochunk *
156                                 sizeof(mj2_sampletochunk_t));
157             tk->sampletochunk[0].first_chunk = 1;
158             tk->sampletochunk[0].samples_per_chunk = 1;
159             tk->sampletochunk[0].sample_descr_idx = 1;
160
161             if (tk->sample_rate == 0) {
162                 opj_event_msg(tk->cinfo, EVT_ERROR,
163                               "Error while initializing MJ2 movie: Sample rate of track"
164                               " %d must be different from zero\n", tk->track_ID);
165                 return 1;
166             }
167
168             for (j = 0; j < tk->num_samples; j++) {
169                 tk->sample[j].sample_delta = tk->timescale / tk->sample_rate;
170             }
171
172             tk->num_tts = 1;
173             tk->tts = (mj2_tts_t*) opj_malloc(tk->num_tts * sizeof(mj2_tts_t));
174             tk->tts[0].sample_count = tk->num_samples;
175             tk->tts[0].sample_delta = tk->timescale / tk->sample_rate;
176
177             tk->horizresolution =
178                 0x00480000; /* Horizontal resolution (typically 72)                       */
179             tk->vertresolution =
180                 0x00480000;  /* Vertical resolution (typically 72)                         */
181             tk->compressorname[0] =
182                 0x0f4d6f74;   /* Compressor Name[]: Motion JPEG2000                         */
183             tk->compressorname[1] = 0x696f6e20;
184             tk->compressorname[2] = 0x4a504547;
185             tk->compressorname[3] = 0x32303030;
186             tk->compressorname[4] = 0x00120000;
187             tk->compressorname[5] = 0;
188             tk->compressorname[6] = 0x00000042;
189             tk->compressorname[7] = 0x000000DC;
190             tk->num_url =
191                 0;      /* Number of URL                                              */
192             tk->num_urn =
193                 0;      /* Number of URN                                              */
194             tk->graphicsmode =
195                 0; /* Graphicsmode                                               */
196             tk->opcolor[0] =
197                 0;   /* OpColor                                                    */
198             tk->opcolor[1] =
199                 0;   /* OpColor                                                    */
200             tk->opcolor[2] =
201                 0;   /* OpColor                                                    */
202             tk->creation_time =
203                 movie->creation_time; /* Seconds between 1/1/04 and 1/1/70          */
204             tk->language = 0;     /* Language (undefined)                       */
205             tk->layer = 0;
206             tk->volume = 1 << 8;      /* Movie volume (default = 0x0100) */
207             tk->trans_matrix[0] = 0x00010000; /* Transformation matrix for track */
208             tk->trans_matrix[1] =
209                 0;  /* Unity is { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 }  */
210             tk->trans_matrix[2] = 0;
211             tk->trans_matrix[3] = 0;
212             tk->trans_matrix[4] = 0x00010000;
213             tk->trans_matrix[5] = 0;
214             tk->trans_matrix[6] = 0;
215             tk->trans_matrix[7] = 0;
216             tk->trans_matrix[8] = 0x40000000;
217             tk->fieldcount = 1;
218             tk->fieldorder = 0;
219             tk->or_fieldcount = 1;
220             tk->or_fieldorder = 0;
221             tk->num_br = 2;
222             tk->br = (unsigned int*) opj_malloc(tk->num_br * sizeof(unsigned int));
223             tk->br[0] = MJ2_JP2;
224             tk->br[1] = MJ2_J2P0;
225             tk->num_jp2x = 0;
226             tk->hsub =
227                 2;     /* 4:2:0                                                      */
228             tk->vsub =
229                 2;     /* 4:2:0                                                      */
230             tk->hoff = 0;
231             tk->voff = 0;
232             tk->visual_w = tk->w << 16;
233             tk->visual_h = tk->h << 16;
234         } else {
235             tk->num_br = 0;
236             tk->jp2xdata = NULL;
237         }
238     }
239     return 0;
240 }
241
242 /*
243 * Time To Sample box Decompact
244 *
245 */
246 void mj2_tts_decompact(mj2_tk_t * tk)
247 {
248     int i, j;
249     tk->num_samples = 0;
250     for (i = 0; i < tk->num_tts; i++) {
251         tk->num_samples += tk->tts[i].sample_count;
252     }
253
254     tk->sample = (mj2_sample_t*) opj_malloc(tk->num_samples * sizeof(mj2_sample_t));
255
256     for (i = 0; i < tk->num_tts; i++) {
257         for (j = 0; j < tk->tts[i].sample_count; j++) {
258             tk->sample[j].sample_delta = tk->tts[i].sample_delta;
259         }
260     }
261 }
262
263 /*
264 * Sample To Chunk box Decompact
265 *
266 */
267 void mj2_stsc_decompact(mj2_tk_t * tk)
268 {
269     unsigned int i, j, k, sampleno = 0;
270
271     if (tk->num_samplestochunk == 1) {
272         tk->num_chunks =
273             (unsigned int) ceil((double) tk->num_samples /
274                                 (double) tk->sampletochunk[0].samples_per_chunk);
275         tk->chunk = (mj2_chunk_t*) opj_malloc(tk->num_chunks * sizeof(mj2_chunk_t));
276         for (k = 0; k < tk->num_chunks; k++) {
277             tk->chunk[k].num_samples = tk->sampletochunk[0].samples_per_chunk;
278         }
279
280     } else {
281         tk->chunk = (mj2_chunk_t*) opj_malloc(tk->num_samples * sizeof(mj2_chunk_t));
282         tk->num_chunks = 0;
283         for (i = 0; i < tk->num_samplestochunk - 1 ; i++) {
284             for (j = tk->sampletochunk[i].first_chunk - 1;
285                     j < tk->sampletochunk[i + 1].first_chunk - 1; j++) {
286                 tk->chunk[j].num_samples = tk->sampletochunk[i].samples_per_chunk;
287                 tk->num_chunks++;
288                 sampleno += tk->chunk[j].num_samples;
289             }
290         }
291         tk->num_chunks += (int)(tk->num_samples  - sampleno) /
292                           tk->sampletochunk[tk->num_samplestochunk - 1].samples_per_chunk;
293         for (k = tk->sampletochunk[tk->num_samplestochunk - 1].first_chunk - 1;
294                 k < tk->num_chunks; k++) {
295             tk->chunk[k].num_samples =
296                 tk->sampletochunk[tk->num_samplestochunk - 1].samples_per_chunk;
297         }
298         tk->chunk = (mj2_chunk_t*)
299                     opj_realloc(tk->chunk, tk->num_chunks * sizeof(mj2_chunk_t));
300     }
301
302 }
303
304
305 /*
306 * Chunk offset box Decompact
307 *
308 */
309 void mj2_stco_decompact(mj2_tk_t * tk)
310 {
311     unsigned int i, j, k = 0;
312     unsigned int intra_chunk_offset;
313
314     for (i = 0; i < tk->num_chunks; i++) {
315         intra_chunk_offset = 0;
316         for (j = 0; j < tk->chunk[i].num_samples; j++) {
317             tk->sample[k].offset = intra_chunk_offset + tk->chunk[i].offset;
318             intra_chunk_offset += tk->sample[k].sample_size;
319             k++;
320         }
321     }
322 }
323
324 /*
325 * Write the JP box
326 *
327 * JP Signature box
328 *
329 */
330 void OPJ_CALLCONV mj2_write_jp(opj_cio_t *cio)
331 {
332     mj2_box_t box;
333     box.init_pos = cio_tell(cio);
334     cio_skip(cio, 4);
335
336     cio_write(cio, MJ2_JP, 4);        /* JP */
337     cio_write(cio, 0x0d0a870a, 4);    /* 0x0d0a870a required in a JP box */
338
339     box.length = cio_tell(cio) - box.init_pos;
340     cio_seek(cio, box.init_pos);
341     cio_write(cio, box.length, 4);
342     cio_seek(cio, box.init_pos + box.length);
343 }
344
345 /*
346 * Read the JP box
347 *
348 * JPEG 2000 signature
349 *
350 */
351 int mj2_read_jp(opj_cio_t *cio)
352 {
353     mj2_box_t box;
354
355     mj2_read_boxhdr(&box, cio);
356     if (MJ2_JP != box.type) { /* Check Marker */
357         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected JP Marker\n");
358         return 1;
359     }
360     if (0x0d0a870a != cio_read(cio,
361                                4)) { /* read the 0x0d0a870a required in a JP box */
362         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JP Marker\n");
363         return 1;
364     }
365     if (cio_tell(cio) - box.init_pos != box.length) { /* Check box length */
366         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JP Box size \n");
367         return 1;
368     }
369     return 0;
370
371 }
372
373 /*
374 * Write the FTYP box
375 *
376 * File type box
377 *
378 */
379 void OPJ_CALLCONV mj2_write_ftyp(opj_mj2_t * movie, opj_cio_t *cio)
380 {
381     int i;
382     mj2_box_t box;
383     box.init_pos = cio_tell(cio);
384     cio_skip(cio, 4);
385
386     cio_write(cio, MJ2_FTYP, 4);  /* FTYP       */
387     cio_write(cio, movie->brand, 4);  /* BR         */
388     cio_write(cio, movie->minversion, 4); /* MinV       */
389
390     for (i = 0; i < movie->num_cl; i++) {
391         cio_write(cio, movie->cl[i], 4);    /* CL         */
392     }
393
394     box.length = cio_tell(cio) - box.init_pos;
395     cio_seek(cio, box.init_pos);
396     cio_write(cio, box.length, 4);    /* Length     */
397     cio_seek(cio, box.init_pos + box.length);
398 }
399
400 /*
401 * Read the FTYP box
402 *
403 * File type box
404 *
405 */
406 int mj2_read_ftyp(opj_mj2_t * movie, opj_cio_t *cio)
407 {
408     int i;
409     mj2_box_t box;
410
411     mj2_read_boxhdr(&box, cio);   /* Box Size */
412     if (MJ2_FTYP != box.type) {
413         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected FTYP Marker\n");
414         return 1;
415     }
416
417     movie->brand = cio_read(cio, 4);  /* BR              */
418     movie->minversion = cio_read(cio, 4); /* MinV            */
419     movie->num_cl = (box.length - 16) / 4;
420     movie->cl = (unsigned int*) opj_malloc(movie->num_cl * sizeof(unsigned int));
421
422     for (i = movie->num_cl - 1; i > -1; i--) {
423         movie->cl[i] = cio_read(cio, 4);    /* CLi */
424     }
425
426     if (cio_tell(cio) - box.init_pos != box.length) {
427         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with FTYP Box\n");
428         return 1;
429     }
430     return 0;
431 }
432
433
434 /*
435 * Write the STCO box
436 *
437 * Chunk Offset Box
438 *
439 */
440 void mj2_write_stco(mj2_tk_t * tk, opj_cio_t *cio)
441 {
442     mj2_box_t box;
443     unsigned int i;
444
445     box.init_pos = cio_tell(cio);
446     cio_skip(cio, 4);
447     cio_write(cio, MJ2_STCO, 4);  /* STCO       */
448
449     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
450
451     cio_write(cio, tk->num_chunks, 4);    /* Entry Count */
452
453     for (i = 0; i < tk->num_chunks; i++) {
454         cio_write(cio, tk->chunk[i].offset, 4); /* Entry offset */
455     }
456
457     box.length = cio_tell(cio) - box.init_pos;
458     cio_seek(cio, box.init_pos);
459     cio_write(cio, box.length, 4);    /* L          */
460     cio_seek(cio, box.init_pos + box.length);
461 }
462
463 /*
464 * Read the STCO box
465 *
466 * Chunk Offset Box
467 *
468 */
469 int mj2_read_stco(mj2_tk_t * tk, opj_cio_t *cio)
470 {
471     unsigned int i;
472     mj2_box_t box;
473
474     mj2_read_boxhdr(&box, cio);   /* Box Size */
475     if (MJ2_STCO != box.type) {
476         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STCO Marker\n");
477         return 1;
478     }
479
480     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
481         opj_event_msg(cio->cinfo, EVT_ERROR,
482                       "Error: Only Version 0 handled in STCO box\n");
483         return 1;
484     }
485
486     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
487         opj_event_msg(cio->cinfo, EVT_ERROR,
488                       "Error with flag in STCO box. Expected flag 0\n");
489         return 1;
490     }
491
492
493     if (cio_read(cio, 4) != tk->num_chunks) {
494         opj_event_msg(cio->cinfo, EVT_ERROR,
495                       "Error in STCO box: expecting same amount of entry-count as chunks \n");
496     } else {
497         for (i = 0; i < tk->num_chunks; i++) {
498             tk->chunk[i].offset = cio_read(cio, 4);   /* Entry offset */
499         }
500     }
501
502     mj2_stco_decompact(tk);
503
504
505     if (cio_tell(cio) - box.init_pos != box.length) {
506         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STCO Box size\n");
507         return 1;
508     }
509     return 0;
510 }
511
512 /*
513 * Write the STSZ box
514 *
515 * Sample size box
516 *
517 */
518 void mj2_write_stsz(mj2_tk_t * tk, opj_cio_t *cio)
519 {
520     mj2_box_t box;
521     unsigned int i;
522
523     box.init_pos = cio_tell(cio);
524     cio_skip(cio, 4);
525     cio_write(cio, MJ2_STSZ, 4);  /* STSZ       */
526
527     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
528
529     if (tk->same_sample_size == 1) {  /* If they all have the same size */
530         cio_write(cio, tk->sample[0].sample_size, 4);   /* Size */
531
532         cio_write(cio, 1, 4);       /* Entry count = 1 */
533     }
534
535     else {
536         cio_write(cio, 0,
537                   4);       /* Sample Size = 0 because they all have different sizes */
538
539         cio_write(cio, tk->num_samples, 4); /* Sample Count */
540
541         for (i = 0; i < tk->num_samples; i++) {
542             cio_write(cio, tk->sample[i].sample_size, 4);
543         }
544     }
545
546     box.length = cio_tell(cio) - box.init_pos;
547     cio_seek(cio, box.init_pos);
548     cio_write(cio, box.length, 4);    /* L          */
549     cio_seek(cio, box.init_pos + box.length);
550 }
551
552 /*
553 * Read the STSZ box
554 *
555 * Sample size box
556 *
557 */
558 int mj2_read_stsz(mj2_tk_t * tk, opj_cio_t *cio)
559 {
560     int sample_size;
561     unsigned int i;
562     mj2_box_t box;
563
564     mj2_read_boxhdr(&box, cio);   /* Box Size */
565     if (MJ2_STSZ != box.type) {
566         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STSZ Marker\n");
567         return 1;
568     }
569
570
571     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
572         opj_event_msg(cio->cinfo, EVT_ERROR,
573                       "Error: Only Version 0 handled in STSZ box\n");
574         return 1;
575     }
576
577     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
578         opj_event_msg(cio->cinfo, EVT_ERROR,
579                       "Error with flag in STSZ box. Expected flag 0\n");
580         return 1;
581     }
582
583     sample_size = cio_read(cio, 4);
584
585     if (sample_size != 0) {   /* Samples do have the same size */
586         tk->same_sample_size = 1;
587         for (i = 0; i < tk->num_samples; i++) {
588             tk->sample[i].sample_size = sample_size;
589         }
590         cio_skip(cio, 4);       /* Sample count = 1 */
591     } else {
592         tk->same_sample_size = 0;
593         if (tk->num_samples != cio_read(cio, 4)) {  /* Sample count */
594             opj_event_msg(cio->cinfo, EVT_ERROR,
595                           "Error in STSZ box. Expected that sample-count is number of samples in track\n");
596             return 1;
597         }
598         for (i = 0; i < tk->num_samples; i++) {
599             tk->sample[i].sample_size = cio_read(cio, 4); /* Sample Size */
600         }
601
602         if (cio_tell(cio) - box.init_pos != box.length) {
603             opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STSZ Box size\n");
604             return 1;
605         }
606     }
607     return 0;
608
609 }
610
611 /*
612 * Write the STSC box
613 *
614 * Sample to Chunk
615 *
616 */
617 void mj2_write_stsc(mj2_tk_t * tk, opj_cio_t *cio)
618 {
619     unsigned int i;
620     mj2_box_t box;
621
622     box.init_pos = cio_tell(cio);
623     cio_skip(cio, 4);
624     cio_write(cio, MJ2_STSC, 4);  /* STSC       */
625
626     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
627
628     cio_write(cio, tk->num_samplestochunk, 4);    /* Entry Count */
629
630     for (i = 0; i < tk->num_samplestochunk; i++) {
631         cio_write(cio, tk->sampletochunk[i].first_chunk, 4);    /* First Chunk */
632         cio_write(cio, tk->sampletochunk[i].samples_per_chunk,
633                   4);  /* Samples per chunk */
634         cio_write(cio, tk->sampletochunk[i].sample_descr_idx,
635                   4);   /* Samples description index */
636     }
637
638
639     box.length = cio_tell(cio) - box.init_pos;
640     cio_seek(cio, box.init_pos);
641     cio_write(cio, box.length, 4);    /* L          */
642     cio_seek(cio, box.init_pos + box.length);
643 }
644
645 /*
646 * Read the STSC box
647 *
648 * Sample to Chunk
649 *
650 */
651 int mj2_read_stsc(mj2_tk_t * tk, opj_cio_t *cio)
652 {
653     unsigned int i;
654     mj2_box_t box;
655
656     mj2_read_boxhdr(&box, cio);   /* Box Size */
657     if (MJ2_STSC != box.type) {
658         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STSC Marker\n");
659         return 1;
660     }
661
662
663     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
664         opj_event_msg(cio->cinfo, EVT_ERROR,
665                       "Error: Only Version 0 handled in STSC box\n");
666         return 1;
667     }
668
669     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
670         opj_event_msg(cio->cinfo, EVT_ERROR,
671                       "Error with flag in STSC box. Expected flag 0\n");
672         return 1;
673     }
674
675     tk->num_samplestochunk = cio_read(cio, 4);
676
677     tk->sampletochunk = (mj2_sampletochunk_t*) opj_malloc(tk->num_samplestochunk *
678                         sizeof(mj2_sampletochunk_t));
679
680     for (i = 0; i < tk->num_samplestochunk; i++) {
681         tk->sampletochunk[i].first_chunk = cio_read(cio, 4);
682         tk->sampletochunk[i].samples_per_chunk = cio_read(cio, 4);
683         tk->sampletochunk[i].sample_descr_idx = cio_read(cio, 4);
684     }
685
686     mj2_stsc_decompact(tk);   /* decompact sample to chunk box */
687
688
689     if (cio_tell(cio) - box.init_pos != box.length) {
690         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STSC Box size\n");
691         return 1;
692     }
693     return 0;
694 }
695
696 /*
697 * Write the STTS box
698 *
699 * Time to Sample Box
700 *
701 */
702 void mj2_write_stts(mj2_tk_t * tk, opj_cio_t *cio)
703 {
704
705     int i;
706     mj2_box_t box;
707
708     box.init_pos = cio_tell(cio);
709     cio_skip(cio, 4);
710     cio_write(cio, MJ2_STTS, 4);  /* STTS       */
711
712     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
713
714     cio_write(cio, tk->num_tts, 4);   /* entry_count */
715     for (i = 0; i < tk->num_tts; i++) {
716         cio_write(cio, tk->tts[i].sample_count, 4); /* Sample-count */
717         cio_write(cio, tk->tts[i].sample_delta, 4); /* Sample-Delta */
718     }
719
720     box.length = cio_tell(cio) - box.init_pos;
721     cio_seek(cio, box.init_pos);
722     cio_write(cio, box.length, 4);    /* L          */
723     cio_seek(cio, box.init_pos + box.length);
724 }
725
726 /*
727 * Read the STTS box
728 *
729 *
730 *
731 */
732 int mj2_read_stts(mj2_tk_t * tk, opj_cio_t *cio)
733 {
734     int i;
735
736     mj2_box_t box;
737
738     mj2_read_boxhdr(&box, cio);
739     if (MJ2_STTS != box.type) {
740         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STTS Marker\n");
741         return 1;
742     }
743
744
745     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
746         opj_event_msg(cio->cinfo, EVT_ERROR,
747                       "Error: Only Version 0 handled in STTS box\n");
748         return 1;
749     }
750
751     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
752         opj_event_msg(cio->cinfo, EVT_ERROR,
753                       "Error with flag in STTS box. Expected flag 0\n");
754         return 1;
755     }
756
757     tk->num_tts = cio_read(cio, 4);
758
759     tk->tts = (mj2_tts_t*) opj_malloc(tk->num_tts * sizeof(mj2_tts_t));
760
761     for (i = 0; i < tk->num_tts; i++) {
762         tk->tts[i].sample_count = cio_read(cio, 4);
763         tk->tts[i].sample_delta = cio_read(cio, 4);
764     }
765
766     mj2_tts_decompact(tk);
767
768     if (cio_tell(cio) - box.init_pos != box.length) {
769         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STTS Box size\n");
770         return 1;
771     }
772     return 0;
773 }
774
775 /*
776 * Write the FIEL box
777 *
778 * Field coding Box
779 *
780 */
781 void mj2_write_fiel(mj2_tk_t * tk, opj_cio_t *cio)
782 {
783
784     mj2_box_t box;
785
786     box.init_pos = cio_tell(cio);
787     cio_skip(cio, 4);
788     cio_write(cio, MJ2_FIEL, 4);  /* STTS       */
789
790     cio_write(cio, tk->fieldcount, 1);    /* Field count */
791     cio_write(cio, tk->fieldorder, 1);    /* Field order */
792
793
794     box.length = cio_tell(cio) - box.init_pos;
795     cio_seek(cio, box.init_pos);
796     cio_write(cio, box.length, 4);    /* L          */
797     cio_seek(cio, box.init_pos + box.length);
798 }
799
800 /*
801 * Read the FIEL box
802 *
803 * Field coding Box
804 *
805 */
806 int mj2_read_fiel(mj2_tk_t * tk, opj_cio_t *cio)
807 {
808
809     mj2_box_t box;
810
811     mj2_read_boxhdr(&box, cio);
812     if (MJ2_FIEL != box.type) {
813         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected FIEL Marker\n");
814         return 1;
815     }
816
817
818     tk->fieldcount = cio_read(cio, 1);
819     tk->fieldorder = cio_read(cio, 1);
820
821     if (cio_tell(cio) - box.init_pos != box.length) {
822         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with FIEL Box size\n");
823         return 1;
824     }
825     return 0;
826 }
827
828 /*
829 * Write the ORFO box
830 *
831 * Original Format Box
832 *
833 */
834 void mj2_write_orfo(mj2_tk_t * tk, opj_cio_t *cio)
835 {
836     mj2_box_t box;
837
838     box.init_pos = cio_tell(cio);
839     cio_skip(cio, 4);
840     cio_write(cio, MJ2_ORFO, 4);
841
842     cio_write(cio, tk->or_fieldcount, 1); /* Original Field count */
843     cio_write(cio, tk->or_fieldorder, 1); /* Original Field order */
844
845
846     box.length = cio_tell(cio) - box.init_pos;
847     cio_seek(cio, box.init_pos);
848     cio_write(cio, box.length, 4);    /* L          */
849     cio_seek(cio, box.init_pos + box.length);
850 }
851
852 /*
853 * Read the ORFO box
854 *
855 * Original Format Box
856 *
857 */
858 int mj2_read_orfo(mj2_tk_t * tk, opj_cio_t *cio)
859 {
860
861     mj2_box_t box;
862
863     mj2_read_boxhdr(&box, cio);
864     if (MJ2_ORFO != box.type) {
865         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected ORFO Marker\n");
866         return 1;
867     }
868
869
870     tk->or_fieldcount = cio_read(cio, 1);
871     tk->or_fieldorder = cio_read(cio, 1);
872
873     if (cio_tell(cio) - box.init_pos != box.length) {
874         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with ORFO Box size\n");
875         return 1;
876     }
877     return 0;
878 }
879
880 /*
881 * Write the JP2P box
882 *
883 * MJP2 Profile Box
884 *
885 */
886 void mj2_write_jp2p(mj2_tk_t * tk, opj_cio_t *cio)
887 {
888
889     int i;
890     mj2_box_t box;
891
892     box.init_pos = cio_tell(cio);
893     cio_skip(cio, 4);
894     cio_write(cio, MJ2_JP2P, 4);
895
896     cio_write(cio, 0, 4);     /* Version 0, flags =0 */
897
898     for (i = 0; i < tk->num_br; i++) {
899         cio_write(cio, tk->br[i], 4);
900     }
901
902     box.length = cio_tell(cio) - box.init_pos;
903     cio_seek(cio, box.init_pos);
904     cio_write(cio, box.length, 4);    /* L          */
905     cio_seek(cio, box.init_pos + box.length);
906 }
907
908 /*
909 * Read the JP2P box
910 *
911 * MJP2 Profile Box
912 *
913 */
914 int mj2_read_jp2p(mj2_tk_t * tk, opj_cio_t *cio)
915 {
916     int i;
917
918     mj2_box_t box;
919
920     mj2_read_boxhdr(&box, cio);
921     if (MJ2_JP2P != box.type) {
922         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected JP2P Marker\n");
923         return 1;
924     }
925
926     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
927         opj_event_msg(cio->cinfo, EVT_ERROR,
928                       "Error: Only Version 0 handled in JP2P box\n");
929         return 1;
930     }
931
932     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
933         opj_event_msg(cio->cinfo, EVT_ERROR,
934                       "Error with flag in JP2P box. Expected flag 0\n");
935         return 1;
936     }
937
938
939     tk->num_br = (box.length - 12) / 4;
940     tk->br = (unsigned int*) opj_malloc(tk->num_br * sizeof(unsigned int));
941
942     for (i = 0; i < tk->num_br; i++) {
943         tk->br[i] = cio_read(cio, 4);
944     }
945
946     if (cio_tell(cio) - box.init_pos != box.length) {
947         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JP2P Box size\n");
948         return 1;
949     }
950     return 0;
951 }
952
953 /*
954 * Write the JP2X box
955 *
956 * MJP2 Prefix Box
957 *
958 */
959 void mj2_write_jp2x(mj2_tk_t * tk, opj_cio_t *cio)
960 {
961
962     int i;
963     mj2_box_t box;
964
965     box.init_pos = cio_tell(cio);
966     cio_skip(cio, 4);
967     cio_write(cio, MJ2_JP2X, 4);
968
969     for (i = 0; i < tk->num_jp2x; i++) {
970         cio_write(cio, tk->jp2xdata[i], 1);
971     }
972
973     box.length = cio_tell(cio) - box.init_pos;
974     cio_seek(cio, box.init_pos);
975     cio_write(cio, box.length, 4);    /* L          */
976     cio_seek(cio, box.init_pos + box.length);
977 }
978
979 /*
980 * Read the JP2X box
981 *
982 * MJP2 Prefix Box
983 *
984 */
985 int mj2_read_jp2x(mj2_tk_t * tk, opj_cio_t *cio)
986 {
987     unsigned int i;
988
989     mj2_box_t box;
990
991     mj2_read_boxhdr(&box, cio);
992     if (MJ2_JP2X != box.type) {
993         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected JP2X Marker\n");
994         return 1;
995     }
996
997
998     tk->num_jp2x = (box.length - 8);
999     tk->jp2xdata = (unsigned char*) opj_malloc(tk->num_jp2x * sizeof(
1000                        unsigned char));
1001
1002     for (i = 0; i < tk->num_jp2x; i++) {
1003         tk->jp2xdata[i] = cio_read(cio, 1);
1004     }
1005
1006     if (cio_tell(cio) - box.init_pos != box.length) {
1007         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JP2X Box size\n");
1008         return 1;
1009     }
1010     return 0;
1011 }
1012
1013 /*
1014 * Write the JSUB box
1015 *
1016 * MJP2 Subsampling Box
1017 *
1018 */
1019 void mj2_write_jsub(mj2_tk_t * tk, opj_cio_t *cio)
1020 {
1021
1022     mj2_box_t box;
1023
1024     box.init_pos = cio_tell(cio);
1025     cio_skip(cio, 4);
1026     cio_write(cio, MJ2_JSUB, 4);
1027
1028     cio_write(cio, tk->hsub, 1);
1029     cio_write(cio, tk->vsub, 1);
1030     cio_write(cio, tk->hoff, 1);
1031     cio_write(cio, tk->voff, 1);
1032
1033     box.length = cio_tell(cio) - box.init_pos;
1034     cio_seek(cio, box.init_pos);
1035     cio_write(cio, box.length, 4);    /* L          */
1036     cio_seek(cio, box.init_pos + box.length);
1037 }
1038
1039 /*
1040 * Read the JSUB box
1041 *
1042 * MJP2 Subsampling Box
1043 *
1044 */
1045 int mj2_read_jsub(mj2_tk_t * tk, opj_cio_t *cio)
1046 {
1047     mj2_box_t box;
1048
1049     mj2_read_boxhdr(&box, cio);
1050     if (MJ2_JSUB != box.type) {
1051         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected JSUB Marker\n");
1052         return 1;
1053     }
1054
1055     tk->hsub = cio_read(cio, 1);
1056     tk->vsub = cio_read(cio, 1);
1057     tk->hoff = cio_read(cio, 1);;
1058     tk->voff = cio_read(cio, 1);
1059
1060     if (cio_tell(cio) - box.init_pos != box.length) {
1061         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JSUB Box size\n");
1062         return 1;
1063     }
1064     return 0;
1065 }
1066
1067 /*
1068 * Write the SMJ2 box
1069 *
1070 * Visual Sample Entry Description
1071 *
1072 */
1073 void mj2_write_smj2(mj2_tk_t * tk, opj_cio_t *cio)
1074 {
1075     mj2_box_t box;
1076
1077     box.init_pos = cio_tell(cio);
1078     cio_skip(cio, 4);
1079     cio_write(cio, MJ2_MJ2, 4);   /* MJ2       */
1080
1081     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
1082
1083     cio_write(cio, 1, 4);
1084
1085     cio_write(cio, 0, 2);     /* Pre-defined */
1086
1087     cio_write(cio, 0, 2);     /* Reserved */
1088
1089     cio_write(cio, 0, 4);     /* Pre-defined */
1090     cio_write(cio, 0, 4);     /* Pre-defined */
1091     cio_write(cio, 0, 4);     /* Pre-defined */
1092
1093     cio_write(cio, tk->w, 2);     /* Width  */
1094     cio_write(cio, tk->h, 2);     /* Height */
1095
1096     cio_write(cio, tk->horizresolution, 4);   /* Horizontal resolution */
1097     cio_write(cio, tk->vertresolution, 4);    /* Vertical resolution   */
1098
1099     cio_write(cio, 0, 4);     /* Reserved */
1100
1101     cio_write(cio, 1, 2);     /* Pre-defined = 1 */
1102
1103     cio_write(cio, tk->compressorname[0], 4); /* Compressor Name */
1104     cio_write(cio, tk->compressorname[1], 4);
1105     cio_write(cio, tk->compressorname[2], 4);
1106     cio_write(cio, tk->compressorname[3], 4);
1107     cio_write(cio, tk->compressorname[4], 4);
1108     cio_write(cio, tk->compressorname[5], 4);
1109     cio_write(cio, tk->compressorname[6], 4);
1110     cio_write(cio, tk->compressorname[7], 4);
1111
1112     cio_write(cio, tk->depth, 2); /* Depth */
1113
1114     cio_write(cio, 0xffff, 2);        /* Pre-defined = -1 */
1115
1116     jp2_write_jp2h(&tk->jp2_struct, cio);
1117
1118     mj2_write_fiel(tk, cio);
1119
1120     if (tk->num_br != 0) {
1121         mj2_write_jp2p(tk, cio);
1122     }
1123     if (tk->num_jp2x != 0) {
1124         mj2_write_jp2x(tk, cio);
1125     }
1126
1127     mj2_write_jsub(tk, cio);
1128     mj2_write_orfo(tk, cio);
1129
1130     box.length = cio_tell(cio) - box.init_pos;
1131     cio_seek(cio, box.init_pos);
1132     cio_write(cio, box.length, 4);    /* L          */
1133     cio_seek(cio, box.init_pos + box.length);
1134 }
1135
1136 /*
1137 * Read the SMJ2 box
1138 *
1139 * Visual Sample Entry Description
1140 *
1141 */
1142 int mj2_read_smj2(opj_image_t * img, mj2_tk_t * tk, opj_cio_t *cio)
1143 {
1144     mj2_box_t box;
1145     mj2_box_t box2;
1146     opj_jp2_color_t color;
1147     int i;
1148     opj_bool ok;
1149
1150     mj2_read_boxhdr(&box, cio);
1151
1152     if (MJ2_MJ2 != box.type) {
1153         opj_event_msg(cio->cinfo, EVT_ERROR,
1154                       "Error in SMJ2 box: Expected MJ2 Marker\n");
1155         return 1;
1156     }
1157
1158     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
1159         opj_event_msg(cio->cinfo, EVT_ERROR,
1160                       "Error: Only Version 0 handled in MJP2 box\n");
1161         return 1;
1162     }
1163
1164     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
1165         opj_event_msg(cio->cinfo, EVT_ERROR,
1166                       "Error with flag in MJP2 box. Expected flag 0\n");
1167         return 1;
1168     }
1169
1170     cio_skip(cio, 4);
1171
1172     cio_skip(cio, 2);         /* Pre-defined */
1173
1174     cio_skip(cio, 2);         /* Reserved */
1175
1176     cio_skip(cio, 4);         /* Pre-defined */
1177     cio_skip(cio, 4);         /* Pre-defined */
1178     cio_skip(cio, 4);         /* Pre-defined */
1179
1180     tk->w = cio_read(cio, 2);     /* Width  */
1181     tk->h = cio_read(cio, 2);     /* Height */
1182
1183     tk->horizresolution = cio_read(cio, 4);   /* Horizontal resolution */
1184     tk->vertresolution = cio_read(cio, 4);    /* Vertical resolution   */
1185
1186     cio_skip(cio, 4);         /* Reserved */
1187
1188     cio_skip(cio, 2);         /* Pre-defined = 1 */
1189
1190     tk->compressorname[0] = cio_read(cio, 4); /* Compressor Name */
1191     tk->compressorname[1] = cio_read(cio, 4);
1192     tk->compressorname[2] = cio_read(cio, 4);
1193     tk->compressorname[3] = cio_read(cio, 4);
1194     tk->compressorname[4] = cio_read(cio, 4);
1195     tk->compressorname[5] = cio_read(cio, 4);
1196     tk->compressorname[6] = cio_read(cio, 4);
1197     tk->compressorname[7] = cio_read(cio, 4);
1198
1199     tk->depth = cio_read(cio, 2); /* Depth */
1200
1201     /* Init std value */
1202     tk->num_jp2x = 0;
1203     tk->fieldcount = 1;
1204     tk->fieldorder = 0;
1205     tk->or_fieldcount = 1;
1206     tk->or_fieldorder = 0;
1207
1208     cio_skip(cio, 2);         /* Pre-defined = -1 */
1209     memset(&color, 0, sizeof(opj_jp2_color_t));
1210     tk->jp2_struct.cinfo = tk->cinfo;
1211
1212     ok = jp2_read_jp2h(&tk->jp2_struct, cio, &color);
1213
1214     tk->jp2_struct.cinfo = NULL;
1215
1216     if (ok == OPJ_FALSE) {
1217         opj_event_msg(tk->cinfo, EVT_ERROR, "Error reading JP2H Box\n");
1218         return 1;
1219     }
1220
1221     tk->jp2_struct.comps = (opj_jp2_comps_t*) opj_malloc(tk->jp2_struct.numcomps *
1222                            sizeof(opj_jp2_comps_t));
1223     tk->jp2_struct.cl = (unsigned int*) opj_malloc(sizeof(unsigned int));
1224
1225     tk->num_br = 0;
1226     tk->num_jp2x = 0;
1227
1228     for (i = 0; cio_tell(cio) - box.init_pos < box.length; i++) {
1229         mj2_read_boxhdr(&box2, cio);
1230         cio_seek(cio, box2.init_pos);
1231         switch (box2.type) {
1232         case MJ2_FIEL:
1233             if (mj2_read_fiel(tk, cio)) {
1234                 return 1;
1235             }
1236             break;
1237
1238         case MJ2_JP2P:
1239             if (mj2_read_jp2p(tk, cio)) {
1240                 return 1;
1241             }
1242             break;
1243
1244         case MJ2_JP2X:
1245             if (mj2_read_jp2x(tk, cio)) {
1246                 return 1;
1247             }
1248             break;
1249
1250         case MJ2_JSUB:
1251             if (mj2_read_jsub(tk, cio)) {
1252                 return 1;
1253             }
1254             break;
1255
1256         case MJ2_ORFO:
1257             if (mj2_read_orfo(tk, cio)) {
1258                 return 1;
1259             }
1260             break;
1261
1262         default:
1263             opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MJP2 Box size\n");
1264             return 1;
1265             break;
1266
1267         }
1268     }
1269     return 0;
1270 }
1271
1272
1273 /*
1274 * Write the STSD box
1275 *
1276 * Sample Description
1277 *
1278 */
1279 void mj2_write_stsd(mj2_tk_t * tk, opj_cio_t *cio)
1280 {
1281     mj2_box_t box;
1282
1283     box.init_pos = cio_tell(cio);
1284     cio_skip(cio, 4);
1285     cio_write(cio, MJ2_STSD, 4);  /* STSD       */
1286
1287     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
1288
1289     cio_write(cio, 1,
1290               4);     /* entry_count = 1 (considering same JP2 headerboxes) */
1291
1292     if (tk->track_type == 0) {
1293         mj2_write_smj2(tk, cio);
1294     } else if (tk->track_type == 1) {
1295         /* Not implemented*/
1296     }
1297     if (tk->track_type == 2) {
1298         /* Not implemented*/
1299     }
1300
1301
1302     box.length = cio_tell(cio) - box.init_pos;
1303     cio_seek(cio, box.init_pos);
1304     cio_write(cio, box.length, 4);    /* L          */
1305     cio_seek(cio, box.init_pos + box.length);
1306 }
1307
1308 /*
1309 * Read the STSD box
1310 *
1311 * Sample Description
1312 *
1313 */
1314 int mj2_read_stsd(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
1315 {
1316     int i;
1317     int entry_count, len_2skip;
1318
1319     mj2_box_t box;
1320
1321     mj2_read_boxhdr(&box, cio);
1322
1323     if (MJ2_STSD != box.type) {
1324         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STSD Marker\n");
1325         return 1;
1326     }
1327
1328     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
1329         opj_event_msg(cio->cinfo, EVT_ERROR,
1330                       "Error: Only Version 0 handled in STSD box\n");
1331         return 1;
1332     }
1333
1334     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
1335         opj_event_msg(cio->cinfo, EVT_ERROR,
1336                       "Error with flag in STSD box. Expected flag 0\n");
1337         return 1;
1338     }
1339
1340     entry_count = cio_read(cio, 4);
1341
1342     if (tk->track_type == 0) {
1343         for (i = 0; i < entry_count; i++) {
1344             if (mj2_read_smj2(img, tk, cio)) {
1345                 return 1;
1346             }
1347         }
1348     } else if (tk->track_type == 1) {
1349         len_2skip = cio_read(cio, 4);   /* Not implemented -> skipping box*/
1350         cio_skip(cio, len_2skip - 4);
1351     } else if (tk->track_type == 2) {
1352         len_2skip = cio_read(cio, 4);   /* Not implemented -> skipping box*/
1353         cio_skip(cio, len_2skip - 4);
1354     }
1355
1356
1357     if (cio_tell(cio) - box.init_pos != box.length) {
1358         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STSD Box size\n");
1359         return 1;
1360     }
1361     return 0;
1362 }
1363
1364 /*
1365 * Write the STBL box
1366 *
1367 * Sample table box box
1368 *
1369 */
1370 void mj2_write_stbl(mj2_tk_t * tk, opj_cio_t *cio)
1371 {
1372     mj2_box_t box;
1373
1374     box.init_pos = cio_tell(cio);
1375     cio_skip(cio, 4);
1376     cio_write(cio, MJ2_STBL, 4);  /* STBL       */
1377
1378     mj2_write_stsd(tk, cio);
1379     mj2_write_stts(tk, cio);
1380     mj2_write_stsc(tk, cio);
1381     mj2_write_stsz(tk, cio);
1382     mj2_write_stco(tk, cio);
1383
1384     box.length = cio_tell(cio) - box.init_pos;
1385     cio_seek(cio, box.init_pos);
1386     cio_write(cio, box.length, 4);    /* L          */
1387     cio_seek(cio, box.init_pos + box.length);
1388 }
1389
1390 /*
1391 * Read the STBL box
1392 *
1393 * Sample table box box
1394 *
1395 */
1396 int mj2_read_stbl(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
1397 {
1398     mj2_box_t box;
1399
1400     mj2_read_boxhdr(&box, cio);
1401     if (MJ2_STBL != box.type) {
1402         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STBL Marker\n");
1403         return 1;
1404     }
1405
1406     if (mj2_read_stsd(tk, img, cio)) {
1407         return 1;
1408     }
1409     if (mj2_read_stts(tk, cio)) {
1410         return 1;
1411     }
1412     if (mj2_read_stsc(tk, cio)) {
1413         return 1;
1414     }
1415     if (mj2_read_stsz(tk, cio)) {
1416         return 1;
1417     }
1418     if (mj2_read_stco(tk, cio)) {
1419         return 1;
1420     }
1421
1422     if (cio_tell(cio) - box.init_pos != box.length) {
1423         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STBL Box size\n");
1424         return 1;
1425     }
1426     return 0;
1427 }
1428
1429 /*
1430 * Write the URL box
1431 *
1432 * URL box
1433 *
1434 */
1435 void mj2_write_url(mj2_tk_t * tk, int url_num, opj_cio_t *cio)
1436 {
1437     mj2_box_t box;
1438
1439     box.init_pos = cio_tell(cio);
1440     cio_skip(cio, 4);
1441     cio_write(cio, MJ2_URL, 4);   /* URL       */
1442
1443     if (url_num == 0) {
1444         cio_write(cio, 1,
1445                   4);    /* Version = 0, flags = 1 because stored in same file */
1446     } else {
1447         cio_write(cio, 0, 4);       /* Version = 0, flags =  0 */
1448         cio_write(cio, tk->url[url_num - 1].location[0], 4);
1449         cio_write(cio, tk->url[url_num - 1].location[1], 4);
1450         cio_write(cio, tk->url[url_num - 1].location[2], 4);
1451         cio_write(cio, tk->url[url_num - 1].location[3], 4);
1452     }
1453
1454     box.length = cio_tell(cio) - box.init_pos;
1455     cio_seek(cio, box.init_pos);
1456     cio_write(cio, box.length, 4);    /* L          */
1457     cio_seek(cio, box.init_pos + box.length);
1458 }
1459
1460 /*
1461 * Read the URL box
1462 *
1463 * URL box
1464 *
1465 */
1466 int mj2_read_url(mj2_tk_t * tk, int urn_num, opj_cio_t *cio)
1467 {
1468     mj2_box_t box;
1469
1470     mj2_read_boxhdr(&box, cio);
1471     if (MJ2_URL != box.type) {
1472         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected URL Marker\n");
1473         return 1;
1474     }
1475
1476     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
1477         opj_event_msg(cio->cinfo, EVT_ERROR,
1478                       "Error: Only Version 0 handled in URL box\n");
1479         return 1;
1480     }
1481
1482     if (1 != cio_read(cio, 3)) {  /* If flags = 1 --> media data in file */
1483         tk->url[urn_num].location[0] = cio_read(cio, 4);
1484         tk->url[urn_num].location[1] = cio_read(cio, 4);
1485         tk->url[urn_num].location[2] = cio_read(cio, 4);
1486         tk->url[urn_num].location[3] = cio_read(cio, 4);
1487     } else {
1488         tk->num_url--;
1489     }
1490
1491
1492     if (cio_tell(cio) - box.init_pos != box.length) {
1493         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with URL Box size\n");
1494         return 1;
1495     }
1496     return 0;
1497 }
1498
1499 /*
1500 * Write the URN box
1501 *
1502 * URN box
1503 *
1504 */
1505 void mj2_write_urn(mj2_tk_t * tk, int urn_num, opj_cio_t *cio)
1506 {
1507     mj2_box_t box;
1508
1509     box.init_pos = cio_tell(cio);
1510     cio_skip(cio, 4);
1511     cio_write(cio, MJ2_URN, 4);   /* URN       */
1512
1513     cio_write(cio, 0, 4);     /* Version = 0, flags =  0 */
1514
1515     cio_write(cio, tk->urn[urn_num].name[0], 4);
1516     cio_write(cio, tk->urn[urn_num].name[1], 4);
1517     cio_write(cio, tk->urn[urn_num].name[2], 4);
1518     cio_write(cio, tk->urn[urn_num].name[3], 4);
1519     cio_write(cio, tk->urn[urn_num].location[0], 4);
1520     cio_write(cio, tk->urn[urn_num].location[1], 4);
1521     cio_write(cio, tk->urn[urn_num].location[2], 4);
1522     cio_write(cio, tk->urn[urn_num].location[3], 4);
1523
1524     box.length = cio_tell(cio) - box.init_pos;
1525     cio_seek(cio, box.init_pos);
1526     cio_write(cio, box.length, 4);    /* L          */
1527     cio_seek(cio, box.init_pos + box.length);
1528 }
1529
1530 /*
1531 * Read the URN box
1532 *
1533 * URN box
1534 *
1535 */
1536 int mj2_read_urn(mj2_tk_t * tk, int urn_num, opj_cio_t *cio)
1537 {
1538
1539     mj2_box_t box;
1540
1541     mj2_read_boxhdr(&box, cio);
1542     if (MJ2_URN != box.type) {
1543         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected URN Marker\n");
1544         return 1;
1545     }
1546
1547     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
1548         opj_event_msg(cio->cinfo, EVT_ERROR,
1549                       "Error: Only Version 0 handled in URN box\n");
1550         return 1;
1551     }
1552
1553     if (1 != cio_read(cio, 3)) {  /* If flags = 1 --> media data in file */
1554         tk->urn[urn_num].name[0] = cio_read(cio, 4);
1555         tk->urn[urn_num].name[1] = cio_read(cio, 4);
1556         tk->urn[urn_num].name[2] = cio_read(cio, 4);
1557         tk->urn[urn_num].name[3] = cio_read(cio, 4);
1558         tk->urn[urn_num].location[0] = cio_read(cio, 4);
1559         tk->urn[urn_num].location[1] = cio_read(cio, 4);
1560         tk->urn[urn_num].location[2] = cio_read(cio, 4);
1561         tk->urn[urn_num].location[3] = cio_read(cio, 4);
1562     }
1563
1564
1565     if (cio_tell(cio) - box.init_pos != box.length) {
1566         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with URN Box size\n");
1567         return 1;
1568     }
1569     return 0;
1570 }
1571
1572
1573 /*
1574 * Write the DREF box
1575 *
1576 * Data reference box
1577 *
1578 */
1579 void mj2_write_dref(mj2_tk_t * tk, opj_cio_t *cio)
1580 {
1581     int i;
1582     mj2_box_t box;
1583
1584     box.init_pos = cio_tell(cio);
1585     cio_skip(cio, 4);
1586     cio_write(cio, MJ2_DREF, 4);  /* DREF       */
1587
1588     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
1589
1590     if (tk->num_url + tk->num_urn == 0) { /* Media data in same file */
1591         cio_write(cio, 1, 4);       /* entry_count = 1 */
1592         mj2_write_url(tk, 0, cio);
1593     } else {
1594         cio_write(cio, tk->num_url + tk->num_urn, 4);   /* entry_count */
1595
1596         for (i = 0; i < tk->num_url; i++) {
1597             mj2_write_url(tk, i + 1, cio);
1598         }
1599
1600         for (i = 0; i < tk->num_urn; i++) {
1601             mj2_write_urn(tk, i, cio);
1602         }
1603     }
1604
1605     box.length = cio_tell(cio) - box.init_pos;
1606     cio_seek(cio, box.init_pos);
1607     cio_write(cio, box.length, 4);    /* L          */
1608     cio_seek(cio, box.init_pos + box.length);
1609 }
1610
1611 /*
1612 * Read the DREF box
1613 *
1614 * Data reference box
1615 *
1616 */
1617 int mj2_read_dref(mj2_tk_t * tk, opj_cio_t *cio)
1618 {
1619
1620     int i;
1621     int entry_count, marker;
1622     mj2_box_t box;
1623
1624     mj2_read_boxhdr(&box, cio);
1625     if (MJ2_DREF != box.type) {
1626         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected DREF Marker\n");
1627         return 1;
1628     }
1629
1630     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
1631         opj_event_msg(cio->cinfo, EVT_ERROR,
1632                       "Error: Only Version 0 handled in DREF box\n");
1633         return 1;
1634     }
1635
1636     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
1637         opj_event_msg(cio->cinfo, EVT_ERROR,
1638                       "Error with flag in DREF box. Expected flag 0\n");
1639         return 1;
1640     }
1641
1642     entry_count = cio_read(cio, 4);
1643     tk->num_url = 0;
1644     tk->num_urn = 0;
1645
1646     for (i = 0; i < entry_count; i++) {
1647         cio_skip(cio, 4);
1648         marker = cio_read(cio, 4);
1649         if (marker == MJ2_URL) {
1650             cio_skip(cio, -8);
1651             tk->num_url++;
1652             if (mj2_read_url(tk, tk->num_url, cio)) {
1653                 return 1;
1654             }
1655         } else if (marker == MJ2_URN) {
1656             cio_skip(cio, -8);
1657             tk->num_urn++;
1658             if (mj2_read_urn(tk, tk->num_urn, cio)) {
1659                 return 1;
1660             }
1661         } else {
1662             opj_event_msg(cio->cinfo, EVT_ERROR,
1663                           "Error with in DREF box. Expected URN or URL box\n");
1664             return 1;
1665         }
1666
1667     }
1668
1669
1670     if (cio_tell(cio) - box.init_pos != box.length) {
1671         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with DREF Box size\n");
1672         return 1;
1673     }
1674     return 0;
1675 }
1676
1677 /*
1678 * Write the DINF box
1679 *
1680 * Data information box
1681 *
1682 */
1683 void mj2_write_dinf(mj2_tk_t * tk, opj_cio_t *cio)
1684 {
1685     mj2_box_t box;
1686
1687     box.init_pos = cio_tell(cio);
1688     cio_skip(cio, 4);
1689     cio_write(cio, MJ2_DINF, 4);  /* DINF       */
1690
1691     mj2_write_dref(tk, cio);
1692
1693     box.length = cio_tell(cio) - box.init_pos;
1694     cio_seek(cio, box.init_pos);
1695     cio_write(cio, box.length, 4);    /* L          */
1696     cio_seek(cio, box.init_pos + box.length);
1697 }
1698
1699 /*
1700 * Read the DINF box
1701 *
1702 * Data information box
1703 *
1704 */
1705 int mj2_read_dinf(mj2_tk_t * tk, opj_cio_t *cio)
1706 {
1707     mj2_box_t box;
1708
1709     mj2_read_boxhdr(&box, cio);
1710     if (MJ2_DINF != box.type) {
1711         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected DINF Marker\n");
1712         return 1;
1713     }
1714
1715     if (mj2_read_dref(tk, cio)) {
1716         return 1;
1717     }
1718
1719     if (cio_tell(cio) - box.init_pos != box.length) {
1720         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with DINF Box size\n");
1721         return 1;
1722     }
1723     return 0;
1724 }
1725
1726 /*
1727 * Write the VMHD box
1728 *
1729 * Video Media information box
1730 *
1731 */
1732 void mj2_write_vmhd(mj2_tk_t * tk, opj_cio_t *cio)
1733 {
1734     mj2_box_t box;
1735
1736     box.init_pos = cio_tell(cio);
1737     cio_skip(cio, 4);
1738     cio_write(cio, MJ2_VMHD, 4);  /* VMHD       */
1739
1740     cio_write(cio, 1, 4);     /* Version = 0, flags = 1 */
1741
1742     cio_write(cio, tk->graphicsmode, 2);
1743     cio_write(cio, tk->opcolor[0], 2);
1744     cio_write(cio, tk->opcolor[1], 2);
1745     cio_write(cio, tk->opcolor[2], 2);
1746
1747     box.length = cio_tell(cio) - box.init_pos;
1748     cio_seek(cio, box.init_pos);
1749     cio_write(cio, box.length, 4);    /* L          */
1750     cio_seek(cio, box.init_pos + box.length);
1751 }
1752
1753 /*
1754 * Read the VMHD box
1755 *
1756 * Video Media information box
1757 *
1758 */
1759 int mj2_read_vmhd(mj2_tk_t * tk, opj_cio_t *cio)
1760 {
1761     mj2_box_t box;
1762
1763     mj2_read_boxhdr(&box, cio);
1764     if (MJ2_VMHD != box.type) {
1765         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected VMHD Marker\n");
1766         return 1;
1767     }
1768
1769     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
1770         opj_event_msg(cio->cinfo, EVT_ERROR,
1771                       "Error: Only Version 0 handled in VMHD box\n");
1772         return 1;
1773     }
1774
1775     if (1 != cio_read(cio, 3)) {  /* Flags = 1  */
1776         opj_event_msg(cio->cinfo, EVT_ERROR,
1777                       "Error with flag in VMHD box. Expected flag 1\n");
1778         return 1;
1779     }
1780
1781     tk->track_type = 0;
1782     tk->graphicsmode = cio_read(cio, 2);
1783     tk->opcolor[0] = cio_read(cio, 2);
1784     tk->opcolor[1] = cio_read(cio, 2);
1785     tk->opcolor[2] = cio_read(cio, 2);
1786
1787     if (cio_tell(cio) - box.init_pos != box.length) {
1788         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with VMHD Box size\n");
1789         return 1;
1790     }
1791     return 0;
1792 }
1793
1794 /*
1795 * Write the SMHD box
1796 *
1797 * Sound Media information box
1798 *
1799 */
1800 void mj2_write_smhd(mj2_tk_t * tk, opj_cio_t *cio)
1801 {
1802     mj2_box_t box;
1803
1804     box.init_pos = cio_tell(cio);
1805     cio_skip(cio, 4);
1806     cio_write(cio, MJ2_SMHD, 4);  /* SMHD       */
1807
1808     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
1809
1810     cio_write(cio, tk->balance, 2);
1811
1812     cio_write(cio, 0, 2);     /* Reserved */
1813
1814     box.length = cio_tell(cio) - box.init_pos;
1815     cio_seek(cio, box.init_pos);
1816     cio_write(cio, box.length, 4);    /* L          */
1817     cio_seek(cio, box.init_pos + box.length);
1818 }
1819
1820 /*
1821 * Read the SMHD box
1822 *
1823 * Sound Media information box
1824 *
1825 */
1826 int mj2_read_smhd(mj2_tk_t * tk, opj_cio_t *cio)
1827 {
1828     mj2_box_t box;
1829
1830     mj2_read_boxhdr(&box, cio);
1831     if (MJ2_SMHD != box.type) {
1832         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected SMHD Marker\n");
1833         return 1;
1834     }
1835
1836     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
1837         opj_event_msg(cio->cinfo, EVT_ERROR,
1838                       "Error: Only Version 0 handled in SMHD box\n");
1839         return 1;
1840     }
1841
1842     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
1843         opj_event_msg(cio->cinfo, EVT_ERROR,
1844                       "Error with flag in SMHD box. Expected flag 0\n");
1845         return 1;
1846     }
1847
1848     tk->track_type = 1;
1849     tk->balance = cio_read(cio, 2);
1850
1851     /* Init variables to zero to avoid problems when freeeing memory
1852     The values will possibly be overidded when decoding the track structure */
1853     tk->num_br = 0;
1854     tk->num_url = 0;
1855     tk->num_urn = 0;
1856     tk->num_chunks = 0;
1857     tk->num_tts = 0;
1858     tk->num_samplestochunk = 0;
1859     tk->num_samples = 0;
1860
1861     cio_skip(cio, 2);         /* Reserved */
1862
1863     if (cio_tell(cio) - box.init_pos != box.length) {
1864         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with SMHD Box size\n");
1865         return 1;
1866     }
1867     return 0;
1868 }
1869
1870 /*
1871 * Write the HMHD box
1872 *
1873 * Hint Media information box
1874 *
1875 */
1876 void mj2_write_hmhd(mj2_tk_t * tk, opj_cio_t *cio)
1877 {
1878     mj2_box_t box;
1879
1880     box.init_pos = cio_tell(cio);
1881     cio_skip(cio, 4);
1882     cio_write(cio, MJ2_HMHD, 4);  /* HMHD       */
1883
1884     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
1885
1886     cio_write(cio, tk->maxPDUsize, 2);
1887     cio_write(cio, tk->avgPDUsize, 2);
1888     cio_write(cio, tk->maxbitrate, 4);
1889     cio_write(cio, tk->avgbitrate, 4);
1890     cio_write(cio, tk->slidingavgbitrate, 4);
1891
1892     box.length = cio_tell(cio) - box.init_pos;
1893     cio_seek(cio, box.init_pos);
1894     cio_write(cio, box.length, 4);    /* L          */
1895     cio_seek(cio, box.init_pos + box.length);
1896 }
1897
1898 /*
1899 * Read the HMHD box
1900 *
1901 * Hint Media information box
1902 *
1903 */
1904 int mj2_read_hmhd(mj2_tk_t * tk, opj_cio_t *cio)
1905 {
1906     mj2_box_t box;
1907
1908     mj2_read_boxhdr(&box, cio);
1909     if (MJ2_HMHD != box.type) {
1910         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected HMHD Marker\n");
1911         return 1;
1912     }
1913
1914     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
1915         opj_event_msg(cio->cinfo, EVT_ERROR,
1916                       "Error: Only Version 0 handled in HMHD box\n");
1917         return 1;
1918     }
1919
1920     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
1921         opj_event_msg(cio->cinfo, EVT_ERROR,
1922                       "Error with flag in HMHD box. Expected flag 0\n");
1923         return 1;
1924     }
1925
1926     tk->track_type = 2;
1927     tk->maxPDUsize = cio_read(cio, 2);
1928     tk->avgPDUsize = cio_read(cio, 2);
1929     tk->maxbitrate = cio_read(cio, 4);
1930     tk->avgbitrate = cio_read(cio, 4);
1931     tk->slidingavgbitrate = cio_read(cio, 4);
1932
1933     /* Init variables to zero to avoid problems when freeeing memory
1934     The values will possibly be overidded when decoding the track structure */
1935     tk->num_br = 0;
1936     tk->num_url = 0;
1937     tk->num_urn = 0;
1938     tk->num_chunks = 0;
1939     tk->num_tts = 0;
1940     tk->num_samplestochunk = 0;
1941     tk->num_samples = 0;
1942
1943
1944     if (cio_tell(cio) - box.init_pos != box.length) {
1945         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with HMHD Box size\n");
1946         return 1;
1947     }
1948     return 0;
1949 }
1950
1951 /*
1952 * Write the MINF box
1953 *
1954 * Media information box
1955 *
1956 */
1957 void mj2_write_minf(mj2_tk_t * tk, opj_cio_t *cio)
1958 {
1959     mj2_box_t box;
1960
1961     box.init_pos = cio_tell(cio);
1962     cio_skip(cio, 4);
1963     cio_write(cio, MJ2_MINF, 4);  /* MINF       */
1964
1965     if (tk->track_type == 0) {
1966         mj2_write_vmhd(tk, cio);
1967     } else if (tk->track_type == 1) {
1968         mj2_write_smhd(tk, cio);
1969     } else if (tk->track_type == 2) {
1970         mj2_write_hmhd(tk, cio);
1971     }
1972
1973     mj2_write_dinf(tk, cio);
1974     mj2_write_stbl(tk, cio);
1975
1976     box.length = cio_tell(cio) - box.init_pos;
1977     cio_seek(cio, box.init_pos);
1978     cio_write(cio, box.length, 4);    /* L          */
1979     cio_seek(cio, box.init_pos + box.length);
1980 }
1981
1982 /*
1983 * Read the MINF box
1984 *
1985 * Media information box
1986 *
1987 */
1988 int mj2_read_minf(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
1989 {
1990
1991     unsigned int box_type;
1992     mj2_box_t box;
1993
1994     mj2_read_boxhdr(&box, cio);
1995     if (MJ2_MINF != box.type) {
1996         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected MINF Marker\n");
1997         return 1;
1998     }
1999
2000     cio_skip(cio, 4);
2001     box_type = cio_read(cio, 4);
2002     cio_skip(cio, -8);
2003
2004     if (box_type == MJ2_VMHD) {
2005         if (mj2_read_vmhd(tk, cio)) {
2006             return 1;
2007         }
2008     } else if (box_type == MJ2_SMHD) {
2009         if (mj2_read_smhd(tk, cio)) {
2010             return 1;
2011         }
2012     } else if (box_type == MJ2_HMHD) {
2013         if (mj2_read_hmhd(tk, cio)) {
2014             return 1;
2015         }
2016     } else {
2017         opj_event_msg(cio->cinfo, EVT_ERROR,
2018                       "Error in MINF box expected vmhd, smhd or hmhd\n");
2019         return 1;
2020     }
2021
2022     if (mj2_read_dinf(tk, cio)) {
2023         return 1;
2024     }
2025
2026     if (mj2_read_stbl(tk, img, cio)) {
2027         return 1;
2028     }
2029
2030     if (cio_tell(cio) - box.init_pos != box.length) {
2031         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MINF Box size\n");
2032         return 1;
2033     }
2034     return 0;
2035 }
2036
2037 /*
2038 * Write the HDLR box
2039 *
2040 * Handler reference box
2041 *
2042 */
2043 void mj2_write_hdlr(mj2_tk_t * tk, opj_cio_t *cio)
2044 {
2045     mj2_box_t box;
2046
2047     box.init_pos = cio_tell(cio);
2048     cio_skip(cio, 4);
2049     cio_write(cio, MJ2_HDLR, 4);  /* HDLR       */
2050
2051     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
2052
2053     cio_write(cio, 0, 4);     /* Predefine */
2054
2055     tk->name =
2056         0;         /* The track name is immediately determined by the track type */
2057
2058     if (tk->track_type == 0) {
2059         tk->handler_type = 0x76696465;  /* Handler type: vide */
2060         cio_write(cio, tk->handler_type, 4);
2061
2062         cio_write(cio, 0, 4);
2063         cio_write(cio, 0, 4);
2064         cio_write(cio, 0, 4);       /* Reserved */
2065
2066         cio_write(cio, 0x76696465, 4);
2067         cio_write(cio, 0x6F206d65, 4);
2068         cio_write(cio, 0x64696120, 4);
2069         cio_write(cio, 0x74726163, 4);
2070         cio_write(cio, 0x6b00, 2);  /* String: video media track */
2071     } else if (tk->track_type == 1) {
2072         tk->handler_type = 0x736F756E;  /* Handler type: soun */
2073         cio_write(cio, tk->handler_type, 4);
2074
2075         cio_write(cio, 0, 4);
2076         cio_write(cio, 0, 4);
2077         cio_write(cio, 0, 4);       /* Reserved */
2078
2079         cio_write(cio, 0x536F756E, 4);
2080         cio_write(cio, 0x6400, 2);  /* String: Sound */
2081     } else if (tk->track_type == 2) {
2082         tk->handler_type = 0x68696E74;  /* Handler type: hint */
2083         cio_write(cio, tk->handler_type, 4);
2084
2085         cio_write(cio, 0, 4);
2086         cio_write(cio, 0, 4);
2087         cio_write(cio, 0, 4);       /* Reserved */
2088
2089         cio_write(cio, 0x48696E74, 4);
2090         cio_write(cio, 0, 2);       /* String: Hint */
2091     }
2092
2093     box.length = cio_tell(cio) - box.init_pos;
2094     cio_seek(cio, box.init_pos);
2095     cio_write(cio, box.length, 4);    /* L          */
2096     cio_seek(cio, box.init_pos + box.length);
2097 }
2098
2099 /*
2100 * Read the HDLR box
2101 *
2102 * Handler reference box
2103 *
2104 */
2105 int mj2_read_hdlr(mj2_tk_t * tk, opj_cio_t *cio)
2106 {
2107     int i;
2108     mj2_box_t box;
2109
2110     mj2_read_boxhdr(&box, cio);
2111     if (MJ2_HDLR != box.type) {
2112         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected HDLR Marker\n");
2113         return 1;
2114     }
2115
2116
2117     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
2118         opj_event_msg(cio->cinfo, EVT_ERROR,
2119                       "Error: Only Version 0 handled in HDLR box\n");
2120         return 1;
2121     }
2122
2123     if (0 != cio_read(cio, 3)) {  /* Flags = 0  */
2124         opj_event_msg(cio->cinfo, EVT_ERROR,
2125                       "Error with flag in HDLR box. Expected flag 0\n");
2126         return 1;
2127     }
2128
2129     cio_skip(cio, 4);         /* Reserved */
2130
2131     tk->handler_type = cio_read(cio, 4);
2132     cio_skip(cio, 12);        /* Reserved */
2133
2134     tk->name_size = box.length - 32;
2135
2136     tk->name = (char*) opj_malloc(tk->name_size * sizeof(char));
2137     for (i = 0; i < tk->name_size; i++) {
2138         tk->name[i] = cio_read(cio, 1); /* Name */
2139     }
2140
2141     if (cio_tell(cio) - box.init_pos != box.length) {
2142         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with HDLR Box size\n");
2143         return 1;
2144     }
2145     return 0;
2146 }
2147
2148 /*
2149 * Write the MDHD box
2150 *
2151 * Media Header Box
2152 *
2153 */
2154 void mj2_write_mdhd(mj2_tk_t * tk, opj_cio_t *cio)
2155 {
2156     mj2_box_t box;
2157     unsigned int i;
2158     time_t ltime;
2159     unsigned int modification_time;
2160
2161     box.init_pos = cio_tell(cio);
2162     cio_skip(cio, 4);
2163     cio_write(cio, MJ2_MDHD, 4);  /* MDHD       */
2164
2165     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
2166
2167     cio_write(cio, tk->creation_time, 4); /* Creation Time */
2168
2169     time(&ltime);         /* Time since 1/1/70 */
2170     modification_time = (unsigned int)ltime +
2171                         2082844800; /* Seoonds between 1/1/04 and 1/1/70 */
2172
2173     cio_write(cio, modification_time, 4); /* Modification Time */
2174
2175     cio_write(cio, tk->timescale, 4); /* Timescale */
2176
2177     tk->duration = 0;
2178
2179     for (i = 0; i < tk->num_samples; i++) {
2180         tk->duration += tk->sample[i].sample_delta;
2181     }
2182
2183     cio_write(cio, tk->duration, 4);  /* Duration */
2184
2185     cio_write(cio, tk->language, 2);  /* Language */
2186
2187     cio_write(cio, 0, 2);     /* Predefined */
2188
2189     box.length = cio_tell(cio) - box.init_pos;
2190     cio_seek(cio, box.init_pos);
2191     cio_write(cio, box.length, 4);    /* L          */
2192     cio_seek(cio, box.init_pos + box.length);
2193 }
2194
2195 /*
2196 * Read the MDHD box
2197 *
2198 * Media Header Box
2199 *
2200 */
2201 int mj2_read_mdhd(mj2_tk_t * tk, opj_cio_t *cio)
2202 {
2203     mj2_box_t box;
2204
2205     mj2_read_boxhdr(&box, cio);
2206     if (!(MJ2_MHDR == box.type ||
2207             MJ2_MDHD == box.type)) {    /* Kakadu writes MHDR instead of MDHD*/
2208         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected MDHD Marker\n");
2209         return 1;
2210     }
2211
2212     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
2213         opj_event_msg(cio->cinfo, EVT_ERROR,
2214                       "Error: Only Version 0 handled in MDHD box\n");
2215         return 1;
2216     }
2217
2218     if (0 != cio_read(cio, 3)) {  /* Flags = 0 */
2219         opj_event_msg(cio->cinfo, EVT_ERROR,
2220                       "Error with flag in MDHD box. Expected flag 0\n");
2221         return 1;
2222     }
2223
2224
2225     tk->creation_time = cio_read(cio, 4); /* Creation Time */
2226
2227     tk->modification_time = cio_read(cio, 4); /* Modification Time */
2228
2229     tk->timescale = cio_read(cio, 4); /* Timescale */
2230
2231     tk->duration = cio_read(cio, 4);  /* Duration */
2232
2233     tk->language = cio_read(cio, 2);  /* Language */
2234
2235     cio_skip(cio, 2);         /* Predefined */
2236
2237     if (cio_tell(cio) - box.init_pos != box.length) {
2238         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MDHD Box size\n");
2239         return 1;
2240     }
2241     return 0;
2242 }
2243
2244 /*
2245 * Write the MDIA box
2246 *
2247 * Media box
2248 *
2249 */
2250 void mj2_write_mdia(mj2_tk_t * tk, opj_cio_t *cio)
2251 {
2252     mj2_box_t box;
2253
2254     box.init_pos = cio_tell(cio);
2255     cio_skip(cio, 4);
2256     cio_write(cio, MJ2_MDIA, 4);  /* MDIA       */
2257
2258     mj2_write_mdhd(tk, cio);
2259     mj2_write_hdlr(tk, cio);
2260     mj2_write_minf(tk, cio);
2261
2262     box.length = cio_tell(cio) - box.init_pos;
2263     cio_seek(cio, box.init_pos);
2264     cio_write(cio, box.length, 4);    /* L          */
2265     cio_seek(cio, box.init_pos + box.length);
2266 }
2267
2268 /*
2269 * Read the MDIA box
2270 *
2271 * Media box
2272 *
2273 */
2274 int mj2_read_mdia(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
2275 {
2276     mj2_box_t box;
2277
2278     mj2_read_boxhdr(&box, cio);
2279     if (MJ2_MDIA != box.type) {
2280         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected MDIA Marker\n");
2281         return 1;
2282     }
2283
2284     if (mj2_read_mdhd(tk, cio)) {
2285         return 1;
2286     }
2287     if (mj2_read_hdlr(tk, cio)) {
2288         return 1;
2289     }
2290     if (mj2_read_minf(tk, img, cio)) {
2291         return 1;
2292     }
2293
2294     if (cio_tell(cio) - box.init_pos != box.length) {
2295         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MDIA Box size\n");
2296         return 1;
2297     }
2298     return 0;
2299 }
2300
2301 /*
2302 * Write the TKHD box
2303 *
2304 * Track Header box
2305 *
2306 */
2307 void mj2_write_tkhd(mj2_tk_t * tk, opj_cio_t *cio)
2308 {
2309     mj2_box_t box;
2310     unsigned int i;
2311     time_t ltime;
2312
2313     box.init_pos = cio_tell(cio);
2314     cio_skip(cio, 4);
2315
2316     cio_write(cio, MJ2_TKHD, 4);  /* TKHD       */
2317
2318     cio_write(cio, 3, 4);     /* Version=0, flags=3 */
2319
2320     time(&ltime);         /* Time since 1/1/70 */
2321     tk->modification_time = (unsigned int)ltime +
2322                             2082844800; /* Seoonds between 1/1/04 and 1/1/70 */
2323
2324     cio_write(cio, tk->creation_time, 4); /* Creation Time */
2325
2326     cio_write(cio, tk->modification_time, 4); /* Modification Time */
2327
2328     cio_write(cio, tk->track_ID, 4);  /* Track ID */
2329
2330     cio_write(cio, 0, 4);     /* Reserved */
2331
2332     tk->duration = 0;
2333
2334     for (i = 0; i < tk->num_samples; i++) {
2335         tk->duration += tk->sample[i].sample_delta;
2336     }
2337
2338     cio_write(cio, tk->duration, 4);  /* Duration */
2339
2340     cio_write(cio, 0, 4);     /* Reserved */
2341     cio_write(cio, 0, 4);     /* Reserved */
2342
2343     cio_write(cio, tk->layer, 2); /* Layer    */
2344
2345     cio_write(cio, 0, 2);     /* Predefined */
2346
2347     cio_write(cio, tk->volume, 2);    /* Volume       */
2348
2349     cio_write(cio, 0, 2);     /* Reserved */
2350
2351     cio_write(cio, tk->trans_matrix[0], 4);   /* Transformation matrix for track */
2352     cio_write(cio, tk->trans_matrix[1], 4);
2353     cio_write(cio, tk->trans_matrix[2], 4);
2354     cio_write(cio, tk->trans_matrix[3], 4);
2355     cio_write(cio, tk->trans_matrix[4], 4);
2356     cio_write(cio, tk->trans_matrix[5], 4);
2357     cio_write(cio, tk->trans_matrix[6], 4);
2358     cio_write(cio, tk->trans_matrix[7], 4);
2359     cio_write(cio, tk->trans_matrix[8], 4);
2360
2361     cio_write(cio, tk->visual_w, 4);  /* Video Visual Width  */
2362
2363     cio_write(cio, tk->visual_h, 4);  /* Video Visual Height */
2364
2365     box.length = cio_tell(cio) - box.init_pos;
2366     cio_seek(cio, box.init_pos);
2367     cio_write(cio, box.length, 4);    /* L          */
2368     cio_seek(cio, box.init_pos + box.length);
2369 }
2370
2371 /*
2372 * Read the TKHD box
2373 *
2374 * Track Header box
2375 *
2376 */
2377 int mj2_read_tkhd(mj2_tk_t * tk, opj_cio_t *cio)
2378 {
2379     int flag;
2380
2381     mj2_box_t box;
2382
2383     mj2_read_boxhdr(&box, cio);
2384
2385     if (MJ2_TKHD != box.type) {
2386         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected TKHD Marker\n");
2387         return 1;
2388     }
2389
2390     if (0 != cio_read(cio, 1)) {  /* Version = 0 */
2391         opj_event_msg(cio->cinfo, EVT_ERROR,
2392                       "Error: Only Version 0 handled in TKHD box\n");
2393         return 1;
2394     }
2395
2396     flag = cio_read(cio, 3);
2397
2398     if (!(flag == 1 || flag == 2 || flag == 3 ||
2399             flag == 4)) {    /* Flags = 1,2,3 or 4 */
2400         opj_event_msg(cio->cinfo, EVT_ERROR,
2401                       "Error with flag in TKHD box: Expected flag 1,2,3 or 4\n");
2402         return 1;
2403     }
2404
2405     tk->creation_time = cio_read(cio, 4); /* Creation Time */
2406
2407     tk->modification_time = cio_read(cio, 4); /* Modification Time */
2408
2409     tk->track_ID = cio_read(cio, 4);  /* Track ID */
2410
2411     cio_skip(cio, 4);         /* Reserved */
2412
2413     tk->duration = cio_read(cio, 4);  /* Duration */
2414
2415     cio_skip(cio, 8);         /* Reserved */
2416
2417     tk->layer = cio_read(cio, 2); /* Layer    */
2418
2419     cio_read(cio, 2);         /* Predefined */
2420
2421     tk->volume = cio_read(cio, 2);    /* Volume       */
2422
2423     cio_skip(cio, 2);         /* Reserved */
2424
2425     tk->trans_matrix[0] = cio_read(cio, 4);   /* Transformation matrix for track */
2426     tk->trans_matrix[1] = cio_read(cio, 4);
2427     tk->trans_matrix[2] = cio_read(cio, 4);
2428     tk->trans_matrix[3] = cio_read(cio, 4);
2429     tk->trans_matrix[4] = cio_read(cio, 4);
2430     tk->trans_matrix[5] = cio_read(cio, 4);
2431     tk->trans_matrix[6] = cio_read(cio, 4);
2432     tk->trans_matrix[7] = cio_read(cio, 4);
2433     tk->trans_matrix[8] = cio_read(cio, 4);
2434
2435     tk->visual_w = cio_read(cio, 4);  /* Video Visual Width  */
2436
2437     tk->visual_h = cio_read(cio, 4);  /* Video Visual Height */
2438
2439     if (cio_tell(cio) - box.init_pos != box.length) {
2440         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with TKHD Box size\n");
2441         return 1;
2442     }
2443     return 0;
2444 }
2445
2446 /*
2447 * Write the TRAK box
2448 *
2449 * Track box
2450 *
2451 */
2452 void mj2_write_trak(mj2_tk_t * tk, opj_cio_t *cio)
2453 {
2454     mj2_box_t box;
2455
2456     box.init_pos = cio_tell(cio);
2457     cio_skip(cio, 4);
2458
2459     cio_write(cio, MJ2_TRAK, 4);  /* TRAK       */
2460
2461     mj2_write_tkhd(tk, cio);
2462     mj2_write_mdia(tk, cio);
2463
2464     box.length = cio_tell(cio) - box.init_pos;
2465     cio_seek(cio, box.init_pos);
2466     cio_write(cio, box.length, 4);    /* L          */
2467     cio_seek(cio, box.init_pos + box.length);
2468 }
2469
2470 /*
2471 * Read the TRAK box
2472 *
2473 * Track box
2474 *
2475 */
2476 int mj2_read_trak(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
2477 {
2478     mj2_box_t box;
2479
2480     mj2_read_boxhdr(&box, cio);
2481     if (MJ2_TRAK != box.type) {
2482         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected TRAK Marker\n");
2483         return 1;
2484     }
2485     if (mj2_read_tkhd(tk, cio)) {
2486         return 1;
2487     }
2488     if (mj2_read_mdia(tk, img, cio)) {
2489         return 1;
2490     }
2491     if (cio_tell(cio) - box.init_pos != box.length) {
2492         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with TRAK Box\n");
2493         return 1;
2494     }
2495     return 0;
2496 }
2497
2498 /*
2499 * Write the MVHD box
2500 *
2501 * Movie header Box
2502 *
2503 */
2504 void mj2_write_mvhd(opj_mj2_t * movie, opj_cio_t *cio)
2505 {
2506     int i;
2507     mj2_box_t box;
2508     unsigned j;
2509     time_t ltime;
2510     int max_tk_num = 0;
2511
2512     box.init_pos = cio_tell(cio);
2513     cio_skip(cio, 4);
2514     cio_write(cio, MJ2_MVHD, 4);  /* MVHD       */
2515
2516     cio_write(cio, 0, 4);     /* Version = 0, flags = 0 */
2517
2518     time(&ltime);         /* Time since 1/1/70 */
2519     movie->modification_time = (unsigned int)ltime +
2520                                2082844800;  /* Seoonds between 1/1/04 and 1/1/70 */
2521
2522     cio_write(cio, movie->creation_time, 4);  /* Creation Time */
2523
2524     cio_write(cio, movie->modification_time, 4);  /* Modification Time */
2525
2526     cio_write(cio, movie->timescale, 4);  /* Timescale */
2527
2528     movie->duration = 0;
2529
2530     for (i = 0; i < (movie->num_stk + movie->num_htk + movie->num_vtk); i++) {
2531         mj2_tk_t *tk = &movie->tk[i];
2532
2533         for (j = 0; j < tk->num_samples; j++) {
2534             movie->duration += tk->sample[j].sample_delta;
2535         }
2536     }
2537
2538     cio_write(cio, movie->duration, 4);
2539
2540     cio_write(cio, movie->rate, 4);   /* Rate to play presentation    */
2541
2542     cio_write(cio, movie->volume, 2); /* Volume       */
2543
2544     cio_write(cio, 0, 2);     /* Reserved */
2545     cio_write(cio, 0, 4);     /* Reserved */
2546     cio_write(cio, 0, 4);     /* Reserved */
2547
2548     cio_write(cio, movie->trans_matrix[0],
2549               4);    /* Transformation matrix for video */
2550     cio_write(cio, movie->trans_matrix[1], 4);
2551     cio_write(cio, movie->trans_matrix[2], 4);
2552     cio_write(cio, movie->trans_matrix[3], 4);
2553     cio_write(cio, movie->trans_matrix[4], 4);
2554     cio_write(cio, movie->trans_matrix[5], 4);
2555     cio_write(cio, movie->trans_matrix[6], 4);
2556     cio_write(cio, movie->trans_matrix[7], 4);
2557     cio_write(cio, movie->trans_matrix[8], 4);
2558
2559     cio_write(cio, 0, 4);     /* Pre-defined */
2560     cio_write(cio, 0, 4);     /* Pre-defined */
2561     cio_write(cio, 0, 4);     /* Pre-defined */
2562     cio_write(cio, 0, 4);     /* Pre-defined */
2563     cio_write(cio, 0, 4);     /* Pre-defined */
2564     cio_write(cio, 0, 4);     /* Pre-defined */
2565
2566
2567     for (i = 0; i < movie->num_htk + movie->num_stk + movie->num_vtk; i++) {
2568         if (max_tk_num < movie->tk[i].track_ID) {
2569             max_tk_num = movie->tk[i].track_ID;
2570         }
2571     }
2572
2573     movie->next_tk_id = max_tk_num + 1;
2574
2575     cio_write(cio, movie->next_tk_id, 4); /* ID of Next track to be added */
2576
2577     box.length = cio_tell(cio) - box.init_pos;
2578     cio_seek(cio, box.init_pos);
2579     cio_write(cio, box.length, 4);    /* L          */
2580     cio_seek(cio, box.init_pos + box.length);
2581 }
2582
2583 /*
2584 * Read the MVHD box
2585 *
2586 * Movie header Box
2587 *
2588 */
2589 int mj2_read_mvhd(opj_mj2_t * movie, opj_cio_t *cio)
2590 {
2591     mj2_box_t box;
2592
2593     mj2_read_boxhdr(&box, cio);
2594     if (MJ2_MVHD != box.type) {
2595         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected MVHD Marker\n");
2596         return 1;
2597     }
2598
2599
2600     if (0 != cio_read(cio, 4)) {  /* Version = 0, flags = 0 */
2601         opj_event_msg(cio->cinfo, EVT_ERROR,
2602                       "Error: Only Version 0 handled in MVHD box\n");
2603     }
2604
2605     movie->creation_time = cio_read(cio, 4);  /* Creation Time */
2606
2607     movie->modification_time = cio_read(cio, 4);  /* Modification Time */
2608
2609     movie->timescale = cio_read(cio, 4);  /* Timescale */
2610
2611     movie->duration = cio_read(cio, 4);   /* Duration */
2612
2613     movie->rate = cio_read(cio, 4);       /* Rate to play presentation    */
2614
2615     movie->volume = cio_read(cio, 2);     /* Volume       */
2616
2617     cio_skip(cio, 10);            /* Reserved */
2618
2619     movie->trans_matrix[0] = cio_read(cio,
2620                                       4);    /* Transformation matrix for video */
2621     movie->trans_matrix[1] = cio_read(cio, 4);
2622     movie->trans_matrix[2] = cio_read(cio, 4);
2623     movie->trans_matrix[3] = cio_read(cio, 4);
2624     movie->trans_matrix[4] = cio_read(cio, 4);
2625     movie->trans_matrix[5] = cio_read(cio, 4);
2626     movie->trans_matrix[6] = cio_read(cio, 4);
2627     movie->trans_matrix[7] = cio_read(cio, 4);
2628     movie->trans_matrix[8] = cio_read(cio, 4);
2629
2630     cio_skip(cio, 24);        /* Pre-defined */
2631
2632     movie->next_tk_id = cio_read(cio, 4); /* ID of Next track to be added */
2633
2634     if (cio_tell(cio) - box.init_pos != box.length) {
2635         opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MVHD Box Size\n");
2636         return 1;
2637     }
2638     return 0;
2639 }
2640
2641
2642 /*
2643 * Write the MOOV box
2644 *
2645 * Movie Box
2646 *
2647 */
2648 void OPJ_CALLCONV mj2_write_moov(opj_mj2_t * movie, opj_cio_t *cio)
2649 {
2650     int i;
2651     mj2_box_t box;
2652
2653     box.init_pos = cio_tell(cio);
2654     cio_skip(cio, 4);
2655     cio_write(cio, MJ2_MOOV, 4);  /* MOOV       */
2656
2657     mj2_write_mvhd(movie, cio);
2658
2659     for (i = 0; i < (movie->num_stk + movie->num_htk + movie->num_vtk); i++) {
2660         mj2_write_trak(&movie->tk[i], cio);
2661     }
2662
2663     box.length = cio_tell(cio) - box.init_pos;
2664     cio_seek(cio, box.init_pos);
2665     cio_write(cio, box.length, 4);    /* L          */
2666     cio_seek(cio, box.init_pos + box.length);
2667 }
2668
2669 /*
2670 * Read the MOOV box
2671 *
2672 * Movie Box
2673 *
2674 */
2675 int mj2_read_moov(opj_mj2_t * movie, opj_image_t * img, opj_cio_t *cio)
2676 {
2677     unsigned int i;
2678     mj2_box_t box;
2679     mj2_box_t box2;
2680
2681     mj2_read_boxhdr(&box, cio);
2682     if (MJ2_MOOV != box.type) {
2683         opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected MOOV Marker\n");
2684         return 1;
2685     }
2686
2687     if (mj2_read_mvhd(movie, cio)) {
2688         return 1;
2689     }
2690
2691     movie->tk = (mj2_tk_t*) opj_malloc((movie->next_tk_id - 1) * sizeof(mj2_tk_t));
2692
2693     for (i = 0; cio_tell(cio) - box.init_pos < box.length; i++) {
2694         mj2_tk_t *tk = &movie->tk[i];
2695         tk->cinfo = movie->cinfo;
2696         mj2_read_boxhdr(&box2, cio);
2697         if (box2.type == MJ2_TRAK) {
2698             cio_seek(cio, box2.init_pos);
2699             if (mj2_read_trak(tk, img, cio)) {
2700                 return 1;
2701             }
2702
2703             if (tk->track_type == 0) {
2704                 movie->num_vtk++;
2705             } else if (tk->track_type == 1) {
2706                 movie->num_stk++;
2707             } else if (tk->track_type == 2) {
2708                 movie->num_htk++;
2709             }
2710         } else if (box2.type == MJ2_MVEX) {
2711             cio_seek(cio, box2.init_pos);
2712             cio_skip(cio, box2.length);
2713             i--;
2714         } else {
2715             opj_event_msg(cio->cinfo, EVT_ERROR,
2716                           "Error with MOOV Box: Expected TRAK or MVEX box\n");
2717             return 1;
2718         }
2719     }
2720     return 0;
2721 }
2722
2723 int OPJ_CALLCONV mj2_read_struct(FILE *file, opj_mj2_t *movie)
2724 {
2725     mj2_box_t box;
2726     opj_image_t img;
2727     unsigned char * src;
2728     int fsresult;
2729     int foffset;
2730     opj_cio_t *cio;
2731
2732     /* open a byte stream for reading */
2733     src = (unsigned char*) opj_malloc(300 * sizeof(unsigned char));
2734
2735     /* Assuming that jp and ftyp markers size do
2736      not exceed 300 bytes */
2737     fread(src, 300, 1, file);
2738
2739     cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, 300);
2740
2741     if (mj2_read_jp(cio)) {
2742         return 1;
2743     }
2744     if (mj2_read_ftyp(movie, cio)) {
2745         return 1;
2746     }
2747
2748     fsresult = fseek(file, cio_tell(cio), SEEK_SET);
2749     if (fsresult) {
2750         opj_event_msg(cio->cinfo, EVT_ERROR,
2751                       "End of file reached while trying to read data after FTYP box\n");
2752         return 1;
2753     }
2754
2755     foffset = cio_tell(cio);
2756
2757     box.type = 0;
2758
2759     fread(src, 30, 1, file);
2760     cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, 300);
2761     mj2_read_boxhdr(&box, cio);
2762
2763     while (box.type != MJ2_MOOV) {
2764
2765         switch (box.type) {
2766         case MJ2_MDAT:
2767             fsresult = fseek(file, foffset + box.length, SEEK_SET);
2768             if (fsresult) {
2769                 opj_event_msg(cio->cinfo, EVT_ERROR,
2770                               "End of file reached while trying to read MDAT box\n");
2771                 return 1;
2772             }
2773             foffset += box.length;
2774             break;
2775
2776         case MJ2_MOOF:
2777             fsresult = fseek(file, foffset + box.length, SEEK_SET);
2778             if (fsresult) {
2779                 opj_event_msg(cio->cinfo, EVT_ERROR,
2780                               "End of file reached while trying to read MOOF box\n");
2781                 return 1;
2782             }
2783             foffset += box.length;
2784             break;
2785         case MJ2_FREE:
2786             fsresult = fseek(file, foffset + box.length, SEEK_SET);
2787             if (fsresult) {
2788                 opj_event_msg(cio->cinfo, EVT_ERROR,
2789                               "End of file reached while trying to read FREE box\n");
2790                 return 1;
2791             }
2792             foffset += box.length;
2793             break;
2794         case MJ2_SKIP:
2795             fsresult = fseek(file, foffset + box.length, SEEK_SET);
2796             if (fsresult) {
2797                 opj_event_msg(cio->cinfo, EVT_ERROR,
2798                               "End of file reached while trying to read SKIP box\n");
2799                 return 1;
2800             }
2801             foffset += box.length;
2802             break;
2803         default:
2804             opj_event_msg(cio->cinfo, EVT_ERROR, "Unknown box in MJ2 stream\n");
2805             fsresult = fseek(file, foffset + box.length, SEEK_SET);
2806             if (fsresult) {
2807                 opj_event_msg(cio->cinfo, EVT_ERROR,
2808                               "End of file reached while trying to read end of unknown box\n");
2809                 return 1;
2810             }
2811             foffset += box.length;
2812             break;
2813         }
2814         fsresult = fread(src, 8, 1, file);
2815         if (fsresult != 1) {
2816             opj_event_msg(cio->cinfo, EVT_ERROR, "MOOV box not found in file\n");
2817             return 1;
2818         }
2819         cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, 8);
2820         mj2_read_boxhdr(&box, cio);
2821     }
2822
2823     fseek(file, foffset, SEEK_SET);
2824     src = (unsigned char*)opj_realloc(src, box.length);
2825     fsresult = fread(src, box.length, 1, file);
2826     if (fsresult != 1) {
2827         opj_event_msg(cio->cinfo, EVT_ERROR,
2828                       "End of file reached while trying to read MOOV box\n");
2829         return 1;
2830     }
2831
2832     cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, box.length);
2833
2834     if (mj2_read_moov(movie, &img, cio)) {
2835         return 1;
2836     }
2837
2838     opj_free(src);
2839     return 0;
2840 }
2841
2842 /* ----------------------------------------------------------------------- */
2843 /* MJ2 decoder interface                                                                                 */
2844 /* ----------------------------------------------------------------------- */
2845
2846 opj_dinfo_t* OPJ_CALLCONV mj2_create_decompress()
2847 {
2848     opj_mj2_t* mj2;
2849     opj_dinfo_t *dinfo = (opj_dinfo_t*) opj_calloc(1, sizeof(opj_dinfo_t));
2850     if (!dinfo) {
2851         return NULL;
2852     }
2853
2854     dinfo->is_decompressor = OPJ_TRUE;
2855
2856     mj2 = (opj_mj2_t*) opj_calloc(1, sizeof(opj_mj2_t));
2857     dinfo->mj2_handle = mj2;
2858     if (mj2) {
2859         mj2->cinfo = (opj_common_ptr)dinfo;
2860     }
2861     mj2->j2k = j2k_create_decompress((opj_common_ptr)dinfo);
2862     dinfo->j2k_handle = mj2->j2k;
2863
2864     return dinfo;
2865 }
2866
2867 void OPJ_CALLCONV mj2_setup_decoder(opj_mj2_t *movie,
2868                                     mj2_dparameters_t *mj2_parameters)
2869 {
2870     movie->num_vtk = 0;
2871     movie->num_stk = 0;
2872     movie->num_htk = 0;
2873
2874     /* setup the J2K decoder parameters */
2875     j2k_setup_decoder((opj_j2k_t*)movie->cinfo->j2k_handle,
2876                       &mj2_parameters->j2k_parameters);
2877
2878 }
2879
2880 void OPJ_CALLCONV mj2_destroy_decompress(opj_mj2_t *movie)
2881 {
2882     if (movie) {
2883         int i;
2884         mj2_tk_t *tk = NULL;
2885
2886         if (movie->cinfo->j2k_handle) {
2887             j2k_destroy_compress(movie->j2k);
2888         }
2889
2890         if (movie->num_cl != 0) {
2891             opj_free(movie->cl);
2892         }
2893
2894         for (i = 0; i < movie->num_vtk + movie->num_stk + movie->num_htk; i++) {
2895             tk = &movie->tk[i];
2896             if (tk->name_size != 0) {
2897                 opj_free(tk->name);
2898             }
2899             if (tk->track_type == 0)  {/* Video track*/
2900                 if (tk->jp2_struct.comps != NULL) {
2901                     opj_free(tk->jp2_struct.comps);
2902                 }
2903                 if (tk->jp2_struct.cl != NULL) {
2904                     opj_free(tk->jp2_struct.cl);
2905                 }
2906                 if (tk->num_jp2x != 0) {
2907                     opj_free(tk->jp2xdata);
2908                 }
2909
2910             }
2911             if (tk->num_url != 0) {
2912                 opj_free(tk->url);
2913             }
2914             if (tk->num_urn != 0) {
2915                 opj_free(tk->urn);
2916             }
2917             if (tk->num_br != 0) {
2918                 opj_free(tk->br);
2919             }
2920             if (tk->num_tts != 0) {
2921                 opj_free(tk->tts);
2922             }
2923             if (tk->num_chunks != 0) {
2924                 opj_free(tk->chunk);
2925             }
2926             if (tk->num_samplestochunk != 0) {
2927                 opj_free(tk->sampletochunk);
2928             }
2929             if (tk->num_samples != 0) {
2930                 opj_free(tk->sample);
2931             }
2932         }
2933
2934         opj_free(movie->tk);
2935     }
2936     opj_free(movie);
2937 }
2938
2939 /* ----------------------------------------------------------------------- */
2940 /* MJ2 encoder interface                                                                                 */
2941 /* ----------------------------------------------------------------------- */
2942
2943 opj_cinfo_t* OPJ_CALLCONV mj2_create_compress()
2944 {
2945     opj_mj2_t* mj2;
2946     opj_cinfo_t *cinfo = (opj_cinfo_t*) opj_calloc(1, sizeof(opj_cinfo_t));
2947     if (!cinfo) {
2948         return NULL;
2949     }
2950
2951     mj2 = (opj_mj2_t*) opj_calloc(1, sizeof(opj_mj2_t));
2952     cinfo->mj2_handle = mj2;
2953     if (mj2) {
2954         mj2->cinfo = (opj_common_ptr)cinfo;
2955     }
2956
2957     mj2->j2k = j2k_create_compress(mj2->cinfo);
2958     cinfo->j2k_handle = mj2->j2k;
2959
2960     return cinfo;
2961 }
2962
2963 void OPJ_CALLCONV mj2_setup_encoder(opj_mj2_t *movie,
2964                                     mj2_cparameters_t *parameters)
2965 {
2966     if (movie && parameters) {
2967         opj_jp2_t *jp2_struct;
2968
2969         movie->num_htk = 0;   /* No hint tracks*/
2970         movie->num_stk = 0;   /* No sound tracks*/
2971         movie->num_vtk = 1;   /* One video track*/
2972
2973         movie->brand = MJ2_MJ2;  /* One brand: MJ2*/
2974         movie->num_cl = 2;    /* Two compatible brands: MJ2 and MJ2S*/
2975         movie->cl = (unsigned int*) opj_malloc(movie->num_cl * sizeof(unsigned int));
2976         movie->cl[0] = MJ2_MJ2;
2977         movie->cl[1] = MJ2_MJ2S;
2978         movie->minversion = 0;    /* Minimum version: 0 */
2979
2980         movie->tk = (mj2_tk_t*) opj_malloc(sizeof(
2981                                                mj2_tk_t)); /*Memory allocation for the video track*/
2982         movie->tk[0].track_ID = 1;    /* Track ID = 1 */
2983         movie->tk[0].track_type = 0;      /* Video track */
2984         movie->tk[0].Dim[0] = parameters->Dim[0];
2985         movie->tk[0].Dim[1] = parameters->Dim[1];
2986         movie->tk[0].w = parameters->w;
2987         movie->tk[0].h = parameters->h;
2988         movie->tk[0].CbCr_subsampling_dx = parameters->CbCr_subsampling_dx;
2989         movie->tk[0].CbCr_subsampling_dy = parameters->CbCr_subsampling_dy;
2990         movie->tk[0].sample_rate = parameters->frame_rate;
2991         movie->tk[0].name_size = 0;
2992         movie->tk[0].chunk = (mj2_chunk_t*) opj_malloc(sizeof(mj2_chunk_t));
2993         movie->tk[0].sample = (mj2_sample_t*) opj_malloc(sizeof(mj2_sample_t));
2994         movie->tk[0].depth = parameters->prec;
2995
2996         jp2_struct = &movie->tk[0].jp2_struct;
2997         jp2_struct->numcomps = parameters->numcomps;    /* NC */
2998         jp2_struct->comps = (opj_jp2_comps_t*) opj_malloc(jp2_struct->numcomps * sizeof(
2999                                 opj_jp2_comps_t));
3000         jp2_struct->precedence = 0;   /* PRECEDENCE*/
3001         jp2_struct->approx = 0;   /* APPROX*/
3002         jp2_struct->brand = JP2_JP2;    /* BR         */
3003         jp2_struct->minversion = 0; /* MinV       */
3004         jp2_struct->numcl = 1;
3005         jp2_struct->cl = (unsigned int*) opj_malloc(jp2_struct->numcl * sizeof(
3006                              unsigned int));
3007         jp2_struct->cl[0] = JP2_JP2;    /* CL0 : JP2  */
3008         jp2_struct->C = 7;      /* C : Always 7*/
3009         jp2_struct->UnkC = 0;      /* UnkC, colorspace specified in colr box*/
3010         jp2_struct->IPR = 0;      /* IPR, no intellectual property*/
3011         jp2_struct->w = parameters->w;
3012         jp2_struct->h = parameters->h;
3013         jp2_struct->bpc = 7;
3014         jp2_struct->meth = parameters->meth;
3015         jp2_struct->enumcs = parameters->enumcs;
3016     }
3017 }
3018
3019 void OPJ_CALLCONV mj2_destroy_compress(opj_mj2_t *movie)
3020 {
3021     if (movie) {
3022         int i;
3023         mj2_tk_t *tk = NULL;
3024
3025         if (movie->cinfo->j2k_handle) {
3026             j2k_destroy_compress(movie->j2k);
3027         }
3028
3029         if (movie->num_cl != 0) {
3030             opj_free(movie->cl);
3031         }
3032
3033         for (i = 0; i < movie->num_vtk + movie->num_stk + movie->num_htk; i++) {
3034             tk = &movie->tk[i];
3035             if (tk->name_size != 0) {
3036                 opj_free(tk->name);
3037             }
3038             if (tk->track_type == 0)  {/* Video track*/
3039                 if (tk->jp2_struct.comps != NULL) {
3040                     opj_free(tk->jp2_struct.comps);
3041                 }
3042                 if (tk->jp2_struct.cl != NULL) {
3043                     opj_free(tk->jp2_struct.cl);
3044                 }
3045                 if (tk->num_jp2x != 0) {
3046                     opj_free(tk->jp2xdata);
3047                 }
3048
3049             }
3050             if (tk->num_url != 0) {
3051                 opj_free(tk->url);
3052             }
3053             if (tk->num_urn != 0) {
3054                 opj_free(tk->urn);
3055             }
3056             if (tk->num_br != 0) {
3057                 opj_free(tk->br);
3058             }
3059             if (tk->num_tts != 0) {
3060                 opj_free(tk->tts);
3061             }
3062             if (tk->num_chunks != 0) {
3063                 opj_free(tk->chunk);
3064             }
3065             if (tk->num_samplestochunk != 0) {
3066                 opj_free(tk->sampletochunk);
3067             }
3068             if (tk->num_samples != 0) {
3069                 opj_free(tk->sample);
3070             }
3071         }
3072
3073         opj_free(movie->tk);
3074     }
3075     opj_free(movie);
3076 }
3077
3078 /*@}*/
3079
3080 /*@}*/
3081