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.
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.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
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.
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.
34 #include "opj_includes.h"
37 /** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */
40 /** @name Local static functions */
49 int mj2_read_boxhdr(mj2_box_t * box, opj_cio_t *cio)
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");
60 box->length = cio_read(cio, 4);
61 if (box->length == 0) {
62 box->length = cio_numbytesleft(cio) + 12;
64 } else if (box->length == 0) {
65 box->length = cio_numbytesleft(cio) + 8;
72 * Initialisation of a Standard Movie, given a simple movie structure defined by the user
73 * The movie will have one sample per chunk
75 * Arguments: opj_mj2_t * movie
76 * Several variables of "movie" must be defined in order to enable a correct execution of
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)
81 * The track type (tk->track_type)
82 * The number of sample (tk->num_samples)
83 * The sample rate (tk->sample_rate)
87 int OPJ_CALLCONV mj2_init_stdmovie(opj_mj2_t * movie)
94 movie->brand = MJ2_MJ2;
95 movie->minversion = 0;
97 movie->cl = (unsigned int*) opj_malloc(movie->num_cl * sizeof(unsigned int));
99 movie->cl[0] = MJ2_MJ2;
100 movie->cl[1] = MJ2_MJ2S;
101 time(<ime); /* 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;
107 16; /* Rate to play presentation (default = 0x00010000) */
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;
128 for (i = 0; i < movie->num_htk + movie->num_stk + movie->num_vtk; i++) {
129 mj2_tk_t *tk = &movie->tk[i];
132 tk->jp2_struct.comps = NULL;
133 tk->jp2_struct.cl = NULL;
135 if (tk->track_type == 0) { /* no sound or hint track */
136 if (tk->num_samples == 0) {
147 1000; /* Timescale = 1 ms */
149 tk->chunk[0].num_samples = 1;
150 tk->chunk[0].sample_descr_idx = 1;
152 tk->same_sample_size = 0;
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;
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);
168 for (j = 0; j < tk->num_samples; j++) {
169 tk->sample[j].sample_delta = tk->timescale / tk->sample_rate;
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;
177 tk->horizresolution =
178 0x00480000; /* Horizontal resolution (typically 72) */
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;
191 0; /* Number of URL */
193 0; /* Number of URN */
195 0; /* Graphicsmode */
203 movie->creation_time; /* Seconds between 1/1/04 and 1/1/70 */
204 tk->language = 0; /* Language (undefined) */
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;
219 tk->or_fieldcount = 1;
220 tk->or_fieldorder = 0;
222 tk->br = (unsigned int*) opj_malloc(tk->num_br * sizeof(unsigned int));
224 tk->br[1] = MJ2_J2P0;
232 tk->visual_w = tk->w << 16;
233 tk->visual_h = tk->h << 16;
243 * Time To Sample box Decompact
246 void mj2_tts_decompact(mj2_tk_t * tk)
250 for (i = 0; i < tk->num_tts; i++) {
251 tk->num_samples += tk->tts[i].sample_count;
254 tk->sample = (mj2_sample_t*) opj_malloc(tk->num_samples * sizeof(mj2_sample_t));
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;
264 * Sample To Chunk box Decompact
267 void mj2_stsc_decompact(mj2_tk_t * tk)
269 unsigned int i, j, k, sampleno = 0;
271 if (tk->num_samplestochunk == 1) {
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;
281 tk->chunk = (mj2_chunk_t*) opj_malloc(tk->num_samples * sizeof(mj2_chunk_t));
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;
288 sampleno += tk->chunk[j].num_samples;
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;
298 tk->chunk = (mj2_chunk_t*)
299 opj_realloc(tk->chunk, tk->num_chunks * sizeof(mj2_chunk_t));
306 * Chunk offset box Decompact
309 void mj2_stco_decompact(mj2_tk_t * tk)
311 unsigned int i, j, k = 0;
312 unsigned int intra_chunk_offset;
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;
330 void OPJ_CALLCONV mj2_write_jp(opj_cio_t *cio)
333 box.init_pos = cio_tell(cio);
336 cio_write(cio, MJ2_JP, 4); /* JP */
337 cio_write(cio, 0x0d0a870a, 4); /* 0x0d0a870a required in a JP box */
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);
348 * JPEG 2000 signature
351 int mj2_read_jp(opj_cio_t *cio)
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");
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");
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");
379 void OPJ_CALLCONV mj2_write_ftyp(opj_mj2_t * movie, opj_cio_t *cio)
383 box.init_pos = cio_tell(cio);
386 cio_write(cio, MJ2_FTYP, 4); /* FTYP */
387 cio_write(cio, movie->brand, 4); /* BR */
388 cio_write(cio, movie->minversion, 4); /* MinV */
390 for (i = 0; i < movie->num_cl; i++) {
391 cio_write(cio, movie->cl[i], 4); /* CL */
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);
406 int mj2_read_ftyp(opj_mj2_t * movie, opj_cio_t *cio)
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");
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));
422 for (i = movie->num_cl - 1; i > -1; i--) {
423 movie->cl[i] = cio_read(cio, 4); /* CLi */
426 if (cio_tell(cio) - box.init_pos != box.length) {
427 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with FTYP Box\n");
440 void mj2_write_stco(mj2_tk_t * tk, opj_cio_t *cio)
445 box.init_pos = cio_tell(cio);
447 cio_write(cio, MJ2_STCO, 4); /* STCO */
449 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
451 cio_write(cio, tk->num_chunks, 4); /* Entry Count */
453 for (i = 0; i < tk->num_chunks; i++) {
454 cio_write(cio, tk->chunk[i].offset, 4); /* Entry offset */
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);
469 int mj2_read_stco(mj2_tk_t * tk, opj_cio_t *cio)
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");
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");
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");
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");
497 for (i = 0; i < tk->num_chunks; i++) {
498 tk->chunk[i].offset = cio_read(cio, 4); /* Entry offset */
502 mj2_stco_decompact(tk);
505 if (cio_tell(cio) - box.init_pos != box.length) {
506 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STCO Box size\n");
518 void mj2_write_stsz(mj2_tk_t * tk, opj_cio_t *cio)
523 box.init_pos = cio_tell(cio);
525 cio_write(cio, MJ2_STSZ, 4); /* STSZ */
527 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
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 */
532 cio_write(cio, 1, 4); /* Entry count = 1 */
537 4); /* Sample Size = 0 because they all have different sizes */
539 cio_write(cio, tk->num_samples, 4); /* Sample Count */
541 for (i = 0; i < tk->num_samples; i++) {
542 cio_write(cio, tk->sample[i].sample_size, 4);
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);
558 int mj2_read_stsz(mj2_tk_t * tk, opj_cio_t *cio)
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");
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");
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");
583 sample_size = cio_read(cio, 4);
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;
590 cio_skip(cio, 4); /* Sample count = 1 */
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");
598 for (i = 0; i < tk->num_samples; i++) {
599 tk->sample[i].sample_size = cio_read(cio, 4); /* Sample Size */
602 if (cio_tell(cio) - box.init_pos != box.length) {
603 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STSZ Box size\n");
617 void mj2_write_stsc(mj2_tk_t * tk, opj_cio_t *cio)
622 box.init_pos = cio_tell(cio);
624 cio_write(cio, MJ2_STSC, 4); /* STSC */
626 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
628 cio_write(cio, tk->num_samplestochunk, 4); /* Entry Count */
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 */
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);
651 int mj2_read_stsc(mj2_tk_t * tk, opj_cio_t *cio)
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");
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");
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");
675 tk->num_samplestochunk = cio_read(cio, 4);
677 tk->sampletochunk = (mj2_sampletochunk_t*) opj_malloc(tk->num_samplestochunk *
678 sizeof(mj2_sampletochunk_t));
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);
686 mj2_stsc_decompact(tk); /* decompact sample to chunk box */
689 if (cio_tell(cio) - box.init_pos != box.length) {
690 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STSC Box size\n");
702 void mj2_write_stts(mj2_tk_t * tk, opj_cio_t *cio)
708 box.init_pos = cio_tell(cio);
710 cio_write(cio, MJ2_STTS, 4); /* STTS */
712 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
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 */
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);
732 int mj2_read_stts(mj2_tk_t * tk, opj_cio_t *cio)
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");
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");
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");
757 tk->num_tts = cio_read(cio, 4);
759 tk->tts = (mj2_tts_t*) opj_malloc(tk->num_tts * sizeof(mj2_tts_t));
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);
766 mj2_tts_decompact(tk);
768 if (cio_tell(cio) - box.init_pos != box.length) {
769 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STTS Box size\n");
781 void mj2_write_fiel(mj2_tk_t * tk, opj_cio_t *cio)
786 box.init_pos = cio_tell(cio);
788 cio_write(cio, MJ2_FIEL, 4); /* STTS */
790 cio_write(cio, tk->fieldcount, 1); /* Field count */
791 cio_write(cio, tk->fieldorder, 1); /* Field order */
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);
806 int mj2_read_fiel(mj2_tk_t * tk, opj_cio_t *cio)
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");
818 tk->fieldcount = cio_read(cio, 1);
819 tk->fieldorder = cio_read(cio, 1);
821 if (cio_tell(cio) - box.init_pos != box.length) {
822 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with FIEL Box size\n");
831 * Original Format Box
834 void mj2_write_orfo(mj2_tk_t * tk, opj_cio_t *cio)
838 box.init_pos = cio_tell(cio);
840 cio_write(cio, MJ2_ORFO, 4);
842 cio_write(cio, tk->or_fieldcount, 1); /* Original Field count */
843 cio_write(cio, tk->or_fieldorder, 1); /* Original Field order */
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);
855 * Original Format Box
858 int mj2_read_orfo(mj2_tk_t * tk, opj_cio_t *cio)
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");
870 tk->or_fieldcount = cio_read(cio, 1);
871 tk->or_fieldorder = cio_read(cio, 1);
873 if (cio_tell(cio) - box.init_pos != box.length) {
874 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with ORFO Box size\n");
886 void mj2_write_jp2p(mj2_tk_t * tk, opj_cio_t *cio)
892 box.init_pos = cio_tell(cio);
894 cio_write(cio, MJ2_JP2P, 4);
896 cio_write(cio, 0, 4); /* Version 0, flags =0 */
898 for (i = 0; i < tk->num_br; i++) {
899 cio_write(cio, tk->br[i], 4);
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);
914 int mj2_read_jp2p(mj2_tk_t * tk, opj_cio_t *cio)
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");
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");
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");
939 tk->num_br = (box.length - 12) / 4;
940 tk->br = (unsigned int*) opj_malloc(tk->num_br * sizeof(unsigned int));
942 for (i = 0; i < tk->num_br; i++) {
943 tk->br[i] = cio_read(cio, 4);
946 if (cio_tell(cio) - box.init_pos != box.length) {
947 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JP2P Box size\n");
959 void mj2_write_jp2x(mj2_tk_t * tk, opj_cio_t *cio)
965 box.init_pos = cio_tell(cio);
967 cio_write(cio, MJ2_JP2X, 4);
969 for (i = 0; i < tk->num_jp2x; i++) {
970 cio_write(cio, tk->jp2xdata[i], 1);
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);
985 int mj2_read_jp2x(mj2_tk_t * tk, opj_cio_t *cio)
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");
998 tk->num_jp2x = (box.length - 8);
999 tk->jp2xdata = (unsigned char*) opj_malloc(tk->num_jp2x * sizeof(
1002 for (i = 0; i < tk->num_jp2x; i++) {
1003 tk->jp2xdata[i] = cio_read(cio, 1);
1006 if (cio_tell(cio) - box.init_pos != box.length) {
1007 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JP2X Box size\n");
1014 * Write the JSUB box
1016 * MJP2 Subsampling Box
1019 void mj2_write_jsub(mj2_tk_t * tk, opj_cio_t *cio)
1024 box.init_pos = cio_tell(cio);
1026 cio_write(cio, MJ2_JSUB, 4);
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);
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);
1042 * MJP2 Subsampling Box
1045 int mj2_read_jsub(mj2_tk_t * tk, opj_cio_t *cio)
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");
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);
1060 if (cio_tell(cio) - box.init_pos != box.length) {
1061 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JSUB Box size\n");
1068 * Write the SMJ2 box
1070 * Visual Sample Entry Description
1073 void mj2_write_smj2(mj2_tk_t * tk, opj_cio_t *cio)
1077 box.init_pos = cio_tell(cio);
1079 cio_write(cio, MJ2_MJ2, 4); /* MJ2 */
1081 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1083 cio_write(cio, 1, 4);
1085 cio_write(cio, 0, 2); /* Pre-defined */
1087 cio_write(cio, 0, 2); /* Reserved */
1089 cio_write(cio, 0, 4); /* Pre-defined */
1090 cio_write(cio, 0, 4); /* Pre-defined */
1091 cio_write(cio, 0, 4); /* Pre-defined */
1093 cio_write(cio, tk->w, 2); /* Width */
1094 cio_write(cio, tk->h, 2); /* Height */
1096 cio_write(cio, tk->horizresolution, 4); /* Horizontal resolution */
1097 cio_write(cio, tk->vertresolution, 4); /* Vertical resolution */
1099 cio_write(cio, 0, 4); /* Reserved */
1101 cio_write(cio, 1, 2); /* Pre-defined = 1 */
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);
1112 cio_write(cio, tk->depth, 2); /* Depth */
1114 cio_write(cio, 0xffff, 2); /* Pre-defined = -1 */
1116 jp2_write_jp2h(&tk->jp2_struct, cio);
1118 mj2_write_fiel(tk, cio);
1120 if (tk->num_br != 0) {
1121 mj2_write_jp2p(tk, cio);
1123 if (tk->num_jp2x != 0) {
1124 mj2_write_jp2x(tk, cio);
1127 mj2_write_jsub(tk, cio);
1128 mj2_write_orfo(tk, cio);
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);
1139 * Visual Sample Entry Description
1142 int mj2_read_smj2(opj_image_t * img, mj2_tk_t * tk, opj_cio_t *cio)
1146 opj_jp2_color_t color;
1150 mj2_read_boxhdr(&box, cio);
1152 if (MJ2_MJ2 != box.type) {
1153 opj_event_msg(cio->cinfo, EVT_ERROR,
1154 "Error in SMJ2 box: Expected MJ2 Marker\n");
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");
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");
1172 cio_skip(cio, 2); /* Pre-defined */
1174 cio_skip(cio, 2); /* Reserved */
1176 cio_skip(cio, 4); /* Pre-defined */
1177 cio_skip(cio, 4); /* Pre-defined */
1178 cio_skip(cio, 4); /* Pre-defined */
1180 tk->w = cio_read(cio, 2); /* Width */
1181 tk->h = cio_read(cio, 2); /* Height */
1183 tk->horizresolution = cio_read(cio, 4); /* Horizontal resolution */
1184 tk->vertresolution = cio_read(cio, 4); /* Vertical resolution */
1186 cio_skip(cio, 4); /* Reserved */
1188 cio_skip(cio, 2); /* Pre-defined = 1 */
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);
1199 tk->depth = cio_read(cio, 2); /* Depth */
1201 /* Init std value */
1205 tk->or_fieldcount = 1;
1206 tk->or_fieldorder = 0;
1208 cio_skip(cio, 2); /* Pre-defined = -1 */
1209 memset(&color, 0, sizeof(opj_jp2_color_t));
1210 tk->jp2_struct.cinfo = tk->cinfo;
1212 ok = jp2_read_jp2h(&tk->jp2_struct, cio, &color);
1214 tk->jp2_struct.cinfo = NULL;
1216 if (ok == OPJ_FALSE) {
1217 opj_event_msg(tk->cinfo, EVT_ERROR, "Error reading JP2H Box\n");
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));
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) {
1233 if (mj2_read_fiel(tk, cio)) {
1239 if (mj2_read_jp2p(tk, cio)) {
1245 if (mj2_read_jp2x(tk, cio)) {
1251 if (mj2_read_jsub(tk, cio)) {
1257 if (mj2_read_orfo(tk, cio)) {
1263 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MJP2 Box size\n");
1274 * Write the STSD box
1276 * Sample Description
1279 void mj2_write_stsd(mj2_tk_t * tk, opj_cio_t *cio)
1283 box.init_pos = cio_tell(cio);
1285 cio_write(cio, MJ2_STSD, 4); /* STSD */
1287 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1290 4); /* entry_count = 1 (considering same JP2 headerboxes) */
1292 if (tk->track_type == 0) {
1293 mj2_write_smj2(tk, cio);
1294 } else if (tk->track_type == 1) {
1295 /* Not implemented*/
1297 if (tk->track_type == 2) {
1298 /* Not implemented*/
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);
1311 * Sample Description
1314 int mj2_read_stsd(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
1317 int entry_count, len_2skip;
1321 mj2_read_boxhdr(&box, cio);
1323 if (MJ2_STSD != box.type) {
1324 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STSD Marker\n");
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");
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");
1340 entry_count = cio_read(cio, 4);
1342 if (tk->track_type == 0) {
1343 for (i = 0; i < entry_count; i++) {
1344 if (mj2_read_smj2(img, tk, cio)) {
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);
1357 if (cio_tell(cio) - box.init_pos != box.length) {
1358 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STSD Box size\n");
1365 * Write the STBL box
1367 * Sample table box box
1370 void mj2_write_stbl(mj2_tk_t * tk, opj_cio_t *cio)
1374 box.init_pos = cio_tell(cio);
1376 cio_write(cio, MJ2_STBL, 4); /* STBL */
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);
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);
1393 * Sample table box box
1396 int mj2_read_stbl(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
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");
1406 if (mj2_read_stsd(tk, img, cio)) {
1409 if (mj2_read_stts(tk, cio)) {
1412 if (mj2_read_stsc(tk, cio)) {
1415 if (mj2_read_stsz(tk, cio)) {
1418 if (mj2_read_stco(tk, cio)) {
1422 if (cio_tell(cio) - box.init_pos != box.length) {
1423 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STBL Box size\n");
1435 void mj2_write_url(mj2_tk_t * tk, int url_num, opj_cio_t *cio)
1439 box.init_pos = cio_tell(cio);
1441 cio_write(cio, MJ2_URL, 4); /* URL */
1445 4); /* Version = 0, flags = 1 because stored in same file */
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);
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);
1466 int mj2_read_url(mj2_tk_t * tk, int urn_num, opj_cio_t *cio)
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");
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");
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);
1492 if (cio_tell(cio) - box.init_pos != box.length) {
1493 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with URL Box size\n");
1505 void mj2_write_urn(mj2_tk_t * tk, int urn_num, opj_cio_t *cio)
1509 box.init_pos = cio_tell(cio);
1511 cio_write(cio, MJ2_URN, 4); /* URN */
1513 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
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);
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);
1536 int mj2_read_urn(mj2_tk_t * tk, int urn_num, opj_cio_t *cio)
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");
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");
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);
1565 if (cio_tell(cio) - box.init_pos != box.length) {
1566 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with URN Box size\n");
1574 * Write the DREF box
1576 * Data reference box
1579 void mj2_write_dref(mj2_tk_t * tk, opj_cio_t *cio)
1584 box.init_pos = cio_tell(cio);
1586 cio_write(cio, MJ2_DREF, 4); /* DREF */
1588 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
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);
1594 cio_write(cio, tk->num_url + tk->num_urn, 4); /* entry_count */
1596 for (i = 0; i < tk->num_url; i++) {
1597 mj2_write_url(tk, i + 1, cio);
1600 for (i = 0; i < tk->num_urn; i++) {
1601 mj2_write_urn(tk, i, cio);
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);
1614 * Data reference box
1617 int mj2_read_dref(mj2_tk_t * tk, opj_cio_t *cio)
1621 int entry_count, marker;
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");
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");
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");
1642 entry_count = cio_read(cio, 4);
1646 for (i = 0; i < entry_count; i++) {
1648 marker = cio_read(cio, 4);
1649 if (marker == MJ2_URL) {
1652 if (mj2_read_url(tk, tk->num_url, cio)) {
1655 } else if (marker == MJ2_URN) {
1658 if (mj2_read_urn(tk, tk->num_urn, cio)) {
1662 opj_event_msg(cio->cinfo, EVT_ERROR,
1663 "Error with in DREF box. Expected URN or URL box\n");
1670 if (cio_tell(cio) - box.init_pos != box.length) {
1671 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with DREF Box size\n");
1678 * Write the DINF box
1680 * Data information box
1683 void mj2_write_dinf(mj2_tk_t * tk, opj_cio_t *cio)
1687 box.init_pos = cio_tell(cio);
1689 cio_write(cio, MJ2_DINF, 4); /* DINF */
1691 mj2_write_dref(tk, cio);
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);
1702 * Data information box
1705 int mj2_read_dinf(mj2_tk_t * tk, opj_cio_t *cio)
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");
1715 if (mj2_read_dref(tk, cio)) {
1719 if (cio_tell(cio) - box.init_pos != box.length) {
1720 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with DINF Box size\n");
1727 * Write the VMHD box
1729 * Video Media information box
1732 void mj2_write_vmhd(mj2_tk_t * tk, opj_cio_t *cio)
1736 box.init_pos = cio_tell(cio);
1738 cio_write(cio, MJ2_VMHD, 4); /* VMHD */
1740 cio_write(cio, 1, 4); /* Version = 0, flags = 1 */
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);
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);
1756 * Video Media information box
1759 int mj2_read_vmhd(mj2_tk_t * tk, opj_cio_t *cio)
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");
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");
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");
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);
1787 if (cio_tell(cio) - box.init_pos != box.length) {
1788 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with VMHD Box size\n");
1795 * Write the SMHD box
1797 * Sound Media information box
1800 void mj2_write_smhd(mj2_tk_t * tk, opj_cio_t *cio)
1804 box.init_pos = cio_tell(cio);
1806 cio_write(cio, MJ2_SMHD, 4); /* SMHD */
1808 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1810 cio_write(cio, tk->balance, 2);
1812 cio_write(cio, 0, 2); /* Reserved */
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);
1823 * Sound Media information box
1826 int mj2_read_smhd(mj2_tk_t * tk, opj_cio_t *cio)
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");
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");
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");
1849 tk->balance = cio_read(cio, 2);
1851 /* Init variables to zero to avoid problems when freeeing memory
1852 The values will possibly be overidded when decoding the track structure */
1858 tk->num_samplestochunk = 0;
1859 tk->num_samples = 0;
1861 cio_skip(cio, 2); /* Reserved */
1863 if (cio_tell(cio) - box.init_pos != box.length) {
1864 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with SMHD Box size\n");
1871 * Write the HMHD box
1873 * Hint Media information box
1876 void mj2_write_hmhd(mj2_tk_t * tk, opj_cio_t *cio)
1880 box.init_pos = cio_tell(cio);
1882 cio_write(cio, MJ2_HMHD, 4); /* HMHD */
1884 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
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);
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);
1901 * Hint Media information box
1904 int mj2_read_hmhd(mj2_tk_t * tk, opj_cio_t *cio)
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");
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");
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");
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);
1933 /* Init variables to zero to avoid problems when freeeing memory
1934 The values will possibly be overidded when decoding the track structure */
1940 tk->num_samplestochunk = 0;
1941 tk->num_samples = 0;
1944 if (cio_tell(cio) - box.init_pos != box.length) {
1945 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with HMHD Box size\n");
1952 * Write the MINF box
1954 * Media information box
1957 void mj2_write_minf(mj2_tk_t * tk, opj_cio_t *cio)
1961 box.init_pos = cio_tell(cio);
1963 cio_write(cio, MJ2_MINF, 4); /* MINF */
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);
1973 mj2_write_dinf(tk, cio);
1974 mj2_write_stbl(tk, cio);
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);
1985 * Media information box
1988 int mj2_read_minf(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
1991 unsigned int box_type;
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");
2001 box_type = cio_read(cio, 4);
2004 if (box_type == MJ2_VMHD) {
2005 if (mj2_read_vmhd(tk, cio)) {
2008 } else if (box_type == MJ2_SMHD) {
2009 if (mj2_read_smhd(tk, cio)) {
2012 } else if (box_type == MJ2_HMHD) {
2013 if (mj2_read_hmhd(tk, cio)) {
2017 opj_event_msg(cio->cinfo, EVT_ERROR,
2018 "Error in MINF box expected vmhd, smhd or hmhd\n");
2022 if (mj2_read_dinf(tk, cio)) {
2026 if (mj2_read_stbl(tk, img, cio)) {
2030 if (cio_tell(cio) - box.init_pos != box.length) {
2031 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MINF Box size\n");
2038 * Write the HDLR box
2040 * Handler reference box
2043 void mj2_write_hdlr(mj2_tk_t * tk, opj_cio_t *cio)
2047 box.init_pos = cio_tell(cio);
2049 cio_write(cio, MJ2_HDLR, 4); /* HDLR */
2051 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
2053 cio_write(cio, 0, 4); /* Predefine */
2056 0; /* The track name is immediately determined by the track type */
2058 if (tk->track_type == 0) {
2059 tk->handler_type = 0x76696465; /* Handler type: vide */
2060 cio_write(cio, tk->handler_type, 4);
2062 cio_write(cio, 0, 4);
2063 cio_write(cio, 0, 4);
2064 cio_write(cio, 0, 4); /* Reserved */
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);
2075 cio_write(cio, 0, 4);
2076 cio_write(cio, 0, 4);
2077 cio_write(cio, 0, 4); /* Reserved */
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);
2085 cio_write(cio, 0, 4);
2086 cio_write(cio, 0, 4);
2087 cio_write(cio, 0, 4); /* Reserved */
2089 cio_write(cio, 0x48696E74, 4);
2090 cio_write(cio, 0, 2); /* String: Hint */
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);
2102 * Handler reference box
2105 int mj2_read_hdlr(mj2_tk_t * tk, opj_cio_t *cio)
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");
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");
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");
2129 cio_skip(cio, 4); /* Reserved */
2131 tk->handler_type = cio_read(cio, 4);
2132 cio_skip(cio, 12); /* Reserved */
2134 tk->name_size = box.length - 32;
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 */
2141 if (cio_tell(cio) - box.init_pos != box.length) {
2142 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with HDLR Box size\n");
2149 * Write the MDHD box
2154 void mj2_write_mdhd(mj2_tk_t * tk, opj_cio_t *cio)
2159 unsigned int modification_time;
2161 box.init_pos = cio_tell(cio);
2163 cio_write(cio, MJ2_MDHD, 4); /* MDHD */
2165 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
2167 cio_write(cio, tk->creation_time, 4); /* Creation Time */
2169 time(<ime); /* Time since 1/1/70 */
2170 modification_time = (unsigned int)ltime +
2171 2082844800; /* Seoonds between 1/1/04 and 1/1/70 */
2173 cio_write(cio, modification_time, 4); /* Modification Time */
2175 cio_write(cio, tk->timescale, 4); /* Timescale */
2179 for (i = 0; i < tk->num_samples; i++) {
2180 tk->duration += tk->sample[i].sample_delta;
2183 cio_write(cio, tk->duration, 4); /* Duration */
2185 cio_write(cio, tk->language, 2); /* Language */
2187 cio_write(cio, 0, 2); /* Predefined */
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);
2201 int mj2_read_mdhd(mj2_tk_t * tk, opj_cio_t *cio)
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");
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");
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");
2225 tk->creation_time = cio_read(cio, 4); /* Creation Time */
2227 tk->modification_time = cio_read(cio, 4); /* Modification Time */
2229 tk->timescale = cio_read(cio, 4); /* Timescale */
2231 tk->duration = cio_read(cio, 4); /* Duration */
2233 tk->language = cio_read(cio, 2); /* Language */
2235 cio_skip(cio, 2); /* Predefined */
2237 if (cio_tell(cio) - box.init_pos != box.length) {
2238 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MDHD Box size\n");
2245 * Write the MDIA box
2250 void mj2_write_mdia(mj2_tk_t * tk, opj_cio_t *cio)
2254 box.init_pos = cio_tell(cio);
2256 cio_write(cio, MJ2_MDIA, 4); /* MDIA */
2258 mj2_write_mdhd(tk, cio);
2259 mj2_write_hdlr(tk, cio);
2260 mj2_write_minf(tk, cio);
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);
2274 int mj2_read_mdia(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
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");
2284 if (mj2_read_mdhd(tk, cio)) {
2287 if (mj2_read_hdlr(tk, cio)) {
2290 if (mj2_read_minf(tk, img, cio)) {
2294 if (cio_tell(cio) - box.init_pos != box.length) {
2295 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MDIA Box size\n");
2302 * Write the TKHD box
2307 void mj2_write_tkhd(mj2_tk_t * tk, opj_cio_t *cio)
2313 box.init_pos = cio_tell(cio);
2316 cio_write(cio, MJ2_TKHD, 4); /* TKHD */
2318 cio_write(cio, 3, 4); /* Version=0, flags=3 */
2320 time(<ime); /* Time since 1/1/70 */
2321 tk->modification_time = (unsigned int)ltime +
2322 2082844800; /* Seoonds between 1/1/04 and 1/1/70 */
2324 cio_write(cio, tk->creation_time, 4); /* Creation Time */
2326 cio_write(cio, tk->modification_time, 4); /* Modification Time */
2328 cio_write(cio, tk->track_ID, 4); /* Track ID */
2330 cio_write(cio, 0, 4); /* Reserved */
2334 for (i = 0; i < tk->num_samples; i++) {
2335 tk->duration += tk->sample[i].sample_delta;
2338 cio_write(cio, tk->duration, 4); /* Duration */
2340 cio_write(cio, 0, 4); /* Reserved */
2341 cio_write(cio, 0, 4); /* Reserved */
2343 cio_write(cio, tk->layer, 2); /* Layer */
2345 cio_write(cio, 0, 2); /* Predefined */
2347 cio_write(cio, tk->volume, 2); /* Volume */
2349 cio_write(cio, 0, 2); /* Reserved */
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);
2361 cio_write(cio, tk->visual_w, 4); /* Video Visual Width */
2363 cio_write(cio, tk->visual_h, 4); /* Video Visual Height */
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);
2377 int mj2_read_tkhd(mj2_tk_t * tk, opj_cio_t *cio)
2383 mj2_read_boxhdr(&box, cio);
2385 if (MJ2_TKHD != box.type) {
2386 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected TKHD Marker\n");
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");
2396 flag = cio_read(cio, 3);
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");
2405 tk->creation_time = cio_read(cio, 4); /* Creation Time */
2407 tk->modification_time = cio_read(cio, 4); /* Modification Time */
2409 tk->track_ID = cio_read(cio, 4); /* Track ID */
2411 cio_skip(cio, 4); /* Reserved */
2413 tk->duration = cio_read(cio, 4); /* Duration */
2415 cio_skip(cio, 8); /* Reserved */
2417 tk->layer = cio_read(cio, 2); /* Layer */
2419 cio_read(cio, 2); /* Predefined */
2421 tk->volume = cio_read(cio, 2); /* Volume */
2423 cio_skip(cio, 2); /* Reserved */
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);
2435 tk->visual_w = cio_read(cio, 4); /* Video Visual Width */
2437 tk->visual_h = cio_read(cio, 4); /* Video Visual Height */
2439 if (cio_tell(cio) - box.init_pos != box.length) {
2440 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with TKHD Box size\n");
2447 * Write the TRAK box
2452 void mj2_write_trak(mj2_tk_t * tk, opj_cio_t *cio)
2456 box.init_pos = cio_tell(cio);
2459 cio_write(cio, MJ2_TRAK, 4); /* TRAK */
2461 mj2_write_tkhd(tk, cio);
2462 mj2_write_mdia(tk, cio);
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);
2476 int mj2_read_trak(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
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");
2485 if (mj2_read_tkhd(tk, cio)) {
2488 if (mj2_read_mdia(tk, img, cio)) {
2491 if (cio_tell(cio) - box.init_pos != box.length) {
2492 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with TRAK Box\n");
2499 * Write the MVHD box
2504 void mj2_write_mvhd(opj_mj2_t * movie, opj_cio_t *cio)
2512 box.init_pos = cio_tell(cio);
2514 cio_write(cio, MJ2_MVHD, 4); /* MVHD */
2516 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
2518 time(<ime); /* Time since 1/1/70 */
2519 movie->modification_time = (unsigned int)ltime +
2520 2082844800; /* Seoonds between 1/1/04 and 1/1/70 */
2522 cio_write(cio, movie->creation_time, 4); /* Creation Time */
2524 cio_write(cio, movie->modification_time, 4); /* Modification Time */
2526 cio_write(cio, movie->timescale, 4); /* Timescale */
2528 movie->duration = 0;
2530 for (i = 0; i < (movie->num_stk + movie->num_htk + movie->num_vtk); i++) {
2531 mj2_tk_t *tk = &movie->tk[i];
2533 for (j = 0; j < tk->num_samples; j++) {
2534 movie->duration += tk->sample[j].sample_delta;
2538 cio_write(cio, movie->duration, 4);
2540 cio_write(cio, movie->rate, 4); /* Rate to play presentation */
2542 cio_write(cio, movie->volume, 2); /* Volume */
2544 cio_write(cio, 0, 2); /* Reserved */
2545 cio_write(cio, 0, 4); /* Reserved */
2546 cio_write(cio, 0, 4); /* Reserved */
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);
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 */
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;
2573 movie->next_tk_id = max_tk_num + 1;
2575 cio_write(cio, movie->next_tk_id, 4); /* ID of Next track to be added */
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);
2589 int mj2_read_mvhd(opj_mj2_t * movie, opj_cio_t *cio)
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");
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");
2605 movie->creation_time = cio_read(cio, 4); /* Creation Time */
2607 movie->modification_time = cio_read(cio, 4); /* Modification Time */
2609 movie->timescale = cio_read(cio, 4); /* Timescale */
2611 movie->duration = cio_read(cio, 4); /* Duration */
2613 movie->rate = cio_read(cio, 4); /* Rate to play presentation */
2615 movie->volume = cio_read(cio, 2); /* Volume */
2617 cio_skip(cio, 10); /* Reserved */
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);
2630 cio_skip(cio, 24); /* Pre-defined */
2632 movie->next_tk_id = cio_read(cio, 4); /* ID of Next track to be added */
2634 if (cio_tell(cio) - box.init_pos != box.length) {
2635 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MVHD Box Size\n");
2643 * Write the MOOV box
2648 void OPJ_CALLCONV mj2_write_moov(opj_mj2_t * movie, opj_cio_t *cio)
2653 box.init_pos = cio_tell(cio);
2655 cio_write(cio, MJ2_MOOV, 4); /* MOOV */
2657 mj2_write_mvhd(movie, cio);
2659 for (i = 0; i < (movie->num_stk + movie->num_htk + movie->num_vtk); i++) {
2660 mj2_write_trak(&movie->tk[i], cio);
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);
2675 int mj2_read_moov(opj_mj2_t * movie, opj_image_t * img, opj_cio_t *cio)
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");
2687 if (mj2_read_mvhd(movie, cio)) {
2691 movie->tk = (mj2_tk_t*) opj_malloc((movie->next_tk_id - 1) * sizeof(mj2_tk_t));
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)) {
2703 if (tk->track_type == 0) {
2705 } else if (tk->track_type == 1) {
2707 } else if (tk->track_type == 2) {
2710 } else if (box2.type == MJ2_MVEX) {
2711 cio_seek(cio, box2.init_pos);
2712 cio_skip(cio, box2.length);
2715 opj_event_msg(cio->cinfo, EVT_ERROR,
2716 "Error with MOOV Box: Expected TRAK or MVEX box\n");
2723 int OPJ_CALLCONV mj2_read_struct(FILE *file, opj_mj2_t *movie)
2727 unsigned char * src;
2732 /* open a byte stream for reading */
2733 src = (unsigned char*) opj_malloc(300 * sizeof(unsigned char));
2735 /* Assuming that jp and ftyp markers size do
2736 not exceed 300 bytes */
2737 fread(src, 300, 1, file);
2739 cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, 300);
2741 if (mj2_read_jp(cio)) {
2744 if (mj2_read_ftyp(movie, cio)) {
2748 fsresult = fseek(file, cio_tell(cio), SEEK_SET);
2750 opj_event_msg(cio->cinfo, EVT_ERROR,
2751 "End of file reached while trying to read data after FTYP box\n");
2755 foffset = cio_tell(cio);
2759 fread(src, 30, 1, file);
2760 cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, 300);
2761 mj2_read_boxhdr(&box, cio);
2763 while (box.type != MJ2_MOOV) {
2767 fsresult = fseek(file, foffset + box.length, SEEK_SET);
2769 opj_event_msg(cio->cinfo, EVT_ERROR,
2770 "End of file reached while trying to read MDAT box\n");
2773 foffset += box.length;
2777 fsresult = fseek(file, foffset + box.length, SEEK_SET);
2779 opj_event_msg(cio->cinfo, EVT_ERROR,
2780 "End of file reached while trying to read MOOF box\n");
2783 foffset += box.length;
2786 fsresult = fseek(file, foffset + box.length, SEEK_SET);
2788 opj_event_msg(cio->cinfo, EVT_ERROR,
2789 "End of file reached while trying to read FREE box\n");
2792 foffset += box.length;
2795 fsresult = fseek(file, foffset + box.length, SEEK_SET);
2797 opj_event_msg(cio->cinfo, EVT_ERROR,
2798 "End of file reached while trying to read SKIP box\n");
2801 foffset += box.length;
2804 opj_event_msg(cio->cinfo, EVT_ERROR, "Unknown box in MJ2 stream\n");
2805 fsresult = fseek(file, foffset + box.length, SEEK_SET);
2807 opj_event_msg(cio->cinfo, EVT_ERROR,
2808 "End of file reached while trying to read end of unknown box\n");
2811 foffset += box.length;
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");
2819 cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, 8);
2820 mj2_read_boxhdr(&box, cio);
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");
2832 cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, box.length);
2834 if (mj2_read_moov(movie, &img, cio)) {
2842 /* ----------------------------------------------------------------------- */
2843 /* MJ2 decoder interface */
2844 /* ----------------------------------------------------------------------- */
2846 opj_dinfo_t* OPJ_CALLCONV mj2_create_decompress()
2849 opj_dinfo_t *dinfo = (opj_dinfo_t*) opj_calloc(1, sizeof(opj_dinfo_t));
2854 dinfo->is_decompressor = OPJ_TRUE;
2856 mj2 = (opj_mj2_t*) opj_calloc(1, sizeof(opj_mj2_t));
2857 dinfo->mj2_handle = mj2;
2859 mj2->cinfo = (opj_common_ptr)dinfo;
2861 mj2->j2k = j2k_create_decompress((opj_common_ptr)dinfo);
2862 dinfo->j2k_handle = mj2->j2k;
2867 void OPJ_CALLCONV mj2_setup_decoder(opj_mj2_t *movie,
2868 mj2_dparameters_t *mj2_parameters)
2874 /* setup the J2K decoder parameters */
2875 j2k_setup_decoder((opj_j2k_t*)movie->cinfo->j2k_handle,
2876 &mj2_parameters->j2k_parameters);
2880 void OPJ_CALLCONV mj2_destroy_decompress(opj_mj2_t *movie)
2884 mj2_tk_t *tk = NULL;
2886 if (movie->cinfo->j2k_handle) {
2887 j2k_destroy_compress(movie->j2k);
2890 if (movie->num_cl != 0) {
2891 opj_free(movie->cl);
2894 for (i = 0; i < movie->num_vtk + movie->num_stk + movie->num_htk; i++) {
2896 if (tk->name_size != 0) {
2899 if (tk->track_type == 0) {/* Video track*/
2900 if (tk->jp2_struct.comps != NULL) {
2901 opj_free(tk->jp2_struct.comps);
2903 if (tk->jp2_struct.cl != NULL) {
2904 opj_free(tk->jp2_struct.cl);
2906 if (tk->num_jp2x != 0) {
2907 opj_free(tk->jp2xdata);
2911 if (tk->num_url != 0) {
2914 if (tk->num_urn != 0) {
2917 if (tk->num_br != 0) {
2920 if (tk->num_tts != 0) {
2923 if (tk->num_chunks != 0) {
2924 opj_free(tk->chunk);
2926 if (tk->num_samplestochunk != 0) {
2927 opj_free(tk->sampletochunk);
2929 if (tk->num_samples != 0) {
2930 opj_free(tk->sample);
2934 opj_free(movie->tk);
2939 /* ----------------------------------------------------------------------- */
2940 /* MJ2 encoder interface */
2941 /* ----------------------------------------------------------------------- */
2943 opj_cinfo_t* OPJ_CALLCONV mj2_create_compress()
2946 opj_cinfo_t *cinfo = (opj_cinfo_t*) opj_calloc(1, sizeof(opj_cinfo_t));
2951 mj2 = (opj_mj2_t*) opj_calloc(1, sizeof(opj_mj2_t));
2952 cinfo->mj2_handle = mj2;
2954 mj2->cinfo = (opj_common_ptr)cinfo;
2957 mj2->j2k = j2k_create_compress(mj2->cinfo);
2958 cinfo->j2k_handle = mj2->j2k;
2963 void OPJ_CALLCONV mj2_setup_encoder(opj_mj2_t *movie,
2964 mj2_cparameters_t *parameters)
2966 if (movie && parameters) {
2967 opj_jp2_t *jp2_struct;
2969 movie->num_htk = 0; /* No hint tracks*/
2970 movie->num_stk = 0; /* No sound tracks*/
2971 movie->num_vtk = 1; /* One video track*/
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 */
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;
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(
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(
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;
3019 void OPJ_CALLCONV mj2_destroy_compress(opj_mj2_t *movie)
3023 mj2_tk_t *tk = NULL;
3025 if (movie->cinfo->j2k_handle) {
3026 j2k_destroy_compress(movie->j2k);
3029 if (movie->num_cl != 0) {
3030 opj_free(movie->cl);
3033 for (i = 0; i < movie->num_vtk + movie->num_stk + movie->num_htk; i++) {
3035 if (tk->name_size != 0) {
3038 if (tk->track_type == 0) {/* Video track*/
3039 if (tk->jp2_struct.comps != NULL) {
3040 opj_free(tk->jp2_struct.comps);
3042 if (tk->jp2_struct.cl != NULL) {
3043 opj_free(tk->jp2_struct.cl);
3045 if (tk->num_jp2x != 0) {
3046 opj_free(tk->jp2xdata);
3050 if (tk->num_url != 0) {
3053 if (tk->num_urn != 0) {
3056 if (tk->num_br != 0) {
3059 if (tk->num_tts != 0) {
3062 if (tk->num_chunks != 0) {
3063 opj_free(tk->chunk);
3065 if (tk->num_samplestochunk != 0) {
3066 opj_free(tk->sampletochunk);
3068 if (tk->num_samples != 0) {
3069 opj_free(tk->sample);
3073 opj_free(movie->tk);