Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright (c) 2001-2002, David Janssens
  3.  * Copyright (c) 2003-2004, Yannick Verschueren
  4.  * Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
  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.  
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include <setjmp.h>
  34. #include <math.h>
  35.  
  36. #include "j2k.h"
  37. #include "cio.h"
  38. #include "tcd.h"
  39. #include "int.h"
  40. #include "jpip.h"
  41. #include "jp2.h"
  42.  
  43. #define J2K_MS_SOC 0xff4f
  44. #define J2K_MS_SOT 0xff90
  45. #define J2K_MS_SOD 0xff93
  46. #define J2K_MS_EOC 0xffd9
  47. #define J2K_MS_SIZ 0xff51
  48. #define J2K_MS_COD 0xff52
  49. #define J2K_MS_COC 0xff53
  50. #define J2K_MS_RGN 0xff5e
  51. #define J2K_MS_QCD 0xff5c
  52. #define J2K_MS_QCC 0xff5d
  53. #define J2K_MS_POC 0xff5f
  54. #define J2K_MS_TLM 0xff55
  55. #define J2K_MS_PLM 0xff57
  56. #define J2K_MS_PLT 0xff58
  57. #define J2K_MS_PPM 0xff60
  58. #define J2K_MS_PPT 0xff61
  59. #define J2K_MS_SOP 0xff91
  60. #define J2K_MS_EPH 0xff92
  61. #define J2K_MS_CRG 0xff63
  62. #define J2K_MS_COM 0xff64
  63.  
  64. #define J2K_STATE_MHSOC 0x0001
  65. #define J2K_STATE_MHSIZ 0x0002
  66. #define J2K_STATE_MH 0x0004
  67. #define J2K_STATE_TPHSOT 0x0008
  68. #define J2K_STATE_TPH 0x0010
  69. #define J2K_STATE_MT 0x0020
  70.  
  71. #define START_NB 5
  72. #define INCREMENT 5
  73.  
  74. jmp_buf j2k_error;
  75.  
  76. static int j2k_state;
  77. static int j2k_curtileno;
  78. static j2k_tcp_t j2k_default_tcp;
  79. static unsigned char *j2k_eot;
  80.  
  81. static j2k_image_t *j2k_img;
  82. static j2k_cp_t *j2k_cp;
  83.  
  84. static unsigned char **j2k_tile_data;
  85. static int *j2k_tile_len;
  86.  
  87. static info_image_t img;
  88.  
  89.  
  90. void j2k_clean() {
  91.   int tileno = 0;
  92.   int compno=0, resno=0, precno=0;
  93.  
  94.   tcd_free(j2k_img, j2k_cp);
  95.   for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) {
  96.     info_tile_t *tile_Idx = &img.tile[tileno];
  97.    
  98.     for (compno = 0; compno < img.Comp; compno++)
  99.       {
  100.         info_compo_t *compo_Idx = &tile_Idx->compo[compno];
  101.         for(resno = 0; resno < img.Decomposition + 1; resno++)
  102.           {
  103.             info_reso_t *reso_Idx = &compo_Idx->reso[resno];
  104.             for (precno = 0; precno < img.tile[tileno].pw * img.tile[tileno].ph; precno++)
  105.               {
  106.                 info_prec_t *prec_Idx = &reso_Idx->prec[precno];
  107.                 free(prec_Idx->layer);
  108.               }
  109.             free(reso_Idx->prec);
  110.           }
  111.         free(compo_Idx->reso);
  112.       }
  113.     free(tile_Idx->compo);
  114.     free(tile_Idx->marker);
  115.     free(tile_Idx->tile_parts);
  116.     free(tile_Idx->marker_mul.COC);
  117.     free(tile_Idx->marker_mul.RGN);
  118.     free(tile_Idx->marker_mul.QCC);
  119.     free(tile_Idx->marker_mul.PLT);
  120.     free(tile_Idx->marker_mul.PPT);
  121.     free(tile_Idx->marker_mul.COM);
  122. }
  123.   free(img.tile);
  124.   free(img.marker);
  125.   free(img.marker_mul.COC);
  126.   free(img.marker_mul.RGN);
  127.   free(img.marker_mul.QCC);
  128.   free(img.marker_mul.PLM);
  129.   free(img.marker_mul.PPM);
  130.   free(img.marker_mul.COM);
  131. }
  132.  
  133.  
  134.  
  135. void j2k_read_soc() {
  136.   j2k_state=J2K_STATE_MHSIZ;
  137. }
  138.  
  139.  
  140.  
  141. void j2k_read_siz() {
  142.     int len, i;
  143.     info_tile_t *tile;
  144.  
  145.     len = cio_read(2);
  146.  
  147.     /* <INDEX> [MHIX BOX] */
  148.     img.marker[img.num_marker].type = J2K_MS_SIZ;
  149.     img.marker[img.num_marker].start_pos = cio_tell()-2;
  150.     img.marker[img.num_marker].len = len;
  151.     img.num_marker++;
  152.     /* </INDEX> [MHIX BOX] */
  153.    
  154.     cio_read(2);                      /* Rsiz (capabilities) */
  155.     j2k_img->x1 = cio_read(4);        /* Xsiz                */
  156.     j2k_img->y1 = cio_read(4);        /* Ysiz                */
  157.     j2k_img->x0 = cio_read(4);        /* X0siz               */
  158.     j2k_img->y0 = cio_read(4);        /* Y0siz               */
  159.     j2k_cp->tdx = cio_read(4);        /* XTsiz               */
  160.     j2k_cp->tdy = cio_read(4);        /* YTsiz               */
  161.     j2k_cp->tx0 = cio_read(4);        /* XT0siz              */
  162.     j2k_cp->ty0 = cio_read(4);        /* YTOsiz              */
  163.  
  164.     j2k_img->numcomps = cio_read(2);  /* Csiz                */
  165.     j2k_img->comps = (j2k_comp_t*)malloc(j2k_img->numcomps * sizeof(j2k_comp_t));
  166.     for (i = 0; i < j2k_img->numcomps; i++) {
  167.         int tmp, w, h;
  168.         tmp = cio_read(1);
  169.         j2k_img->comps[i].prec = (tmp & 0x7f) + 1;
  170.         j2k_img->comps[i].sgnd = tmp >> 7;
  171.         j2k_img->comps[i].dx = cio_read(1);
  172.         j2k_img->comps[i].dy = cio_read(1);
  173.         w = int_ceildiv(j2k_img->x1-j2k_img->x0, j2k_img->comps[i].dx);
  174.         h = int_ceildiv(j2k_img->y1-j2k_img->y0, j2k_img->comps[i].dy);
  175.         j2k_img->comps[i].data = (int*)malloc(sizeof(int) * w * h);
  176.     }
  177.     j2k_cp->tw = int_ceildiv(j2k_img->x1 - j2k_cp->tx0, j2k_cp->tdx);
  178.     j2k_cp->th = int_ceildiv(j2k_img->y1 - j2k_cp->ty0, j2k_cp->tdy);
  179.  
  180.     j2k_cp->tcps = (j2k_tcp_t*)calloc((j2k_cp->tw * j2k_cp->th), sizeof(j2k_tcp_t));
  181.  
  182.     for (i = 0; i < j2k_cp->tw * j2k_cp->th; i++)
  183.       {
  184.         j2k_cp->tcps[i].POC = 0;
  185.         j2k_cp->tcps[i].numpocs = 0;
  186.         // j2k_cp->tcps[i].first=1;
  187.       }
  188.  
  189.     /* Initialization for PPM marker */
  190.     j2k_cp->ppm = 0;
  191.     j2k_cp->ppm_data = NULL;
  192.     j2k_cp->ppm_previous = 0;
  193.     j2k_cp->ppm_store = 0;
  194.  
  195.     j2k_default_tcp.tccps = (j2k_tccp_t*)malloc(j2k_img->numcomps * sizeof(j2k_tccp_t));
  196.     for (i = 0; i < j2k_cp->tw * j2k_cp->th; i++) {
  197.         j2k_cp->tcps[i].tccps = (j2k_tccp_t*)malloc(j2k_img->numcomps * sizeof(j2k_tccp_t));
  198.     }
  199.     j2k_tile_data = (unsigned char**)calloc(j2k_cp->tw * j2k_cp->th, sizeof(char*));
  200.     j2k_tile_len = (int*)calloc(j2k_cp->tw * j2k_cp->th, sizeof(int));
  201.     j2k_state = J2K_STATE_MH;
  202.  
  203.     /* <INDEX> */
  204.     img.Im_w = j2k_img->x1 - j2k_img->x0;
  205.     img.Im_h = j2k_img->y1 - j2k_img->y0;
  206.     img.Tile_x = j2k_cp->tdx;
  207.     img.Tile_y = j2k_cp->tdy;
  208.     img.Comp = j2k_img->numcomps;
  209.     img.tw = j2k_cp->tw;
  210.     img.th = j2k_cp->th;
  211.     img.tile = (info_tile_t*)malloc(img.tw * img.th * sizeof(info_tile_t));
  212.  
  213.     for (i = 0; i < img.tw * img.th; i++)
  214.       {
  215.         tile = &img.tile[i];
  216.         tile->marker = (info_marker_t*)malloc(32 * sizeof(info_marker_t));
  217.         tile->num_marker = 0;
  218.         tile->marker_mul.num_COC = 0;
  219.         tile->marker_mul.CzCOC = START_NB;
  220.         tile->marker_mul.num_RGN = 0;
  221.         tile->marker_mul.CzRGN = START_NB;
  222.         tile->marker_mul.num_QCC = 0;
  223.         tile->marker_mul.CzQCC = START_NB;
  224.         tile->marker_mul.num_PLT = 0;
  225.         tile->marker_mul.CzPLT = START_NB;
  226.         tile->marker_mul.num_PPT = 0;
  227.         tile->marker_mul.CzPPT = START_NB;
  228.         tile->marker_mul.num_COM = 0;
  229.         tile->marker_mul.CzCOM = START_NB;
  230.       }
  231.     /* </INDEX> */
  232.  
  233.  
  234.  }
  235.  
  236. void j2k_read_com() {
  237.     int len;
  238.     info_tile_t *tile;
  239.     info_marker_t *tmp;
  240.  
  241.     len = cio_read(2);
  242.  
  243.     /* <INDEX> [MHIX BOX] */
  244.     if (j2k_state == J2K_STATE_MH)
  245.       {
  246.         if (!img.marker_mul.num_COM)
  247.           img.marker_mul.COM = (info_marker_t*)malloc(img.marker_mul.CzCOM * sizeof(info_marker_t));
  248.         if (img.marker_mul.num_COM >= img.marker_mul.CzCOM)
  249.           {
  250.             tmp = (info_marker_t*)malloc(2 * img.marker_mul.CzCOM * sizeof(info_marker_t));
  251.             memcpy(tmp,img.marker_mul.COM,img.marker_mul.CzCOM);
  252.             img.marker_mul.CzCOM *= 2;
  253.             free(img.marker_mul.COM);
  254.             img.marker_mul.COM = tmp;
  255.           }
  256.  
  257.         img.marker_mul.COM[img.marker_mul.num_COM].type = J2K_MS_COM;
  258.         img.marker_mul.COM[img.marker_mul.num_COM].start_pos = cio_tell()-2;
  259.         img.marker_mul.COM[img.marker_mul.num_COM].len = len;
  260.         img.marker_mul.num_COM++;
  261.       } else
  262.         {
  263.           tile = &img.tile[j2k_curtileno];
  264.           if (!tile->marker_mul.num_COM)
  265.             tile->marker_mul.COM = (info_marker_t*)calloc(START_NB, sizeof(info_marker_t));
  266.           if (tile->marker_mul.num_COM >= tile->marker_mul.CzCOM)
  267.             {
  268.               tmp = (info_marker_t*)malloc(2 * tile->marker_mul.CzCOM * sizeof(info_marker_t));
  269.               memcpy(tmp,tile->marker_mul.COM,tile->marker_mul.CzCOM);
  270.               tile->marker_mul.CzCOM *= 2;
  271.               free(tile->marker_mul.COM);
  272.               tile->marker_mul.COM = tmp;
  273.             }
  274.           tile->marker_mul.COM[tile->marker_mul.num_COM].type = J2K_MS_COM;
  275.           tile->marker_mul.COM[tile->marker_mul.num_COM].start_pos = cio_tell()-2;
  276.           tile->marker_mul.COM[tile->marker_mul.num_COM].len = len;
  277.           tile->marker_mul.num_COM++;
  278.         }
  279.     /* </INDEX> [MHIX BOX] */
  280.  
  281.     cio_skip(len - 2);
  282. }
  283.  
  284.  
  285.  
  286.  
  287. void j2k_read_cox(int compno) {
  288.     int i;
  289.     j2k_tcp_t *tcp;
  290.     j2k_tccp_t *tccp;
  291.  
  292.     tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
  293.     tccp = &tcp->tccps[compno];
  294.     tccp->numresolutions = cio_read(1) + 1;
  295.  
  296.     img.Decomposition = tccp->numresolutions - 1; /* <INDEX> */
  297.  
  298.     tccp->cblkw = cio_read(1) + 2;
  299.     tccp->cblkh = cio_read(1) + 2;
  300.     tccp->cblksty = cio_read(1);
  301.     tccp->qmfbid = cio_read(1);
  302.     if (tccp->csty&J2K_CP_CSTY_PRT) {
  303.         for (i = 0; i < tccp->numresolutions; i++) {
  304.             int tmp = cio_read(1);
  305.             tccp->prcw[i] = tmp&0xf;
  306.             tccp->prch[i] = tmp>>4;
  307.         }
  308.     }
  309. }
  310.  
  311.  
  312.  
  313.  
  314. void j2k_read_cod() {
  315.     int len, i, pos;
  316.     j2k_tcp_t *tcp;
  317.     info_tile_t *tile;
  318.  
  319.     tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
  320.     len = cio_read(2);
  321.  
  322.     /* <INDEX> [MHIX BOX] */
  323.     if (j2k_state == J2K_STATE_MH)
  324.       {
  325.         img.marker[img.num_marker].type = J2K_MS_SIZ;
  326.         img.marker[img.num_marker].start_pos = cio_tell()-2;
  327.         img.marker[img.num_marker].len = len;
  328.         img.num_marker++;
  329.       }
  330.     else
  331.       {
  332.         tile = &img.tile[j2k_curtileno];
  333.         tile->marker[tile->num_marker].type = J2K_MS_SIZ;
  334.         tile->marker[tile->num_marker].start_pos = cio_tell()-2;
  335.         tile->marker[tile->num_marker].len = len;
  336.         tile->num_marker++;
  337.   }
  338.     /* </INDEX> [MHIX BOX] */
  339.    
  340.     tcp->csty = cio_read(1);
  341.     tcp->prg = cio_read(1);
  342.     tcp->numlayers = cio_read(2);
  343.     tcp->mct = cio_read(1);
  344.  
  345.     pos = cio_tell();
  346.     for (i = 0; i < j2k_img->numcomps; i++) {
  347.         tcp->tccps[i].csty = tcp->csty&J2K_CP_CSTY_PRT;
  348.         cio_seek(pos);
  349.         j2k_read_cox(i);
  350.     }
  351.    
  352.     /* <INDEX> */
  353.     img.Prog = tcp->prg;
  354.     img.Layer = tcp->numlayers;
  355.     /* </INDEX> */
  356. }
  357.  
  358.  
  359.  
  360.  
  361. void j2k_read_coc() {
  362.     int len, compno;
  363.     j2k_tcp_t *tcp;
  364.     info_tile_t *tile;
  365.     info_marker_t *tmp;
  366.  
  367.     tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
  368.     len = cio_read(2);
  369.    
  370.     /* <INDEX> [MHIX BOX] */
  371.     if (j2k_state == J2K_STATE_MH)
  372.       {
  373.         if (!img.marker_mul.num_COC)
  374.           img.marker_mul.COC = (info_marker_t*)malloc(img.marker_mul.CzCOC * sizeof(info_marker_t));
  375.         if (img.marker_mul.num_COC >= img.marker_mul.CzCOC)
  376.           {
  377.             tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzCOC) * sizeof(info_marker_t));
  378.             memcpy(tmp,img.marker_mul.COC,img.marker_mul.CzCOC);
  379.             img.marker_mul.CzCOC += INCREMENT;
  380.             free(img.marker_mul.COC);
  381.             img.marker_mul.COC = tmp;
  382.           }
  383.         img.marker_mul.COC[img.marker_mul.num_COC].type = J2K_MS_COC;
  384.         img.marker_mul.COC[img.marker_mul.num_COC].start_pos = cio_tell()-2;
  385.         img.marker_mul.COC[img.marker_mul.num_COC].len = len;
  386.         img.marker_mul.num_COC++;
  387.       } else
  388.         {
  389.           tile = &img.tile[j2k_curtileno];
  390.           if (!tile->marker_mul.num_COC)
  391.             tile->marker_mul.COC = (info_marker_t*)malloc(tile->marker_mul.CzCOC * sizeof(info_marker_t));
  392.           if (tile->marker_mul.num_COC >= tile->marker_mul.CzCOC)
  393.             {
  394.               tmp = (info_marker_t*)malloc((INCREMENT + tile->marker_mul.CzCOC) * sizeof(info_marker_t));
  395.               memcpy(tmp,tile->marker_mul.COC,tile->marker_mul.CzCOC);
  396.               tile->marker_mul.CzCOC += INCREMENT;
  397.               free(tile->marker_mul.COC);
  398.               tile->marker_mul.COC = tmp;
  399.             }
  400.           tile->marker_mul.COC[tile->marker_mul.num_COC].type = J2K_MS_COC;
  401.           tile->marker_mul.COC[tile->marker_mul.num_COC].start_pos = cio_tell() - 2;
  402.           tile->marker_mul.COC[tile->marker_mul.num_COC].len = len;
  403.           tile->marker_mul.num_COC++;
  404.         }
  405.     /* </INDEX> [MHIX BOX] */
  406.    
  407.     compno =cio_read(j2k_img->numcomps <= 256 ? 1 : 2);
  408.  
  409.     tcp->tccps[compno].csty = cio_read(1);
  410.     j2k_read_cox(compno);
  411. }
  412.  
  413.  
  414.  
  415.  
  416. void j2k_read_qcx(int compno, int len) {
  417.     int tmp;
  418.     j2k_tcp_t *tcp;
  419.     j2k_tccp_t *tccp;
  420.     int bandno, numbands;
  421.  
  422.     tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
  423.     tccp = &tcp->tccps[compno];
  424.     tmp = cio_read(1);
  425.     tccp->qntsty = tmp & 0x1f;
  426.     tccp->numgbits = tmp >> 5;
  427.     numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT ? len - 1 : (len - 1) / 2);
  428.     for (bandno = 0; bandno < numbands; bandno++) {
  429.         int expn, mant;
  430.         if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { /* WHY STEPSIZES WHEN NOQNT ? */
  431.             expn = cio_read(1) >> 3;
  432.             mant = 0;
  433.         } else {
  434.             tmp = cio_read(2);
  435.             expn = tmp >> 11;
  436.             mant = tmp & 0x7ff;
  437.         }
  438.         tccp->stepsizes[bandno].expn = expn;
  439.         tccp->stepsizes[bandno].mant = mant;
  440.     }
  441. }
  442.  
  443.  
  444.  
  445.  
  446. void j2k_read_qcd() {
  447.     int len, i, pos;
  448.     info_tile_t *tile;
  449.  
  450.     len = cio_read(2);    
  451.  
  452.     /* <INDEX> [MHIX BOX] */
  453.     if (j2k_state == J2K_STATE_MH)
  454.       {
  455.         img.marker[img.num_marker].type = J2K_MS_QCD;
  456.         img.marker[img.num_marker].start_pos = cio_tell()-2;
  457.         img.marker[img.num_marker].len = len;
  458.         img.num_marker++;
  459.       }  else
  460.         {
  461.           tile = &img.tile[j2k_curtileno];
  462.           tile->marker[tile->num_marker].type = J2K_MS_QCD;
  463.           tile->marker[tile->num_marker].start_pos = cio_tell()-2;
  464.           tile->marker[tile->num_marker].len = len;
  465.           tile->num_marker++;
  466.         }
  467.     /* </INDEX> [MHIX BOX] */
  468.    
  469.    
  470.     pos=cio_tell();
  471.     for (i = 0; i < j2k_img->numcomps; i++) {
  472.         cio_seek(pos);
  473.         j2k_read_qcx(i, len - 2);
  474.     }
  475. }
  476.  
  477.  
  478.  
  479.  
  480. void j2k_read_qcc() {
  481.   int len, compno;
  482.   info_tile_t *tile;
  483.   info_marker_t *tmp;
  484.  
  485.   len = cio_read(2);  
  486.   /* <INDEX> [MHIX BOX] */
  487.   if (j2k_state == J2K_STATE_MH)
  488.     {
  489.       if (!img.marker_mul.num_QCC)
  490.         img.marker_mul.QCC = (info_marker_t*)malloc(img.marker_mul.CzQCC * sizeof(info_marker_t));
  491.         if (img.marker_mul.num_QCC >= img.marker_mul.CzQCC)
  492.           {
  493.             tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzQCC) * sizeof(info_marker_t));
  494.             memcpy(tmp,img.marker_mul.QCC,img.marker_mul.CzQCC);
  495.             img.marker_mul.CzQCC += INCREMENT;
  496.             free(img.marker_mul.QCC);
  497.             img.marker_mul.QCC = tmp;
  498.           }
  499.       img.marker_mul.QCC[img.marker_mul.num_QCC].type = J2K_MS_QCC;
  500.       img.marker_mul.QCC[img.marker_mul.num_QCC].start_pos = cio_tell() - 2;
  501.       img.marker_mul.QCC[img.marker_mul.num_QCC].len = len;
  502.       img.marker_mul.num_QCC++;
  503.     } else
  504.       {
  505.         tile = &img.tile[j2k_curtileno];
  506.         if (!tile->marker_mul.num_QCC)
  507.           tile->marker_mul.QCC = (info_marker_t*)malloc(tile->marker_mul.CzQCC * sizeof(info_marker_t));
  508.         if (tile->marker_mul.num_QCC >= tile->marker_mul.CzQCC)
  509.           {
  510.             tmp = (info_marker_t*)malloc((INCREMENT + tile->marker_mul.CzQCC) * sizeof(info_marker_t));
  511.             memcpy(tmp,tile->marker_mul.QCC,tile->marker_mul.CzQCC);
  512.             tile->marker_mul.CzQCC += INCREMENT;
  513.             free(tile->marker_mul.QCC);
  514.             tile->marker_mul.QCC = tmp;
  515.           }
  516.         tile->marker_mul.QCC[tile->marker_mul.num_QCC].type = J2K_MS_QCC;
  517.         tile->marker_mul.QCC[tile->marker_mul.num_QCC].start_pos = cio_tell()-2;
  518.         tile->marker_mul.QCC[tile->marker_mul.num_QCC].len = len;
  519.         tile->marker_mul.num_QCC++;
  520.       }
  521.   /* </INDEX> [MHIX BOX] */
  522.  
  523.   compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);
  524.   j2k_read_qcx(compno, len - 2 - (j2k_img->numcomps <= 256 ? 1 : 2));
  525. }
  526.  
  527.  
  528.  
  529.  
  530. void j2k_read_poc() {
  531.   int len, numpchgs, i, old_poc;
  532.   j2k_tcp_t *tcp;
  533.   j2k_tccp_t *tccp;
  534.   info_tile_t *tile;
  535.  
  536.   tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
  537.   old_poc = tcp->POC ? tcp->numpocs+1 : 0;
  538.   tcp->POC = 1;
  539.   tccp = &tcp->tccps[0];
  540.   len = cio_read(2);
  541.  
  542.   /* <INDEX> [MHIX BOX] */
  543.   if (j2k_state == J2K_STATE_MH)
  544.     {
  545.       img.marker[img.num_marker].type = J2K_MS_POC;
  546.       img.marker[img.num_marker].start_pos = cio_tell()-2;
  547.       img.marker[img.num_marker].len = len;
  548.       img.num_marker++;
  549.     } else
  550.       {
  551.         tile = &img.tile[j2k_curtileno];
  552.         tile->marker[tile->num_marker].type = J2K_MS_POC;
  553.         tile->marker[tile->num_marker].start_pos = cio_tell()-2;
  554.         tile->marker[tile->num_marker].len = len;
  555.         tile->num_marker++;
  556.       }
  557.   /* </INDEX> [MHIX BOX] */
  558.  
  559.     numpchgs = (len - 2) / (5 + 2 * (j2k_img->numcomps <= 256 ? 1 : 2));
  560.     for (i = 0; i < numpchgs; i++) {
  561.       j2k_poc_t *poc;
  562.       poc = &tcp->pocs[i];
  563.       poc->resno0 = cio_read(1);
  564.       poc->compno0 = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);
  565.       poc->layno1 = int_min(cio_read(2), tcp->numlayers);
  566.       poc->resno1 = int_min(cio_read(1), tccp->numresolutions);
  567.       poc->compno1 = int_min(cio_read(j2k_img->numcomps <= 256 ? 1 : 2), j2k_img->numcomps);
  568.       poc->prg = cio_read(1);
  569.     }
  570.  
  571.     tcp->numpocs = numpchgs + old_poc - 1;
  572. }
  573.  
  574.  
  575.  
  576.  
  577. void j2k_read_crg() {
  578.     int len, i, Xcrg_i, Ycrg_i;
  579.  
  580.     len = cio_read(2);
  581.  
  582.     /* <INDEX> [MHIX BOX] */
  583.     img.marker[img.num_marker].type = J2K_MS_CRG;
  584.     img.marker[img.num_marker].start_pos = cio_tell()-2;
  585.     img.marker[img.num_marker].len = len;
  586.     img.num_marker++;
  587.     /* </INDEX> [MHIX BOX] */
  588.  
  589.     for (i = 0; i < j2k_img->numcomps; i++)
  590.       {  
  591.         Xcrg_i = cio_read(2);
  592.         Ycrg_i = cio_read(2);
  593.       }
  594. }
  595.  
  596.  
  597.  
  598.  
  599. void j2k_read_tlm() {
  600.     int len, Ztlm, Stlm, ST, SP, tile_tlm, i;
  601.     long int Ttlm_i, Ptlm_i;
  602.     info_marker_t *tmp;
  603.  
  604.     len = cio_read(2);
  605.  
  606.     /* <INDEX> [MHIX BOX] */
  607.     if (!img.marker_mul.num_TLM)
  608.       img.marker_mul.TLM = (info_marker_t*)malloc(img.marker_mul.CzTLM * sizeof(info_marker_t));
  609.     if (img.marker_mul.num_TLM >= img.marker_mul.CzTLM)
  610.       {
  611.         tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzTLM) * sizeof(info_marker_t));
  612.         memcpy(tmp,img.marker_mul.TLM,img.marker_mul.CzTLM);
  613.         img.marker_mul.CzTLM += INCREMENT;
  614.         free(img.marker_mul.TLM);
  615.         img.marker_mul.TLM = tmp;
  616.       }
  617.     img.marker_mul.TLM[img.marker_mul.num_TLM].type = J2K_MS_TLM;
  618.     img.marker_mul.TLM[img.marker_mul.num_TLM].start_pos = cio_tell()-2;
  619.     img.marker_mul.TLM[img.marker_mul.num_TLM].len = len;
  620.     img.marker_mul.num_TLM++;
  621.     /* </INDEX> [MHIX BOX] */
  622.    
  623.     Ztlm = cio_read(1);
  624.     Stlm = cio_read(1);
  625.     ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
  626.     SP = (Stlm >> 6) & 0x01;
  627.     tile_tlm = (len - 4) / ((SP + 1) * 2 + ST);
  628.     for (i = 0; i < tile_tlm; i++)
  629.       {
  630.         Ttlm_i = cio_read(ST);
  631.         Ptlm_i = cio_read(SP ? 4 : 2);
  632.       }
  633. }
  634.  
  635.  
  636.  
  637.  
  638. void j2k_read_plm() {
  639.     int len, i, Z_plm, N_plm, add, packet_len=0;
  640.     info_marker_t *tmp;
  641.  
  642.     len=cio_read(2);
  643.  
  644.     /* <INDEX> [MHIX BOX] */
  645.     if (!img.marker_mul.num_PLM)
  646.       img.marker_mul.PLM = (info_marker_t*)malloc(img.marker_mul.CzPLM * sizeof(info_marker_t));
  647.     if (img.marker_mul.num_PLM >= img.marker_mul.CzPLM)
  648.       {
  649.         tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzPLM) * sizeof(info_marker_t));
  650.         memcpy(tmp,img.marker_mul.PLM,img.marker_mul.CzPLM);
  651.         img.marker_mul.CzPLM += INCREMENT;
  652.         free(img.marker_mul.PLM);
  653.         img.marker_mul.PLM = tmp;
  654.       }
  655.     img.marker_mul.PLM[img.marker_mul.num_PLM].type = J2K_MS_PLM;
  656.     img.marker_mul.PLM[img.marker_mul.num_PLM].start_pos = cio_tell()-2;
  657.     img.marker_mul.PLM[img.marker_mul.num_PLM].len = len;
  658.     img.marker_mul.num_PLM++;
  659.     /* </INDEX> [MHIX BOX] */
  660.  
  661.     Z_plm = cio_read(1);
  662.     len -= 3;
  663.     while (len > 0)
  664.       {
  665.         N_plm = cio_read(4);
  666.         len -= 4;
  667.         for (i = N_plm ; i > 0 ; i--)
  668.           {
  669.             add = cio_read(1);
  670.             len--;
  671.             packet_len = (packet_len << 7) + add;
  672.             if ((add & 0x80) == 0)
  673.               {
  674.                 /* New packet */
  675.                 packet_len = 0;
  676.               }
  677.             if (len <= 0) break;
  678.           }
  679.       }
  680. }
  681.  
  682.  
  683.  
  684.  
  685. void j2k_read_plt() {
  686.     int len, i, Zplt, packet_len=0, add;
  687.     info_tile_t *tile;
  688.     info_marker_t *tmp;
  689. ;
  690.     len = cio_read(2);
  691.  
  692.     /* <INDEX> [MHIX BOX] */
  693.     tile = &img.tile[j2k_curtileno];
  694.     if (!tile->marker_mul.num_PLT)
  695.       tile->marker_mul.PLT = (info_marker_t*)malloc(tile->marker_mul.CzPLT * sizeof(info_marker_t));
  696.     if (tile->marker_mul.num_PLT >= tile->marker_mul.CzPLT)
  697.       {
  698.         tmp = (info_marker_t*)malloc((INCREMENT + tile->marker_mul.CzPLT) * sizeof(info_marker_t));
  699.         memcpy(tmp,tile->marker_mul.PLT,tile->marker_mul.CzPLT);
  700.         tile->marker_mul.CzPLT += INCREMENT;
  701.         free(tile->marker_mul.PLT);
  702.         tile->marker_mul.PLT = tmp;
  703.       }
  704.  
  705.     tile->marker_mul.PLT[tile->marker_mul.num_PLT].type = J2K_MS_PLT;
  706.     tile->marker_mul.PLT[tile->marker_mul.num_PLT].start_pos = cio_tell()-2;
  707.     tile->marker_mul.PLT[tile->marker_mul.num_PLT].len = len;
  708.     tile->marker_mul.num_PLT++;
  709.     /* </INDEX> [MHIX BOX] */
  710.    
  711.     Zplt = cio_read(1);
  712.     for (i = len-3; i > 0; i--)
  713.       {
  714.         add = cio_read(1);
  715.         packet_len = (packet_len << 7) + add;
  716.         if ((add & 0x80) == 0)
  717.           {
  718.             /* New packet */
  719.             packet_len = 0;
  720.           }
  721.       }
  722. }
  723.  
  724.  
  725.  
  726.  
  727. void j2k_read_ppm() {
  728.     int len, Z_ppm, i, j;
  729.     int N_ppm;
  730.     info_marker_t *tmp;
  731.  
  732.     len = cio_read(2);
  733.    
  734.     /* <INDEX> [MHIX BOX] */
  735.     if (!img.marker_mul.num_PPM)
  736.       img.marker_mul.PPM = (info_marker_t*)malloc(img.marker_mul.CzPPM * sizeof(info_marker_t));
  737.     if (img.marker_mul.num_PPM >= img.marker_mul.CzPPM)
  738.       {
  739.         tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzPPM) * sizeof(info_marker_t));
  740.         memcpy(tmp,img.marker_mul.PPM,img.marker_mul.CzPPM);
  741.         img.marker_mul.CzPPM += INCREMENT;
  742.         free(img.marker_mul.PPM);
  743.         img.marker_mul.PPM = tmp;
  744.       }
  745.     img.marker_mul.PLM[img.marker_mul.num_PPM].type = J2K_MS_PPM;
  746.     img.marker_mul.PLM[img.marker_mul.num_PPM].start_pos = cio_tell()-2;
  747.     img.marker_mul.PLM[img.marker_mul.num_PPM].len = len;
  748.     img.marker_mul.num_PPM++;
  749.     /* </INDEX> [MHIX BOX] */
  750.    
  751.     j2k_cp->ppm = 1;
  752.    
  753.     Z_ppm = cio_read(1); /* Z_ppm */
  754.     len -= 3;
  755.     while (len > 0)
  756.       {
  757.         if (j2k_cp->ppm_previous == 0)
  758.           {
  759.             N_ppm = cio_read(4); /* N_ppm */
  760.             len -= 4;
  761.           } else
  762.             {
  763.               N_ppm = j2k_cp->ppm_previous;
  764.             }
  765.        
  766.         j = j2k_cp->ppm_store;
  767.         if (Z_ppm == 0) /* First PPM marker */
  768.           j2k_cp->ppm_data = (unsigned char*)calloc(N_ppm, sizeof(unsigned char));
  769.         else      /* NON-first PPM marker */
  770.           j2k_cp->ppm_data = (unsigned char*)realloc(j2k_cp->ppm_data, (N_ppm + j2k_cp->ppm_store) * sizeof(unsigned char));
  771.        
  772.         for (i = N_ppm ; i > 0 ; i--) /* Read packet header */
  773.           {
  774.             j2k_cp->ppm_data[j] = cio_read(1);
  775.             j++;
  776.             len--;
  777.             if (len == 0) break; /* Case of non-finished packet header in present marker but finished in next one */
  778.           }
  779.        
  780.         j2k_cp->ppm_previous = i - 1;
  781.         j2k_cp->ppm_store = j;
  782.       }
  783. }
  784.  
  785.  
  786.  
  787.  
  788. void j2k_read_ppt() {
  789.     int len, Z_ppt, i, j = 0;
  790.     j2k_tcp_t *tcp;
  791.     info_tile_t *tile;
  792.     len=cio_read(2);
  793.  
  794.     /* <INDEX> [MHIX BOX] */
  795.     tile = & img.tile[j2k_curtileno];
  796.     tile->marker[tile->num_marker].type = J2K_MS_PPT;
  797.     tile->marker[tile->num_marker].start_pos = cio_tell()-2;
  798.     tile->marker[tile->num_marker].len = len;
  799.     tile->num_marker++;
  800.     /* </INDEX> [MHIX BOX] */
  801.  
  802.     Z_ppt = cio_read(1);
  803.     tcp = &j2k_cp->tcps[j2k_curtileno];
  804.     tcp->ppt = 1;
  805.     if (Z_ppt == 0) /* First PPT marker */
  806.       {
  807.         tcp->ppt_data = (unsigned char*)calloc(len - 3, sizeof(unsigned char));
  808.         tcp->ppt_store = 0;
  809.       }
  810.     else      /* NON-first PPT marker */
  811.       tcp->ppt_data = (unsigned char*)realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char));
  812.    
  813.     j = tcp->ppt_store;
  814.     for (i = len - 3 ; i > 0 ; i--)
  815.       {
  816.         tcp->ppt_data[j] = cio_read(1);
  817.         j++;
  818.       }
  819.     tcp->ppt_store = j;
  820. }
  821.  
  822.  
  823.  
  824.  
  825. void j2k_read_sot() {
  826.     int len, tileno, totlen, partno, numparts, i;
  827.     j2k_tcp_t *tcp;
  828.     j2k_tccp_t *tmp;
  829.     info_tile_t *tile;
  830.     info_tile_part_t *tilepart_tmp;
  831.    
  832.  
  833.     //fprintf(stderr,"SOT\n");
  834.     len = cio_read(2);
  835.     tileno = cio_read(2);
  836.     /* <INDEX> [MHIX BOX] */
  837.     tile = & img.tile[tileno];
  838.     tile->marker[tile->num_marker].type = J2K_MS_SOT;
  839.     tile->marker[tile->num_marker].start_pos = cio_tell() - 4;
  840.     tile->marker[tile->num_marker].len = len;
  841.     tile->num_marker++;
  842.     /* </INDEX> [MHIX BOX] */
  843.  
  844.     totlen = cio_read(4);
  845.     if (!totlen) totlen = cio_numbytesleft() + 8;
  846.     partno = cio_read(1);
  847.     numparts = cio_read(1);
  848.  
  849.     /* <INDEX> */
  850.     if (tileno == 0 && partno == 0 )
  851.       img.Main_head_end = cio_tell() - 7;  /* Correction End = First byte of first SOT */
  852.    
  853.     img.tile[tileno].num_tile = tileno;
  854.     /* </INDEX> */
  855.  
  856.     tile->numparts = partno + 1;                                               /* INDEX : Number of tile_parts for the tile */
  857.     img.num_max_tile_parts = int_max(tile->numparts, img.num_max_tile_parts);  /* INDEX : Maximum number of tile_part per tile */
  858.  
  859.     if (partno == 0)
  860.     {
  861.       tile->tile_parts = (info_tile_part_t*)malloc(START_NB * sizeof(info_tile_part_t*));
  862.       tile->Cztile_parts = START_NB;
  863.     }
  864.     if (partno >= tile->Cztile_parts)
  865.       {
  866.         tilepart_tmp = (info_tile_part_t*)malloc((INCREMENT + tile->Cztile_parts) * sizeof(info_tile_part_t));
  867.         memcpy(tilepart_tmp, tile->tile_parts, tile->Cztile_parts);
  868.         tile->Cztile_parts += INCREMENT;
  869.         free(tile->tile_parts);
  870.         tile->tile_parts = tilepart_tmp;
  871.       }
  872.  
  873.     tile->tile_parts[partno].start_pos = cio_tell() - 12;        /* INDEX : start_pos of the tile_part       */
  874.     tile->tile_parts[partno].length = totlen;                    /* INDEX : length of the tile_part          */  
  875.     tile->tile_parts[partno].end_pos = totlen + cio_tell() - 12; /* INDEX : end position of the tile_part    */
  876.  
  877.  
  878.     j2k_curtileno = tileno;
  879.     j2k_eot = cio_getbp() - 12 + totlen;
  880.     j2k_state = J2K_STATE_TPH;
  881.     tcp = &j2k_cp->tcps[j2k_curtileno];
  882.    
  883.     tile->tile_parts[numparts].num_reso_AUX = tcp->tccps[0].numresolutions; /* INDEX : AUX value for TPIX       */
  884.  
  885.      if (partno == 0)
  886.        //  if (tcp->first == 1)
  887.       {
  888.         tmp = tcp->tccps;
  889.         *tcp = j2k_default_tcp;
  890.         /* Initialization PPT */
  891.         tcp->ppt = 0;
  892.         tcp->ppt_data = NULL;
  893.        
  894.         tcp->tccps = tmp;
  895.         for (i = 0; i < j2k_img->numcomps; i++) {
  896.           tcp->tccps[i] = j2k_default_tcp.tccps[i];
  897.         }
  898.         //j2k_cp->tcps[j2k_curtileno].first=0;
  899.       }
  900. }
  901.  
  902.  
  903.  
  904. void j2k_read_rgn() {
  905.     int len, compno, roisty;
  906.     j2k_tcp_t *tcp;
  907.     info_tile_t *tile;
  908.     info_marker_t *tmp;
  909.     // fprintf(stderr,"RGN\n");
  910.     tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp;
  911.     len = cio_read(2);
  912.    
  913.     /* <INDEX> [MHIX BOX]*/
  914.     if (j2k_state == J2K_STATE_MH)
  915.       {
  916.         if (!img.marker_mul.num_RGN)
  917.           img.marker_mul.RGN = (info_marker_t*)malloc(img.marker_mul.CzRGN * sizeof(info_marker_t));
  918.         if (img.marker_mul.num_RGN >= img.marker_mul.CzRGN)
  919.           {
  920.             tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzRGN) * sizeof(info_marker_t));
  921.             memcpy(tmp,img.marker_mul.RGN, img.marker_mul.CzRGN);
  922.             img.marker_mul.CzRGN += INCREMENT;
  923.             free(img.marker_mul.RGN);
  924.             img.marker_mul.RGN = tmp;
  925.           }
  926.         img.marker_mul.RGN[img.marker_mul.num_RGN].type = J2K_MS_RGN;
  927.         img.marker_mul.RGN[img.marker_mul.num_RGN].start_pos = cio_tell() - 2;
  928.         img.marker_mul.RGN[img.marker_mul.num_RGN].len = len;
  929.         img.marker_mul.num_RGN++;
  930.       } else
  931.       {
  932.         tile = &img.tile[j2k_curtileno];
  933.         if (!tile->marker_mul.num_RGN)
  934.           tile->marker_mul.RGN = (info_marker_t*)malloc(tile->marker_mul.CzRGN * sizeof(info_marker_t));
  935.         if (tile->marker_mul.num_RGN >= tile->marker_mul.CzRGN)
  936.           {
  937.             tmp = (info_marker_t*)malloc((INCREMENT + tile->marker_mul.CzRGN) * sizeof(info_marker_t));
  938.             memcpy(tmp,tile->marker_mul.RGN,tile->marker_mul.CzRGN);
  939.             tile->marker_mul.CzRGN += INCREMENT;
  940.             free(tile->marker_mul.RGN);
  941.             tile->marker_mul.RGN = tmp;
  942.           }
  943.  
  944.         tile->marker_mul.RGN[tile->marker_mul.num_RGN].type = J2K_MS_RGN;
  945.         tile->marker_mul.RGN[tile->marker_mul.num_RGN].start_pos = cio_tell() - 2;
  946.         tile->marker_mul.RGN[tile->marker_mul.num_RGN].len = len;
  947.         tile->marker_mul.num_RGN++;
  948.       }
  949.     /* </INDEX> [MHIX BOX] */
  950.    
  951.     compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2);
  952.     roisty = cio_read(1);
  953.     tcp->tccps[compno].roishift = cio_read(1);
  954. }
  955.  
  956.  
  957.  
  958.  
  959.  
  960. void j2k_read_sod() {
  961.     int len;
  962.     unsigned char *data;
  963.     info_tile_t *tile;
  964.     info_tile_part_t *tile_part;
  965.     // fprintf(stderr,"SOD\n");
  966.     /* <INDEX> [MHIX BOX] */
  967.     tile = &img.tile[j2k_curtileno];
  968.     tile->marker[tile->num_marker].type = J2K_MS_SOD;
  969.     tile->marker[tile->num_marker].start_pos = cio_tell();
  970.     tile->marker[tile->num_marker].len = 0;
  971.     tile->num_marker++;
  972.     /* </INDEX> [MHIX BOX] */
  973.  
  974.     tile_part = &tile->tile_parts[tile->numparts - 1];                   /* INDEX : Current tilepart of a tile                  */
  975.     tile_part->length_header = cio_tell() - 1 - tile_part->start_pos;    /* INDEX : length of the tile-part header              */
  976.     tile_part->end_header = cio_tell() - 1;                              /* INDEX : end header position of the tile-part header */
  977.  
  978.     len = int_min(j2k_eot - cio_getbp(), cio_numbytesleft());
  979.    
  980.     j2k_tile_len[j2k_curtileno] += len;
  981.     data = (unsigned char*)realloc(j2k_tile_data[j2k_curtileno], j2k_tile_len[j2k_curtileno]);  
  982.     memcpy(data, cio_getbp(), len);
  983.     j2k_tile_data[j2k_curtileno] = data;
  984.     cio_skip(len);
  985.     j2k_state = J2K_STATE_TPHSOT;
  986. }
  987.  
  988. void j2k_read_eoc() {
  989.     int tileno;
  990.     tcd_init(j2k_img, j2k_cp, &img);
  991.     for (tileno = 0; tileno<j2k_cp->tw * j2k_cp->th; tileno++) {
  992.         tcd_decode_tile(j2k_tile_data[tileno], j2k_tile_len[tileno], tileno, &img);
  993.     }
  994.  
  995.     j2k_state = J2K_STATE_MT;
  996.      longjmp(j2k_error, 1);
  997. }
  998.  
  999.  
  1000.  
  1001.  
  1002. void j2k_read_unk() {
  1003.     fprintf(stderr, "warning: unknown marker\n");
  1004. }
  1005.  
  1006.  
  1007.  
  1008.  
  1009. int j2k_index_JPIP(char *Idx_file, char *J2K_file, int len, int version){
  1010.   FILE *dest;
  1011.   unsigned char *index;
  1012.   int pos_iptr, end_pos;
  1013.   int len_cidx, pos_cidx;
  1014.   int len_jp2c, pos_jp2c;
  1015.   int len_fidx, pos_fidx;
  1016.  
  1017.   dest=fopen(Idx_file, "wb");
  1018.   if (!dest) {
  1019.     fprintf(stderr, "Failed to open %s for reading !!\n", Idx_file);
  1020.     return 0;
  1021.   }
  1022.  
  1023.   /* INDEX MODE JPIP */
  1024.  index = (unsigned char*)malloc(len);
  1025.  cio_init(index, len);
  1026.  jp2_write_jp();
  1027.  jp2_write_ftyp();
  1028.  
  1029.  jp2_write_jp2h(j2k_img);
  1030.  jp2_write_dbtl(Idx_file);
  1031.  
  1032.  pos_iptr=cio_tell();
  1033.  cio_skip(24); /* IPTR further ! */
  1034.  
  1035.  pos_jp2c = cio_tell();
  1036.  len_jp2c = jp2_write_jp2c(J2K_file);
  1037.  
  1038.  pos_cidx = cio_tell();
  1039.  len_cidx = jpip_write_cidx(pos_jp2c + 8,img, j2k_cp, version); /* Correction len_jp2C --> pos_jp2c + 8 */  
  1040.  
  1041.  
  1042.  pos_fidx = cio_tell();
  1043.  len_fidx = jpip_write_fidx(pos_jp2c, len_jp2c, pos_cidx, len_cidx);
  1044.  
  1045. end_pos = cio_tell();
  1046.  
  1047.  cio_seek(pos_iptr);
  1048.  jpip_write_iptr(pos_fidx,len_fidx);
  1049.  cio_seek(end_pos);
  1050.  
  1051.  fwrite(index, 1, cio_tell(), dest);
  1052.  free(index);
  1053.  
  1054.  fclose(dest);
  1055.  return 1;
  1056. }
  1057.  
  1058.  
  1059.  
  1060. typedef struct {
  1061.   int id;
  1062.     int states;
  1063.     void (*handler)();
  1064. } j2k_dec_mstabent_t;
  1065.  
  1066. j2k_dec_mstabent_t j2k_dec_mstab[]={
  1067.     {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc},
  1068.     {J2K_MS_SOT, J2K_STATE_MH|J2K_STATE_TPHSOT, j2k_read_sot},
  1069.     {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod},
  1070.     {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc},
  1071.     {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz},
  1072.     {J2K_MS_COD, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_cod},
  1073.     {J2K_MS_COC, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_coc},
  1074.     {J2K_MS_RGN, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_rgn},
  1075.     {J2K_MS_QCD, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_qcd},
  1076.     {J2K_MS_QCC, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_qcc},
  1077.     {J2K_MS_POC, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_poc},
  1078.     {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm},
  1079.     {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm},
  1080.     {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt},
  1081.     {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm},
  1082.     {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt},
  1083.     {J2K_MS_SOP, 0, 0},
  1084.     {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg},
  1085.     {J2K_MS_COM, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_com},
  1086.     {0, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_unk}
  1087. };
  1088.  
  1089. j2k_dec_mstabent_t *j2k_dec_mstab_lookup(int id) {
  1090.   j2k_dec_mstabent_t *e;
  1091.   for (e = j2k_dec_mstab; e->id != 0; e++) {
  1092.     if (e->id == id) {
  1093.       break;
  1094.     }
  1095.   }
  1096.   return e;
  1097. }
  1098.  
  1099. int j2k_decode(unsigned char *src, int len, j2k_image_t **image, j2k_cp_t **cp) {
  1100.     if (setjmp(j2k_error)) {
  1101.         if (j2k_state != J2K_STATE_MT) {
  1102.             fprintf(stderr, "WARNING: incomplete bitstream\n");
  1103.             return 0;
  1104.         }
  1105.         return cio_numbytes();
  1106.     }
  1107.     j2k_img = (j2k_image_t*)calloc(1, sizeof(j2k_image_t));
  1108.     j2k_cp = (j2k_cp_t*)calloc(1, sizeof(j2k_cp_t));
  1109.     *image = j2k_img;
  1110.     *cp = j2k_cp;
  1111.     j2k_state = J2K_STATE_MHSOC;
  1112.     cio_init(src, len);
  1113.     for (;;) {
  1114.         j2k_dec_mstabent_t *e;
  1115.         int id = cio_read(2);
  1116.         if (id >> 8 != 0xff) {
  1117.             fprintf(stderr, "%.8x: expected a marker instead of %x\n", cio_tell() - 2, id);
  1118.             return 0;
  1119.         }
  1120.         e = j2k_dec_mstab_lookup(id);
  1121.         if (!(j2k_state & e->states)) {
  1122.             fprintf(stderr, "%.8x: unexpected marker %x\n", cio_tell() - 2, id);
  1123.             return 0;
  1124.         }
  1125.         if (e->handler) {
  1126.             (*e->handler)();
  1127.         }
  1128.     }
  1129.  
  1130. }
  1131.  
  1132.  
  1133. #ifdef _WIN32
  1134. #include <windows.h>
  1135.  
  1136. BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
  1137.     switch (ul_reason_for_call) {
  1138.                 case DLL_PROCESS_ATTACH:
  1139.                 case DLL_THREAD_ATTACH:
  1140.                 case DLL_THREAD_DETACH:
  1141.                 case DLL_PROCESS_DETACH:
  1142.                         break;
  1143.     }
  1144.     return TRUE;
  1145. }
  1146. #endif /* _WIN32 */
  1147.  
  1148. int main(int argc, char **argv)
  1149. {  
  1150.   FILE *src;
  1151.   int totlen;
  1152.   unsigned char *j2kfile;
  1153.   j2k_image_t *imgg;
  1154.   j2k_cp_t *cp;
  1155.   int version;
  1156.  
  1157.   if (argc != 4)
  1158.     {
  1159.       fprintf(stderr,"\nUSAGE : ./index_create J2K-file JP2-file version\n\nVersion : 0, 1, 2 or 3\n  0 : [faix] 4-byte and no AUX fields\n  1 : [faix] 8-byte and no AUX fields\n  2 : [faix] 4-byte and AUX fields\n  3 : [faix] 8-byte and AUX fields\n\nReference Document : annex I from JPIP-FCD-version 2 (SC 29 N5727)\n\n");
  1160.       return 1;
  1161.     }
  1162.  
  1163.   src=fopen(argv[1], "rb");
  1164.   if (!src) {
  1165.     fprintf(stderr, "Failed to open %s for reading !!\n", argv[1]);
  1166.     return 1;
  1167.   }
  1168.  
  1169.   /* length of the codestream */
  1170.   fseek(src, 0, SEEK_END);
  1171.   totlen = ftell(src);
  1172.   fseek(src, 0, SEEK_SET);
  1173.  
  1174.   j2kfile = (unsigned char*)malloc(totlen);
  1175.   fread(j2kfile, 1, totlen, src);
  1176.   fclose(src);
  1177.  
  1178.   img.marker = (info_marker_t*)malloc(32 * sizeof(info_marker_t));
  1179.   img.num_marker = 0;
  1180.   img.num_max_tile_parts = 0;
  1181.   img.marker_mul.num_COC = 0;
  1182.   img.marker_mul.CzCOC = START_NB;
  1183.   img.marker_mul.num_RGN = 0;
  1184.   img.marker_mul.CzRGN = START_NB;
  1185.   img.marker_mul.num_QCC = 0;
  1186.   img.marker_mul.CzQCC = START_NB;
  1187.   img.marker_mul.num_TLM = 0;
  1188.   img.marker_mul.CzTLM = START_NB;
  1189.   img.marker_mul.num_PLM = 0;
  1190.   img.marker_mul.CzPLM = START_NB;
  1191.   img.marker_mul.num_PPM = 0;
  1192.   img.marker_mul.CzPPM = START_NB;
  1193.   img.marker_mul.num_COM = 0;
  1194.   img.marker_mul.CzCOM = START_NB;
  1195.  
  1196.   /* decode */
  1197.  
  1198.   if (!j2k_decode(j2kfile, totlen, &imgg, &cp)) {
  1199.     fprintf(stderr, "Index_creator: failed to decode image!\n");
  1200.     free(j2kfile);
  1201.     return 1;
  1202.   }
  1203.   free(j2kfile);
  1204.  
  1205.   // fseek(src, 0, SEEK_SET);
  1206.   img.codestream_size = totlen;
  1207.   sscanf(argv[3], "%d", &version);
  1208.   if (version > 3)
  1209.     {
  1210.       fprintf(stderr,"Error : value of version unauthorized !!  Value accepted : 0, 1, 2 or 3 !!\n");
  1211.       return 0;
  1212.     }
  1213.  
  1214.   j2k_index_JPIP(argv[2], argv[1], totlen * 2 > 60000 ? totlen * 2 : 60000, version);
  1215.  
  1216.   j2k_clean();
  1217.   return 0;
  1218. }
  1219.  
  1220.