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, "Error: Cannot handle box sizes higher than 2^32\n");
59 box->length = cio_read(cio, 4);
61 box->length = cio_numbytesleft(cio) + 12;
63 else if (box->length == 0) {
64 box->length = cio_numbytesleft(cio) + 8;
71 * Initialisation of a Standard Movie, given a simple movie structure defined by the user
72 * The movie will have one sample per chunk
74 * Arguments: opj_mj2_t * movie
75 * Several variables of "movie" must be defined in order to enable a correct execution of
77 * - The number of tracks of each type (movie->num_vtk, movie->num_stk, movie->num_htk)
78 * - The memory for each must be allocated (movie->tk)
80 * The track type (tk->track_type)
81 * The number of sample (tk->num_samples)
82 * The sample rate (tk->sample_rate)
86 int OPJ_CALLCONV mj2_init_stdmovie(opj_mj2_t * movie)
93 movie->brand = MJ2_MJ2;
94 movie->minversion = 0;
96 movie->cl = (unsigned int*) opj_malloc(movie->num_cl * sizeof(unsigned int));
98 movie->cl[0] = MJ2_MJ2;
99 movie->cl[1] = MJ2_MJ2S;
100 time(<ime); /* Time since 1/1/70 */
101 movie->creation_time = (unsigned int) ltime + 2082844800; /* Seconds between 1/1/04 and 1/1/70 */
102 movie->timescale = 1000;
104 movie->rate = 1 << 16; /* Rate to play presentation (default = 0x00010000) */
105 movie->volume = 1 << 8; /* Movie volume (default = 0x0100) */
106 movie->trans_matrix[0] = 0x00010000; /* Transformation matrix for video */
107 movie->trans_matrix[1] = 0; /* Unity is { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 } */
108 movie->trans_matrix[2] = 0;
109 movie->trans_matrix[3] = 0;
110 movie->trans_matrix[4] = 0x00010000;
111 movie->trans_matrix[5] = 0;
112 movie->trans_matrix[6] = 0;
113 movie->trans_matrix[7] = 0;
114 movie->trans_matrix[8] = 0x40000000;
115 movie->next_tk_id = 1;
118 w = tk0->w; h = tk0->h; prec = tk0->depth;
120 for (i = 0; i < movie->num_htk + movie->num_stk + movie->num_vtk; i++)
122 mj2_tk_t *tk = &movie->tk[i];
125 tk->jp2_struct.comps = NULL;
126 tk->jp2_struct.cl = NULL;
128 if (tk->track_type == 0) /* no sound or hint track */
130 if (tk->num_samples == 0)
133 tk->w = w; tk->h = h; tk->depth = prec;
137 tk->timescale = 1000; /* Timescale = 1 ms */
139 tk->chunk[0].num_samples = 1;
140 tk->chunk[0].sample_descr_idx = 1;
142 tk->same_sample_size = 0;
144 tk->num_samplestochunk = 1; /* One sample per chunk */
145 tk->sampletochunk = (mj2_sampletochunk_t*) opj_malloc(tk->num_samplestochunk * sizeof(mj2_sampletochunk_t));
146 tk->sampletochunk[0].first_chunk = 1;
147 tk->sampletochunk[0].samples_per_chunk = 1;
148 tk->sampletochunk[0].sample_descr_idx = 1;
150 if (tk->sample_rate == 0)
152 opj_event_msg(tk->cinfo, EVT_ERROR,
153 "Error while initializing MJ2 movie: Sample rate of track"
154 " %d must be different from zero\n", tk->track_ID);
158 for (j = 0; j < tk->num_samples; j++)
160 tk->sample[j].sample_delta = tk->timescale / tk->sample_rate;
164 tk->tts = (mj2_tts_t*) opj_malloc(tk->num_tts * sizeof(mj2_tts_t));
165 tk->tts[0].sample_count = tk->num_samples;
166 tk->tts[0].sample_delta = tk->timescale / tk->sample_rate;
168 tk->horizresolution = 0x00480000; /* Horizontal resolution (typically 72) */
169 tk->vertresolution = 0x00480000; /* Vertical resolution (typically 72) */
170 tk->compressorname[0] = 0x0f4d6f74; /* Compressor Name[]: Motion JPEG2000 */
171 tk->compressorname[1] = 0x696f6e20;
172 tk->compressorname[2] = 0x4a504547;
173 tk->compressorname[3] = 0x32303030;
174 tk->compressorname[4] = 0x00120000;
175 tk->compressorname[5] = 0;
176 tk->compressorname[6] = 0x00000042;
177 tk->compressorname[7] = 0x000000DC;
178 tk->num_url = 0; /* Number of URL */
179 tk->num_urn = 0; /* Number of URN */
180 tk->graphicsmode = 0; /* Graphicsmode */
181 tk->opcolor[0] = 0; /* OpColor */
182 tk->opcolor[1] = 0; /* OpColor */
183 tk->opcolor[2] = 0; /* OpColor */
184 tk->creation_time = movie->creation_time; /* Seconds between 1/1/04 and 1/1/70 */
185 tk->language = 0; /* Language (undefined) */
187 tk->volume = 1 << 8; /* Movie volume (default = 0x0100) */
188 tk->trans_matrix[0] = 0x00010000; /* Transformation matrix for track */
189 tk->trans_matrix[1] = 0; /* Unity is { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 } */
190 tk->trans_matrix[2] = 0;
191 tk->trans_matrix[3] = 0;
192 tk->trans_matrix[4] = 0x00010000;
193 tk->trans_matrix[5] = 0;
194 tk->trans_matrix[6] = 0;
195 tk->trans_matrix[7] = 0;
196 tk->trans_matrix[8] = 0x40000000;
199 tk->or_fieldcount = 1;
200 tk->or_fieldorder = 0;
202 tk->br = (unsigned int*) opj_malloc(tk->num_br * sizeof(unsigned int));
204 tk->br[1] = MJ2_J2P0;
206 tk->hsub = 2; /* 4:2:0 */
207 tk->vsub = 2; /* 4:2:0 */
210 tk->visual_w = tk->w << 16;
211 tk->visual_h = tk->h << 16;
222 * Time To Sample box Decompact
225 void mj2_tts_decompact(mj2_tk_t * tk)
229 for (i = 0; i < tk->num_tts; i++) {
230 tk->num_samples += tk->tts[i].sample_count;
233 tk->sample = (mj2_sample_t*) opj_malloc(tk->num_samples * sizeof(mj2_sample_t));
235 for (i = 0; i < tk->num_tts; i++) {
236 for (j = 0; j < tk->tts[i].sample_count; j++) {
237 tk->sample[j].sample_delta = tk->tts[i].sample_delta;
243 * Sample To Chunk box Decompact
246 void mj2_stsc_decompact(mj2_tk_t * tk)
248 unsigned int i, j, k, sampleno = 0;
250 if (tk->num_samplestochunk == 1) {
252 (unsigned int) ceil((double) tk->num_samples /
253 (double) tk->sampletochunk[0].samples_per_chunk);
254 tk->chunk = (mj2_chunk_t*) opj_malloc(tk->num_chunks * sizeof(mj2_chunk_t));
255 for (k = 0; k < tk->num_chunks; k++) {
256 tk->chunk[k].num_samples = tk->sampletochunk[0].samples_per_chunk;
260 tk->chunk = (mj2_chunk_t*) opj_malloc(tk->num_samples * sizeof(mj2_chunk_t));
262 for (i = 0; i < tk->num_samplestochunk -1 ; i++) {
263 for (j = tk->sampletochunk[i].first_chunk - 1;
264 j < tk->sampletochunk[i + 1].first_chunk - 1; j++) {
265 tk->chunk[j].num_samples = tk->sampletochunk[i].samples_per_chunk;
267 sampleno += tk->chunk[j].num_samples;
270 tk->num_chunks += (int)(tk->num_samples - sampleno) / tk->sampletochunk[tk->num_samplestochunk - 1].samples_per_chunk;
271 for (k = tk->sampletochunk[tk->num_samplestochunk - 1].first_chunk - 1;
272 k < tk->num_chunks; k++) {
273 tk->chunk[k].num_samples =
274 tk->sampletochunk[tk->num_samplestochunk - 1].samples_per_chunk;
276 tk->chunk = (mj2_chunk_t*)
277 opj_realloc(tk->chunk, tk->num_chunks * sizeof(mj2_chunk_t));
284 * Chunk offset box Decompact
287 void mj2_stco_decompact(mj2_tk_t * tk)
289 unsigned int i, j, k = 0;
290 unsigned int intra_chunk_offset;
292 for (i = 0; i < tk->num_chunks; i++) {
293 intra_chunk_offset = 0;
294 for (j = 0; j < tk->chunk[i].num_samples; j++) {
295 tk->sample[k].offset = intra_chunk_offset + tk->chunk[i].offset;
296 intra_chunk_offset += tk->sample[k].sample_size;
308 void OPJ_CALLCONV mj2_write_jp(opj_cio_t *cio)
311 box.init_pos = cio_tell(cio);
314 cio_write(cio, MJ2_JP, 4); /* JP */
315 cio_write(cio, 0x0d0a870a, 4); /* 0x0d0a870a required in a JP box */
317 box.length = cio_tell(cio) - box.init_pos;
318 cio_seek(cio, box.init_pos);
319 cio_write(cio, box.length, 4);
320 cio_seek(cio, box.init_pos + box.length);
326 * JPEG 2000 signature
329 int mj2_read_jp(opj_cio_t *cio)
333 mj2_read_boxhdr(&box, cio);
334 if (MJ2_JP != box.type) { /* Check Marker */
335 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected JP Marker\n");
338 if (0x0d0a870a != cio_read(cio, 4)) { /* read the 0x0d0a870a required in a JP box */
339 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JP Marker\n");
342 if (cio_tell(cio) - box.init_pos != box.length) { /* Check box length */
343 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JP Box size \n");
356 void OPJ_CALLCONV mj2_write_ftyp(opj_mj2_t * movie, opj_cio_t *cio)
360 box.init_pos = cio_tell(cio);
363 cio_write(cio, MJ2_FTYP, 4); /* FTYP */
364 cio_write(cio, movie->brand, 4); /* BR */
365 cio_write(cio, movie->minversion, 4); /* MinV */
367 for (i = 0; i < movie->num_cl; i++)
368 cio_write(cio, movie->cl[i], 4); /* CL */
370 box.length = cio_tell(cio) - box.init_pos;
371 cio_seek(cio, box.init_pos);
372 cio_write(cio, box.length, 4); /* Length */
373 cio_seek(cio, box.init_pos + box.length);
382 int mj2_read_ftyp(opj_mj2_t * movie, opj_cio_t *cio)
387 mj2_read_boxhdr(&box, cio); /* Box Size */
388 if (MJ2_FTYP != box.type) {
389 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected FTYP Marker\n");
393 movie->brand = cio_read(cio, 4); /* BR */
394 movie->minversion = cio_read(cio, 4); /* MinV */
395 movie->num_cl = (box.length - 16) / 4;
396 movie->cl = (unsigned int*) opj_malloc(movie->num_cl * sizeof(unsigned int));
398 for (i = movie->num_cl - 1; i > -1; i--)
399 movie->cl[i] = cio_read(cio, 4); /* CLi */
401 if (cio_tell(cio) - box.init_pos != box.length) {
402 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with FTYP Box\n");
415 void mj2_write_stco(mj2_tk_t * tk, opj_cio_t *cio)
420 box.init_pos = cio_tell(cio);
422 cio_write(cio, MJ2_STCO, 4); /* STCO */
424 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
426 cio_write(cio, tk->num_chunks, 4); /* Entry Count */
428 for (i = 0; i < tk->num_chunks; i++) {
429 cio_write(cio, tk->chunk[i].offset, 4); /* Entry offset */
432 box.length = cio_tell(cio) - box.init_pos;
433 cio_seek(cio, box.init_pos);
434 cio_write(cio, box.length, 4); /* L */
435 cio_seek(cio, box.init_pos + box.length);
444 int mj2_read_stco(mj2_tk_t * tk, opj_cio_t *cio)
449 mj2_read_boxhdr(&box, cio); /* Box Size */
450 if (MJ2_STCO != box.type) {
451 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STCO Marker\n");
455 if (0 != cio_read(cio, 1)) { /* Version = 0 */
456 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in STCO box\n");
460 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
461 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in STCO box. Expected flag 0\n");
466 if (cio_read(cio, 4) != tk->num_chunks) {
467 opj_event_msg(cio->cinfo, EVT_ERROR,
468 "Error in STCO box: expecting same amount of entry-count as chunks \n");
470 for (i = 0; i < tk->num_chunks; i++) {
471 tk->chunk[i].offset = cio_read(cio, 4); /* Entry offset */
475 mj2_stco_decompact(tk);
478 if (cio_tell(cio) - box.init_pos != box.length) {
479 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STCO Box size\n");
491 void mj2_write_stsz(mj2_tk_t * tk, opj_cio_t *cio)
496 box.init_pos = cio_tell(cio);
498 cio_write(cio, MJ2_STSZ, 4); /* STSZ */
500 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
502 if (tk->same_sample_size == 1) { /* If they all have the same size */
503 cio_write(cio, tk->sample[0].sample_size, 4); /* Size */
505 cio_write(cio, 1, 4); /* Entry count = 1 */
509 cio_write(cio, 0, 4); /* Sample Size = 0 becase they all have different sizes */
511 cio_write(cio, tk->num_samples, 4); /* Sample Count */
513 for (i = 0; i < tk->num_samples; i++) {
514 cio_write(cio, tk->sample[i].sample_size, 4);
518 box.length = cio_tell(cio) - box.init_pos;
519 cio_seek(cio, box.init_pos);
520 cio_write(cio, box.length, 4); /* L */
521 cio_seek(cio, box.init_pos + box.length);
530 int mj2_read_stsz(mj2_tk_t * tk, opj_cio_t *cio)
536 mj2_read_boxhdr(&box, cio); /* Box Size */
537 if (MJ2_STSZ != box.type) {
538 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STSZ Marker\n");
543 if (0 != cio_read(cio, 1)) { /* Version = 0 */
544 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in STSZ box\n");
548 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
549 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in STSZ box. Expected flag 0\n");
553 sample_size = cio_read(cio, 4);
555 if (sample_size != 0) { /* Samples do have the same size */
556 tk->same_sample_size = 1;
557 for (i = 0; i < tk->num_samples; i++) {
558 tk->sample[i].sample_size = sample_size;
560 cio_skip(cio,4); /* Sample count = 1 */
562 tk->same_sample_size = 0;
563 if (tk->num_samples != cio_read(cio, 4)) { /* Sample count */
564 opj_event_msg(cio->cinfo, EVT_ERROR,
565 "Error in STSZ box. Expected that sample-count is number of samples in track\n");
568 for (i = 0; i < tk->num_samples; i++) {
569 tk->sample[i].sample_size = cio_read(cio, 4); /* Sample Size */
572 if (cio_tell(cio) - box.init_pos != box.length) {
573 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STSZ Box size\n");
587 void mj2_write_stsc(mj2_tk_t * tk, opj_cio_t *cio)
592 box.init_pos = cio_tell(cio);
594 cio_write(cio, MJ2_STSC, 4); /* STSC */
596 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
598 cio_write(cio, tk->num_samplestochunk, 4); /* Entry Count */
600 for (i = 0; i < tk->num_samplestochunk; i++) {
601 cio_write(cio, tk->sampletochunk[i].first_chunk, 4); /* First Chunk */
602 cio_write(cio, tk->sampletochunk[i].samples_per_chunk, 4); /* Samples per chunk */
603 cio_write(cio, tk->sampletochunk[i].sample_descr_idx, 4); /* Samples description index */
607 box.length = cio_tell(cio) - box.init_pos;
608 cio_seek(cio, box.init_pos);
609 cio_write(cio, box.length, 4); /* L */
610 cio_seek(cio, box.init_pos + box.length);
619 int mj2_read_stsc(mj2_tk_t * tk, opj_cio_t *cio)
624 mj2_read_boxhdr(&box, cio); /* Box Size */
625 if (MJ2_STSC != box.type) {
626 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STSC Marker\n");
631 if (0 != cio_read(cio, 1)) { /* Version = 0 */
632 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in STSC box\n");
636 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
637 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in STSC box. Expected flag 0\n");
641 tk->num_samplestochunk = cio_read(cio, 4);
643 tk->sampletochunk = (mj2_sampletochunk_t*) opj_malloc(tk->num_samplestochunk * sizeof(mj2_sampletochunk_t));
645 for (i = 0; i < tk->num_samplestochunk; i++) {
646 tk->sampletochunk[i].first_chunk = cio_read(cio, 4);
647 tk->sampletochunk[i].samples_per_chunk = cio_read(cio, 4);
648 tk->sampletochunk[i].sample_descr_idx = cio_read(cio, 4);
651 mj2_stsc_decompact(tk); /* decompact sample to chunk box */
654 if (cio_tell(cio) - box.init_pos != box.length) {
655 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STSC Box size\n");
667 void mj2_write_stts(mj2_tk_t * tk, opj_cio_t *cio)
673 box.init_pos = cio_tell(cio);
675 cio_write(cio, MJ2_STTS, 4); /* STTS */
677 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
679 cio_write(cio, tk->num_tts, 4); /* entry_count */
680 for (i = 0; i < tk->num_tts; i++) {
681 cio_write(cio, tk->tts[i].sample_count, 4); /* Sample-count */
682 cio_write(cio, tk->tts[i].sample_delta, 4); /* Sample-Delta */
685 box.length = cio_tell(cio) - box.init_pos;
686 cio_seek(cio, box.init_pos);
687 cio_write(cio, box.length, 4); /* L */
688 cio_seek(cio, box.init_pos + box.length);
697 int mj2_read_stts(mj2_tk_t * tk, opj_cio_t *cio)
703 mj2_read_boxhdr(&box, cio);
704 if (MJ2_STTS != box.type) {
705 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STTS Marker\n");
710 if (0 != cio_read(cio, 1)) { /* Version = 0 */
711 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in STTS box\n");
715 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
716 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in STTS box. Expected flag 0\n");
720 tk->num_tts = cio_read(cio, 4);
722 tk->tts = (mj2_tts_t*) opj_malloc(tk->num_tts * sizeof(mj2_tts_t));
724 for (i = 0; i < tk->num_tts; i++) {
725 tk->tts[i].sample_count = cio_read(cio, 4);
726 tk->tts[i].sample_delta = cio_read(cio, 4);
729 mj2_tts_decompact(tk);
731 if (cio_tell(cio) - box.init_pos != box.length) {
732 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STTS Box size\n");
744 void mj2_write_fiel(mj2_tk_t * tk, opj_cio_t *cio)
749 box.init_pos = cio_tell(cio);
751 cio_write(cio, MJ2_FIEL, 4); /* STTS */
753 cio_write(cio, tk->fieldcount, 1); /* Field count */
754 cio_write(cio, tk->fieldorder, 1); /* Field order */
757 box.length = cio_tell(cio) - box.init_pos;
758 cio_seek(cio, box.init_pos);
759 cio_write(cio, box.length, 4); /* L */
760 cio_seek(cio, box.init_pos + box.length);
769 int mj2_read_fiel(mj2_tk_t * tk, opj_cio_t *cio)
774 mj2_read_boxhdr(&box, cio);
775 if (MJ2_FIEL != box.type) {
776 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected FIEL Marker\n");
781 tk->fieldcount = cio_read(cio, 1);
782 tk->fieldorder = cio_read(cio, 1);
784 if (cio_tell(cio) - box.init_pos != box.length) {
785 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with FIEL Box size\n");
794 * Original Format Box
797 void mj2_write_orfo(mj2_tk_t * tk, opj_cio_t *cio)
801 box.init_pos = cio_tell(cio);
803 cio_write(cio, MJ2_ORFO, 4);
805 cio_write(cio, tk->or_fieldcount, 1); /* Original Field count */
806 cio_write(cio, tk->or_fieldorder, 1); /* Original Field order */
809 box.length = cio_tell(cio) - box.init_pos;
810 cio_seek(cio, box.init_pos);
811 cio_write(cio, box.length, 4); /* L */
812 cio_seek(cio, box.init_pos + box.length);
818 * Original Format Box
821 int mj2_read_orfo(mj2_tk_t * tk, opj_cio_t *cio)
826 mj2_read_boxhdr(&box, cio);
827 if (MJ2_ORFO != box.type) {
828 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected ORFO Marker\n");
833 tk->or_fieldcount = cio_read(cio, 1);
834 tk->or_fieldorder = cio_read(cio, 1);
836 if (cio_tell(cio) - box.init_pos != box.length) {
837 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with ORFO Box size\n");
849 void mj2_write_jp2p(mj2_tk_t * tk, opj_cio_t *cio)
855 box.init_pos = cio_tell(cio);
857 cio_write(cio, MJ2_JP2P, 4);
859 cio_write(cio, 0, 4); /* Version 0, flags =0 */
861 for (i = 0; i < tk->num_br; i++) {
862 cio_write(cio, tk->br[i], 4);
865 box.length = cio_tell(cio) - box.init_pos;
866 cio_seek(cio, box.init_pos);
867 cio_write(cio, box.length, 4); /* L */
868 cio_seek(cio, box.init_pos + box.length);
877 int mj2_read_jp2p(mj2_tk_t * tk, opj_cio_t *cio)
883 mj2_read_boxhdr(&box, cio);
884 if (MJ2_JP2P != box.type) {
885 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected JP2P Marker\n");
889 if (0 != cio_read(cio, 1)) { /* Version = 0 */
890 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in JP2P box\n");
894 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
895 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in JP2P box. Expected flag 0\n");
900 tk->num_br = (box.length - 12) / 4;
901 tk->br = (unsigned int*) opj_malloc(tk->num_br * sizeof(unsigned int));
903 for (i = 0; i < tk->num_br; i++) {
904 tk->br[i] = cio_read(cio, 4);
907 if (cio_tell(cio) - box.init_pos != box.length) {
908 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JP2P Box size\n");
920 void mj2_write_jp2x(mj2_tk_t * tk, opj_cio_t *cio)
926 box.init_pos = cio_tell(cio);
928 cio_write(cio, MJ2_JP2X, 4);
930 for (i = 0; i < tk->num_jp2x; i++) {
931 cio_write(cio, tk->jp2xdata[i], 1);
934 box.length = cio_tell(cio) - box.init_pos;
935 cio_seek(cio, box.init_pos);
936 cio_write(cio, box.length, 4); /* L */
937 cio_seek(cio, box.init_pos + box.length);
946 int mj2_read_jp2x(mj2_tk_t * tk, opj_cio_t *cio)
952 mj2_read_boxhdr(&box, cio);
953 if (MJ2_JP2X != box.type) {
954 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected JP2X Marker\n");
959 tk->num_jp2x = (box.length - 8);
960 tk->jp2xdata = (unsigned char*) opj_malloc(tk->num_jp2x * sizeof(unsigned char));
962 for (i = 0; i < tk->num_jp2x; i++) {
963 tk->jp2xdata[i] = cio_read(cio, 1);
966 if (cio_tell(cio) - box.init_pos != box.length) {
967 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JP2X Box size\n");
976 * MJP2 Subsampling Box
979 void mj2_write_jsub(mj2_tk_t * tk, opj_cio_t *cio)
984 box.init_pos = cio_tell(cio);
986 cio_write(cio, MJ2_JSUB, 4);
988 cio_write(cio, tk->hsub, 1);
989 cio_write(cio, tk->vsub, 1);
990 cio_write(cio, tk->hoff, 1);
991 cio_write(cio, tk->voff, 1);
993 box.length = cio_tell(cio) - box.init_pos;
994 cio_seek(cio, box.init_pos);
995 cio_write(cio, box.length, 4); /* L */
996 cio_seek(cio, box.init_pos + box.length);
1002 * MJP2 Subsampling Box
1005 int mj2_read_jsub(mj2_tk_t * tk, opj_cio_t *cio)
1009 mj2_read_boxhdr(&box, cio);
1010 if (MJ2_JSUB != box.type) {
1011 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected JSUB Marker\n");
1015 tk->hsub = cio_read(cio, 1);
1016 tk->vsub = cio_read(cio, 1);
1017 tk->hoff = cio_read(cio, 1);;
1018 tk->voff = cio_read(cio, 1);
1020 if (cio_tell(cio) - box.init_pos != box.length) {
1021 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with JSUB Box size\n");
1028 * Write the SMJ2 box
1030 * Visual Sample Entry Description
1033 void mj2_write_smj2(mj2_tk_t * tk, opj_cio_t *cio)
1037 box.init_pos = cio_tell(cio);
1039 cio_write(cio, MJ2_MJ2, 4); /* MJ2 */
1041 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1043 cio_write(cio, 1, 4);
1045 cio_write(cio, 0, 2); /* Pre-defined */
1047 cio_write(cio, 0, 2); /* Reserved */
1049 cio_write(cio, 0, 4); /* Pre-defined */
1050 cio_write(cio, 0, 4); /* Pre-defined */
1051 cio_write(cio, 0, 4); /* Pre-defined */
1053 cio_write(cio, tk->w, 2); /* Width */
1054 cio_write(cio, tk->h, 2); /* Height */
1056 cio_write(cio, tk->horizresolution, 4); /* Horizontal resolution */
1057 cio_write(cio, tk->vertresolution, 4); /* Vertical resolution */
1059 cio_write(cio, 0, 4); /* Reserved */
1061 cio_write(cio, 1, 2); /* Pre-defined = 1 */
1063 cio_write(cio, tk->compressorname[0], 4); /* Compressor Name */
1064 cio_write(cio, tk->compressorname[1], 4);
1065 cio_write(cio, tk->compressorname[2], 4);
1066 cio_write(cio, tk->compressorname[3], 4);
1067 cio_write(cio, tk->compressorname[4], 4);
1068 cio_write(cio, tk->compressorname[5], 4);
1069 cio_write(cio, tk->compressorname[6], 4);
1070 cio_write(cio, tk->compressorname[7], 4);
1072 cio_write(cio, tk->depth, 2); /* Depth */
1074 cio_write(cio, 0xffff, 2); /* Pre-defined = -1 */
1076 jp2_write_jp2h(&tk->jp2_struct, cio);
1078 mj2_write_fiel(tk, cio);
1080 if (tk->num_br != 0)
1081 mj2_write_jp2p(tk, cio);
1082 if (tk->num_jp2x != 0)
1083 mj2_write_jp2x(tk, cio);
1085 mj2_write_jsub(tk, cio);
1086 mj2_write_orfo(tk, cio);
1088 box.length = cio_tell(cio) - box.init_pos;
1089 cio_seek(cio, box.init_pos);
1090 cio_write(cio, box.length, 4); /* L */
1091 cio_seek(cio, box.init_pos + box.length);
1097 * Visual Sample Entry Description
1100 int mj2_read_smj2(opj_image_t * img, mj2_tk_t * tk, opj_cio_t *cio)
1104 opj_jp2_color_t color;
1108 mj2_read_boxhdr(&box, cio);
1110 if (MJ2_MJ2 != box.type) {
1111 opj_event_msg(cio->cinfo, EVT_ERROR, "Error in SMJ2 box: Expected MJ2 Marker\n");
1115 if (0 != cio_read(cio, 1)) { /* Version = 0 */
1116 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in MJP2 box\n");
1120 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
1121 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in MJP2 box. Expected flag 0\n");
1127 cio_skip(cio,2); /* Pre-defined */
1129 cio_skip(cio,2); /* Reserved */
1131 cio_skip(cio,4); /* Pre-defined */
1132 cio_skip(cio,4); /* Pre-defined */
1133 cio_skip(cio,4); /* Pre-defined */
1135 tk->w = cio_read(cio, 2); /* Width */
1136 tk->h = cio_read(cio, 2); /* Height */
1138 tk->horizresolution = cio_read(cio, 4); /* Horizontal resolution */
1139 tk->vertresolution = cio_read(cio, 4); /* Vertical resolution */
1141 cio_skip(cio,4); /* Reserved */
1143 cio_skip(cio,2); /* Pre-defined = 1 */
1145 tk->compressorname[0] = cio_read(cio, 4); /* Compressor Name */
1146 tk->compressorname[1] = cio_read(cio, 4);
1147 tk->compressorname[2] = cio_read(cio, 4);
1148 tk->compressorname[3] = cio_read(cio, 4);
1149 tk->compressorname[4] = cio_read(cio, 4);
1150 tk->compressorname[5] = cio_read(cio, 4);
1151 tk->compressorname[6] = cio_read(cio, 4);
1152 tk->compressorname[7] = cio_read(cio, 4);
1154 tk->depth = cio_read(cio, 2); /* Depth */
1156 /* Init std value */
1160 tk->or_fieldcount = 1;
1161 tk->or_fieldorder = 0;
1163 cio_skip(cio,2); /* Pre-defined = -1 */
1164 memset(&color, 0, sizeof(opj_jp2_color_t));
1165 tk->jp2_struct.cinfo = tk->cinfo;
1167 ok = jp2_read_jp2h(&tk->jp2_struct, cio, &color);
1169 tk->jp2_struct.cinfo = NULL;
1173 opj_event_msg(tk->cinfo, EVT_ERROR, "Error reading JP2H Box\n");
1177 tk->jp2_struct.comps = (opj_jp2_comps_t*) opj_malloc(tk->jp2_struct.numcomps * sizeof(opj_jp2_comps_t));
1178 tk->jp2_struct.cl = (unsigned int*) opj_malloc(sizeof(unsigned int));
1183 for (i = 0; cio_tell(cio) - box.init_pos < box.length; i++) {
1184 mj2_read_boxhdr(&box2, cio);
1185 cio_seek(cio, box2.init_pos);
1186 switch (box2.type) {
1188 if (mj2_read_fiel(tk, cio))
1193 if (mj2_read_jp2p(tk, cio))
1198 if (mj2_read_jp2x(tk, cio))
1203 if (mj2_read_jsub(tk, cio))
1208 if (mj2_read_orfo(tk, cio))
1213 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MJP2 Box size\n");
1224 * Write the STSD box
1226 * Sample Description
1229 void mj2_write_stsd(mj2_tk_t * tk, opj_cio_t *cio)
1233 box.init_pos = cio_tell(cio);
1235 cio_write(cio, MJ2_STSD, 4); /* STSD */
1237 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1239 cio_write(cio, 1, 4); /* entry_count = 1 (considering same JP2 headerboxes) */
1241 if (tk->track_type == 0) {
1242 mj2_write_smj2(tk, cio);
1243 } else if (tk->track_type == 1) {
1244 /* Not implemented*/
1246 if (tk->track_type == 2) {
1247 /* Not implemented*/
1251 box.length = cio_tell(cio) - box.init_pos;
1252 cio_seek(cio, box.init_pos);
1253 cio_write(cio, box.length, 4); /* L */
1254 cio_seek(cio, box.init_pos + box.length);
1260 * Sample Description
1263 int mj2_read_stsd(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
1266 int entry_count, len_2skip;
1270 mj2_read_boxhdr(&box, cio);
1272 if (MJ2_STSD != box.type) {
1273 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STSD Marker\n");
1277 if (0 != cio_read(cio, 1)) { /* Version = 0 */
1278 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in STSD box\n");
1282 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
1283 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in STSD box. Expected flag 0\n");
1287 entry_count = cio_read(cio, 4);
1289 if (tk->track_type == 0) {
1290 for (i = 0; i < entry_count; i++) {
1291 if (mj2_read_smj2(img, tk, cio))
1294 } else if (tk->track_type == 1) {
1295 len_2skip = cio_read(cio, 4); /* Not implemented -> skipping box*/
1296 cio_skip(cio,len_2skip - 4);
1297 } else if (tk->track_type == 2) {
1298 len_2skip = cio_read(cio, 4); /* Not implemented -> skipping box*/
1299 cio_skip(cio,len_2skip - 4);
1303 if (cio_tell(cio) - box.init_pos != box.length) {
1304 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STSD Box size\n");
1311 * Write the STBL box
1313 * Sample table box box
1316 void mj2_write_stbl(mj2_tk_t * tk, opj_cio_t *cio)
1320 box.init_pos = cio_tell(cio);
1322 cio_write(cio, MJ2_STBL, 4); /* STBL */
1324 mj2_write_stsd(tk, cio);
1325 mj2_write_stts(tk, cio);
1326 mj2_write_stsc(tk, cio);
1327 mj2_write_stsz(tk, cio);
1328 mj2_write_stco(tk, cio);
1330 box.length = cio_tell(cio) - box.init_pos;
1331 cio_seek(cio, box.init_pos);
1332 cio_write(cio, box.length, 4); /* L */
1333 cio_seek(cio, box.init_pos + box.length);
1339 * Sample table box box
1342 int mj2_read_stbl(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
1346 mj2_read_boxhdr(&box, cio);
1347 if (MJ2_STBL != box.type) {
1348 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected STBL Marker\n");
1352 if (mj2_read_stsd(tk, img, cio))
1354 if (mj2_read_stts(tk, cio))
1356 if (mj2_read_stsc(tk, cio))
1358 if (mj2_read_stsz(tk, cio))
1360 if (mj2_read_stco(tk, cio))
1363 if (cio_tell(cio) - box.init_pos != box.length) {
1364 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with STBL Box size\n");
1376 void mj2_write_url(mj2_tk_t * tk, int url_num, opj_cio_t *cio)
1380 box.init_pos = cio_tell(cio);
1382 cio_write(cio, MJ2_URL, 4); /* URL */
1385 cio_write(cio, 1, 4); /* Version = 0, flags = 1 because stored in same file */
1387 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1388 cio_write(cio, tk->url[url_num - 1].location[0], 4);
1389 cio_write(cio, tk->url[url_num - 1].location[1], 4);
1390 cio_write(cio, tk->url[url_num - 1].location[2], 4);
1391 cio_write(cio, tk->url[url_num - 1].location[3], 4);
1394 box.length = cio_tell(cio) - box.init_pos;
1395 cio_seek(cio, box.init_pos);
1396 cio_write(cio, box.length, 4); /* L */
1397 cio_seek(cio, box.init_pos + box.length);
1406 int mj2_read_url(mj2_tk_t * tk, int urn_num, opj_cio_t *cio)
1410 mj2_read_boxhdr(&box, cio);
1411 if (MJ2_URL != box.type) {
1412 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected URL Marker\n");
1416 if (0 != cio_read(cio, 1)) { /* Version = 0 */
1417 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in URL box\n");
1421 if (1 != cio_read(cio, 3)) { /* If flags = 1 --> media data in file */
1422 tk->url[urn_num].location[0] = cio_read(cio, 4);
1423 tk->url[urn_num].location[1] = cio_read(cio, 4);
1424 tk->url[urn_num].location[2] = cio_read(cio, 4);
1425 tk->url[urn_num].location[3] = cio_read(cio, 4);
1431 if (cio_tell(cio) - box.init_pos != box.length) {
1432 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with URL Box size\n");
1444 void mj2_write_urn(mj2_tk_t * tk, int urn_num, opj_cio_t *cio)
1448 box.init_pos = cio_tell(cio);
1450 cio_write(cio, MJ2_URN, 4); /* URN */
1452 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1454 cio_write(cio, tk->urn[urn_num].name[0], 4);
1455 cio_write(cio, tk->urn[urn_num].name[1], 4);
1456 cio_write(cio, tk->urn[urn_num].name[2], 4);
1457 cio_write(cio, tk->urn[urn_num].name[3], 4);
1458 cio_write(cio, tk->urn[urn_num].location[0], 4);
1459 cio_write(cio, tk->urn[urn_num].location[1], 4);
1460 cio_write(cio, tk->urn[urn_num].location[2], 4);
1461 cio_write(cio, tk->urn[urn_num].location[3], 4);
1463 box.length = cio_tell(cio) - box.init_pos;
1464 cio_seek(cio, box.init_pos);
1465 cio_write(cio, box.length, 4); /* L */
1466 cio_seek(cio, box.init_pos + box.length);
1475 int mj2_read_urn(mj2_tk_t * tk, int urn_num, opj_cio_t *cio)
1480 mj2_read_boxhdr(&box, cio);
1481 if (MJ2_URN != box.type) {
1482 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected URN Marker\n");
1486 if (0 != cio_read(cio, 1)) { /* Version = 0 */
1487 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in URN box\n");
1491 if (1 != cio_read(cio, 3)) { /* If flags = 1 --> media data in file */
1492 tk->urn[urn_num].name[0] = cio_read(cio, 4);
1493 tk->urn[urn_num].name[1] = cio_read(cio, 4);
1494 tk->urn[urn_num].name[2] = cio_read(cio, 4);
1495 tk->urn[urn_num].name[3] = cio_read(cio, 4);
1496 tk->urn[urn_num].location[0] = cio_read(cio, 4);
1497 tk->urn[urn_num].location[1] = cio_read(cio, 4);
1498 tk->urn[urn_num].location[2] = cio_read(cio, 4);
1499 tk->urn[urn_num].location[3] = cio_read(cio, 4);
1503 if (cio_tell(cio) - box.init_pos != box.length) {
1504 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with URN Box size\n");
1512 * Write the DREF box
1514 * Data reference box
1517 void mj2_write_dref(mj2_tk_t * tk, opj_cio_t *cio)
1522 box.init_pos = cio_tell(cio);
1524 cio_write(cio, MJ2_DREF, 4); /* DREF */
1526 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1528 if (tk->num_url + tk->num_urn == 0) { /* Media data in same file */
1529 cio_write(cio, 1, 4); /* entry_count = 1 */
1530 mj2_write_url(tk, 0, cio);
1532 cio_write(cio, tk->num_url + tk->num_urn, 4); /* entry_count */
1534 for (i = 0; i < tk->num_url; i++)
1535 mj2_write_url(tk, i + 1, cio);
1537 for (i = 0; i < tk->num_urn; i++)
1538 mj2_write_urn(tk, i, cio);
1541 box.length = cio_tell(cio) - box.init_pos;
1542 cio_seek(cio, box.init_pos);
1543 cio_write(cio, box.length, 4); /* L */
1544 cio_seek(cio, box.init_pos + box.length);
1550 * Data reference box
1553 int mj2_read_dref(mj2_tk_t * tk, opj_cio_t *cio)
1557 int entry_count, marker;
1560 mj2_read_boxhdr(&box, cio);
1561 if (MJ2_DREF != box.type) {
1562 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected DREF Marker\n");
1566 if (0 != cio_read(cio, 1)) { /* Version = 0 */
1567 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in DREF box\n");
1571 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
1572 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in DREF box. Expected flag 0\n");
1576 entry_count = cio_read(cio, 4);
1580 for (i = 0; i < entry_count; i++) {
1582 marker = cio_read(cio, 4);
1583 if (marker == MJ2_URL) {
1586 if (mj2_read_url(tk, tk->num_url, cio))
1588 } else if (marker == MJ2_URN) {
1591 if (mj2_read_urn(tk, tk->num_urn, cio))
1594 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with in DREF box. Expected URN or URL box\n");
1601 if (cio_tell(cio) - box.init_pos != box.length) {
1602 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with DREF Box size\n");
1609 * Write the DINF box
1611 * Data information box
1614 void mj2_write_dinf(mj2_tk_t * tk, opj_cio_t *cio)
1618 box.init_pos = cio_tell(cio);
1620 cio_write(cio, MJ2_DINF, 4); /* DINF */
1622 mj2_write_dref(tk, cio);
1624 box.length = cio_tell(cio) - box.init_pos;
1625 cio_seek(cio, box.init_pos);
1626 cio_write(cio, box.length, 4); /* L */
1627 cio_seek(cio, box.init_pos + box.length);
1633 * Data information box
1636 int mj2_read_dinf(mj2_tk_t * tk, opj_cio_t *cio)
1640 mj2_read_boxhdr(&box, cio);
1641 if (MJ2_DINF != box.type) {
1642 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected DINF Marker\n");
1646 if (mj2_read_dref(tk, cio))
1649 if (cio_tell(cio) - box.init_pos != box.length) {
1650 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with DINF Box size\n");
1657 * Write the VMHD box
1659 * Video Media information box
1662 void mj2_write_vmhd(mj2_tk_t * tk, opj_cio_t *cio)
1666 box.init_pos = cio_tell(cio);
1668 cio_write(cio, MJ2_VMHD, 4); /* VMHD */
1670 cio_write(cio, 1, 4); /* Version = 0, flags = 1 */
1672 cio_write(cio, tk->graphicsmode, 2);
1673 cio_write(cio, tk->opcolor[0], 2);
1674 cio_write(cio, tk->opcolor[1], 2);
1675 cio_write(cio, tk->opcolor[2], 2);
1677 box.length = cio_tell(cio) - box.init_pos;
1678 cio_seek(cio, box.init_pos);
1679 cio_write(cio, box.length, 4); /* L */
1680 cio_seek(cio, box.init_pos + box.length);
1686 * Video Media information box
1689 int mj2_read_vmhd(mj2_tk_t * tk, opj_cio_t *cio)
1693 mj2_read_boxhdr(&box, cio);
1694 if (MJ2_VMHD != box.type) {
1695 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected VMHD Marker\n");
1699 if (0 != cio_read(cio, 1)) { /* Version = 0 */
1700 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in VMHD box\n");
1704 if (1 != cio_read(cio, 3)) { /* Flags = 1 */
1705 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in VMHD box. Expected flag 1\n");
1710 tk->graphicsmode = cio_read(cio, 2);
1711 tk->opcolor[0] = cio_read(cio, 2);
1712 tk->opcolor[1] = cio_read(cio, 2);
1713 tk->opcolor[2] = cio_read(cio, 2);
1715 if (cio_tell(cio) - box.init_pos != box.length) {
1716 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with VMHD Box size\n");
1723 * Write the SMHD box
1725 * Sound Media information box
1728 void mj2_write_smhd(mj2_tk_t * tk, opj_cio_t *cio)
1732 box.init_pos = cio_tell(cio);
1734 cio_write(cio, MJ2_SMHD, 4); /* SMHD */
1736 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1738 cio_write(cio, tk->balance, 2);
1740 cio_write(cio, 0, 2); /* Reserved */
1742 box.length = cio_tell(cio) - box.init_pos;
1743 cio_seek(cio, box.init_pos);
1744 cio_write(cio, box.length, 4); /* L */
1745 cio_seek(cio, box.init_pos + box.length);
1751 * Sound Media information box
1754 int mj2_read_smhd(mj2_tk_t * tk, opj_cio_t *cio)
1758 mj2_read_boxhdr(&box, cio);
1759 if (MJ2_SMHD != box.type) {
1760 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected SMHD Marker\n");
1764 if (0 != cio_read(cio, 1)) { /* Version = 0 */
1765 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in SMHD box\n");
1769 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
1770 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in SMHD box. Expected flag 0\n");
1775 tk->balance = cio_read(cio, 2);
1777 /* Init variables to zero to avoid problems when freeeing memory
1778 The values will possibly be overidded when decoding the track structure */
1784 tk->num_samplestochunk = 0;
1785 tk->num_samples = 0;
1787 cio_skip(cio,2); /* Reserved */
1789 if (cio_tell(cio) - box.init_pos != box.length) {
1790 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with SMHD Box size\n");
1797 * Write the HMHD box
1799 * Hint Media information box
1802 void mj2_write_hmhd(mj2_tk_t * tk, opj_cio_t *cio)
1806 box.init_pos = cio_tell(cio);
1808 cio_write(cio, MJ2_HMHD, 4); /* HMHD */
1810 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1812 cio_write(cio, tk->maxPDUsize, 2);
1813 cio_write(cio, tk->avgPDUsize, 2);
1814 cio_write(cio, tk->maxbitrate, 4);
1815 cio_write(cio, tk->avgbitrate, 4);
1816 cio_write(cio, tk->slidingavgbitrate, 4);
1818 box.length = cio_tell(cio) - box.init_pos;
1819 cio_seek(cio, box.init_pos);
1820 cio_write(cio, box.length, 4); /* L */
1821 cio_seek(cio, box.init_pos + box.length);
1827 * Hint Media information box
1830 int mj2_read_hmhd(mj2_tk_t * tk, opj_cio_t *cio)
1834 mj2_read_boxhdr(&box, cio);
1835 if (MJ2_HMHD != box.type) {
1836 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected HMHD Marker\n");
1840 if (0 != cio_read(cio, 1)) { /* Version = 0 */
1841 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in HMHD box\n");
1845 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
1846 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in HMHD box. Expected flag 0\n");
1851 tk->maxPDUsize = cio_read(cio, 2);
1852 tk->avgPDUsize = cio_read(cio, 2);
1853 tk->maxbitrate = cio_read(cio, 4);
1854 tk->avgbitrate = cio_read(cio, 4);
1855 tk->slidingavgbitrate = cio_read(cio, 4);
1857 /* Init variables to zero to avoid problems when freeeing memory
1858 The values will possibly be overidded when decoding the track structure */
1864 tk->num_samplestochunk = 0;
1865 tk->num_samples = 0;
1868 if (cio_tell(cio) - box.init_pos != box.length) {
1869 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with HMHD Box size\n");
1876 * Write the MINF box
1878 * Media information box
1881 void mj2_write_minf(mj2_tk_t * tk, opj_cio_t *cio)
1885 box.init_pos = cio_tell(cio);
1887 cio_write(cio, MJ2_MINF, 4); /* MINF */
1889 if (tk->track_type == 0) {
1890 mj2_write_vmhd(tk, cio);
1891 } else if (tk->track_type == 1) {
1892 mj2_write_smhd(tk, cio);
1893 } else if (tk->track_type == 2) {
1894 mj2_write_hmhd(tk, cio);
1897 mj2_write_dinf(tk, cio);
1898 mj2_write_stbl(tk, cio);
1900 box.length = cio_tell(cio) - box.init_pos;
1901 cio_seek(cio, box.init_pos);
1902 cio_write(cio, box.length, 4); /* L */
1903 cio_seek(cio, box.init_pos + box.length);
1909 * Media information box
1912 int mj2_read_minf(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
1915 unsigned int box_type;
1918 mj2_read_boxhdr(&box, cio);
1919 if (MJ2_MINF != box.type) {
1920 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected MINF Marker\n");
1925 box_type = cio_read(cio, 4);
1928 if (box_type == MJ2_VMHD) {
1929 if (mj2_read_vmhd(tk, cio))
1931 } else if (box_type == MJ2_SMHD) {
1932 if (mj2_read_smhd(tk, cio))
1934 } else if (box_type == MJ2_HMHD) {
1935 if (mj2_read_hmhd(tk, cio))
1938 opj_event_msg(cio->cinfo, EVT_ERROR, "Error in MINF box expected vmhd, smhd or hmhd\n");
1942 if (mj2_read_dinf(tk, cio))
1945 if (mj2_read_stbl(tk, img, cio))
1948 if (cio_tell(cio) - box.init_pos != box.length) {
1949 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MINF Box size\n");
1956 * Write the HDLR box
1958 * Handler reference box
1961 void mj2_write_hdlr(mj2_tk_t * tk, opj_cio_t *cio)
1965 box.init_pos = cio_tell(cio);
1967 cio_write(cio, MJ2_HDLR, 4); /* HDLR */
1969 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
1971 cio_write(cio, 0, 4); /* Predefine */
1973 tk->name = 0; /* The track name is immediately determined by the track type */
1975 if (tk->track_type == 0) {
1976 tk->handler_type = 0x76696465; /* Handler type: vide */
1977 cio_write(cio, tk->handler_type, 4);
1979 cio_write(cio, 0, 4);
1980 cio_write(cio, 0, 4);
1981 cio_write(cio, 0, 4); /* Reserved */
1983 cio_write(cio, 0x76696465, 4);
1984 cio_write(cio, 0x6F206d65, 4);
1985 cio_write(cio, 0x64696120, 4);
1986 cio_write(cio, 0x74726163, 4);
1987 cio_write(cio, 0x6b00, 2); /* String: video media track */
1988 } else if (tk->track_type == 1) {
1989 tk->handler_type = 0x736F756E; /* Handler type: soun */
1990 cio_write(cio, tk->handler_type, 4);
1992 cio_write(cio, 0, 4);
1993 cio_write(cio, 0, 4);
1994 cio_write(cio, 0, 4); /* Reserved */
1996 cio_write(cio, 0x536F756E, 4);
1997 cio_write(cio, 0x6400, 2); /* String: Sound */
1998 } else if (tk->track_type == 2) {
1999 tk->handler_type = 0x68696E74; /* Handler type: hint */
2000 cio_write(cio, tk->handler_type, 4);
2002 cio_write(cio, 0, 4);
2003 cio_write(cio, 0, 4);
2004 cio_write(cio, 0, 4); /* Reserved */
2006 cio_write(cio, 0x48696E74, 4);
2007 cio_write(cio, 0, 2); /* String: Hint */
2010 box.length = cio_tell(cio) - box.init_pos;
2011 cio_seek(cio, box.init_pos);
2012 cio_write(cio, box.length, 4); /* L */
2013 cio_seek(cio, box.init_pos + box.length);
2019 * Handler reference box
2022 int mj2_read_hdlr(mj2_tk_t * tk, opj_cio_t *cio)
2027 mj2_read_boxhdr(&box, cio);
2028 if (MJ2_HDLR != box.type) {
2029 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected HDLR Marker\n");
2034 if (0 != cio_read(cio, 1)) { /* Version = 0 */
2035 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in HDLR box\n");
2039 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
2040 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in HDLR box. Expected flag 0\n");
2044 cio_skip(cio,4); /* Reserved */
2046 tk->handler_type = cio_read(cio, 4);
2047 cio_skip(cio,12); /* Reserved */
2049 tk->name_size = box.length - 32;
2051 tk->name = (char*) opj_malloc(tk->name_size * sizeof(char));
2052 for (i = 0; i < tk->name_size; i++) {
2053 tk->name[i] = cio_read(cio, 1); /* Name */
2056 if (cio_tell(cio) - box.init_pos != box.length) {
2057 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with HDLR Box size\n");
2064 * Write the MDHD box
2069 void mj2_write_mdhd(mj2_tk_t * tk, opj_cio_t *cio)
2074 unsigned int modification_time;
2076 box.init_pos = cio_tell(cio);
2078 cio_write(cio, MJ2_MDHD, 4); /* MDHD */
2080 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
2082 cio_write(cio, tk->creation_time, 4); /* Creation Time */
2084 time(<ime); /* Time since 1/1/70 */
2085 modification_time = (unsigned int)ltime + 2082844800; /* Seoonds between 1/1/04 and 1/1/70 */
2087 cio_write(cio, modification_time, 4); /* Modification Time */
2089 cio_write(cio, tk->timescale, 4); /* Timescale */
2093 for (i = 0; i < tk->num_samples; i++)
2094 tk->duration += tk->sample[i].sample_delta;
2096 cio_write(cio, tk->duration, 4); /* Duration */
2098 cio_write(cio, tk->language, 2); /* Language */
2100 cio_write(cio, 0, 2); /* Predefined */
2102 box.length = cio_tell(cio) - box.init_pos;
2103 cio_seek(cio, box.init_pos);
2104 cio_write(cio, box.length, 4); /* L */
2105 cio_seek(cio, box.init_pos + box.length);
2114 int mj2_read_mdhd(mj2_tk_t * tk, opj_cio_t *cio)
2118 mj2_read_boxhdr(&box, cio);
2119 if (!(MJ2_MHDR == box.type || MJ2_MDHD == box.type)) { /* Kakadu writes MHDR instead of MDHD*/
2120 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected MDHD Marker\n");
2124 if (0 != cio_read(cio, 1)) { /* Version = 0 */
2125 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in MDHD box\n");
2129 if (0 != cio_read(cio, 3)) { /* Flags = 0 */
2130 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with flag in MDHD box. Expected flag 0\n");
2135 tk->creation_time = cio_read(cio, 4); /* Creation Time */
2137 tk->modification_time = cio_read(cio, 4); /* Modification Time */
2139 tk->timescale = cio_read(cio, 4); /* Timescale */
2141 tk->duration = cio_read(cio, 4); /* Duration */
2143 tk->language = cio_read(cio, 2); /* Language */
2145 cio_skip(cio,2); /* Predefined */
2147 if (cio_tell(cio) - box.init_pos != box.length) {
2148 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MDHD Box size\n");
2155 * Write the MDIA box
2160 void mj2_write_mdia(mj2_tk_t * tk, opj_cio_t *cio)
2164 box.init_pos = cio_tell(cio);
2166 cio_write(cio, MJ2_MDIA, 4); /* MDIA */
2168 mj2_write_mdhd(tk, cio);
2169 mj2_write_hdlr(tk, cio);
2170 mj2_write_minf(tk, cio);
2172 box.length = cio_tell(cio) - box.init_pos;
2173 cio_seek(cio, box.init_pos);
2174 cio_write(cio, box.length, 4); /* L */
2175 cio_seek(cio, box.init_pos + box.length);
2184 int mj2_read_mdia(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
2188 mj2_read_boxhdr(&box, cio);
2189 if (MJ2_MDIA != box.type) {
2190 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected MDIA Marker\n");
2194 if (mj2_read_mdhd(tk, cio))
2196 if (mj2_read_hdlr(tk, cio))
2198 if (mj2_read_minf(tk, img, cio))
2201 if (cio_tell(cio) - box.init_pos != box.length) {
2202 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MDIA Box size\n");
2209 * Write the TKHD box
2214 void mj2_write_tkhd(mj2_tk_t * tk, opj_cio_t *cio)
2220 box.init_pos = cio_tell(cio);
2223 cio_write(cio, MJ2_TKHD, 4); /* TKHD */
2225 cio_write(cio, 3, 4); /* Version=0, flags=3 */
2227 time(<ime); /* Time since 1/1/70 */
2228 tk->modification_time = (unsigned int)ltime + 2082844800; /* Seoonds between 1/1/04 and 1/1/70 */
2230 cio_write(cio, tk->creation_time, 4); /* Creation Time */
2232 cio_write(cio, tk->modification_time, 4); /* Modification Time */
2234 cio_write(cio, tk->track_ID, 4); /* Track ID */
2236 cio_write(cio, 0, 4); /* Reserved */
2240 for (i = 0; i < tk->num_samples; i++)
2241 tk->duration += tk->sample[i].sample_delta;
2243 cio_write(cio, tk->duration, 4); /* Duration */
2245 cio_write(cio, 0, 4); /* Reserved */
2246 cio_write(cio, 0, 4); /* Reserved */
2248 cio_write(cio, tk->layer, 2); /* Layer */
2250 cio_write(cio, 0, 2); /* Predefined */
2252 cio_write(cio, tk->volume, 2); /* Volume */
2254 cio_write(cio, 0, 2); /* Reserved */
2256 cio_write(cio, tk->trans_matrix[0], 4); /* Transformation matrix for track */
2257 cio_write(cio, tk->trans_matrix[1], 4);
2258 cio_write(cio, tk->trans_matrix[2], 4);
2259 cio_write(cio, tk->trans_matrix[3], 4);
2260 cio_write(cio, tk->trans_matrix[4], 4);
2261 cio_write(cio, tk->trans_matrix[5], 4);
2262 cio_write(cio, tk->trans_matrix[6], 4);
2263 cio_write(cio, tk->trans_matrix[7], 4);
2264 cio_write(cio, tk->trans_matrix[8], 4);
2266 cio_write(cio, tk->visual_w, 4); /* Video Visual Width */
2268 cio_write(cio, tk->visual_h, 4); /* Video Visual Height */
2270 box.length = cio_tell(cio) - box.init_pos;
2271 cio_seek(cio, box.init_pos);
2272 cio_write(cio, box.length, 4); /* L */
2273 cio_seek(cio, box.init_pos + box.length);
2282 int mj2_read_tkhd(mj2_tk_t * tk, opj_cio_t *cio)
2288 mj2_read_boxhdr(&box, cio);
2290 if (MJ2_TKHD != box.type) {
2291 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected TKHD Marker\n");
2295 if (0 != cio_read(cio, 1)) { /* Version = 0 */
2296 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in TKHD box\n");
2300 flag = cio_read(cio, 3);
2302 if (!(flag == 1 || flag == 2 || flag == 3 || flag == 4)) { /* Flags = 1,2,3 or 4 */
2303 opj_event_msg(cio->cinfo, EVT_ERROR,
2304 "Error with flag in TKHD box: Expected flag 1,2,3 or 4\n");
2308 tk->creation_time = cio_read(cio, 4); /* Creation Time */
2310 tk->modification_time = cio_read(cio, 4); /* Modification Time */
2312 tk->track_ID = cio_read(cio, 4); /* Track ID */
2314 cio_skip(cio,4); /* Reserved */
2316 tk->duration = cio_read(cio, 4); /* Duration */
2318 cio_skip(cio,8); /* Reserved */
2320 tk->layer = cio_read(cio, 2); /* Layer */
2322 cio_read(cio, 2); /* Predefined */
2324 tk->volume = cio_read(cio, 2); /* Volume */
2326 cio_skip(cio,2); /* Reserved */
2328 tk->trans_matrix[0] = cio_read(cio, 4); /* Transformation matrix for track */
2329 tk->trans_matrix[1] = cio_read(cio, 4);
2330 tk->trans_matrix[2] = cio_read(cio, 4);
2331 tk->trans_matrix[3] = cio_read(cio, 4);
2332 tk->trans_matrix[4] = cio_read(cio, 4);
2333 tk->trans_matrix[5] = cio_read(cio, 4);
2334 tk->trans_matrix[6] = cio_read(cio, 4);
2335 tk->trans_matrix[7] = cio_read(cio, 4);
2336 tk->trans_matrix[8] = cio_read(cio, 4);
2338 tk->visual_w = cio_read(cio, 4); /* Video Visual Width */
2340 tk->visual_h = cio_read(cio, 4); /* Video Visual Height */
2342 if (cio_tell(cio) - box.init_pos != box.length) {
2343 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with TKHD Box size\n");
2350 * Write the TRAK box
2355 void mj2_write_trak(mj2_tk_t * tk, opj_cio_t *cio)
2359 box.init_pos = cio_tell(cio);
2362 cio_write(cio, MJ2_TRAK, 4); /* TRAK */
2364 mj2_write_tkhd(tk, cio);
2365 mj2_write_mdia(tk, cio);
2367 box.length = cio_tell(cio) - box.init_pos;
2368 cio_seek(cio, box.init_pos);
2369 cio_write(cio, box.length, 4); /* L */
2370 cio_seek(cio, box.init_pos + box.length);
2379 int mj2_read_trak(mj2_tk_t * tk, opj_image_t * img, opj_cio_t *cio)
2383 mj2_read_boxhdr(&box, cio);
2384 if (MJ2_TRAK != box.type) {
2385 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected TRAK Marker\n");
2388 if (mj2_read_tkhd(tk, cio))
2390 if (mj2_read_mdia(tk, img, cio))
2392 if (cio_tell(cio) - box.init_pos != box.length) {
2393 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with TRAK Box\n");
2400 * Write the MVHD box
2405 void mj2_write_mvhd(opj_mj2_t * movie, opj_cio_t *cio)
2413 box.init_pos = cio_tell(cio);
2415 cio_write(cio, MJ2_MVHD, 4); /* MVHD */
2417 cio_write(cio, 0, 4); /* Version = 0, flags = 0 */
2419 time(<ime); /* Time since 1/1/70 */
2420 movie->modification_time = (unsigned int)ltime + 2082844800; /* Seoonds between 1/1/04 and 1/1/70 */
2422 cio_write(cio, movie->creation_time, 4); /* Creation Time */
2424 cio_write(cio, movie->modification_time, 4); /* Modification Time */
2426 cio_write(cio, movie->timescale, 4); /* Timescale */
2428 movie->duration = 0;
2430 for (i = 0; i < (movie->num_stk + movie->num_htk + movie->num_vtk); i++) {
2431 mj2_tk_t *tk = &movie->tk[i];
2433 for (j = 0; j < tk->num_samples; j++) {
2434 movie->duration += tk->sample[j].sample_delta;
2438 cio_write(cio, movie->duration, 4);
2440 cio_write(cio, movie->rate, 4); /* Rate to play presentation */
2442 cio_write(cio, movie->volume, 2); /* Volume */
2444 cio_write(cio, 0, 2); /* Reserved */
2445 cio_write(cio, 0, 4); /* Reserved */
2446 cio_write(cio, 0, 4); /* Reserved */
2448 cio_write(cio, movie->trans_matrix[0], 4); /* Transformation matrix for video */
2449 cio_write(cio, movie->trans_matrix[1], 4);
2450 cio_write(cio, movie->trans_matrix[2], 4);
2451 cio_write(cio, movie->trans_matrix[3], 4);
2452 cio_write(cio, movie->trans_matrix[4], 4);
2453 cio_write(cio, movie->trans_matrix[5], 4);
2454 cio_write(cio, movie->trans_matrix[6], 4);
2455 cio_write(cio, movie->trans_matrix[7], 4);
2456 cio_write(cio, movie->trans_matrix[8], 4);
2458 cio_write(cio, 0, 4); /* Pre-defined */
2459 cio_write(cio, 0, 4); /* Pre-defined */
2460 cio_write(cio, 0, 4); /* Pre-defined */
2461 cio_write(cio, 0, 4); /* Pre-defined */
2462 cio_write(cio, 0, 4); /* Pre-defined */
2463 cio_write(cio, 0, 4); /* Pre-defined */
2466 for (i = 0; i < movie->num_htk + movie->num_stk + movie->num_vtk; i++) {
2467 if (max_tk_num < movie->tk[i].track_ID)
2468 max_tk_num = movie->tk[i].track_ID;
2471 movie->next_tk_id = max_tk_num + 1;
2473 cio_write(cio, movie->next_tk_id, 4); /* ID of Next track to be added */
2475 box.length = cio_tell(cio) - box.init_pos;
2476 cio_seek(cio, box.init_pos);
2477 cio_write(cio, box.length, 4); /* L */
2478 cio_seek(cio, box.init_pos + box.length);
2487 int mj2_read_mvhd(opj_mj2_t * movie, opj_cio_t *cio)
2491 mj2_read_boxhdr(&box, cio);
2492 if (MJ2_MVHD != box.type) {
2493 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected MVHD Marker\n");
2498 if (0 != cio_read(cio, 4)) { /* Version = 0, flags = 0 */
2499 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Only Version 0 handled in MVHD box\n");
2502 movie->creation_time = cio_read(cio, 4); /* Creation Time */
2504 movie->modification_time = cio_read(cio, 4); /* Modification Time */
2506 movie->timescale = cio_read(cio, 4); /* Timescale */
2508 movie->duration = cio_read(cio, 4); /* Duration */
2510 movie->rate = cio_read(cio, 4); /* Rate to play presentation */
2512 movie->volume = cio_read(cio, 2); /* Volume */
2514 cio_skip(cio,10); /* Reserved */
2516 movie->trans_matrix[0] = cio_read(cio, 4); /* Transformation matrix for video */
2517 movie->trans_matrix[1] = cio_read(cio, 4);
2518 movie->trans_matrix[2] = cio_read(cio, 4);
2519 movie->trans_matrix[3] = cio_read(cio, 4);
2520 movie->trans_matrix[4] = cio_read(cio, 4);
2521 movie->trans_matrix[5] = cio_read(cio, 4);
2522 movie->trans_matrix[6] = cio_read(cio, 4);
2523 movie->trans_matrix[7] = cio_read(cio, 4);
2524 movie->trans_matrix[8] = cio_read(cio, 4);
2526 cio_skip(cio,24); /* Pre-defined */
2528 movie->next_tk_id = cio_read(cio, 4); /* ID of Next track to be added */
2530 if (cio_tell(cio) - box.init_pos != box.length) {
2531 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MVHD Box Size\n");
2539 * Write the MOOV box
2544 void OPJ_CALLCONV mj2_write_moov(opj_mj2_t * movie, opj_cio_t *cio)
2549 box.init_pos = cio_tell(cio);
2551 cio_write(cio, MJ2_MOOV, 4); /* MOOV */
2553 mj2_write_mvhd(movie, cio);
2555 for (i = 0; i < (movie->num_stk + movie->num_htk + movie->num_vtk); i++) {
2556 mj2_write_trak(&movie->tk[i], cio);
2559 box.length = cio_tell(cio) - box.init_pos;
2560 cio_seek(cio, box.init_pos);
2561 cio_write(cio, box.length, 4); /* L */
2562 cio_seek(cio, box.init_pos + box.length);
2571 int mj2_read_moov(opj_mj2_t * movie, opj_image_t * img, opj_cio_t *cio)
2577 mj2_read_boxhdr(&box, cio);
2578 if (MJ2_MOOV != box.type) {
2579 opj_event_msg(cio->cinfo, EVT_ERROR, "Error: Expected MOOV Marker\n");
2583 if (mj2_read_mvhd(movie, cio))
2586 movie->tk = (mj2_tk_t*) opj_malloc((movie->next_tk_id - 1) * sizeof(mj2_tk_t));
2588 for (i = 0; cio_tell(cio) - box.init_pos < box.length; i++) {
2589 mj2_tk_t *tk = &movie->tk[i];
2590 tk->cinfo = movie->cinfo;
2591 mj2_read_boxhdr(&box2, cio);
2592 if (box2.type == MJ2_TRAK) {
2593 cio_seek(cio, box2.init_pos);
2594 if (mj2_read_trak(tk, img, cio))
2597 if (tk->track_type == 0) {
2599 } else if (tk->track_type == 1) {
2601 } else if (tk->track_type == 2) {
2604 } else if (box2.type == MJ2_MVEX) {
2605 cio_seek(cio, box2.init_pos);
2606 cio_skip(cio,box2.length);
2609 opj_event_msg(cio->cinfo, EVT_ERROR, "Error with MOOV Box: Expected TRAK or MVEX box\n");
2616 int OPJ_CALLCONV mj2_read_struct(FILE *file, opj_mj2_t *movie) {
2619 unsigned char * src;
2624 /* open a byte stream for reading */
2625 src = (unsigned char*) opj_malloc(300 * sizeof(unsigned char));
2627 /* Assuming that jp and ftyp markers size do
2628 not exceed 300 bytes */
2629 fread(src,300,1, file);
2631 cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, 300);
2633 if (mj2_read_jp(cio))
2635 if (mj2_read_ftyp(movie, cio))
2638 fsresult = fseek(file,cio_tell(cio),SEEK_SET);
2640 opj_event_msg(cio->cinfo, EVT_ERROR, "End of file reached while trying to read data after FTYP box\n" );
2644 foffset = cio_tell(cio);
2648 fread(src,30,1,file);
2649 cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, 300);
2650 mj2_read_boxhdr(&box, cio);
2652 while(box.type != MJ2_MOOV) {
2657 fsresult = fseek(file,foffset+box.length,SEEK_SET);
2659 opj_event_msg(cio->cinfo, EVT_ERROR, "End of file reached while trying to read MDAT box\n" );
2662 foffset += box.length;
2666 fsresult = fseek(file,foffset+box.length,SEEK_SET);
2668 opj_event_msg(cio->cinfo, EVT_ERROR, "End of file reached while trying to read MOOF box\n" );
2671 foffset += box.length;
2674 fsresult = fseek(file,foffset+box.length,SEEK_SET);
2676 opj_event_msg(cio->cinfo, EVT_ERROR, "End of file reached while trying to read FREE box\n" );
2679 foffset += box.length;
2682 fsresult = fseek(file,foffset+box.length,SEEK_SET);
2684 opj_event_msg(cio->cinfo, EVT_ERROR, "End of file reached while trying to read SKIP box\n" );
2687 foffset += box.length;
2690 opj_event_msg(cio->cinfo, EVT_ERROR, "Unknown box in MJ2 stream\n");
2691 fsresult = fseek(file,foffset+box.length,SEEK_SET);
2693 opj_event_msg(cio->cinfo, EVT_ERROR, "End of file reached while trying to read end of unknown box\n");
2696 foffset += box.length;
2699 fsresult = fread(src,8,1,file);
2700 if (fsresult != 1) {
2701 opj_event_msg(cio->cinfo, EVT_ERROR, "MOOV box not found in file\n");
2704 cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, 8);
2705 mj2_read_boxhdr(&box, cio);
2708 fseek(file,foffset,SEEK_SET);
2709 src = (unsigned char*)opj_realloc(src,box.length);
2710 fsresult = fread(src,box.length,1,file);
2711 if (fsresult != 1) {
2712 opj_event_msg(cio->cinfo, EVT_ERROR, "End of file reached while trying to read MOOV box\n");
2716 cio = opj_cio_open((opj_common_ptr)movie->cinfo, src, box.length);
2718 if (mj2_read_moov(movie, &img, cio))
2725 /* ----------------------------------------------------------------------- */
2726 /* MJ2 decoder interface */
2727 /* ----------------------------------------------------------------------- */
2729 opj_dinfo_t* OPJ_CALLCONV mj2_create_decompress() {
2731 opj_dinfo_t *dinfo = (opj_dinfo_t*) opj_calloc(1, sizeof(opj_dinfo_t));
2732 if(!dinfo) return NULL;
2734 dinfo->is_decompressor = OPJ_TRUE;
2736 mj2 = (opj_mj2_t*) opj_calloc(1, sizeof(opj_mj2_t));
2737 dinfo->mj2_handle = mj2;
2739 mj2->cinfo = (opj_common_ptr)dinfo;
2741 mj2->j2k = j2k_create_decompress((opj_common_ptr)dinfo);
2742 dinfo->j2k_handle = mj2->j2k;
2747 void OPJ_CALLCONV mj2_setup_decoder(opj_mj2_t *movie, mj2_dparameters_t *mj2_parameters) {
2752 /* setup the J2K decoder parameters */
2753 j2k_setup_decoder((opj_j2k_t*)movie->cinfo->j2k_handle,
2754 &mj2_parameters->j2k_parameters);
2758 void OPJ_CALLCONV mj2_destroy_decompress(opj_mj2_t *movie) {
2763 if (movie->cinfo->j2k_handle)
2764 j2k_destroy_compress(movie->j2k);
2766 if (movie->num_cl != 0)
2767 opj_free(movie->cl);
2769 for (i = 0; i < movie->num_vtk + movie->num_stk + movie->num_htk; i++) {
2771 if (tk->name_size != 0)
2773 if (tk->track_type == 0) {/* Video track*/
2774 if (tk->jp2_struct.comps != NULL)
2775 opj_free(tk->jp2_struct.comps);
2776 if (tk->jp2_struct.cl != NULL)
2777 opj_free(tk->jp2_struct.cl);
2778 if (tk->num_jp2x != 0)
2779 opj_free(tk->jp2xdata);
2782 if (tk->num_url != 0)
2784 if (tk->num_urn != 0)
2786 if (tk->num_br != 0)
2788 if (tk->num_tts != 0)
2790 if (tk->num_chunks != 0)
2791 opj_free(tk->chunk);
2792 if (tk->num_samplestochunk != 0)
2793 opj_free(tk->sampletochunk);
2794 if (tk->num_samples != 0)
2795 opj_free(tk->sample);
2798 opj_free(movie->tk);
2803 /* ----------------------------------------------------------------------- */
2804 /* MJ2 encoder interface */
2805 /* ----------------------------------------------------------------------- */
2807 opj_cinfo_t* OPJ_CALLCONV mj2_create_compress() {
2809 opj_cinfo_t *cinfo = (opj_cinfo_t*) opj_calloc(1, sizeof(opj_cinfo_t));
2810 if(!cinfo) return NULL;
2812 mj2 = (opj_mj2_t*) opj_calloc(1, sizeof(opj_mj2_t));
2813 cinfo->mj2_handle = mj2;
2815 mj2->cinfo = (opj_common_ptr)cinfo;
2818 mj2->j2k = j2k_create_compress(mj2->cinfo);
2819 cinfo->j2k_handle = mj2->j2k;
2824 void OPJ_CALLCONV mj2_setup_encoder(opj_mj2_t *movie, mj2_cparameters_t *parameters) {
2825 if(movie && parameters) {
2826 opj_jp2_t *jp2_struct;
2828 movie->num_htk = 0; /* No hint tracks*/
2829 movie->num_stk = 0; /* No sound tracks*/
2830 movie->num_vtk = 1; /* One video track*/
2832 movie->brand = MJ2_MJ2; /* One brand: MJ2*/
2833 movie->num_cl = 2; /* Two compatible brands: MJ2 and MJ2S*/
2834 movie->cl = (unsigned int*) opj_malloc(movie->num_cl * sizeof(unsigned int));
2835 movie->cl[0] = MJ2_MJ2;
2836 movie->cl[1] = MJ2_MJ2S;
2837 movie->minversion = 0; /* Minimum version: 0 */
2839 movie->tk = (mj2_tk_t*) opj_malloc(sizeof(mj2_tk_t)); /*Memory allocation for the video track*/
2840 movie->tk[0].track_ID = 1; /* Track ID = 1 */
2841 movie->tk[0].track_type = 0; /* Video track */
2842 movie->tk[0].Dim[0] = parameters->Dim[0];
2843 movie->tk[0].Dim[1] = parameters->Dim[1];
2844 movie->tk[0].w = parameters->w;
2845 movie->tk[0].h = parameters->h;
2846 movie->tk[0].CbCr_subsampling_dx = parameters->CbCr_subsampling_dx;
2847 movie->tk[0].CbCr_subsampling_dy = parameters->CbCr_subsampling_dy;
2848 movie->tk[0].sample_rate = parameters->frame_rate;
2849 movie->tk[0].name_size = 0;
2850 movie->tk[0].chunk = (mj2_chunk_t*) opj_malloc(sizeof(mj2_chunk_t));
2851 movie->tk[0].sample = (mj2_sample_t*) opj_malloc(sizeof(mj2_sample_t));
2852 movie->tk[0].depth = parameters->prec;
2854 jp2_struct = &movie->tk[0].jp2_struct;
2855 jp2_struct->numcomps = parameters->numcomps; /* NC */
2856 jp2_struct->comps = (opj_jp2_comps_t*) opj_malloc(jp2_struct->numcomps * sizeof(opj_jp2_comps_t));
2857 jp2_struct->precedence = 0; /* PRECEDENCE*/
2858 jp2_struct->approx = 0; /* APPROX*/
2859 jp2_struct->brand = JP2_JP2; /* BR */
2860 jp2_struct->minversion = 0; /* MinV */
2861 jp2_struct->numcl = 1;
2862 jp2_struct->cl = (unsigned int*) opj_malloc(jp2_struct->numcl * sizeof(unsigned int));
2863 jp2_struct->cl[0] = JP2_JP2; /* CL0 : JP2 */
2864 jp2_struct->C = 7; /* C : Always 7*/
2865 jp2_struct->UnkC = 0; /* UnkC, colorspace specified in colr box*/
2866 jp2_struct->IPR = 0; /* IPR, no intellectual property*/
2867 jp2_struct->w = parameters->w;
2868 jp2_struct->h = parameters->h;
2869 jp2_struct->bpc = 7;
2870 jp2_struct->meth = parameters->meth;
2871 jp2_struct->enumcs = parameters->enumcs;
2875 void OPJ_CALLCONV mj2_destroy_compress(opj_mj2_t *movie) {
2880 if (movie->cinfo->j2k_handle) {
2881 j2k_destroy_compress(movie->j2k);
2884 if (movie->num_cl != 0)
2885 opj_free(movie->cl);
2887 for (i = 0; i < movie->num_vtk + movie->num_stk + movie->num_htk; i++) {
2889 if (tk->name_size != 0)
2891 if (tk->track_type == 0) {/* Video track*/
2892 if (tk->jp2_struct.comps != NULL)
2893 opj_free(tk->jp2_struct.comps);
2894 if (tk->jp2_struct.cl != NULL)
2895 opj_free(tk->jp2_struct.cl);
2896 if (tk->num_jp2x != 0)
2897 opj_free(tk->jp2xdata);
2900 if (tk->num_url != 0)
2902 if (tk->num_urn != 0)
2904 if (tk->num_br != 0)
2906 if (tk->num_tts != 0)
2908 if (tk->num_chunks != 0)
2909 opj_free(tk->chunk);
2910 if (tk->num_samplestochunk != 0)
2911 opj_free(tk->sampletochunk);
2912 if (tk->num_samples != 0)
2913 opj_free(tk->sample);
2916 opj_free(movie->tk);