Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Copyright (c) 2001-2003, David Janssens
  3.  * Copyright (c) 2002-2003, Yannick Verschueren
  4.  * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
  5.  * Copyright (c) 2005, HervĂ© Drolon, FreeImage Team
  6.  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
  7.  * Copyright (c) 2005-2006, Dept. of Electronic and Information Engineering, Universita' degli Studi di Perugia, Italy
  8.  * All rights reserved.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
  20.  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  23.  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24.  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25.  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  27.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  28.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29.  * POSSIBILITY OF SUCH DAMAGE.
  30.  */
  31.  
  32. #include "../libopenjpeg/opj_includes.h"
  33.  
  34. #ifdef USE_JPWL
  35.  
  36. /** @defgroup JPWL JPWL - JPEG-2000 Part11 (JPWL) codestream manager */
  37. /*@{*/
  38.  
  39. /** @name Local static variables */
  40. /*@{*/
  41.  
  42. /** number of JPWL prepared markers */
  43. static int jwmarker_num;
  44. /** properties of JPWL markers to insert */
  45. static jpwl_marker_t jwmarker[JPWL_MAX_NO_MARKERS];
  46.  
  47. /*@}*/
  48.  
  49. /*@}*/
  50.  
  51. /** @name Local static functions */
  52. /*@{*/
  53.  
  54. /** create an EPC marker segment
  55. @param j2k J2K compressor handle
  56. @param esd_on true if ESD is activated
  57. @param red_on true if RED is activated
  58. @param epb_on true if EPB is activated
  59. @param info_on true if informative techniques are activated
  60. @return returns the freshly created EPC
  61. */
  62. jpwl_epc_ms_t *jpwl_epc_create(opj_j2k_t *j2k, bool esd_on, bool red_on, bool epb_on, bool info_on);
  63.  
  64. /*@}*/
  65.  
  66. /** create an EPC marker segment
  67. @param j2k J2K compressor handle
  68. @param comps considered component (-1=average, 0/1/2/...=component no.)
  69. @param addrm addressing mode (0=packet, 1=byte range, 2=packet range, 3=reserved)
  70. @param ad_size size of addresses (2/4 bytes)
  71. @param senst sensitivity type
  72. @param se_size sensitivity values size (1/2 bytes)
  73. @param tileno tile where this ESD lies (-1 means MH)
  74. @param svalnum number of sensitivity values (if 0, they will be automatically filled)
  75. @param sensval pointer to an array of sensitivity values (if NULL, they will be automatically filled)
  76. @return returns the freshly created ESD
  77. */
  78. jpwl_esd_ms_t *jpwl_esd_create(opj_j2k_t *j2k, int comps, unsigned char addrm, unsigned char ad_size,
  79.                                                                 unsigned char senst, int se_size, int tileno,
  80.                                                                 unsigned long int svalnum, void *sensval);
  81.                        
  82. /** this function is used to compare two JPWL markers based on
  83. their relevant wishlist position
  84. @param arg1 pointer to first marker
  85. @param arg2 pointer to second marker
  86. @return 1 if arg1>arg2, 0 if arg1=arg2, -1 if arg1<arg2
  87. */
  88. int jpwl_markcomp(const void *arg1, const void *arg2);
  89.  
  90. /** write an EPB MS to a buffer
  91. @param j2k J2K compressor handle
  92. @param epbmark pointer to the EPB MS
  93. @param buf pointer to the memory buffer
  94. */
  95. void jpwl_epb_write(opj_j2k_t *j2k, jpwl_epb_ms_t *epbmark, unsigned char *buf);
  96.  
  97. /** write an EPC MS to a buffer
  98. @param j2k J2K compressor handle
  99. @param epcmark pointer to the EPC MS
  100. @param buf pointer to the memory buffer
  101. */
  102. void jpwl_epc_write(opj_j2k_t *j2k, jpwl_epc_ms_t *epcmark, unsigned char *buf);
  103.  
  104. /** write an ESD MS to a buffer
  105. @param j2k J2K compressor handle
  106. @param esdmark pointer to the ESD MS
  107. @param buf pointer to the memory buffer
  108. */
  109. void jpwl_esd_write(opj_j2k_t *j2k, jpwl_esd_ms_t *esdmark, unsigned char *buf);
  110.  
  111. /*-----------------------------------------------------------------*/
  112.  
  113. void jpwl_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
  114.  
  115.         int mm;
  116.  
  117.         /* let's reset some settings */
  118.  
  119.         /* clear the existing markers */
  120.         for (mm = 0; mm < jwmarker_num; mm++) {
  121.  
  122.                 switch (jwmarker[mm].id) {
  123.  
  124.                 case J2K_MS_EPB:
  125.                         opj_free(jwmarker[mm].m.epbmark);
  126.                         break;
  127.  
  128.                 case J2K_MS_EPC:
  129.                         opj_free(jwmarker[mm].m.epcmark);
  130.                         break;
  131.  
  132.                 case J2K_MS_ESD:
  133.                         opj_free(jwmarker[mm].m.esdmark);
  134.                         break;
  135.  
  136.                 case J2K_MS_RED:
  137.                         opj_free(jwmarker[mm].m.redmark);
  138.                         break;
  139.  
  140.                 default:
  141.                         break;
  142.                 }
  143.         }
  144.  
  145.         /* clear the marker structure array */
  146.         memset(jwmarker, 0, sizeof(jpwl_marker_t) * JPWL_MAX_NO_MARKERS);
  147.  
  148.         /* no more markers in the list */
  149.         jwmarker_num = 0;
  150.  
  151.         /* let's begin creating a marker list, according to user wishes */
  152.         jpwl_prepare_marks(j2k, cio, image);
  153.  
  154.         /* now we dump the JPWL markers on the codestream */
  155.         jpwl_dump_marks(j2k, cio, image);
  156.  
  157.         /* do not know exactly what is this for,
  158.         but it gets called during index creation */
  159.         j2k->pos_correction = 0;
  160.  
  161. }
  162.  
  163. void j2k_add_marker(opj_codestream_info_t *cstr_info, unsigned short int type, int pos, int len) {
  164.  
  165.         if (!cstr_info)
  166.                 return;
  167.  
  168.         /* expand the list? */
  169.         if ((cstr_info->marknum + 1) > cstr_info->maxmarknum) {
  170.                 cstr_info->maxmarknum = 100 + (int) ((float) cstr_info->maxmarknum * 1.0F);
  171.                 cstr_info->marker = opj_realloc(cstr_info->marker, cstr_info->maxmarknum);
  172.         }
  173.  
  174.         /* add the marker */
  175.         cstr_info->marker[cstr_info->marknum].type = type;
  176.         cstr_info->marker[cstr_info->marknum].pos = pos;
  177.         cstr_info->marker[cstr_info->marknum].len = len;
  178.         cstr_info->marknum++;
  179.  
  180. }
  181.  
  182. void jpwl_prepare_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
  183.  
  184.         unsigned short int socsiz_len = 0;
  185.         int ciopos = cio_tell(cio), soc_pos = j2k->cstr_info->main_head_start;
  186.         unsigned char *socp = NULL;
  187.  
  188.         int tileno, acc_tpno, tpno, tilespec, hprot, sens, pprot, packspec, lastileno, packno;
  189.  
  190.         jpwl_epb_ms_t *epb_mark;
  191.         jpwl_epc_ms_t *epc_mark;
  192.         jpwl_esd_ms_t *esd_mark;
  193.  
  194.         /* find (SOC + SIZ) length */
  195.         /* I assume SIZ is always the first marker after SOC */
  196.         cio_seek(cio, soc_pos + 4);
  197.         socsiz_len = (unsigned short int) cio_read(cio, 2) + 4; /* add the 2 marks length itself */
  198.         cio_seek(cio, soc_pos + 0);
  199.         socp = cio_getbp(cio); /* pointer to SOC */
  200.  
  201.         /*
  202.          EPC MS for Main Header: if we are here it's required
  203.         */
  204.         /* create the EPC */
  205.         if ((epc_mark = jpwl_epc_create(
  206.                         j2k,
  207.                         j2k->cp->esd_on, /* is ESD present? */
  208.                         j2k->cp->red_on, /* is RED present? */
  209.                         j2k->cp->epb_on, /* is EPB present? */
  210.                         false /* are informative techniques present? */
  211.                 ))) {
  212.  
  213.                 /* Add this marker to the 'insertanda' list */
  214.                 if (epc_mark) {
  215.                         jwmarker[jwmarker_num].id = J2K_MS_EPC; /* its type */
  216.                         jwmarker[jwmarker_num].m.epcmark = epc_mark; /* the EPC */
  217.                         jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* after SIZ */
  218.                         jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.1; /* not so first */
  219.                         jwmarker[jwmarker_num].len = epc_mark->Lepc; /* its length */
  220.                         jwmarker[jwmarker_num].len_ready = true; /* ready */
  221.                         jwmarker[jwmarker_num].pos_ready = true; /* ready */
  222.                         jwmarker[jwmarker_num].parms_ready = false; /* not ready */
  223.                         jwmarker[jwmarker_num].data_ready = true; /* ready */
  224.                         jwmarker_num++;
  225.                 };
  226.  
  227.                 opj_event_msg(j2k->cinfo, EVT_INFO,
  228.                         "MH  EPC : setting %s%s%s\n",
  229.                         j2k->cp->esd_on ? "ESD, " : "",
  230.                         j2k->cp->red_on ? "RED, " : "",
  231.                         j2k->cp->epb_on ? "EPB, " : ""
  232.                         );
  233.  
  234.         } else {
  235.                 /* ooops, problems */
  236.                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH EPC\n");                             
  237.         };
  238.  
  239.         /*
  240.          ESD MS for Main Header
  241.         */
  242.         /* first of all, must MH have an ESD MS? */
  243.         if (j2k->cp->esd_on && (j2k->cp->sens_MH >= 0)) {
  244.  
  245.                 /* Create the ESD */
  246.                 if ((esd_mark = jpwl_esd_create(
  247.                         j2k, /* this encoder handle */
  248.                         -1, /* we are averaging over all components */
  249.                         (unsigned char) j2k->cp->sens_range, /* range method */
  250.                         (unsigned char) j2k->cp->sens_addr, /* sensitivity addressing */
  251.                         (unsigned char) j2k->cp->sens_MH, /* sensitivity method */
  252.                         j2k->cp->sens_size, /* sensitivity size */
  253.                         -1, /* this ESD is in main header */
  254.                         0 /*j2k->cstr_info->num*/, /* number of packets in codestream */
  255.                         NULL /*sensval*/ /* pointer to sensitivity data of packets */
  256.                         ))) {
  257.                        
  258.                         /* Add this marker to the 'insertanda' list */
  259.                         if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
  260.                                 jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */
  261.                                 jwmarker[jwmarker_num].m.esdmark = esd_mark; /* the EPB */
  262.                                 jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* we choose to place it after SIZ */
  263.                                 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */
  264.                                 jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */
  265.                                 jwmarker[jwmarker_num].len_ready = true; /* not ready, yet */
  266.                                 jwmarker[jwmarker_num].pos_ready = true; /* ready */
  267.                                 jwmarker[jwmarker_num].parms_ready = true; /* not ready */
  268.                                 jwmarker[jwmarker_num].data_ready = false; /* not ready */
  269.                                 jwmarker_num++;
  270.                         }
  271.  
  272.                         opj_event_msg(j2k->cinfo, EVT_INFO,
  273.                                 "MH  ESDs: method %d\n",
  274.                                 j2k->cp->sens_MH
  275.                                 );
  276.  
  277.                 } else {
  278.                         /* ooops, problems */
  279.                         opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH ESD\n");                             
  280.                 };
  281.  
  282.         }
  283.  
  284.         /*
  285.          ESD MSs for Tile Part Headers
  286.         */
  287.         /* cycle through tiles */
  288.         sens = -1; /* default spec: no ESD */
  289.         tilespec = 0; /* first tile spec */
  290.         acc_tpno = 0;
  291.         for (tileno = 0; tileno < j2k->cstr_info->tw * j2k->cstr_info->th; tileno++) {
  292.  
  293.                 opj_event_msg(j2k->cinfo, EVT_INFO,
  294.                         "Tile %d has %d tile part(s)\n",
  295.                         tileno, j2k->cstr_info->tile[tileno].num_tps
  296.                         );
  297.  
  298.                 /* for every tile part in the tile */
  299.                 for (tpno = 0; tpno < j2k->cstr_info->tile[tileno].num_tps; tpno++, acc_tpno++) {
  300.        
  301.                         int sot_len, Psot, Psotp, mm;
  302.                         unsigned long sot_pos, post_sod_pos;
  303.  
  304.                         unsigned long int left_THmarks_len;
  305.  
  306.                         /******* sot_pos = j2k->cstr_info->tile[tileno].start_pos; */
  307.                         sot_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos;
  308.                         cio_seek(cio, sot_pos + 2);
  309.                         sot_len = cio_read(cio, 2); /* SOT Len */
  310.                         cio_skip(cio, 2);
  311.                         Psotp = cio_tell(cio);
  312.                         Psot = cio_read(cio, 4); /* tile length */
  313.  
  314.                         /******* post_sod_pos = j2k->cstr_info->tile[tileno].end_header + 1; */
  315.                         post_sod_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_end_header + 1;
  316.                         left_THmarks_len = post_sod_pos - sot_pos;
  317.  
  318.                         /* add all the lengths of the markers which are len-ready and stay within SOT and SOD */
  319.                         for (mm = 0; mm < jwmarker_num; mm++) {
  320.                                 if ((jwmarker[mm].pos >= sot_pos) && (jwmarker[mm].pos < post_sod_pos)) {
  321.                                         if (jwmarker[mm].len_ready)
  322.                                                 left_THmarks_len += jwmarker[mm].len + 2;
  323.                                         else {
  324.                                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up TH EPB\n",
  325.                                                         jwmarker[mm].id, jwmarker[mm].dpos);                           
  326.                                                 exit(1);
  327.                                         }
  328.                                 }
  329.                         }
  330.  
  331.                         /******* if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->sens_TPH_tileno[tilespec] == tileno)) */
  332.                         if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->sens_TPH_tileno[tilespec] == acc_tpno))
  333.                                 /* we got a specification from this tile onwards */
  334.                                 sens = j2k->cp->sens_TPH[tilespec++];
  335.                
  336.                         /* must this TPH have an ESD MS? */
  337.                         if (j2k->cp->esd_on && (sens >= 0)) {
  338.  
  339.                                 /* Create the ESD */
  340.                                 if ((esd_mark = jpwl_esd_create(
  341.                                         j2k, /* this encoder handle */
  342.                                         -1, /* we are averaging over all components */
  343.                                         (unsigned char) j2k->cp->sens_range, /* range method */
  344.                                         (unsigned char) j2k->cp->sens_addr, /* sensitivity addressing size */
  345.                                         (unsigned char) sens, /* sensitivity method */
  346.                                         j2k->cp->sens_size, /* sensitivity value size */
  347.                                         tileno, /* this ESD is in a tile */
  348.                                         0, /* number of packets in codestream */
  349.                                         NULL /* pointer to sensitivity data of packets */
  350.                                         ))) {
  351.                                        
  352.                                         /* Add this marker to the 'insertanda' list */
  353.                                         if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
  354.                                                 jwmarker[jwmarker_num].id = J2K_MS_ESD; /* its type */
  355.                                                 jwmarker[jwmarker_num].m.esdmark = esd_mark; /* the EPB */
  356.                                                 /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */
  357.                                                 jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */
  358.                                                 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos + 0.2; /* not first at all! */
  359.                                                 jwmarker[jwmarker_num].len = esd_mark->Lesd; /* its length */
  360.                                                 jwmarker[jwmarker_num].len_ready = true; /* ready, yet */
  361.                                                 jwmarker[jwmarker_num].pos_ready = true; /* ready */
  362.                                                 jwmarker[jwmarker_num].parms_ready = true; /* not ready */
  363.                                                 jwmarker[jwmarker_num].data_ready = false; /* ready */
  364.                                                 jwmarker_num++;
  365.                                         }
  366.  
  367.                                         /* update Psot of the tile  */
  368.                                         cio_seek(cio, Psotp);
  369.                                         cio_write(cio, Psot + esd_mark->Lesd + 2, 4);
  370.  
  371.                                         opj_event_msg(j2k->cinfo, EVT_INFO,
  372.                                                 /******* "TPH ESDs: tile %02d, method %d\n", */
  373.                                                 "TPH ESDs: tile %02d, part %02d, method %d\n",
  374.                                                 /******* tileno, */
  375.                                                 tileno, tpno,
  376.                                                 sens
  377.                                                 );
  378.  
  379.                                 } else {
  380.                                         /* ooops, problems */
  381.                                         /***** opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH ESD #%d\n", tileno); */
  382.                                         opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH ESD #%d,%d\n", tileno, tpno);
  383.                                 };
  384.  
  385.                         }
  386.                        
  387.                 }
  388.        
  389.         };
  390.  
  391.         /*
  392.          EPB MS for Main Header
  393.         */
  394.         /* first of all, must MH have an EPB MS? */
  395.         if (j2k->cp->epb_on && (j2k->cp->hprot_MH > 0)) {
  396.  
  397.                 int mm;
  398.  
  399.                 /* position of SOT */
  400.                 unsigned int sot_pos = j2k->cstr_info->main_head_end + 1;
  401.  
  402.                 /* how much space is there between end of SIZ and beginning of SOT? */
  403.                 int left_MHmarks_len = sot_pos - socsiz_len;
  404.  
  405.                 /* add all the lengths of the markers which are len-ready and stay within SOC and SOT */
  406.                 for (mm = 0; mm < jwmarker_num; mm++) {
  407.                         if ((jwmarker[mm].pos >=0) && (jwmarker[mm].pos < sot_pos)) {
  408.                                 if (jwmarker[mm].len_ready)
  409.                                         left_MHmarks_len += jwmarker[mm].len + 2;
  410.                                 else {
  411.                                         opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up MH EPB\n",
  412.                                                 jwmarker[mm].id, jwmarker[mm].dpos);                           
  413.                                         exit(1);
  414.                                 }
  415.                         }
  416.                 }
  417.  
  418.                 /* Create the EPB */
  419.                 if ((epb_mark = jpwl_epb_create(
  420.                         j2k, /* this encoder handle */
  421.                         true, /* is it the latest? */
  422.                         true, /* is it packed? not for now */
  423.                         -1, /* we are in main header */
  424.                         0, /* its index is 0 (first) */
  425.                         j2k->cp->hprot_MH, /* protection type parameters of data */
  426.                         socsiz_len, /* pre-data: only SOC+SIZ */
  427.                         left_MHmarks_len /* post-data: from SOC to SOT, and all JPWL markers within */
  428.                         ))) {
  429.                        
  430.                         /* Add this marker to the 'insertanda' list */
  431.                         if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
  432.                                 jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */
  433.                                 jwmarker[jwmarker_num].m.epbmark = epb_mark; /* the EPB */
  434.                                 jwmarker[jwmarker_num].pos = soc_pos + socsiz_len; /* after SIZ */
  435.                                 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */
  436.                                 jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */
  437.                                 jwmarker[jwmarker_num].len_ready = true; /* ready */
  438.                                 jwmarker[jwmarker_num].pos_ready = true; /* ready */
  439.                                 jwmarker[jwmarker_num].parms_ready = true; /* ready */
  440.                                 jwmarker[jwmarker_num].data_ready = false; /* not ready */
  441.                                 jwmarker_num++;
  442.                         }
  443.  
  444.                         opj_event_msg(j2k->cinfo, EVT_INFO,
  445.                                 "MH  EPB : prot. %d\n",
  446.                                 j2k->cp->hprot_MH
  447.                                 );
  448.  
  449.                 } else {
  450.                         /* ooops, problems */
  451.                         opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create MH EPB\n");                             
  452.                 };
  453.         }
  454.  
  455.         /*
  456.          EPB MSs for Tile Parts
  457.         */
  458.         /* cycle through TPHs */
  459.         hprot = j2k->cp->hprot_MH; /* default spec */
  460.         tilespec = 0; /* first tile spec */
  461.         lastileno = 0;
  462.         packspec = 0;
  463.         pprot = -1;
  464.         acc_tpno = 0;
  465.         for (tileno = 0; tileno < j2k->cstr_info->tw * j2k->cstr_info->th; tileno++) {
  466.  
  467.                 opj_event_msg(j2k->cinfo, EVT_INFO,
  468.                         "Tile %d has %d tile part(s)\n",
  469.                         tileno, j2k->cstr_info->tile[tileno].num_tps
  470.                         );
  471.  
  472.                 /* for every tile part in the tile */
  473.                 for (tpno = 0; tpno < j2k->cstr_info->tile[tileno].num_tps; tpno++, acc_tpno++) {
  474.                
  475.                         int sot_len, Psot, Psotp, mm, epb_index = 0, prot_len = 0;
  476.                         unsigned long sot_pos, post_sod_pos;
  477.                         unsigned long int left_THmarks_len/*, epbs_len = 0*/;
  478.                         int startpack = 0, stoppack = j2k->cstr_info->packno;
  479.                         int first_tp_pack, last_tp_pack;
  480.                         jpwl_epb_ms_t *tph_epb = NULL;
  481.  
  482.                         /****** sot_pos = j2k->cstr_info->tile[tileno].start_pos; */
  483.                         sot_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos;
  484.                         cio_seek(cio, sot_pos + 2);
  485.                         sot_len = cio_read(cio, 2); /* SOT Len */
  486.                         cio_skip(cio, 2);
  487.                         Psotp = cio_tell(cio);
  488.                         Psot = cio_read(cio, 4); /* tile length */
  489.  
  490.                         /* a-priori length of the data dwelling between SOT and SOD */
  491.                         /****** post_sod_pos = j2k->cstr_info->tile[tileno].end_header + 1; */
  492.                         post_sod_pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_end_header + 1;
  493.                         left_THmarks_len = post_sod_pos - (sot_pos + sot_len + 2);
  494.  
  495.                         /* add all the lengths of the JPWL markers which are len-ready and stay within SOT and SOD */
  496.                         for (mm = 0; mm < jwmarker_num; mm++) {
  497.                                 if ((jwmarker[mm].pos >= sot_pos) && (jwmarker[mm].pos < post_sod_pos)) {
  498.                                         if (jwmarker[mm].len_ready)
  499.                                                 left_THmarks_len += jwmarker[mm].len + 2;
  500.                                         else {
  501.                                                 opj_event_msg(j2k->cinfo, EVT_ERROR, "MS %x in %f is not len-ready: could not set up TH EPB\n",
  502.                                                         jwmarker[mm].id, jwmarker[mm].dpos);                           
  503.                                                 exit(1);
  504.                                         }
  505.                                 }
  506.                         }
  507.  
  508.                         /****** if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->hprot_TPH_tileno[tilespec] == tileno)) */
  509.                         if ((tilespec < JPWL_MAX_NO_TILESPECS) && (j2k->cp->hprot_TPH_tileno[tilespec] == acc_tpno))
  510.                                 /* we got a specification from this tile part onwards */
  511.                                 hprot = j2k->cp->hprot_TPH[tilespec++];
  512.                
  513.                         /* must this TPH have an EPB MS? */
  514.                         if (j2k->cp->epb_on && (hprot > 0)) {
  515.  
  516.                                 /* Create the EPB */
  517.                                 if ((epb_mark = jpwl_epb_create(
  518.                                         j2k, /* this encoder handle */
  519.                                         false, /* is it the latest? in TPH, no for now (if huge data size in TPH, we'd need more) */
  520.                                         true, /* is it packed? yes for now */
  521.                                         tileno, /* we are in TPH */
  522.                                         epb_index++, /* its index is 0 (first) */
  523.                                         hprot, /* protection type parameters of following data */
  524.                                         sot_len + 2, /* pre-data length: only SOT */
  525.                                         left_THmarks_len /* post-data length: from SOT end to SOD inclusive */
  526.                                         ))) {
  527.                                        
  528.                                         /* Add this marker to the 'insertanda' list */
  529.                                         if (jwmarker_num < JPWL_MAX_NO_MARKERS) {
  530.                                                 jwmarker[jwmarker_num].id = J2K_MS_EPB; /* its type */
  531.                                                 jwmarker[jwmarker_num].m.epbmark = epb_mark; /* the EPB */
  532.                                                 /****** jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].start_pos + sot_len + 2; */ /* after SOT */
  533.                                                 jwmarker[jwmarker_num].pos = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2; /* after SOT */
  534.                                                 jwmarker[jwmarker_num].dpos = (double) jwmarker[jwmarker_num].pos; /* first first first! */
  535.                                                 jwmarker[jwmarker_num].len = epb_mark->Lepb; /* its length */
  536.                                                 jwmarker[jwmarker_num].len_ready = true; /* ready */
  537.                                                 jwmarker[jwmarker_num].pos_ready = true; /* ready */
  538.                                                 jwmarker[jwmarker_num].parms_ready = true; /* ready */
  539.                                                 jwmarker[jwmarker_num].data_ready = false; /* not ready */
  540.                                                 jwmarker_num++;
  541.                                         }
  542.  
  543.                                         /* update Psot of the tile  */
  544.                                         Psot += epb_mark->Lepb + 2;
  545.  
  546.                                         opj_event_msg(j2k->cinfo, EVT_INFO,
  547.                                                 /***** "TPH EPB : tile %02d, prot. %d\n", */
  548.                                                 "TPH EPB : tile %02d, part %02d, prot. %d\n",
  549.                                                 /***** tileno, */
  550.                                                 tileno, tpno,
  551.                                                 hprot
  552.                                                 );
  553.  
  554.                                         /* save this TPH EPB address */
  555.                                         tph_epb = epb_mark;
  556.  
  557.                                 } else {
  558.                                         /* ooops, problems */
  559.                                         /****** opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB #%d\n", tileno); */
  560.                                         opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not create TPH EPB in #%d,d\n", tileno, tpno);
  561.                                 };
  562.  
  563.                         }                              
  564.                
  565.                         startpack = 0;
  566.                         /* EPB MSs for UEP packet data protection in Tile Parts */
  567.                         /****** for (packno = 0; packno < j2k->cstr_info->num; packno++) { */
  568.                         /*first_tp_pack = (tpno > 0) ? (first_tp_pack + j2k->cstr_info->tile[tileno].tp[tpno - 1].tp_numpacks) : 0;*/
  569.                         first_tp_pack = j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pack;
  570.                         last_tp_pack = first_tp_pack + j2k->cstr_info->tile[tileno].tp[tpno].tp_numpacks - 1;
  571.                         for (packno = 0; packno < j2k->cstr_info->tile[tileno].tp[tpno].tp_numpacks; packno++) {
  572.  
  573.                                 /******** if ((packspec < JPWL_MAX_NO_PACKSPECS) &&
  574.                                         (j2k->cp->pprot_tileno[packspec] == tileno) && (j2k->cp->pprot_packno[packspec] == packno)) { */
  575.                                 if ((packspec < JPWL_MAX_NO_PACKSPECS) &&
  576.                                         (j2k->cp->pprot_tileno[packspec] == acc_tpno) && (j2k->cp->pprot_packno[packspec] == packno)) {
  577.  
  578.                                         /* we got a specification from this tile and packet onwards */
  579.                                         /* print the previous spec */
  580.                                         if (packno > 0) {
  581.                                                 stoppack = packno - 1;                         
  582.                                                 opj_event_msg(j2k->cinfo, EVT_INFO,
  583.                                                         /***** "UEP EPBs: tile %02d, packs. %02d-%02d (B %d-%d), prot. %d\n", */
  584.                                                         "UEP EPBs: tile %02d, part %02d, packs. %02d-%02d (B %d-%d), prot. %d\n",
  585.                                                         /***** tileno, */
  586.                                                         tileno, tpno,
  587.                                                         startpack,
  588.                                                         stoppack,
  589.                                                         /***** j2k->cstr_info->tile[tileno].packet[startpack].start_pos, */
  590.                                                         j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos,
  591.                                                         /***** j2k->cstr_info->tile[tileno].packet[stoppack].end_pos, */
  592.                                                         j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos,
  593.                                                         pprot);
  594.  
  595.                                                 /***** prot_len = j2k->cstr_info->tile[tileno].packet[stoppack].end_pos + 1 -
  596.                                                         j2k->cstr_info->tile[tileno].packet[startpack].start_pos; */
  597.                                                 prot_len = j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos + 1 -
  598.                                                         j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos;
  599.  
  600.                                                 /*
  601.                                                   particular case: if this is the last header and the last packet,
  602.                                                   then it is better to protect even the EOC marker
  603.                                                 */
  604.                                                 /****** if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
  605.                                                         (stoppack == (j2k->cstr_info->num - 1))) */
  606.                                                 if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
  607.                                                         (tpno == (j2k->cstr_info->tile[tileno].num_tps - 1)) &&
  608.                                                         (stoppack == last_tp_pack))
  609.                                                         /* add the EOC len */
  610.                                                         prot_len += 2;
  611.  
  612.                                                 /* let's add the EPBs */
  613.                                                 Psot += jpwl_epbs_add(
  614.                                                         j2k, /* J2K handle */
  615.                                                         jwmarker, /* pointer to JPWL markers list */
  616.                                                         &jwmarker_num, /* pointer to the number of current markers */
  617.                                                         false, /* latest */
  618.                                                         true, /* packed */
  619.                                                         false, /* inside MH */
  620.                                                         &epb_index, /* pointer to EPB index */
  621.                                                         pprot, /* protection type */
  622.                                                         /****** (double) (j2k->cstr_info->tile[tileno].start_pos + sot_len + 2) + 0.0001, */ /* position */
  623.                                                         (double) (j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2) + 0.0001, /* position */
  624.                                                         tileno, /* number of tile */
  625.                                                         0, /* length of pre-data */
  626.                                                         prot_len /*4000*/ /* length of post-data */
  627.                                                         );
  628.                                         }
  629.  
  630.                                         startpack = packno;
  631.                                         pprot = j2k->cp->pprot[packspec++];
  632.                                 }
  633.  
  634.                                 //printf("Tile %02d, pack %02d ==> %d\n", tileno, packno, pprot);
  635.                
  636.                         }
  637.  
  638.                         /* we are at the end: print the remaining spec */
  639.                         stoppack = packno - 1;
  640.                         if (pprot >= 0) {
  641.  
  642.                                 opj_event_msg(j2k->cinfo, EVT_INFO,
  643.                                         /**** "UEP EPBs: tile %02d, packs. %02d-%02d (B %d-%d), prot. %d\n", */
  644.                                         "UEP EPBs: tile %02d, part %02d, packs. %02d-%02d (B %d-%d), prot. %d\n",
  645.                                         /**** tileno, */
  646.                                         tileno, tpno,
  647.                                         startpack,
  648.                                         stoppack,
  649.                                         /***** j2k->image_info->tile[tileno].packet[startpack].start_pos,
  650.                                         j2k->image_info->tile[tileno].packet[stoppack].end_pos, */
  651.                                         j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos,
  652.                                         j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos,
  653.                                         pprot);
  654.  
  655.                                 /***** prot_len = j2k->cstr_info->tile[tileno].packet[stoppack].end_pos + 1 -
  656.                                         j2k->cstr_info->tile[tileno].packet[startpack].start_pos; */
  657.                                 prot_len = j2k->cstr_info->tile[tileno].packet[first_tp_pack + stoppack].end_pos + 1 -
  658.                                         j2k->cstr_info->tile[tileno].packet[first_tp_pack + startpack].start_pos;
  659.  
  660.                                 /*
  661.                                   particular case: if this is the last header and the last packet,
  662.                                   then it is better to protect even the EOC marker
  663.                                 */
  664.                                 /***** if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
  665.                                         (stoppack == (j2k->cstr_info->num - 1))) */
  666.                                 if ((tileno == ((j2k->cstr_info->tw * j2k->cstr_info->th) - 1)) &&
  667.                                         (tpno == (j2k->cstr_info->tile[tileno].num_tps - 1)) &&
  668.                                         (stoppack == last_tp_pack))
  669.                                         /* add the EOC len */
  670.                                         prot_len += 2;
  671.  
  672.                                 /* let's add the EPBs */
  673.                                 Psot += jpwl_epbs_add(
  674.                                                         j2k, /* J2K handle */
  675.                                                         jwmarker, /* pointer to JPWL markers list */
  676.                                                         &jwmarker_num, /* pointer to the number of current markers */
  677.                                                         true, /* latest */
  678.                                                         true, /* packed */
  679.                                                         false, /* inside MH */
  680.                                                         &epb_index, /* pointer to EPB index */
  681.                                                         pprot, /* protection type */
  682.                                                         /***** (double) (j2k->cstr_info->tile[tileno].start_pos + sot_len + 2) + 0.0001,*/ /* position */
  683.                                                         (double) (j2k->cstr_info->tile[tileno].tp[tpno].tp_start_pos + sot_len + 2) + 0.0001, /* position */
  684.                                                         tileno, /* number of tile */
  685.                                                         0, /* length of pre-data */
  686.                                                         prot_len /*4000*/ /* length of post-data */
  687.                                                         );
  688.                         }
  689.  
  690.                         /* we can now check if the TPH EPB was really the last one */
  691.                         if (tph_epb && (epb_index == 1)) {
  692.                                 /* set the TPH EPB to be the last one in current header */
  693.                                 tph_epb->Depb |= (unsigned char) ((true & 0x0001) << 6);
  694.                                 tph_epb = NULL;
  695.                         }
  696.  
  697.                         /* write back Psot */
  698.                         cio_seek(cio, Psotp);
  699.                         cio_write(cio, Psot, 4);
  700.                
  701.                 }
  702.  
  703.         };
  704.  
  705.         /* reset the position */
  706.         cio_seek(cio, ciopos);
  707.  
  708. }
  709.  
  710. void jpwl_dump_marks(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image) {
  711.  
  712.         int mm;
  713.         unsigned long int old_size = j2k->cstr_info->codestream_size;
  714.         unsigned long int new_size = old_size;
  715.         int /*ciopos = cio_tell(cio),*/ soc_pos = j2k->cstr_info->main_head_start;
  716.         unsigned char *jpwl_buf, *orig_buf;
  717.         unsigned long int orig_pos;
  718.         double epbcoding_time = 0.0, esdcoding_time = 0.0;
  719.  
  720.         /* Order JPWL markers according to their wishlist position */
  721.         qsort((void *) jwmarker, (size_t) jwmarker_num, sizeof (jpwl_marker_t), jpwl_markcomp);
  722.  
  723.         /* compute markers total size */
  724.         for (mm = 0; mm < jwmarker_num; mm++) {
  725.                 /*printf("%x, %d, %.10f, %d long\n", jwmarker[mm].id, jwmarker[mm].pos,
  726.                         jwmarker[mm].dpos, jwmarker[mm].len);*/
  727.                 new_size += jwmarker[mm].len + 2;
  728.         }
  729.  
  730.         /* allocate a new buffer of proper size */
  731.         if (!(jpwl_buf = (unsigned char *) opj_malloc((size_t) (new_size + soc_pos) * sizeof(unsigned char)))) {
  732.                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not allocate room for JPWL codestream buffer\n");
  733.                 exit(1);
  734.         };
  735.  
  736.         /* copy the jp2 part, if any */
  737.         orig_buf = jpwl_buf;
  738.         memcpy(jpwl_buf, cio->buffer, soc_pos);
  739.         jpwl_buf += soc_pos;
  740.  
  741.         /* cycle through markers */
  742.         orig_pos = soc_pos + 0; /* start from the beginning */
  743.         cio_seek(cio, soc_pos + 0); /* rewind the original */
  744.         for (mm = 0; mm < jwmarker_num; mm++) {
  745.  
  746.                 /*
  747.                 need to copy a piece of the original codestream
  748.                 if there is such
  749.                 */
  750.                 memcpy(jpwl_buf, cio_getbp(cio), jwmarker[mm].pos - orig_pos);
  751.                 jpwl_buf += jwmarker[mm].pos - orig_pos;
  752.                 orig_pos = jwmarker[mm].pos;
  753.                 cio_seek(cio, orig_pos);
  754.  
  755.                 /*
  756.                 then write down the marker
  757.                 */
  758.                 switch (jwmarker[mm].id) {
  759.  
  760.                 case J2K_MS_EPB:
  761.                         jpwl_epb_write(j2k, jwmarker[mm].m.epbmark, jpwl_buf);
  762.                         break;
  763.  
  764.                 case J2K_MS_EPC:
  765.                         jpwl_epc_write(j2k, jwmarker[mm].m.epcmark, jpwl_buf);
  766.                         break;
  767.  
  768.                 case J2K_MS_ESD:
  769.                         jpwl_esd_write(j2k, jwmarker[mm].m.esdmark, jpwl_buf);
  770.                         break;
  771.  
  772.                 case J2K_MS_RED:
  773.                         memset(jpwl_buf, 0, jwmarker[mm].len + 2); /* placeholder */
  774.                         break;
  775.  
  776.                 default:
  777.                         break;
  778.                 };
  779.  
  780.                 /* we update the markers struct */
  781.                 if (j2k->cstr_info)
  782.                         j2k->cstr_info->marker[j2k->cstr_info->marknum - 1].pos = (jpwl_buf - orig_buf);
  783.                
  784.                 /* we set the marker dpos to the new position in the JPWL codestream */
  785.                 jwmarker[mm].dpos = (double) (jpwl_buf - orig_buf);
  786.  
  787.                 /* advance JPWL buffer position */
  788.                 jpwl_buf += jwmarker[mm].len + 2;
  789.  
  790.         }
  791.  
  792.         /* finish remaining original codestream */
  793.         memcpy(jpwl_buf, cio_getbp(cio), old_size - (orig_pos - soc_pos));
  794.         jpwl_buf += old_size - (orig_pos - soc_pos);
  795.         cio_seek(cio, soc_pos + old_size);
  796.        
  797.         /*
  798.         update info file based on added markers
  799.         */
  800.         if (!jpwl_update_info(j2k, jwmarker, jwmarker_num))
  801.                 opj_event_msg(j2k->cinfo, EVT_ERROR, "Could not update OPJ cstr_info structure\n");
  802.  
  803.         /* now we need to repass some markers and fill their data fields */
  804.        
  805.         /* first of all, DL and Pcrc in EPCs */
  806.         for (mm = 0; mm < jwmarker_num; mm++) {
  807.  
  808.                 /* find the EPCs */
  809.                 if (jwmarker[mm].id == J2K_MS_EPC) {
  810.  
  811.                         int epc_pos = (int) jwmarker[mm].dpos, pp;
  812.                         unsigned short int mycrc = 0x0000;
  813.  
  814.                         /* fix and fill the DL field */
  815.                         jwmarker[mm].m.epcmark->DL = new_size;
  816.                         orig_buf[epc_pos + 6] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 24);
  817.                         orig_buf[epc_pos + 7] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 16);
  818.                         orig_buf[epc_pos + 8] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 8);
  819.                         orig_buf[epc_pos + 9] = (unsigned char) (jwmarker[mm].m.epcmark->DL >> 0);
  820.  
  821.                         /* compute the CRC field (excluding itself) */
  822.                         for (pp = 0; pp < 4; pp++)
  823.                                 jpwl_updateCRC16(&mycrc, orig_buf[epc_pos + pp]);
  824.                         for (pp = 6; pp < (jwmarker[mm].len + 2); pp++)
  825.                                 jpwl_updateCRC16(&mycrc, orig_buf[epc_pos + pp]);
  826.  
  827.                         /* fix and fill the CRC */
  828.                         jwmarker[mm].m.epcmark->Pcrc = mycrc;
  829.                         orig_buf[epc_pos + 4] = (unsigned char) (jwmarker[mm].m.epcmark->Pcrc >> 8);
  830.                         orig_buf[epc_pos + 5] = (unsigned char) (jwmarker[mm].m.epcmark->Pcrc >> 0);
  831.  
  832.                 }
  833.         }
  834.  
  835.         /* then, sensitivity data in ESDs */
  836.         esdcoding_time = opj_clock();
  837.         for (mm = 0; mm < jwmarker_num; mm++) {
  838.  
  839.                 /* find the ESDs */
  840.                 if (jwmarker[mm].id == J2K_MS_ESD) {
  841.  
  842.                         /* remember that they are now in a new position (dpos) */
  843.                         int esd_pos = (int) jwmarker[mm].dpos;
  844.  
  845.                         jpwl_esd_fill(j2k, jwmarker[mm].m.esdmark, &orig_buf[esd_pos]);
  846.                
  847.                 }
  848.  
  849.         }
  850.         esdcoding_time = opj_clock() - esdcoding_time;
  851.         if (j2k->cp->esd_on)
  852.                 opj_event_msg(j2k->cinfo, EVT_INFO, "ESDs sensitivities computed in %f s\n", esdcoding_time);
  853.  
  854.         /* finally, RS or CRC parity in EPBs */
  855.         epbcoding_time = opj_clock();
  856.         for (mm = 0; mm < jwmarker_num; mm++) {
  857.  
  858.                 /* find the EPBs */
  859.                 if (jwmarker[mm].id == J2K_MS_EPB) {
  860.  
  861.                         /* remember that they are now in a new position (dpos) */
  862.                         int nn, accum_len;
  863.  
  864.                         /* let's see how many EPBs are following this one, included itself */
  865.                         /* for this to work, we suppose that the markers are correctly ordered */
  866.                         /* and, overall, that they are in packed mode inside headers */
  867.                         accum_len = 0;
  868.                         for (nn = mm; (nn < jwmarker_num) && (jwmarker[nn].id == J2K_MS_EPB) &&
  869.                                 (jwmarker[nn].pos == jwmarker[mm].pos); nn++)
  870.                                 accum_len += jwmarker[nn].m.epbmark->Lepb + 2;
  871.  
  872.                         /* fill the current (first) EPB with post-data starting from the computed position */
  873.                         jpwl_epb_fill(j2k, jwmarker[mm].m.epbmark, &orig_buf[(int) jwmarker[mm].dpos],
  874.                                 &orig_buf[(int) jwmarker[mm].dpos + accum_len]);
  875.                
  876.                         /* fill the remaining EPBs in the header with post-data starting from the last position */
  877.                         for (nn = mm + 1; (nn < jwmarker_num) && (jwmarker[nn].id == J2K_MS_EPB) &&
  878.                                 (jwmarker[nn].pos == jwmarker[mm].pos); nn++)
  879.                                 jpwl_epb_fill(j2k, jwmarker[nn].m.epbmark, &orig_buf[(int) jwmarker[nn].dpos], NULL);
  880.  
  881.                         /* skip all the processed EPBs */
  882.                         mm = nn - 1;
  883.                 }
  884.  
  885.         }
  886.         epbcoding_time = opj_clock() - epbcoding_time;
  887.         if (j2k->cp->epb_on)
  888.                 opj_event_msg(j2k->cinfo, EVT_INFO, "EPBs redundancy computed in %f s\n", epbcoding_time);
  889.  
  890.         /* free original cio buffer and set it to the JPWL one */
  891.         opj_free(cio->buffer);
  892.         cio->cinfo = cio->cinfo; /* no change */
  893.         cio->openmode = cio->openmode; /* no change */
  894.         cio->buffer = orig_buf;
  895.         cio->length = new_size + soc_pos;
  896.         cio->start = cio->buffer;
  897.         cio->end = cio->buffer + cio->length;
  898.         cio->bp = cio->buffer;
  899.         cio_seek(cio, soc_pos + new_size);
  900.  
  901. }
  902.  
  903.  
  904. void j2k_read_epc(opj_j2k_t *j2k) {
  905.         unsigned long int DL, Lepcp, Pcrcp, l;
  906.         unsigned short int Lepc, Pcrc = 0x0000;
  907.         unsigned char Pepc;    
  908.         opj_cio_t *cio = j2k->cio;
  909.         char *ans1;
  910.  
  911.         /* Simply read the EPC parameters */
  912.         Lepcp = cio_tell(cio);
  913.         Lepc = cio_read(cio, 2);
  914.         Pcrcp = cio_tell(cio);
  915.         cio_skip(cio, 2); /* Pcrc */
  916.         DL = cio_read(cio, 4);
  917.         Pepc = cio_read(cio, 1);
  918.  
  919.         /* compute Pcrc */
  920.         cio_seek(cio, Lepcp - 2);
  921.  
  922.                 /* Marker */
  923.                 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
  924.                 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
  925.  
  926.                 /* Length */
  927.                 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
  928.                 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
  929.  
  930.                 /* skip Pcrc */
  931.                 cio_skip(cio, 2);
  932.  
  933.                 /* read all remaining */
  934.                 for (l = 4; l < Lepc; l++)
  935.                         jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
  936.  
  937.                 /* check Pcrc with the result */
  938.                 cio_seek(cio, Pcrcp);
  939.                 ans1 = (Pcrc == (unsigned short int) cio_read(cio, 2)) ? "crc-ok" : "crc-ko";
  940.  
  941.         /* now we write them to screen */
  942.         opj_event_msg(j2k->cinfo, EVT_INFO,
  943.                 "EPC(%u,%d): %s, DL=%d%s %s %s\n",
  944.                 Lepcp - 2,
  945.                 Lepc,
  946.                 ans1,
  947.                 DL, /* data length this EPC is referring to */
  948.                 (Pepc & 0x10) ? ", esd" : "", /* ESD is present */
  949.                 (Pepc & 0x20) ? ", red" : "", /* RED is present */
  950.                 (Pepc & 0x40) ? ", epb" : ""); /* EPB is present */
  951.  
  952.         cio_seek(cio, Lepcp + Lepc);  
  953. }
  954.  
  955. void j2k_write_epc(opj_j2k_t *j2k) {
  956.  
  957.         unsigned long int DL, Lepcp, Pcrcp, l;
  958.         unsigned short int Lepc, Pcrc;
  959.         unsigned char Pepc;    
  960.  
  961.         opj_cio_t *cio = j2k->cio;
  962.  
  963.         cio_write(cio, J2K_MS_EPC, 2);  /* EPC */
  964.         Lepcp = cio_tell(cio);
  965.         cio_skip(cio, 2);
  966.  
  967.         /* CRC-16 word of the EPC */
  968.         Pcrc = 0x0000; /* initialize */
  969.         Pcrcp = cio_tell(cio);
  970.         cio_write(cio, Pcrc, 2); /* Pcrc placeholder*/
  971.  
  972.         /* data length of the EPC protection domain */
  973.         DL = 0x00000000; /* we leave this set to 0, as if the information is not available */
  974.         cio_write(cio, DL, 4);   /* DL */
  975.  
  976.         /* jpwl capabilities */
  977.         Pepc = 0x00;
  978.         cio_write(cio, Pepc, 1); /* Pepc */
  979.  
  980.         /* ID section */
  981.         /* no ID's, as of now */
  982.  
  983.         Lepc = (unsigned short) (cio_tell(cio) - Lepcp);
  984.         cio_seek(cio, Lepcp);
  985.         cio_write(cio, Lepc, 2); /* Lepc */
  986.  
  987.         /* compute Pcrc */
  988.         cio_seek(cio, Lepcp - 2);
  989.  
  990.                 /* Marker */
  991.                 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
  992.                 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
  993.  
  994.                 /* Length */
  995.                 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
  996.                 jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
  997.  
  998.                 /* skip Pcrc */
  999.                 cio_skip(cio, 2);
  1000.  
  1001.                 /* read all remaining */
  1002.                 for (l = 4; l < Lepc; l++)
  1003.                         jpwl_updateCRC16(&Pcrc, (unsigned char) cio_read(cio, 1));
  1004.  
  1005.                 /* fill Pcrc with the result */
  1006.                 cio_seek(cio, Pcrcp);
  1007.                 cio_write(cio, Pcrc, 2);
  1008.  
  1009.         cio_seek(cio, Lepcp + Lepc);
  1010.  
  1011.         /* marker struct update */
  1012.         j2k_add_marker(j2k->cstr_info, J2K_MS_EPC, Lepcp - 2, Lepc + 2);
  1013.  
  1014. }
  1015.  
  1016. void j2k_read_epb(opj_j2k_t *j2k) {
  1017.         unsigned long int LDPepb, Pepb;
  1018.         unsigned short int Lepb;
  1019.         unsigned char Depb;
  1020.         char str1[25] = "";
  1021.         bool status;
  1022.         static bool first_in_tph = true;
  1023.         int type, pre_len, post_len;
  1024.         static unsigned char *redund = NULL;
  1025.        
  1026.         opj_cio_t *cio = j2k->cio;
  1027.  
  1028.         /* B/W = 45, RGB = 51 */
  1029.         /*           SIZ   SIZ_FIELDS     SIZ_COMPS               FOLLOWING_MARKER */
  1030.         int skipnum = 2  +     38     + 3 * j2k->cp->exp_comps  +         2;
  1031.  
  1032.         if (j2k->cp->correct) {
  1033.  
  1034.                 /* go back to EPB marker value */
  1035.                 cio_seek(cio, cio_tell(cio) - 2);
  1036.  
  1037.                 /* we need to understand where we are */
  1038.                 if (j2k->state == J2K_STATE_MH) {
  1039.                         /* we are in MH */
  1040.                         type = 0; /* MH */
  1041.                         pre_len = skipnum; /* SOC+SIZ */
  1042.                         post_len = -1; /* auto */
  1043.  
  1044.                 } else if ((j2k->state == J2K_STATE_TPH) && first_in_tph) {
  1045.                         /* we are in TPH */
  1046.                         type = 1; /* TPH */
  1047.                         pre_len = 12; /* SOC+SIZ */
  1048.                         first_in_tph = false;
  1049.                         post_len = -1; /* auto */
  1050.  
  1051.                 } else {
  1052.                         /* we are elsewhere */
  1053.                         type = 2; /* other */
  1054.                         pre_len = 0; /* nada */
  1055.                         post_len = -1; /* auto */
  1056.  
  1057.                 }
  1058.  
  1059.                 /* call EPB corrector */
  1060.                 /*printf("before %x, ", redund);*/
  1061.                 status = jpwl_epb_correct(j2k,      /* J2K decompressor handle */
  1062.                                                                   cio->bp,  /* pointer to EPB in codestream buffer */
  1063.                                                                   type,     /* EPB type: MH */
  1064.                                                                   pre_len,  /* length of pre-data */
  1065.                                                                   post_len, /* length of post-data: -1 means auto */
  1066.                                                                   NULL,     /* do everything auto */
  1067.                                                                   &redund
  1068.                                                                  );
  1069.                 /*printf("after %x\n", redund);*/
  1070.  
  1071.                 /* Read the (possibly corrected) EPB parameters */
  1072.                 cio_skip(cio, 2);
  1073.                 Lepb = cio_read(cio, 2);
  1074.                 Depb = cio_read(cio, 1);
  1075.                 LDPepb = cio_read(cio, 4);
  1076.                 Pepb = cio_read(cio, 4);
  1077.  
  1078.                 if (!status) {
  1079.  
  1080.                         opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL correction could not be performed\n");
  1081.  
  1082.                         /* advance to EPB endpoint */
  1083.                         cio_skip(cio, Lepb + 2);  
  1084.  
  1085.                         return;
  1086.                 }
  1087.  
  1088.                 /* last in current header? */
  1089.                 if (Depb & 0x40) {
  1090.                         redund = NULL; /* reset the pointer to L4 buffer */
  1091.                         first_in_tph = true;
  1092.                 }
  1093.  
  1094.                 /* advance to EPB endpoint */
  1095.                 cio_skip(cio, Lepb - 11);  
  1096.  
  1097.         } else {
  1098.  
  1099.                 /* Simply read the EPB parameters */
  1100.                 Lepb = cio_read(cio, 2);
  1101.                 Depb = cio_read(cio, 1);
  1102.                 LDPepb = cio_read(cio, 4);
  1103.                 Pepb = cio_read(cio, 4);
  1104.  
  1105.                 /* What does Pepb tells us about the protection method? */
  1106.                 if (((Pepb & 0xF0000000) >> 28) == 0)
  1107.                         sprintf(str1, "pred"); /* predefined */
  1108.                 else if (((Pepb & 0xF0000000) >> 28) == 1)
  1109.                         sprintf(str1, "crc-%lu", 16 * ((Pepb & 0x00000001) + 1)); /* CRC mode */
  1110.                 else if (((Pepb & 0xF0000000) >> 28) == 2)
  1111.                         sprintf(str1, "rs(%lu,32)", (Pepb & 0x0000FF00) >> 8); /* RS mode */
  1112.                 else if (Pepb == 0xFFFFFFFF)
  1113.                         sprintf(str1, "nometh"); /* RS mode */
  1114.                 else
  1115.                         sprintf(str1, "unknown"); /* unknown */
  1116.  
  1117.                 /* Now we write them to screen */
  1118.                 opj_event_msg(j2k->cinfo, EVT_INFO,
  1119.                         "EPB(%d): (%sl, %sp, %u), %lu, %s\n",
  1120.                         cio_tell(cio) - 13,
  1121.                         (Depb & 0x40) ? "" : "n", /* latest EPB or not? */
  1122.                         (Depb & 0x80) ? "" : "n", /* packed or unpacked EPB? */
  1123.                         (Depb & 0x3F), /* EPB index value */
  1124.                         LDPepb, /*length of the data protected by the EPB */
  1125.                         str1); /* protection method */
  1126.  
  1127.                 cio_skip(cio, Lepb - 11);  
  1128.         }
  1129. }
  1130.  
  1131. void j2k_write_epb(opj_j2k_t *j2k) {
  1132.         unsigned long int LDPepb, Pepb, Lepbp;
  1133.         unsigned short int Lepb;
  1134.         unsigned char Depb;
  1135.  
  1136.         opj_cio_t *cio = j2k->cio;
  1137.  
  1138.         cio_write(cio, J2K_MS_EPB, 2);  /* EPB */
  1139.         Lepbp = cio_tell(cio);
  1140.         cio_skip(cio, 2);
  1141.  
  1142.         /* EPB style */
  1143.         Depb = 0x00; /* test */
  1144.         cio_write(cio, Depb, 1);   /* Depb */
  1145.  
  1146.         /* length of the data to be protected by this EPB */
  1147.         LDPepb = 0x00000000; /* test */
  1148.         cio_write(cio, LDPepb, 4);   /* LDPepb */
  1149.  
  1150.         /* next error correction tool */
  1151.         Pepb = 0x00000000; /* test */
  1152.         cio_write(cio, Pepb, 4);   /* Pepb */
  1153.  
  1154.         /* EPB data */
  1155.         /* no data, as of now */
  1156.  
  1157.         Lepb = (unsigned short) (cio_tell(cio) - Lepbp);
  1158.         cio_seek(cio, Lepbp);
  1159.         cio_write(cio, Lepb, 2);                /* Lepb */
  1160.  
  1161.         cio_seek(cio, Lepbp + Lepb);
  1162.  
  1163.         /* marker struct update */
  1164.         j2k_add_marker(j2k->cstr_info, J2K_MS_EPB, Lepbp - 2, Lepb + 2);
  1165. }
  1166.  
  1167. void j2k_read_esd(opj_j2k_t *j2k) {
  1168.         unsigned short int Lesd, Cesd;
  1169.         unsigned char Pesd;
  1170.  
  1171.         int cesdsize = (j2k->image->numcomps >= 257) ? 2 : 1;
  1172.  
  1173.         char str1[4][4] = {"p", "br", "pr", "res"};
  1174.         char str2[8][8] = {"res", "mse", "mse-r", "psnr", "psnr-i", "maxerr", "tse", "res"};
  1175.        
  1176.         opj_cio_t *cio = j2k->cio;
  1177.  
  1178.         /* Simply read the ESD parameters */
  1179.         Lesd = cio_read(cio, 2);
  1180.         Cesd = cio_read(cio, cesdsize);
  1181.         Pesd = cio_read(cio, 1);
  1182.  
  1183.         /* Now we write them to screen */
  1184.         opj_event_msg(j2k->cinfo, EVT_INFO,
  1185.                 "ESD(%d): c%d, %s, %s, %s, %s, %s\n",
  1186.                 cio_tell(cio) - (5 + cesdsize),
  1187.                 Cesd, /* component number for this ESD */
  1188.                 str1[(Pesd & (unsigned char) 0xC0) >> 6], /* addressing mode */
  1189.                 str2[(Pesd & (unsigned char) 0x38) >> 3], /* sensitivity type */
  1190.                 ((Pesd & (unsigned char) 0x04) >> 2) ? "2Bs" : "1Bs",
  1191.                 ((Pesd & (unsigned char) 0x02) >> 1) ? "4Ba" : "2Ba",
  1192.                 (Pesd & (unsigned char) 0x01) ? "avgc" : "");
  1193.  
  1194.         cio_skip(cio, Lesd - (3 + cesdsize));  
  1195. }
  1196.  
  1197. void j2k_read_red(opj_j2k_t *j2k) {
  1198.         unsigned short int Lred;
  1199.         unsigned char Pred;
  1200.         char str1[4][4] = {"p", "br", "pr", "res"};
  1201.        
  1202.         opj_cio_t *cio = j2k->cio;
  1203.  
  1204.         /* Simply read the RED parameters */
  1205.         Lred = cio_read(cio, 2);
  1206.         Pred = cio_read(cio, 1);
  1207.  
  1208.         /* Now we write them to screen */
  1209.         opj_event_msg(j2k->cinfo, EVT_INFO,
  1210.                 "RED(%d): %s, %dc, %s, %s\n",
  1211.                 cio_tell(cio) - 5,
  1212.                 str1[(Pred & (unsigned char) 0xC0) >> 6], /* addressing mode */
  1213.                 (Pred & (unsigned char) 0x38) >> 3, /* corruption level */
  1214.                 ((Pred & (unsigned char) 0x02) >> 1) ? "4Ba" : "2Ba", /* address range */
  1215.                 (Pred & (unsigned char) 0x01) ? "errs" : "free"); /* error free? */
  1216.  
  1217.         cio_skip(cio, Lred - 3);  
  1218. }
  1219.  
  1220. bool jpwl_check_tile(opj_j2k_t *j2k, opj_tcd_t *tcd, int tileno) {
  1221.  
  1222. #ifdef oerhgierhgvhreit4u
  1223.         /*
  1224.            we navigate through the tile and find possible invalid parameters:
  1225.        this saves a lot of crashes!!!!!
  1226.          */
  1227.         int compno, resno, precno, /*layno,*/ bandno, blockno;
  1228.         int numprecincts, numblocks;
  1229.  
  1230.         /* this is the selected tile */
  1231.         opj_tcd_tile_t *tile = &(tcd->tcd_image->tiles[tileno]);
  1232.  
  1233.         /* will keep the component */
  1234.         opj_tcd_tilecomp_t *comp = NULL;
  1235.  
  1236.         /* will keep the resolution */
  1237.         opj_tcd_resolution_t *res;
  1238.  
  1239.         /* will keep the subband */
  1240.         opj_tcd_band_t *band;
  1241.  
  1242.         /* will keep the precinct */
  1243.         opj_tcd_precinct_t *prec;
  1244.  
  1245.         /* will keep the codeblock */
  1246.         opj_tcd_cblk_t *block;
  1247.  
  1248.         /* check all tile components */
  1249.         for (compno = 0; compno < tile->numcomps; compno++) {
  1250.                 comp = &(tile->comps[compno]);
  1251.  
  1252.                 /* check all component resolutions */
  1253.                 for (resno = 0; resno < comp->numresolutions; resno++) {
  1254.                         res = &(comp->resolutions[resno]);
  1255.                         numprecincts = res->pw * res->ph;
  1256.  
  1257.                         /* check all the subbands */
  1258.                         for (bandno = 0; bandno < res->numbands; bandno++) {
  1259.                                 band = &(res->bands[bandno]);
  1260.  
  1261.                                 /* check all the precincts */
  1262.                                 for (precno = 0; precno < numprecincts; precno++) {
  1263.                                         prec = &(band->precincts[precno]);
  1264.                                         numblocks = prec->ch * prec->cw;
  1265.  
  1266.                                         /* check all the codeblocks */
  1267.                                         for (blockno = 0; blockno < numblocks; blockno++) {
  1268.                                                 block = &(prec->cblks[blockno]);
  1269.  
  1270.                                                 /* x-origin is invalid */
  1271.                                                 if ((block->x0 < prec->x0) || (block->x0 > prec->x1)) {
  1272.                                                         opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR,
  1273.                                                                 "JPWL: wrong x-cord of block origin %d => x-prec is (%d, %d)\n",
  1274.                                                                 block->x0, prec->x0, prec->x1);
  1275.                                                         if (!JPWL_ASSUME || JPWL_ASSUME)
  1276.                                                                 return false;
  1277.                                                 };
  1278.                                         }
  1279.                                 }                              
  1280.                         }
  1281.                 }
  1282.         }
  1283.  
  1284. #endif
  1285.  
  1286.         return true;
  1287. }
  1288.  
  1289. /*@}*/
  1290.  
  1291. #endif /* USE_JPWL */
  1292.  
  1293.  
  1294. #ifdef USE_JPSEC
  1295.  
  1296. /** @defgroup JPSEC JPSEC - JPEG-2000 Part 8 (JPSEC) codestream manager */
  1297. /*@{*/
  1298.  
  1299.  
  1300. /** @name Local static functions */
  1301. /*@{*/
  1302.  
  1303. void j2k_read_sec(opj_j2k_t *j2k) {
  1304.         unsigned short int Lsec;
  1305.        
  1306.         opj_cio_t *cio = j2k->cio;
  1307.  
  1308.         /* Simply read the SEC length */
  1309.         Lsec = cio_read(cio, 2);
  1310.  
  1311.         /* Now we write them to screen */
  1312.         opj_event_msg(j2k->cinfo, EVT_INFO,
  1313.                 "SEC(%d)\n",
  1314.                 cio_tell(cio) - 2
  1315.                 );
  1316.  
  1317.         cio_skip(cio, Lsec - 2);  
  1318. }
  1319.  
  1320. void j2k_write_sec(opj_j2k_t *j2k) {
  1321.         unsigned short int Lsec = 24;
  1322.         int i;
  1323.  
  1324.         opj_cio_t *cio = j2k->cio;
  1325.  
  1326.         cio_write(cio, J2K_MS_SEC, 2);  /* SEC */
  1327.         cio_write(cio, Lsec, 2);
  1328.  
  1329.         /* write dummy data */
  1330.         for (i = 0; i < Lsec - 2; i++)
  1331.                 cio_write(cio, 0, 1);
  1332. }
  1333.  
  1334. void j2k_read_insec(opj_j2k_t *j2k) {
  1335.         unsigned short int Linsec;
  1336.        
  1337.         opj_cio_t *cio = j2k->cio;
  1338.  
  1339.         /* Simply read the INSEC length */
  1340.         Linsec = cio_read(cio, 2);
  1341.  
  1342.         /* Now we write them to screen */
  1343.         opj_event_msg(j2k->cinfo, EVT_INFO,
  1344.                 "INSEC(%d)\n",
  1345.                 cio_tell(cio) - 2
  1346.                 );
  1347.  
  1348.         cio_skip(cio, Linsec - 2);  
  1349. }
  1350.  
  1351.  
  1352. /*@}*/
  1353.  
  1354. /*@}*/
  1355.  
  1356. #endif /* USE_JPSEC */
  1357.  
  1358.