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