Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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