diff options
Diffstat (limited to 'media-libs/openjpeg/files/OPJ_limit_tags_for_decode_UPDATED.patch')
-rw-r--r-- | media-libs/openjpeg/files/OPJ_limit_tags_for_decode_UPDATED.patch | 3765 |
1 files changed, 3765 insertions, 0 deletions
diff --git a/media-libs/openjpeg/files/OPJ_limit_tags_for_decode_UPDATED.patch b/media-libs/openjpeg/files/OPJ_limit_tags_for_decode_UPDATED.patch new file mode 100644 index 0000000..be5cd8b --- /dev/null +++ b/media-libs/openjpeg/files/OPJ_limit_tags_for_decode_UPDATED.patch @@ -0,0 +1,3765 @@ +diff -Naur OpenJPEG/libopenjpeg/j2k.c OpenJPEG-patched/libopenjpeg/j2k.c +--- OpenJPEG/libopenjpeg/j2k.c 2007-02-19 10:59:29.000000000 +0100 ++++ OpenJPEG-patched/libopenjpeg/j2k.c 2007-03-17 14:18:44.000000000 +0100 +@@ -1342,37 +1342,39 @@ + int states; + /** action linked to the marker */ + void (*handler) (opj_j2k_t *j2k); ++ /** The enum value used to limit decode to specific tags. */ ++ OPJ_LIMIT_TAGS limit_tag; + } opj_dec_mstabent_t; + + opj_dec_mstabent_t j2k_dec_mstab[] = { +- {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc}, +- {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot}, +- {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod}, +- {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc}, +- {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz}, +- {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod}, +- {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc}, +- {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn}, +- {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd}, +- {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc}, +- {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc}, +- {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm}, +- {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm}, +- {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt}, +- {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm}, +- {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt}, +- {J2K_MS_SOP, 0, 0}, +- {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg}, +- {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com}, ++ {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc, OPJ_TAG_SOC}, ++ {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot, OPJ_TAG_SOT}, ++ {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod, OPJ_TAG_SOD}, ++ {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc, OPJ_TAG_EOC}, ++ {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz, OPJ_TAG_SIZ}, ++ {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod, OPJ_TAG_COD}, ++ {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc, OPJ_TAG_COC}, ++ {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn, OPJ_TAG_RGN}, ++ {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd, OPJ_TAG_QCD}, ++ {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc, OPJ_TAG_QCC}, ++ {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc, OPJ_TAG_POC}, ++ {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm, OPJ_TAG_TLM}, ++ {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm, OPJ_TAG_PLM}, ++ {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt, OPJ_TAG_PLT}, ++ {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm, OPJ_TAG_PPM}, ++ {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt, OPJ_TAG_PPT}, ++ {J2K_MS_SOP, 0, 0, OPJ_TAG_SOP}, ++ {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg, OPJ_TAG_CRG}, ++ {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com, OPJ_TAG_COM}, + /* UniPG>> */ + #ifdef USE_JPWL +- {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc}, +- {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb}, +- {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd}, +- {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red}, ++ {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc, OPJ_TAG_EPC}, ++ {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb, OPJ_TAG_EPB}, ++ {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd, OPJ_TAG_ESD}, ++ {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red, OPJ_TAG_RED}, + #endif /* USE_JPWL */ + /* <<UniPG */ +- {0, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_unk} ++ {0, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_unk, -1} + }; + + static void j2k_read_unk(opj_j2k_t *j2k) { +@@ -1689,6 +1691,12 @@ + opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); + return 0; + } ++ /* If a partial decode is requested, stop if the current tag ++ * isn't in the list. ++ */ ++ if (j2k->cp->limit_tags && !(j2k->cp->limit_tags & e->limit_tag)) { ++ return image; ++ } + if (e->handler) { + (*e->handler)(j2k); + } +diff -Naur OpenJPEG/libopenjpeg/j2k.c.orig OpenJPEG-patched/libopenjpeg/j2k.c.orig +--- OpenJPEG/libopenjpeg/j2k.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ OpenJPEG-patched/libopenjpeg/j2k.c.orig 2007-02-19 10:59:29.000000000 +0100 +@@ -0,0 +1,2392 @@ ++/* ++ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium ++ * Copyright (c) 2002-2007, Professor Benoit Macq ++ * Copyright (c) 2001-2003, David Janssens ++ * Copyright (c) 2002-2003, Yannick Verschueren ++ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe ++ * Copyright (c) 2005, Herve Drolon, FreeImage Team ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "opj_includes.h" ++ ++/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */ ++/*@{*/ ++ ++/** @name Local static functions */ ++/*@{*/ ++ ++/** ++Write the SOC marker (Start Of Codestream) ++@param j2k J2K handle ++*/ ++static void j2k_write_soc(opj_j2k_t *j2k); ++/** ++Read the SOC marker (Start of Codestream) ++@param j2k J2K handle ++*/ ++static void j2k_read_soc(opj_j2k_t *j2k); ++/** ++Write the SIZ marker (image and tile size) ++@param j2k J2K handle ++*/ ++static void j2k_write_siz(opj_j2k_t *j2k); ++/** ++Read the SIZ marker (image and tile size) ++@param j2k J2K handle ++*/ ++static void j2k_read_siz(opj_j2k_t *j2k); ++/** ++Write the COM marker (comment) ++@param j2k J2K handle ++*/ ++static void j2k_write_com(opj_j2k_t *j2k); ++/** ++Read the COM marker (comment) ++@param j2k J2K handle ++*/ ++static void j2k_read_com(opj_j2k_t *j2k); ++/** ++Write the value concerning the specified component in the marker COD and COC ++@param j2k J2K handle ++@param compno Number of the component concerned by the information written ++*/ ++static void j2k_write_cox(opj_j2k_t *j2k, int compno); ++/** ++Read the value concerning the specified component in the marker COD and COC ++@param j2k J2K handle ++@param compno Number of the component concerned by the information read ++*/ ++static void j2k_read_cox(opj_j2k_t *j2k, int compno); ++/** ++Write the COD marker (coding style default) ++@param j2k J2K handle ++*/ ++static void j2k_write_cod(opj_j2k_t *j2k); ++/** ++Read the COD marker (coding style default) ++@param j2k J2K handle ++*/ ++static void j2k_read_cod(opj_j2k_t *j2k); ++/** ++Write the COC marker (coding style component) ++@param j2k J2K handle ++@param compno Number of the component concerned by the information written ++*/ ++static void j2k_write_coc(opj_j2k_t *j2k, int compno); ++/** ++Read the COC marker (coding style component) ++@param j2k J2K handle ++*/ ++static void j2k_read_coc(opj_j2k_t *j2k); ++/** ++Write the value concerning the specified component in the marker QCD and QCC ++@param j2k J2K handle ++@param compno Number of the component concerned by the information written ++*/ ++static void j2k_write_qcx(opj_j2k_t *j2k, int compno); ++/** ++Read the value concerning the specified component in the marker QCD and QCC ++@param j2k J2K handle ++@param compno Number of the component concern by the information read ++@param len Length of the information in the QCX part of the marker QCD/QCC ++*/ ++static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len); ++/** ++Write the QCD marker (quantization default) ++@param j2k J2K handle ++*/ ++static void j2k_write_qcd(opj_j2k_t *j2k); ++/** ++Read the QCD marker (quantization default) ++@param j2k J2K handle ++*/ ++static void j2k_read_qcd(opj_j2k_t *j2k); ++/** ++Write the QCC marker (quantization component) ++@param j2k J2K handle ++@param compno Number of the component concerned by the information written ++*/ ++static void j2k_write_qcc(opj_j2k_t *j2k, int compno); ++/** ++Read the QCC marker (quantization component) ++@param j2k J2K handle ++*/ ++static void j2k_read_qcc(opj_j2k_t *j2k); ++/** ++Write the POC marker (progression order change) ++@param j2k J2K handle ++*/ ++static void j2k_write_poc(opj_j2k_t *j2k); ++/** ++Read the POC marker (progression order change) ++@param j2k J2K handle ++*/ ++static void j2k_read_poc(opj_j2k_t *j2k); ++/** ++Read the CRG marker (component registration) ++@param j2k J2K handle ++*/ ++static void j2k_read_crg(opj_j2k_t *j2k); ++/** ++Read the TLM marker (tile-part lengths) ++@param j2k J2K handle ++*/ ++static void j2k_read_tlm(opj_j2k_t *j2k); ++/** ++Read the PLM marker (packet length, main header) ++@param j2k J2K handle ++*/ ++static void j2k_read_plm(opj_j2k_t *j2k); ++/** ++Read the PLT marker (packet length, tile-part header) ++@param j2k J2K handle ++*/ ++static void j2k_read_plt(opj_j2k_t *j2k); ++/** ++Read the PPM marker (packet packet headers, main header) ++@param j2k J2K handle ++*/ ++static void j2k_read_ppm(opj_j2k_t *j2k); ++/** ++Read the PPT marker (packet packet headers, tile-part header) ++@param j2k J2K handle ++*/ ++static void j2k_read_ppt(opj_j2k_t *j2k); ++/** ++Write the SOT marker (start of tile-part) ++@param j2k J2K handle ++*/ ++static void j2k_write_sot(opj_j2k_t *j2k); ++/** ++Read the SOT marker (start of tile-part) ++@param j2k J2K handle ++*/ ++static void j2k_read_sot(opj_j2k_t *j2k); ++/** ++Write the SOD marker (start of data) ++@param j2k J2K handle ++@param tile_coder Pointer to a TCD handle ++*/ ++static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder); ++/** ++Read the SOD marker (start of data) ++@param j2k J2K handle ++*/ ++static void j2k_read_sod(opj_j2k_t *j2k); ++/** ++Write the RGN marker (region-of-interest) ++@param j2k J2K handle ++@param compno Number of the component concerned by the information written ++@param tileno Number of the tile concerned by the information written ++*/ ++static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno); ++/** ++Read the RGN marker (region-of-interest) ++@param j2k J2K handle ++*/ ++static void j2k_read_rgn(opj_j2k_t *j2k); ++/** ++Write the EOC marker (end of codestream) ++@param j2k J2K handle ++*/ ++static void j2k_write_eoc(opj_j2k_t *j2k); ++/** ++Read the EOC marker (end of codestream) ++@param j2k J2K handle ++*/ ++static void j2k_read_eoc(opj_j2k_t *j2k); ++/** ++Read an unknown marker ++@param j2k J2K handle ++*/ ++static void j2k_read_unk(opj_j2k_t *j2k); ++ ++/*@}*/ ++ ++/*@}*/ ++ ++/* ----------------------------------------------------------------------- */ ++ ++void j2k_dump_image(FILE *fd, opj_image_t * img) { ++ int compno; ++ fprintf(fd, "image {\n"); ++ fprintf(fd, " x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0, img->x1, img->y1); ++ fprintf(fd, " numcomps=%d\n", img->numcomps); ++ for (compno = 0; compno < img->numcomps; compno++) { ++ opj_image_comp_t *comp = &img->comps[compno]; ++ fprintf(fd, " comp %d {\n", compno); ++ fprintf(fd, " dx=%d, dy=%d\n", comp->dx, comp->dy); ++ fprintf(fd, " prec=%d\n", comp->prec); ++ fprintf(fd, " sgnd=%d\n", comp->sgnd); ++ fprintf(fd, " }\n"); ++ } ++ fprintf(fd, "}\n"); ++} ++ ++void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) { ++ int tileno, compno, layno, bandno, resno, numbands; ++ fprintf(fd, "coding parameters {\n"); ++ fprintf(fd, " tx0=%d, ty0=%d\n", cp->tx0, cp->ty0); ++ fprintf(fd, " tdx=%d, tdy=%d\n", cp->tdx, cp->tdy); ++ fprintf(fd, " tw=%d, th=%d\n", cp->tw, cp->th); ++ for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { ++ opj_tcp_t *tcp = &cp->tcps[tileno]; ++ fprintf(fd, " tile %d {\n", tileno); ++ fprintf(fd, " csty=%x\n", tcp->csty); ++ fprintf(fd, " prg=%d\n", tcp->prg); ++ fprintf(fd, " numlayers=%d\n", tcp->numlayers); ++ fprintf(fd, " mct=%d\n", tcp->mct); ++ fprintf(fd, " rates="); ++ for (layno = 0; layno < tcp->numlayers; layno++) { ++ fprintf(fd, "%.1f ", tcp->rates[layno]); ++ } ++ fprintf(fd, "\n"); ++ for (compno = 0; compno < img->numcomps; compno++) { ++ opj_tccp_t *tccp = &tcp->tccps[compno]; ++ fprintf(fd, " comp %d {\n", compno); ++ fprintf(fd, " csty=%x\n", tccp->csty); ++ fprintf(fd, " numresolutions=%d\n", tccp->numresolutions); ++ fprintf(fd, " cblkw=%d\n", tccp->cblkw); ++ fprintf(fd, " cblkh=%d\n", tccp->cblkh); ++ fprintf(fd, " cblksty=%x\n", tccp->cblksty); ++ fprintf(fd, " qmfbid=%d\n", tccp->qmfbid); ++ fprintf(fd, " qntsty=%d\n", tccp->qntsty); ++ fprintf(fd, " numgbits=%d\n", tccp->numgbits); ++ fprintf(fd, " roishift=%d\n", tccp->roishift); ++ fprintf(fd, " stepsizes="); ++ numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2; ++ for (bandno = 0; bandno < numbands; bandno++) { ++ fprintf(fd, "(%d,%d) ", tccp->stepsizes[bandno].mant, ++ tccp->stepsizes[bandno].expn); ++ } ++ fprintf(fd, "\n"); ++ ++ if (tccp->csty & J2K_CCP_CSTY_PRT) { ++ fprintf(fd, " prcw="); ++ for (resno = 0; resno < tccp->numresolutions; resno++) { ++ fprintf(fd, "%d ", tccp->prcw[resno]); ++ } ++ fprintf(fd, "\n"); ++ fprintf(fd, " prch="); ++ for (resno = 0; resno < tccp->numresolutions; resno++) { ++ fprintf(fd, "%d ", tccp->prch[resno]); ++ } ++ fprintf(fd, "\n"); ++ } ++ fprintf(fd, " }\n"); ++ } ++ fprintf(fd, " }\n"); ++ } ++ fprintf(fd, "}\n"); ++} ++ ++/* ----------------------------------------------------------------------- */ ++ ++static void j2k_write_soc(opj_j2k_t *j2k) { ++ opj_cio_t *cio = j2k->cio; ++ cio_write(cio, J2K_MS_SOC, 2); ++} ++ ++static void j2k_read_soc(opj_j2k_t *j2k) { ++ j2k->state = J2K_STATE_MHSIZ; ++} ++ ++static void j2k_write_siz(opj_j2k_t *j2k) { ++ int i; ++ int lenp, len; ++ ++ opj_cio_t *cio = j2k->cio; ++ opj_image_t *image = j2k->image; ++ opj_cp_t *cp = j2k->cp; ++ ++ cio_write(cio, J2K_MS_SIZ, 2); /* SIZ */ ++ lenp = cio_tell(cio); ++ cio_skip(cio, 2); ++ cio_write(cio, 0, 2); /* Rsiz (capabilities) */ ++ cio_write(cio, image->x1, 4); /* Xsiz */ ++ cio_write(cio, image->y1, 4); /* Ysiz */ ++ cio_write(cio, image->x0, 4); /* X0siz */ ++ cio_write(cio, image->y0, 4); /* Y0siz */ ++ cio_write(cio, cp->tdx, 4); /* XTsiz */ ++ cio_write(cio, cp->tdy, 4); /* YTsiz */ ++ cio_write(cio, cp->tx0, 4); /* XT0siz */ ++ cio_write(cio, cp->ty0, 4); /* YT0siz */ ++ cio_write(cio, image->numcomps, 2); /* Csiz */ ++ for (i = 0; i < image->numcomps; i++) { ++ cio_write(cio, image->comps[i].prec - 1 + (image->comps[i].sgnd << 7), 1); /* Ssiz_i */ ++ cio_write(cio, image->comps[i].dx, 1); /* XRsiz_i */ ++ cio_write(cio, image->comps[i].dy, 1); /* YRsiz_i */ ++ } ++ len = cio_tell(cio) - lenp; ++ cio_seek(cio, lenp); ++ cio_write(cio, len, 2); /* Lsiz */ ++ cio_seek(cio, lenp + len); ++} ++ ++static void j2k_read_siz(opj_j2k_t *j2k) { ++ int len, i; ++ ++ opj_cio_t *cio = j2k->cio; ++ opj_image_t *image = j2k->image; ++ opj_cp_t *cp = j2k->cp; ++ ++ len = cio_read(cio, 2); /* Lsiz */ ++ cio_read(cio, 2); /* Rsiz (capabilities) */ ++ image->x1 = cio_read(cio, 4); /* Xsiz */ ++ image->y1 = cio_read(cio, 4); /* Ysiz */ ++ image->x0 = cio_read(cio, 4); /* X0siz */ ++ image->y0 = cio_read(cio, 4); /* Y0siz */ ++ cp->tdx = cio_read(cio, 4); /* XTsiz */ ++ cp->tdy = cio_read(cio, 4); /* YTsiz */ ++ cp->tx0 = cio_read(cio, 4); /* XT0siz */ ++ cp->ty0 = cio_read(cio, 4); /* YT0siz */ ++ ++ image->numcomps = cio_read(cio, 2); /* Csiz */ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ if (j2k->cp->correct) { ++ /* if JPWL is on, we check whether TX errors have damaged ++ too much the SIZ parameters */ ++ if (!(image->x1 * image->y1)) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "JPWL: bad image size (%d x %d)\n", ++ image->x1, image->y1); ++ if (!JPWL_ASSUME || JPWL_ASSUME) ++ exit(1); ++ } ++ if (image->numcomps != ((len - 38) / 3)) { ++ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, ++ "JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n", ++ image->numcomps, ((len - 38) / 3)); ++ if (!JPWL_ASSUME) ++ exit(1); ++ /* we try to correct */ ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"); ++ if (image->numcomps < ((len - 38) / 3)) { ++ len = 38 + 3 * image->numcomps; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n", ++ len); ++ } else { ++ image->numcomps = ((len - 38) / 3); ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n", ++ image->numcomps); ++ } ++ } ++ ++ /* update components number in the jpwl_exp_comps filed */ ++ cp->exp_comps = image->numcomps; ++ } ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ image->comps = (opj_image_comp_t *) opj_malloc(image->numcomps * sizeof(opj_image_comp_t)); ++ for (i = 0; i < image->numcomps; i++) { ++ int tmp, w, h; ++ tmp = cio_read(cio, 1); /* Ssiz_i */ ++ image->comps[i].prec = (tmp & 0x7f) + 1; ++ image->comps[i].sgnd = tmp >> 7; ++ image->comps[i].dx = cio_read(cio, 1); /* XRsiz_i */ ++ image->comps[i].dy = cio_read(cio, 1); /* YRsiz_i */ ++ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ if (j2k->cp->correct) { ++ /* if JPWL is on, we check whether TX errors have damaged ++ too much the SIZ parameters, again */ ++ if (!(image->comps[i].dx * image->comps[i].dy)) { ++ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, ++ "JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n", ++ i, i, image->comps[i].dx, image->comps[i].dy); ++ if (!JPWL_ASSUME) ++ exit(1); ++ /* we try to correct */ ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"); ++ if (!image->comps[i].dx) { ++ image->comps[i].dx = 1; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n", ++ i, image->comps[i].dx); ++ } ++ if (!image->comps[i].dy) { ++ image->comps[i].dy = 1; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n", ++ i, image->comps[i].dy); ++ } ++ } ++ ++ } ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ ++ ++ /* TODO: unused ? */ ++ w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx); ++ h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy); ++ ++ image->comps[i].resno_decoded = 0; /* number of resolution decoded */ ++ image->comps[i].factor = 0; /* reducing factor per component */ ++ } ++ ++ cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx); ++ cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy); ++/* UniPG>> */ ++#ifdef USE_JPWL ++ if (j2k->cp->correct) { ++ /* if JPWL is on, we check whether TX errors have damaged ++ too much the SIZ parameters */ ++ if ((cp->tw < 1) || (cp->th < 1) || (cp->tw > cp->max_tiles) || (cp->th > cp->max_tiles)) { ++ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, ++ "JPWL: bad number of tiles (%d x %d)\n", ++ cp->tw, cp->th); ++ if (!JPWL_ASSUME) ++ exit(1); ++ /* we try to correct */ ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"); ++ if (cp->tw < 1) { ++ cp->tw= 1; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n", ++ cp->tw); ++ } ++ if (cp->tw > cp->max_tiles) { ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large x, increase expectance of %d\n", ++ cp->max_tiles); ++ cp->tw= 1; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n", ++ cp->tw); ++ } ++ if (cp->th < 1) { ++ cp->th= 1; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n", ++ cp->th); ++ } ++ if (cp->th > cp->max_tiles) { ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large y, increase expectance of %d to continue\n", ++ cp->max_tiles); ++ cp->th= 1; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n", ++ cp->th); ++ } ++ } ++ } ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcp_t)); ++ cp->tileno = (int *) opj_malloc(cp->tw * cp->th * sizeof(int)); ++ cp->tileno_size = 0; ++ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ if (j2k->cp->correct) { ++ if (!cp->tcps) { ++ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, ++ "JPWL: could not alloc tcps field of cp\n"); ++ if (!JPWL_ASSUME || JPWL_ASSUME) ++ exit(1); ++ } ++ } ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ for (i = 0; i < cp->tw * cp->th; i++) { ++ cp->tcps[i].POC = 0; ++ cp->tcps[i].numpocs = 0; ++ cp->tcps[i].first = 1; ++ } ++ ++ /* Initialization for PPM marker */ ++ cp->ppm = 0; ++ cp->ppm_data = NULL; ++ cp->ppm_data_first = NULL; ++ cp->ppm_previous = 0; ++ cp->ppm_store = 0; ++ ++ j2k->default_tcp->tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * image->numcomps); ++ for (i = 0; i < cp->tw * cp->th; i++) { ++ cp->tcps[i].tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * image->numcomps); ++ } ++ j2k->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * sizeof(unsigned char *)); ++ j2k->tile_len = (int *) opj_malloc(cp->tw * cp->th * sizeof(int)); ++ j2k->state = J2K_STATE_MH; ++} ++ ++static void j2k_write_com(opj_j2k_t *j2k) { ++ unsigned int i; ++ int lenp, len; ++ ++ if(j2k->cp->comment) { ++ opj_cio_t *cio = j2k->cio; ++ char *comment = j2k->cp->comment; ++ ++ cio_write(cio, J2K_MS_COM, 2); ++ lenp = cio_tell(cio); ++ cio_skip(cio, 2); ++ cio_write(cio, 0, 2); ++ for (i = 0; i < strlen(comment); i++) { ++ cio_write(cio, comment[i], 1); ++ } ++ len = cio_tell(cio) - lenp; ++ cio_seek(cio, lenp); ++ cio_write(cio, len, 2); ++ cio_seek(cio, lenp + len); ++ } ++} ++ ++static void j2k_read_com(opj_j2k_t *j2k) { ++ int len; ++ ++ opj_cio_t *cio = j2k->cio; ++ ++ len = cio_read(cio, 2); ++ cio_skip(cio, len - 2); ++} ++ ++static void j2k_write_cox(opj_j2k_t *j2k, int compno) { ++ int i; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; ++ opj_tccp_t *tccp = &tcp->tccps[compno]; ++ opj_cio_t *cio = j2k->cio; ++ ++ cio_write(cio, tccp->numresolutions - 1, 1); /* SPcox (D) */ ++ cio_write(cio, tccp->cblkw - 2, 1); /* SPcox (E) */ ++ cio_write(cio, tccp->cblkh - 2, 1); /* SPcox (F) */ ++ cio_write(cio, tccp->cblksty, 1); /* SPcox (G) */ ++ cio_write(cio, tccp->qmfbid, 1); /* SPcox (H) */ ++ ++ if (tccp->csty & J2K_CCP_CSTY_PRT) { ++ for (i = 0; i < tccp->numresolutions; i++) { ++ cio_write(cio, tccp->prcw[i] + (tccp->prch[i] << 4), 1); /* SPcox (I_i) */ ++ } ++ } ++} ++ ++static void j2k_read_cox(opj_j2k_t *j2k, int compno) { ++ int i; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; ++ opj_tccp_t *tccp = &tcp->tccps[compno]; ++ opj_cio_t *cio = j2k->cio; ++ ++ tccp->numresolutions = cio_read(cio, 1) + 1; /* SPcox (D) */ ++ ++ /* check the reduce value */ ++ cp->reduce = int_min((tccp->numresolutions)-1, cp->reduce); ++ tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */ ++ tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */ ++ tccp->cblksty = cio_read(cio, 1); /* SPcox (G) */ ++ tccp->qmfbid = cio_read(cio, 1); /* SPcox (H) */ ++ if (tccp->csty & J2K_CP_CSTY_PRT) { ++ for (i = 0; i < tccp->numresolutions; i++) { ++ int tmp = cio_read(cio, 1); /* SPcox (I_i) */ ++ tccp->prcw[i] = tmp & 0xf; ++ tccp->prch[i] = tmp >> 4; ++ } ++ } ++} ++ ++static void j2k_write_cod(opj_j2k_t *j2k) { ++ opj_cp_t *cp = NULL; ++ opj_tcp_t *tcp = NULL; ++ int lenp, len; ++ ++ opj_cio_t *cio = j2k->cio; ++ ++ cio_write(cio, J2K_MS_COD, 2); /* COD */ ++ ++ lenp = cio_tell(cio); ++ cio_skip(cio, 2); ++ ++ cp = j2k->cp; ++ tcp = &cp->tcps[j2k->curtileno]; ++ ++ cio_write(cio, tcp->csty, 1); /* Scod */ ++ cio_write(cio, tcp->prg, 1); /* SGcod (A) */ ++ cio_write(cio, tcp->numlayers, 2); /* SGcod (B) */ ++ cio_write(cio, tcp->mct, 1); /* SGcod (C) */ ++ ++ j2k_write_cox(j2k, 0); ++ len = cio_tell(cio) - lenp; ++ cio_seek(cio, lenp); ++ cio_write(cio, len, 2); /* Lcod */ ++ cio_seek(cio, lenp + len); ++} ++ ++static void j2k_read_cod(opj_j2k_t *j2k) { ++ int len, i, pos; ++ ++ opj_cio_t *cio = j2k->cio; ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; ++ opj_image_t *image = j2k->image; ++ ++ len = cio_read(cio, 2); /* Lcod */ ++ tcp->csty = cio_read(cio, 1); /* Scod */ ++ tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* SGcod (A) */ ++ tcp->numlayers = cio_read(cio, 2); /* SGcod (B) */ ++ tcp->mct = cio_read(cio, 1); /* SGcod (C) */ ++ ++ pos = cio_tell(cio); ++ for (i = 0; i < image->numcomps; i++) { ++ tcp->tccps[i].csty = tcp->csty & J2K_CP_CSTY_PRT; ++ cio_seek(cio, pos); ++ j2k_read_cox(j2k, i); ++ } ++} ++ ++static void j2k_write_coc(opj_j2k_t *j2k, int compno) { ++ int lenp, len; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; ++ opj_image_t *image = j2k->image; ++ opj_cio_t *cio = j2k->cio; ++ ++ cio_write(cio, J2K_MS_COC, 2); /* COC */ ++ lenp = cio_tell(cio); ++ cio_skip(cio, 2); ++ cio_write(cio, compno, image->numcomps <= 256 ? 1 : 2); /* Ccoc */ ++ cio_write(cio, tcp->tccps[compno].csty, 1); /* Scoc */ ++ j2k_write_cox(j2k, compno); ++ len = cio_tell(cio) - lenp; ++ cio_seek(cio, lenp); ++ cio_write(cio, len, 2); /* Lcoc */ ++ cio_seek(cio, lenp + len); ++} ++ ++static void j2k_read_coc(opj_j2k_t *j2k) { ++ int len, compno; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; ++ opj_image_t *image = j2k->image; ++ opj_cio_t *cio = j2k->cio; ++ ++ len = cio_read(cio, 2); /* Lcoc */ ++ compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2); /* Ccoc */ ++ tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */ ++ j2k_read_cox(j2k, compno); ++} ++ ++static void j2k_write_qcx(opj_j2k_t *j2k, int compno) { ++ int bandno, numbands; ++ int expn, mant; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; ++ opj_tccp_t *tccp = &tcp->tccps[compno]; ++ opj_cio_t *cio = j2k->cio; ++ ++ cio_write(cio, tccp->qntsty + (tccp->numgbits << 5), 1); /* Sqcx */ ++ numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2; ++ ++ for (bandno = 0; bandno < numbands; bandno++) { ++ expn = tccp->stepsizes[bandno].expn; ++ mant = tccp->stepsizes[bandno].mant; ++ ++ if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { ++ cio_write(cio, expn << 3, 1); /* SPqcx_i */ ++ } else { ++ cio_write(cio, (expn << 11) + mant, 2); /* SPqcx_i */ ++ } ++ } ++} ++ ++static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) { ++ int tmp; ++ int bandno, numbands; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; ++ opj_tccp_t *tccp = &tcp->tccps[compno]; ++ opj_cio_t *cio = j2k->cio; ++ ++ tmp = cio_read(cio, 1); /* Sqcx */ ++ tccp->qntsty = tmp & 0x1f; ++ tccp->numgbits = tmp >> 5; ++ numbands = (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? ++ 1 : ((tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ? len - 1 : (len - 1) / 2); ++/* UniPG>> */ ++#ifdef USE_JPWL ++ if (j2k->cp->correct) { ++ ++ /* if JPWL is on, we check whether there are too many subbands */ ++ if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) { ++ opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, ++ "JPWL: bad number of subbands in Sqcx (%d)\n", ++ numbands); ++ if (!JPWL_ASSUME) ++ exit(1); ++ /* we try to correct */ ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"); ++ numbands = 1; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting number of bands to %d => HYPOTHESIS!!!\n", ++ numbands); ++ }; ++ ++ }; ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ for (bandno = 0; bandno < numbands; bandno++) { ++ int expn, mant; ++ if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { ++ expn = cio_read(cio, 1) >> 3; /* SPqcx_i */ ++ mant = 0; ++ } else { ++ tmp = cio_read(cio, 2); /* SPqcx_i */ ++ expn = tmp >> 11; ++ mant = tmp & 0x7ff; ++ } ++ tccp->stepsizes[bandno].expn = expn; ++ tccp->stepsizes[bandno].mant = mant; ++ } ++ ++ /* Add Antonin : if scalar_derived -> compute other stepsizes */ ++ if (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) { ++ for (bandno = 1; bandno < J2K_MAXBANDS; bandno++) { ++ tccp->stepsizes[bandno].expn = ++ ((tccp->stepsizes[0].expn) - ((bandno - 1) / 3) > 0) ? ++ (tccp->stepsizes[0].expn) - ((bandno - 1) / 3) : 0; ++ tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant; ++ } ++ } ++ /* ddA */ ++} ++ ++static void j2k_write_qcd(opj_j2k_t *j2k) { ++ int lenp, len; ++ ++ opj_cio_t *cio = j2k->cio; ++ ++ cio_write(cio, J2K_MS_QCD, 2); /* QCD */ ++ lenp = cio_tell(cio); ++ cio_skip(cio, 2); ++ j2k_write_qcx(j2k, 0); ++ len = cio_tell(cio) - lenp; ++ cio_seek(cio, lenp); ++ cio_write(cio, len, 2); /* Lqcd */ ++ cio_seek(cio, lenp + len); ++} ++ ++static void j2k_read_qcd(opj_j2k_t *j2k) { ++ int len, i, pos; ++ ++ opj_cio_t *cio = j2k->cio; ++ opj_image_t *image = j2k->image; ++ ++ len = cio_read(cio, 2); /* Lqcd */ ++ pos = cio_tell(cio); ++ for (i = 0; i < image->numcomps; i++) { ++ cio_seek(cio, pos); ++ j2k_read_qcx(j2k, i, len - 2); ++ } ++} ++ ++static void j2k_write_qcc(opj_j2k_t *j2k, int compno) { ++ int lenp, len; ++ ++ opj_cio_t *cio = j2k->cio; ++ ++ cio_write(cio, J2K_MS_QCC, 2); /* QCC */ ++ lenp = cio_tell(cio); ++ cio_skip(cio, 2); ++ cio_write(cio, compno, j2k->image->numcomps <= 256 ? 1 : 2); /* Cqcc */ ++ j2k_write_qcx(j2k, compno); ++ len = cio_tell(cio) - lenp; ++ cio_seek(cio, lenp); ++ cio_write(cio, len, 2); /* Lqcc */ ++ cio_seek(cio, lenp + len); ++} ++ ++static void j2k_read_qcc(opj_j2k_t *j2k) { ++ int len, compno; ++ int numcomp = j2k->image->numcomps; ++ opj_cio_t *cio = j2k->cio; ++ ++ len = cio_read(cio, 2); /* Lqcc */ ++ compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ if (j2k->cp->correct) { ++ ++ static int backup_compno = 0; ++ ++ /* compno is negative or larger than the number of components!!! */ ++ if ((compno < 0) || (compno >= numcomp)) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "JPWL: bad component number in QCC (%d out of a maximum of %d)\n", ++ compno, numcomp); ++ if (!JPWL_ASSUME) ++ exit(1); ++ /* we try to correct */ ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"); ++ compno = backup_compno % numcomp; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting component number to %d\n", ++ compno); ++ } ++ ++ /* keep your private count of tiles */ ++ backup_compno++; ++ }; ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2)); ++} ++ ++static void j2k_write_poc(opj_j2k_t *j2k) { ++ int len, numpchgs, i; ++ ++ int numcomps = j2k->image->numcomps; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; ++ opj_tccp_t *tccp = &tcp->tccps[0]; ++ opj_cio_t *cio = j2k->cio; ++ ++ numpchgs = tcp->numpocs; ++ cio_write(cio, J2K_MS_POC, 2); /* POC */ ++ len = 2 + (5 + 2 * (numcomps <= 256 ? 1 : 2)) * numpchgs; ++ cio_write(cio, len, 2); /* Lpoc */ ++ for (i = 0; i < numpchgs; i++) { ++ opj_poc_t *poc = &tcp->pocs[i]; ++ cio_write(cio, poc->resno0, 1); /* RSpoc_i */ ++ cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2)); /* CSpoc_i */ ++ cio_write(cio, poc->layno1, 2); /* LYEpoc_i */ ++ poc->layno1 = int_min(poc->layno1, tcp->numlayers); ++ cio_write(cio, poc->resno1, 1); /* REpoc_i */ ++ poc->resno1 = int_min(poc->resno1, tccp->numresolutions); ++ cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2)); /* CEpoc_i */ ++ poc->compno1 = int_min(poc->compno1, numcomps); ++ cio_write(cio, poc->prg, 1); /* Ppoc_i */ ++ } ++} ++ ++static void j2k_read_poc(opj_j2k_t *j2k) { ++ int len, numpchgs, i, old_poc; ++ ++ int numcomps = j2k->image->numcomps; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; ++ opj_tccp_t *tccp = &tcp->tccps[0]; ++ opj_cio_t *cio = j2k->cio; ++ ++ old_poc = tcp->POC ? tcp->numpocs + 1 : 0; ++ tcp->POC = 1; ++ len = cio_read(cio, 2); /* Lpoc */ ++ numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2)); ++ ++ for (i = old_poc; i < numpchgs + old_poc; i++) { ++ opj_poc_t *poc; ++ poc = &tcp->pocs[i]; ++ poc->resno0 = cio_read(cio, 1); /* RSpoc_i */ ++ poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2); /* CSpoc_i */ ++ poc->layno1 = int_min(cio_read(cio, 2), (unsigned int) tcp->numlayers); /* LYEpoc_i */ ++ poc->resno1 = int_min(cio_read(cio, 1), (unsigned int) tccp->numresolutions); /* REpoc_i */ ++ poc->compno1 = int_min( ++ cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps); /* CEpoc_i */ ++ poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* Ppoc_i */ ++ } ++ ++ tcp->numpocs = numpchgs + old_poc - 1; ++} ++ ++static void j2k_read_crg(opj_j2k_t *j2k) { ++ int len, i, Xcrg_i, Ycrg_i; ++ ++ opj_cio_t *cio = j2k->cio; ++ int numcomps = j2k->image->numcomps; ++ ++ len = cio_read(cio, 2); /* Lcrg */ ++ for (i = 0; i < numcomps; i++) { ++ Xcrg_i = cio_read(cio, 2); /* Xcrg_i */ ++ Ycrg_i = cio_read(cio, 2); /* Ycrg_i */ ++ } ++} ++ ++static void j2k_read_tlm(opj_j2k_t *j2k) { ++ int len, Ztlm, Stlm, ST, SP, tile_tlm, i; ++ long int Ttlm_i, Ptlm_i; ++ ++ opj_cio_t *cio = j2k->cio; ++ ++ len = cio_read(cio, 2); /* Ltlm */ ++ Ztlm = cio_read(cio, 1); /* Ztlm */ ++ Stlm = cio_read(cio, 1); /* Stlm */ ++ ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02); ++ SP = (Stlm >> 6) & 0x01; ++ tile_tlm = (len - 4) / ((SP + 1) * 2 + ST); ++ for (i = 0; i < tile_tlm; i++) { ++ Ttlm_i = cio_read(cio, ST); /* Ttlm_i */ ++ Ptlm_i = cio_read(cio, SP ? 4 : 2); /* Ptlm_i */ ++ } ++} ++ ++static void j2k_read_plm(opj_j2k_t *j2k) { ++ int len, i, Zplm, Nplm, add, packet_len = 0; ++ ++ opj_cio_t *cio = j2k->cio; ++ ++ len = cio_read(cio, 2); /* Lplm */ ++ Zplm = cio_read(cio, 1); /* Zplm */ ++ len -= 3; ++ while (len > 0) { ++ Nplm = cio_read(cio, 4); /* Nplm */ ++ len -= 4; ++ for (i = Nplm; i > 0; i--) { ++ add = cio_read(cio, 1); ++ len--; ++ packet_len = (packet_len << 7) + add; /* Iplm_ij */ ++ if ((add & 0x80) == 0) { ++ /* New packet */ ++ packet_len = 0; ++ } ++ if (len <= 0) ++ break; ++ } ++ } ++} ++ ++static void j2k_read_plt(opj_j2k_t *j2k) { ++ int len, i, Zplt, packet_len = 0, add; ++ ++ opj_cio_t *cio = j2k->cio; ++ ++ len = cio_read(cio, 2); /* Lplt */ ++ Zplt = cio_read(cio, 1); /* Zplt */ ++ for (i = len - 3; i > 0; i--) { ++ add = cio_read(cio, 1); ++ packet_len = (packet_len << 7) + add; /* Iplt_i */ ++ if ((add & 0x80) == 0) { ++ /* New packet */ ++ packet_len = 0; ++ } ++ } ++} ++ ++static void j2k_read_ppm(opj_j2k_t *j2k) { ++ int len, Z_ppm, i, j; ++ int N_ppm; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_cio_t *cio = j2k->cio; ++ ++ len = cio_read(cio, 2); ++ cp->ppm = 1; ++ ++ Z_ppm = cio_read(cio, 1); /* Z_ppm */ ++ len -= 3; ++ while (len > 0) { ++ if (cp->ppm_previous == 0) { ++ N_ppm = cio_read(cio, 4); /* N_ppm */ ++ len -= 4; ++ } else { ++ N_ppm = cp->ppm_previous; ++ } ++ j = cp->ppm_store; ++ if (Z_ppm == 0) { /* First PPM marker */ ++ cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char)); ++ cp->ppm_data_first = cp->ppm_data; ++ cp->ppm_len = N_ppm; ++ } else { /* NON-first PPM marker */ ++ cp->ppm_data = (unsigned char *) opj_realloc(cp->ppm_data, (N_ppm + cp->ppm_store) * sizeof(unsigned char)); ++/* UniPG>> */ ++#ifdef USE_JPWL ++ /* this memory allocation check could be done even in non-JPWL cases */ ++ if (cp->correct) { ++ if (!cp->ppm_data) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "JPWL: failed memory allocation during PPM marker parsing (pos. %x)\n", ++ cio_tell(cio)); ++ if (!JPWL_ASSUME || JPWL_ASSUME) ++ exit(1); ++ } ++ } ++#endif ++/* <<UniPG */ ++ cp->ppm_data_first = cp->ppm_data; ++ cp->ppm_len = N_ppm + cp->ppm_store; ++ } ++ for (i = N_ppm; i > 0; i--) { /* Read packet header */ ++ cp->ppm_data[j] = cio_read(cio, 1); ++ j++; ++ len--; ++ if (len == 0) ++ break; /* Case of non-finished packet header in present marker but finished in next one */ ++ } ++ cp->ppm_previous = i - 1; ++ cp->ppm_store = j; ++ } ++} ++ ++static void j2k_read_ppt(opj_j2k_t *j2k) { ++ int len, Z_ppt, i, j = 0; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = cp->tcps + j2k->curtileno; ++ opj_cio_t *cio = j2k->cio; ++ ++ len = cio_read(cio, 2); ++ Z_ppt = cio_read(cio, 1); ++ tcp->ppt = 1; ++ if (Z_ppt == 0) { /* First PPT marker */ ++ tcp->ppt_data = (unsigned char *) opj_malloc((len - 3) * sizeof(unsigned char)); ++ tcp->ppt_data_first = tcp->ppt_data; ++ tcp->ppt_store = 0; ++ tcp->ppt_len = len - 3; ++ } else { /* NON-first PPT marker */ ++ tcp->ppt_data = (unsigned char *) opj_realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char)); ++ tcp->ppt_data_first = tcp->ppt_data; ++ tcp->ppt_len = len - 3 + tcp->ppt_store; ++ } ++ j = tcp->ppt_store; ++ for (i = len - 3; i > 0; i--) { ++ tcp->ppt_data[j] = cio_read(cio, 1); ++ j++; ++ } ++ tcp->ppt_store = j; ++} ++ ++static void j2k_write_sot(opj_j2k_t *j2k) { ++ int lenp, len; ++ ++ opj_cio_t *cio = j2k->cio; ++ ++ j2k->sot_start = cio_tell(cio); ++ cio_write(cio, J2K_MS_SOT, 2); /* SOT */ ++ lenp = cio_tell(cio); ++ cio_skip(cio, 2); /* Lsot (further) */ ++ cio_write(cio, j2k->curtileno, 2); /* Isot */ ++ cio_skip(cio, 4); /* Psot (further in j2k_write_sod) */ ++ cio_write(cio, 0, 1); /* TPsot */ ++ cio_write(cio, 1, 1); /* TNsot */ ++ len = cio_tell(cio) - lenp; ++ cio_seek(cio, lenp); ++ cio_write(cio, len, 2); /* Lsot */ ++ cio_seek(cio, lenp + len); ++} ++ ++static void j2k_read_sot(opj_j2k_t *j2k) { ++ int len, tileno, totlen, partno, numparts, i; ++ opj_tcp_t *tcp = NULL; ++ char status = 0; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_cio_t *cio = j2k->cio; ++ ++ len = cio_read(cio, 2); ++ tileno = cio_read(cio, 2); ++/* UniPG>> */ ++#ifdef USE_JPWL ++ if (j2k->cp->correct) { ++ ++ static int backup_tileno = 0; ++ ++ /* tileno is negative or larger than the number of tiles!!! */ ++ if ((tileno < 0) || (tileno > (cp->tw * cp->th))) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "JPWL: bad tile number (%d out of a maximum of %d)\n", ++ tileno, (cp->tw * cp->th)); ++ if (!JPWL_ASSUME) ++ exit(1); ++ /* we try to correct */ ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"); ++ tileno = backup_tileno; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting tile number to %d\n", ++ tileno); ++ } ++ ++ /* keep your private count of tiles */ ++ backup_tileno++; ++ }; ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ ++ if (cp->tileno_size == 0) { ++ cp->tileno[cp->tileno_size] = tileno; ++ cp->tileno_size++; ++ } else { ++ i = 0; ++ while (i < cp->tileno_size && status == 0) { ++ status = cp->tileno[i] == tileno ? 1 : 0; ++ i++; ++ } ++ if (status == 0) { ++ cp->tileno[cp->tileno_size] = tileno; ++ cp->tileno_size++; ++ } ++ } ++ ++ totlen = cio_read(cio, 4); ++/* UniPG>> */ ++#ifdef USE_JPWL ++ if (j2k->cp->correct) { ++ ++ /* totlen is negative or larger than the bytes left!!! */ ++ if ((totlen < 0) || (totlen > (cio_numbytesleft(cio) + 8))) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "JPWL: bad tile byte size (%d bytes against %d bytes left)\n", ++ totlen, cio_numbytesleft(cio) + 8); ++ if (!JPWL_ASSUME) ++ exit(1); ++ /* we try to correct */ ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"); ++ totlen = 0; ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Psot to %d => " ++ "assuming it is the last tile\n", ++ totlen); ++ } ++ ++ }; ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ if (!totlen) ++ totlen = cio_numbytesleft(cio) + 8; ++ ++ partno = cio_read(cio, 1); ++ numparts = cio_read(cio, 1); ++ ++ j2k->curtileno = tileno; ++ j2k->eot = cio_getbp(cio) - 12 + totlen; ++ j2k->state = J2K_STATE_TPH; ++ tcp = &cp->tcps[j2k->curtileno]; ++ ++ if (tcp->first == 1) { ++ ++ /* Initialization PPT */ ++ opj_tccp_t *tmp = tcp->tccps; ++ memcpy(tcp, j2k->default_tcp, sizeof(opj_tcp_t)); ++ tcp->ppt = 0; ++ tcp->ppt_data = NULL; ++ tcp->ppt_data_first = NULL; ++ tcp->tccps = tmp; ++ ++ for (i = 0; i < j2k->image->numcomps; i++) { ++ tcp->tccps[i] = j2k->default_tcp->tccps[i]; ++ } ++ cp->tcps[j2k->curtileno].first = 0; ++ } ++} ++ ++static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) { ++ int l, layno; ++ int totlen; ++ opj_tcp_t *tcp = NULL; ++ opj_image_info_t *image_info = NULL; ++ ++ opj_tcd_t *tcd = (opj_tcd_t*)tile_coder; /* cast is needed because of conflicts in header inclusions */ ++ opj_cp_t *cp = j2k->cp; ++ opj_cio_t *cio = j2k->cio; ++ ++ cio_write(cio, J2K_MS_SOD, 2); ++ if (j2k->curtileno == 0) { ++ j2k->sod_start = cio_tell(cio) + j2k->pos_correction; ++ } ++ ++ /* INDEX >> */ ++ image_info = j2k->image_info; ++ if (image_info && image_info->index_on) { ++ image_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1; ++ } ++ /* << INDEX */ ++ ++ tcp = &cp->tcps[j2k->curtileno]; ++ for (layno = 0; layno < tcp->numlayers; layno++) { ++ tcp->rates[layno] -= tcp->rates[layno] ? (j2k->sod_start / (cp->th * cp->tw)) : 0; ++ } ++ if(image_info) { ++ image_info->num = 0; ++ } ++ ++ l = tcd_encode_tile(tcd, j2k->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, image_info); ++ ++ /* Writing Psot in SOT marker */ ++ totlen = cio_tell(cio) + l - j2k->sot_start; ++ cio_seek(cio, j2k->sot_start + 6); ++ cio_write(cio, totlen, 4); ++ cio_seek(cio, j2k->sot_start + totlen); ++} ++ ++static void j2k_read_sod(opj_j2k_t *j2k) { ++ int len, truncate = 0, i; ++ unsigned char *data = NULL, *data_ptr = NULL; ++ ++ opj_cio_t *cio = j2k->cio; ++ int curtileno = j2k->curtileno; ++ ++ len = int_min(j2k->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1); ++ ++ if (len == cio_numbytesleft(cio) + 1) { ++ truncate = 1; /* Case of a truncate codestream */ ++ } ++ ++ data = (unsigned char *) opj_malloc((j2k->tile_len[curtileno] + len) * sizeof(unsigned char)); ++ ++ for (i = 0; i < j2k->tile_len[curtileno]; i++) { ++ data[i] = j2k->tile_data[curtileno][i]; ++ } ++ ++ data_ptr = data + j2k->tile_len[curtileno]; ++ for (i = 0; i < len; i++) { ++ data_ptr[i] = cio_read(cio, 1); ++ } ++ ++ j2k->tile_len[curtileno] += len; ++ opj_free(j2k->tile_data[curtileno]); ++ j2k->tile_data[curtileno] = data; ++ ++ if (!truncate) { ++ j2k->state = J2K_STATE_TPHSOT; ++ } else { ++ j2k->state = J2K_STATE_NEOC; /* RAJOUTE !! */ ++ } ++} ++ ++static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno) { ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = &cp->tcps[tileno]; ++ opj_cio_t *cio = j2k->cio; ++ int numcomps = j2k->image->numcomps; ++ ++ cio_write(cio, J2K_MS_RGN, 2); /* RGN */ ++ cio_write(cio, numcomps <= 256 ? 5 : 6, 2); /* Lrgn */ ++ cio_write(cio, compno, numcomps <= 256 ? 1 : 2); /* Crgn */ ++ cio_write(cio, 0, 1); /* Srgn */ ++ cio_write(cio, tcp->tccps[compno].roishift, 1); /* SPrgn */ ++} ++ ++static void j2k_read_rgn(opj_j2k_t *j2k) { ++ int len, compno, roisty; ++ ++ opj_cp_t *cp = j2k->cp; ++ opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; ++ opj_cio_t *cio = j2k->cio; ++ int numcomps = j2k->image->numcomps; ++ ++ len = cio_read(cio, 2); /* Lrgn */ ++ compno = cio_read(cio, numcomps <= 256 ? 1 : 2); /* Crgn */ ++ roisty = cio_read(cio, 1); /* Srgn */ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ if (j2k->cp->correct) { ++ /* totlen is negative or larger than the bytes left!!! */ ++ if (compno >= numcomps) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "JPWL: bad component number in RGN (%d when there are only %d)\n", ++ compno, numcomps); ++ if (!JPWL_ASSUME || JPWL_ASSUME) ++ exit(1); ++ } ++ }; ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */ ++} ++ ++static void j2k_write_eoc(opj_j2k_t *j2k) { ++ opj_cio_t *cio = j2k->cio; ++ /* opj_event_msg(j2k->cinfo, "%.8x: EOC\n", cio_tell(cio) + j2k->pos_correction); */ ++ cio_write(cio, J2K_MS_EOC, 2); ++} ++ ++static void j2k_read_eoc(opj_j2k_t *j2k) { ++ int i, tileno; ++ ++#ifndef NO_PACKETS_DECODING ++ opj_tcd_t *tcd = tcd_create(j2k->cinfo); ++ tcd_malloc_decode(tcd, j2k->image, j2k->cp); ++ for (i = 0; i < j2k->cp->tileno_size; i++) { ++ tileno = j2k->cp->tileno[i]; ++ tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno); ++ opj_free(j2k->tile_data[tileno]); ++ j2k->tile_data[tileno] = NULL; ++ } ++ tcd_free_decode(tcd); ++ tcd_destroy(tcd); ++#else ++ for (i = 0; i < j2k->cp->tileno_size; i++) { ++ tileno = j2k->cp->tileno[i]; ++ opj_free(j2k->tile_data[tileno]); ++ j2k->tile_data[tileno] = NULL; ++ } ++#endif ++ ++ j2k->state = J2K_STATE_MT; ++} ++ ++typedef struct opj_dec_mstabent { ++ /** marker value */ ++ int id; ++ /** value of the state when the marker can appear */ ++ int states; ++ /** action linked to the marker */ ++ void (*handler) (opj_j2k_t *j2k); ++} opj_dec_mstabent_t; ++ ++opj_dec_mstabent_t j2k_dec_mstab[] = { ++ {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc}, ++ {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot}, ++ {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod}, ++ {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc}, ++ {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz}, ++ {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod}, ++ {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc}, ++ {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn}, ++ {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd}, ++ {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc}, ++ {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc}, ++ {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm}, ++ {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm}, ++ {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt}, ++ {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm}, ++ {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt}, ++ {J2K_MS_SOP, 0, 0}, ++ {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg}, ++ {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com}, ++/* UniPG>> */ ++#ifdef USE_JPWL ++ {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc}, ++ {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb}, ++ {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd}, ++ {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red}, ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ {0, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_unk} ++}; ++ ++static void j2k_read_unk(opj_j2k_t *j2k) { ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "Unknown marker\n"); ++/* UniPG>> */ ++#ifdef USE_JPWL ++ if (j2k->cp->correct) { ++ int m = 0, id, i; ++ int min_id = 0, min_dist = 17, cur_dist = 0, tmp_id; ++ cio_seek(j2k->cio, cio_tell(j2k->cio) - 2); ++ id = cio_read(j2k->cio, 2); ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "JPWL: really don't know this marker %x\n", ++ id); ++ if (!JPWL_ASSUME) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "- possible synch loss due to uncorrectable channel errors => Exiting\n"); ++ exit(1); ++ } ++ /* OK, activate this at your own risk!!! */ ++ /* we look for the marker at the minimum hamming distance from this */ ++ while (j2k_dec_mstab[m].id) { ++ ++ /* 1's where they differ */ ++ tmp_id = j2k_dec_mstab[m].id ^ id; ++ ++ /* compute the hamming distance between our id and the current */ ++ cur_dist = 0; ++ for (i = 0; i < 16; i++) { ++ if ((tmp_id >> i) & 0x0001) { ++ cur_dist++; ++ } ++ } ++ ++ /* if current distance is smaller, set the minimum */ ++ if (cur_dist < min_dist) { ++ min_dist = cur_dist; ++ min_id = j2k_dec_mstab[m].id; ++ } ++ ++ /* jump to the next marker */ ++ m++; ++ } ++ ++ /* do we substitute the marker? */ ++ if (min_dist < JPWL_MAXIMUM_HAMMING) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "- marker %x is at distance %d from the read %x\n", ++ min_id, min_dist, id); ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "- trying to substitute in place and crossing fingers!\n"); ++ cio_seek(j2k->cio, cio_tell(j2k->cio) - 2); ++ cio_write(j2k->cio, min_id, 2); ++ ++ /* rewind */ ++ cio_seek(j2k->cio, cio_tell(j2k->cio) - 2); ++ ++ } ++ ++ }; ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++} ++ ++/** ++Read the lookup table containing all the marker, status and action ++@param id Marker value ++*/ ++static opj_dec_mstabent_t *j2k_dec_mstab_lookup(int id) { ++ opj_dec_mstabent_t *e; ++ for (e = j2k_dec_mstab; e->id != 0; e++) { ++ if (e->id == id) { ++ break; ++ } ++ } ++ return e; ++} ++ ++/* ----------------------------------------------------------------------- */ ++/* J2K / JPT decoder interface */ ++/* ----------------------------------------------------------------------- */ ++ ++opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo) { ++ opj_j2k_t *j2k = (opj_j2k_t*)opj_malloc(sizeof(opj_j2k_t)); ++ if(j2k) { ++ j2k->cinfo = cinfo; ++ j2k->default_tcp = (opj_tcp_t*)opj_malloc(sizeof(opj_tcp_t)); ++ if(!j2k->default_tcp) { ++ opj_free(j2k); ++ return NULL; ++ } ++ } ++ return j2k; ++} ++ ++void j2k_destroy_decompress(opj_j2k_t *j2k) { ++ int i = 0; ++ ++ if(j2k->tile_len != NULL) { ++ opj_free(j2k->tile_len); ++ } ++ if(j2k->tile_data != NULL) { ++ opj_free(j2k->tile_data); ++ } ++ if(j2k->default_tcp != NULL) { ++ opj_tcp_t *default_tcp = j2k->default_tcp; ++ if(default_tcp->ppt_data_first != NULL) { ++ opj_free(default_tcp->ppt_data_first); ++ } ++ if(j2k->default_tcp->tccps != NULL) { ++ opj_free(j2k->default_tcp->tccps); ++ } ++ opj_free(j2k->default_tcp); ++ } ++ if(j2k->cp != NULL) { ++ opj_cp_t *cp = j2k->cp; ++ if(cp->tcps != NULL) { ++ for(i = 0; i < cp->tw * cp->th; i++) { ++ if(cp->tcps[i].ppt_data_first != NULL) { ++ opj_free(cp->tcps[i].ppt_data_first); ++ } ++ if(cp->tcps[i].tccps != NULL) { ++ opj_free(cp->tcps[i].tccps); ++ } ++ } ++ opj_free(cp->tcps); ++ } ++ if(cp->ppm_data_first != NULL) { ++ opj_free(cp->ppm_data_first); ++ } ++ if(cp->tileno != NULL) { ++ opj_free(cp->tileno); ++ } ++ if(cp->comment != NULL) { ++ opj_free(cp->comment); ++ } ++ ++ opj_free(cp); ++ } ++ ++ opj_free(j2k); ++} ++ ++void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) { ++ if(j2k && parameters) { ++ /* create and initialize the coding parameters structure */ ++ opj_cp_t *cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t)); ++ cp->reduce = parameters->cp_reduce; ++ cp->layer = parameters->cp_layer; ++ cp->limit_decoding = parameters->cp_limit_decoding; ++/* UniPG>> */ ++#ifdef USE_JPWL ++ cp->correct = parameters->jpwl_correct; ++ cp->exp_comps = parameters->jpwl_exp_comps; ++ cp->max_tiles = parameters->jpwl_max_tiles; ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ ++ /* keep a link to cp so that we can destroy it later in j2k_destroy_decompress */ ++ j2k->cp = cp; ++ } ++} ++ ++opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio) { ++ opj_image_t *image = NULL; ++ ++ opj_common_ptr cinfo = j2k->cinfo; ++ ++ j2k->cio = cio; ++ ++ /* create an empty image */ ++ image = opj_image_create0(); ++ j2k->image = image; ++ ++ j2k->state = J2K_STATE_MHSOC; ++ ++ for (;;) { ++ opj_dec_mstabent_t *e; ++ int id = cio_read(cio, 2); ++ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ /* we try to honor JPWL correction power */ ++ if (j2k->cp->correct) { ++ ++ int orig_pos = cio_tell(cio); ++ bool status; ++ ++ /* call the corrector */ ++ status = jpwl_correct(j2k); ++ ++ /* go back to where you were */ ++ cio_seek(cio, orig_pos - 2); ++ ++ /* re-read the marker */ ++ id = cio_read(cio, 2); ++ ++ /* check whether it begins with ff */ ++ if (id >> 8 != 0xff) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, ++ "JPWL: possible bad marker %x at %d\n", ++ id, cio_tell(cio) - 2); ++ if (!JPWL_ASSUME) ++ exit(1); ++ /* we try to correct */ ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"); ++ id = id | 0xff00; ++ cio_seek(cio, cio_tell(cio) - 2); ++ cio_write(cio, id, 2); ++ opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting marker to %x\n", ++ id); ++ } ++ ++ } ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ if (id >> 8 != 0xff) { ++ opj_image_destroy(image); ++ opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); ++ return 0; ++ } ++ e = j2k_dec_mstab_lookup(id); ++ // Check if the marker is known ++ if (!(j2k->state & e->states)) { ++ opj_image_destroy(image); ++ opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); ++ return 0; ++ } ++ // Check if the decoding is limited to the main header ++ if (e->id == J2K_MS_SOT && j2k->cp->limit_decoding == LIMIT_TO_MAIN_HEADER) { ++ opj_event_msg(cinfo, EVT_INFO, "Main Header decoded.\n"); ++ return image; ++ } ++ ++ if (e->handler) { ++ (*e->handler)(j2k); ++ } ++ if (j2k->state == J2K_STATE_MT) { ++ break; ++ } ++ if (j2k->state == J2K_STATE_NEOC) { ++ break; ++ } ++ } ++ if (j2k->state == J2K_STATE_NEOC) { ++ j2k_read_eoc(j2k); ++ } ++ ++ if (j2k->state != J2K_STATE_MT) { ++ opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); ++ } ++ ++ return image; ++} ++ ++/* ++* Read a JPT-stream and decode file ++* ++*/ ++opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio) { ++ opj_image_t *image = NULL; ++ opj_jpt_msg_header_t header; ++ int position; ++ ++ opj_common_ptr cinfo = j2k->cinfo; ++ ++ j2k->cio = cio; ++ ++ /* create an empty image */ ++ image = opj_image_create0(); ++ ++ j2k->state = J2K_STATE_MHSOC; ++ ++ /* Initialize the header */ ++ jpt_init_msg_header(&header); ++ /* Read the first header of the message */ ++ jpt_read_msg_header(cinfo, cio, &header); ++ ++ position = cio_tell(cio); ++ if (header.Class_Id != 6) { /* 6 : Main header data-bin message */ ++ opj_image_destroy(image); ++ opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Main header first [class_Id %d] !\n", header.Class_Id); ++ return 0; ++ } ++ ++ for (;;) { ++ opj_dec_mstabent_t *e = NULL; ++ int id; ++ ++ if (!cio_numbytesleft(cio)) { ++ j2k_read_eoc(j2k); ++ return image; ++ } ++ /* data-bin read -> need to read a new header */ ++ if ((unsigned int) (cio_tell(cio) - position) == header.Msg_length) { ++ jpt_read_msg_header(cinfo, cio, &header); ++ position = cio_tell(cio); ++ if (header.Class_Id != 4) { /* 4 : Tile data-bin message */ ++ opj_image_destroy(image); ++ opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Tile info !\n"); ++ return 0; ++ } ++ } ++ ++ id = cio_read(cio, 2); ++ if (id >> 8 != 0xff) { ++ opj_image_destroy(image); ++ opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); ++ return 0; ++ } ++ e = j2k_dec_mstab_lookup(id); ++ if (!(j2k->state & e->states)) { ++ opj_image_destroy(image); ++ opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); ++ return 0; ++ } ++ if (e->handler) { ++ (*e->handler)(j2k); ++ } ++ if (j2k->state == J2K_STATE_MT) { ++ break; ++ } ++ if (j2k->state == J2K_STATE_NEOC) { ++ break; ++ } ++ } ++ if (j2k->state == J2K_STATE_NEOC) { ++ j2k_read_eoc(j2k); ++ } ++ ++ if (j2k->state != J2K_STATE_MT) { ++ opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); ++ } ++ ++ return image; ++} ++ ++/* ----------------------------------------------------------------------- */ ++/* J2K encoder interface */ ++/* ----------------------------------------------------------------------- */ ++ ++opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo) { ++ opj_j2k_t *j2k = (opj_j2k_t*)opj_malloc(sizeof(opj_j2k_t)); ++ if(j2k) { ++ j2k->cinfo = cinfo; ++ } ++ return j2k; ++} ++ ++void j2k_destroy_compress(opj_j2k_t *j2k) { ++ int tileno; ++ ++ if(!j2k) return; ++ ++ if(j2k->image_info != NULL) { ++ opj_image_info_t *image_info = j2k->image_info; ++ if (image_info->index_on && j2k->cp) { ++ opj_cp_t *cp = j2k->cp; ++ for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { ++ opj_tile_info_t *tile_info = &image_info->tile[tileno]; ++ opj_free(tile_info->thresh); ++ opj_free(tile_info->packet); ++ } ++ opj_free(image_info->tile); ++ } ++ opj_free(image_info); ++ } ++ if(j2k->cp != NULL) { ++ opj_cp_t *cp = j2k->cp; ++ ++ if(cp->comment) { ++ opj_free(cp->comment); ++ } ++ if(cp->matrice) { ++ opj_free(cp->matrice); ++ } ++ for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { ++ opj_free(cp->tcps[tileno].tccps); ++ } ++ opj_free(cp->tcps); ++ opj_free(cp); ++ } ++ ++ opj_free(j2k); ++} ++ ++void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image) { ++ int i, j, tileno, numpocs_tile; ++ opj_cp_t *cp = NULL; ++ ++ if(!j2k || !parameters || ! image) { ++ return; ++ } ++ ++ /* create and initialize the coding parameters structure */ ++ cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t)); ++ ++ /* keep a link to cp so that we can destroy it later in j2k_destroy_compress */ ++ j2k->cp = cp; ++ ++ /* set default values for cp */ ++ cp->tw = 1; ++ cp->th = 1; ++ ++ /* ++ copy user encoding parameters ++ */ ++ ++ cp->disto_alloc = parameters->cp_disto_alloc; ++ cp->fixed_alloc = parameters->cp_fixed_alloc; ++ cp->fixed_quality = parameters->cp_fixed_quality; ++ ++ /* mod fixed_quality */ ++ if(parameters->cp_matrice) { ++ size_t array_size = parameters->tcp_numlayers * parameters->numresolution * 3 * sizeof(int); ++ cp->matrice = (int *) opj_malloc(array_size); ++ memcpy(cp->matrice, parameters->cp_matrice, array_size); ++ } ++ ++ /* creation of an index file ? */ ++ cp->index_on = parameters->index_on; ++ if(cp->index_on) { ++ j2k->image_info = (opj_image_info_t*)opj_malloc(sizeof(opj_image_info_t)); ++ } ++ ++ /* tiles */ ++ cp->tdx = parameters->cp_tdx; ++ cp->tdy = parameters->cp_tdy; ++ ++ /* tile offset */ ++ cp->tx0 = parameters->cp_tx0; ++ cp->ty0 = parameters->cp_ty0; ++ ++ /* comment string */ ++ if(parameters->cp_comment) { ++ cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1); ++ if(cp->comment) { ++ strcpy(cp->comment, parameters->cp_comment); ++ } ++ } ++ ++ /* ++ calculate other encoding parameters ++ */ ++ ++ if (parameters->tile_size_on) { ++ cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx); ++ cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy); ++ } else { ++ cp->tdx = image->x1 - cp->tx0; ++ cp->tdy = image->y1 - cp->ty0; ++ } ++ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ /* ++ calculate JPWL encoding parameters ++ */ ++ ++ if (parameters->jpwl_epc_on) { ++ int i; ++ ++ /* set JPWL on */ ++ cp->epc_on = true; ++ cp->info_on = false; /* no informative technique */ ++ ++ /* set EPB on */ ++ if ((parameters->jpwl_hprot_MH > 0) || (parameters->jpwl_hprot_TPH[0] > 0)) { ++ cp->epb_on = true; ++ ++ cp->hprot_MH = parameters->jpwl_hprot_MH; ++ for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { ++ cp->hprot_TPH_tileno[i] = parameters->jpwl_hprot_TPH_tileno[i]; ++ cp->hprot_TPH[i] = parameters->jpwl_hprot_TPH[i]; ++ } ++ /* if tile specs are not specified, copy MH specs */ ++ if (cp->hprot_TPH[0] == -1) { ++ cp->hprot_TPH_tileno[0] = 0; ++ cp->hprot_TPH[0] = parameters->jpwl_hprot_MH; ++ } ++ for (i = 0; i < JPWL_MAX_NO_PACKSPECS; i++) { ++ cp->pprot_tileno[i] = parameters->jpwl_pprot_tileno[i]; ++ cp->pprot_packno[i] = parameters->jpwl_pprot_packno[i]; ++ cp->pprot[i] = parameters->jpwl_pprot[i]; ++ } ++ } ++ ++ /* set ESD writing */ ++ if ((parameters->jpwl_sens_size == 1) || (parameters->jpwl_sens_size == 2)) { ++ cp->esd_on = true; ++ ++ cp->sens_size = parameters->jpwl_sens_size; ++ cp->sens_addr = parameters->jpwl_sens_addr; ++ cp->sens_range = parameters->jpwl_sens_range; ++ ++ cp->sens_MH = parameters->jpwl_sens_MH; ++ for (i = 0; i < JPWL_MAX_NO_TILESPECS; i++) { ++ cp->sens_TPH_tileno[i] = parameters->jpwl_sens_TPH_tileno[i]; ++ cp->sens_TPH[i] = parameters->jpwl_sens_TPH[i]; ++ } ++ } ++ ++ /* always set RED writing to false: we are at the encoder */ ++ cp->red_on = false; ++ ++ } else { ++ cp->epc_on = false; ++ } ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ ++ /* initialize the mutiple tiles */ ++ /* ---------------------------- */ ++ cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tcp_t)); ++ ++ for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { ++ opj_tcp_t *tcp = &cp->tcps[tileno]; ++ tcp->numlayers = parameters->tcp_numlayers; ++ for (j = 0; j < tcp->numlayers; j++) { ++ if (cp->fixed_quality) { /* add fixed_quality */ ++ tcp->distoratio[j] = parameters->tcp_distoratio[j]; ++ } else { ++ tcp->rates[j] = parameters->tcp_rates[j]; ++ } ++ } ++ tcp->csty = parameters->csty; ++ tcp->prg = parameters->prog_order; ++ tcp->mct = image->numcomps == 3 ? 1 : 0; ++ ++ numpocs_tile = 0; ++ tcp->POC = 0; ++ if (parameters->numpocs) { ++ /* initialisation of POC */ ++ tcp->POC = 1; ++ for (i = 0; i < parameters->numpocs; i++) { ++ if((tileno == parameters->POC[i].tile - 1) || (parameters->POC[i].tile == -1)) { ++ opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile]; ++ tcp_poc->resno0 = parameters->POC[numpocs_tile].resno0; ++ tcp_poc->compno0 = parameters->POC[numpocs_tile].compno0; ++ tcp_poc->layno1 = parameters->POC[numpocs_tile].layno1; ++ tcp_poc->resno1 = parameters->POC[numpocs_tile].resno1; ++ tcp_poc->compno1 = parameters->POC[numpocs_tile].compno1; ++ tcp_poc->prg = parameters->POC[numpocs_tile].prg; ++ tcp_poc->tile = parameters->POC[numpocs_tile].tile; ++ numpocs_tile++; ++ } ++ } ++ } ++ tcp->numpocs = numpocs_tile; ++ ++ tcp->tccps = (opj_tccp_t *) opj_malloc(image->numcomps * sizeof(opj_tccp_t)); ++ ++ for (i = 0; i < image->numcomps; i++) { ++ opj_tccp_t *tccp = &tcp->tccps[i]; ++ tccp->csty = parameters->csty & 0x01; /* 0 => one precinct || 1 => custom precinct */ ++ tccp->numresolutions = parameters->numresolution; ++ tccp->cblkw = int_floorlog2(parameters->cblockw_init); ++ tccp->cblkh = int_floorlog2(parameters->cblockh_init); ++ tccp->cblksty = parameters->mode; ++ tccp->qmfbid = parameters->irreversible ? 0 : 1; ++ tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT; ++ tccp->numgbits = 2; ++ if (i == parameters->roi_compno) { ++ tccp->roishift = parameters->roi_shift; ++ } else { ++ tccp->roishift = 0; ++ } ++ if (parameters->csty & J2K_CCP_CSTY_PRT) { ++ int p = 0; ++ for (j = tccp->numresolutions - 1; j >= 0; j--) { ++ if (p < parameters->res_spec) { ++ if (parameters->prcw_init[p] < 1) { ++ tccp->prcw[j] = 1; ++ } else { ++ tccp->prcw[j] = int_floorlog2(parameters->prcw_init[p]); ++ } ++ if (parameters->prch_init[p] < 1) { ++ tccp->prch[j] = 1; ++ } else { ++ tccp->prch[j] = int_floorlog2(parameters->prch_init[p]); ++ } ++ } else { ++ int res_spec = parameters->res_spec; ++ int size_prcw = parameters->prcw_init[res_spec - 1] >> (p - (res_spec - 1)); ++ int size_prch = parameters->prch_init[res_spec - 1] >> (p - (res_spec - 1)); ++ if (size_prcw < 1) { ++ tccp->prcw[j] = 1; ++ } else { ++ tccp->prcw[j] = int_floorlog2(size_prcw); ++ } ++ if (size_prch < 1) { ++ tccp->prch[j] = 1; ++ } else { ++ tccp->prch[j] = int_floorlog2(size_prch); ++ } ++ } ++ p++; ++ /*printf("\nsize precinct for level %d : %d,%d\n", j,tccp->prcw[j], tccp->prch[j]); */ ++ } ++ } else { ++ for (j = 0; j < tccp->numresolutions; j++) { ++ tccp->prcw[j] = 15; ++ tccp->prch[j] = 15; ++ } ++ } ++ ++ dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec); ++ } ++ } ++} ++ ++/** ++Create an index file ++@param j2k ++@param cio ++@param image_info ++@param index Index filename ++@return Returns 1 if successful, returns 0 otherwise ++*/ ++static int j2k_create_index(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_info_t *image_info, char *index) { ++ int tileno, compno, layno, resno, precno, pack_nb, x, y; ++ FILE *stream = NULL; ++ double total_disto = 0; ++ ++ image_info->codestream_size = cio_tell(cio) + j2k->pos_correction; /* Correction 14/4/03 suite rmq de Patrick */ ++ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ /* if JPWL is enabled and the name coincides with our own set ++ then discard the creation of the file: this was just done to ++ enable indexing, we do not want an index file ++ */ ++ if (j2k->cp->epc_on && !strcmp(index, JPWL_PRIVATEINDEX_NAME)) ++ return 1; ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ ++ stream = fopen(index, "w"); ++ if (!stream) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to open %s for writing\n", index); ++ return 0; ++ } ++ ++ fprintf(stream, "%d %d\n", image_info->image_w, image_info->image_h); ++ fprintf(stream, "%d\n", image_info->prog); ++ fprintf(stream, "%d %d\n", image_info->tile_x, image_info->tile_y); ++ fprintf(stream, "%d %d\n", image_info->tw, image_info->th); ++ fprintf(stream, "%d\n", image_info->comp); ++ fprintf(stream, "%d\n", image_info->layer); ++ fprintf(stream, "%d\n", image_info->decomposition); ++ ++ for (resno = image_info->decomposition; resno >= 0; resno--) { ++ fprintf(stream, "[%d,%d] ", ++ (1 << image_info->tile[0].pdx[resno]), (1 << image_info->tile[0].pdx[resno])); /* based on tile 0 */ ++ } ++ fprintf(stream, "\n"); ++ fprintf(stream, "%d\n", image_info->main_head_end); ++ fprintf(stream, "%d\n", image_info->codestream_size); ++ ++ for (tileno = 0; tileno < image_info->tw * image_info->th; tileno++) { ++ fprintf(stream, "%4d %9d %9d %9d %9e %9d %9e\n", ++ image_info->tile[tileno].num_tile, ++ image_info->tile[tileno].start_pos, ++ image_info->tile[tileno].end_header, ++ image_info->tile[tileno].end_pos, ++ image_info->tile[tileno].distotile, image_info->tile[tileno].nbpix, ++ image_info->tile[tileno].distotile / image_info->tile[tileno].nbpix); ++ } ++ ++ for (tileno = 0; tileno < image_info->tw * image_info->th; tileno++) { ++ int start_pos, end_pos; ++ double disto = 0; ++ pack_nb = 0; ++ ++ /* ++ fprintf(stream, "pkno tileno layerno resno compno precno start_pos end_pos deltaSE \n"); ++ */ ++ ++ if (image_info->prog == LRCP) { /* LRCP */ ++ /* ++ fprintf(stream, "pack_nb tileno layno resno compno precno start_pos end_pos disto"); ++ */ ++ for (layno = 0; layno < image_info->layer; layno++) { ++ for (resno = 0; resno < image_info->decomposition + 1; resno++) { ++ for (compno = 0; compno < image_info->comp; compno++) { ++ int prec_max = image_info->tile[tileno].pw[resno] * image_info->tile[tileno].ph[resno]; ++ for (precno = 0; precno < prec_max; precno++) { ++ start_pos = image_info->tile[tileno].packet[pack_nb].start_pos; ++ end_pos = image_info->tile[tileno].packet[pack_nb].end_pos; ++ disto = image_info->tile[tileno].packet[pack_nb].disto; ++ fprintf(stream, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n", ++ pack_nb, tileno, layno, resno, compno, precno, start_pos, end_pos, disto); ++ total_disto += disto; ++ pack_nb++; ++ } ++ } ++ } ++ } ++ } /* LRCP */ ++ else if (image_info->prog == RLCP) { /* RLCP */ ++ /* ++ fprintf(stream, "pack_nb tileno resno layno compno precno start_pos end_pos disto"); ++ */ ++ for (resno = 0; resno < image_info->decomposition + 1; resno++) { ++ for (layno = 0; layno < image_info->layer; layno++) { ++ for (compno = 0; compno < image_info->comp; compno++) { ++ int prec_max = image_info->tile[tileno].pw[resno] * image_info->tile[tileno].ph[resno]; ++ for (precno = 0; precno < prec_max; precno++) { ++ start_pos = image_info->tile[tileno].packet[pack_nb].start_pos; ++ end_pos = image_info->tile[tileno].packet[pack_nb].end_pos; ++ disto = image_info->tile[tileno].packet[pack_nb].disto; ++ fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d %9d %8e\n", ++ pack_nb, tileno, resno, layno, compno, precno, start_pos, end_pos, disto); ++ total_disto += disto; ++ pack_nb++; ++ } ++ } ++ } ++ } ++ } /* RLCP */ ++ else if (image_info->prog == RPCL) { /* RPCL */ ++ /* ++ fprintf(stream, "\npack_nb tileno resno precno compno layno start_pos end_pos disto\n"); ++ */ ++ for (resno = 0; resno < image_info->decomposition + 1; resno++) { ++ /* I suppose components have same XRsiz, YRsiz */ ++ int x0 = image_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tw * image_info->tile_x; ++ int y0 = image_info->tile_Ox + (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tile_y; ++ int x1 = x0 + image_info->tile_x; ++ int y1 = y0 + image_info->tile_y; ++ for(y = y0; y < y1; y++) { ++ for(x = x0; x < x1; x++) { ++ for (compno = 0; compno < image_info->comp; compno++) { ++ int prec_max = image_info->tile[tileno].pw[resno] * image_info->tile[tileno].ph[resno]; ++ for (precno = 0; precno < prec_max; precno++) { ++ int pcnx = image_info->tile[tileno].pw[resno]; ++ int pcx = (int) pow( 2, image_info->tile[tileno].pdx[resno] + image_info->decomposition - resno ); ++ int pcy = (int) pow( 2, image_info->tile[tileno].pdy[resno] + image_info->decomposition - resno ); ++ int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; ++ int precno_y = (int) floor( (float)precno/(float)pcnx ); ++ if (precno_y*pcy == y ) { ++ if (precno_x*pcx == x ) { ++ for (layno = 0; layno < image_info->layer; layno++) { ++ start_pos = image_info->tile[tileno].packet[pack_nb].start_pos; ++ end_pos = image_info->tile[tileno].packet[pack_nb].end_pos; ++ disto = image_info->tile[tileno].packet[pack_nb].disto; ++ fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d %9d %8e\n", ++ pack_nb, tileno, resno, precno, compno, layno, start_pos, end_pos, disto); ++ total_disto += disto; ++ pack_nb++; ++ } ++ } ++ } ++ } /* precno */ ++ } /* compno */ ++ } /* x = x0..x1 */ ++ } /* y = y0..y1 */ ++ } /* resno */ ++ } /* RPCL */ ++ else if (image_info->prog == PCRL) { /* PCRL */ ++ /* I suppose components have same XRsiz, YRsiz */ ++ int x0 = image_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tw * image_info->tile_x; ++ int y0 = image_info->tile_Ox + (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tile_y; ++ int x1 = x0 + image_info->tile_x; ++ int y1 = y0 + image_info->tile_y; ++ /* ++ fprintf(stream, "\npack_nb tileno precno compno resno layno start_pos end_pos disto\n"); ++ */ ++ for(y = y0; y < y1; y++) { ++ for(x = x0; x < x1; x++) { ++ for (compno = 0; compno < image_info->comp; compno++) { ++ for (resno = 0; resno < image_info->decomposition + 1; resno++) { ++ int prec_max = image_info->tile[tileno].pw[resno] * image_info->tile[tileno].ph[resno]; ++ for (precno = 0; precno < prec_max; precno++) { ++ int pcnx = image_info->tile[tileno].pw[resno]; ++ int pcx = (int) pow( 2, image_info->tile[tileno].pdx[resno] + image_info->decomposition - resno ); ++ int pcy = (int) pow( 2, image_info->tile[tileno].pdy[resno] + image_info->decomposition - resno ); ++ int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; ++ int precno_y = (int) floor( (float)precno/(float)pcnx ); ++ if (precno_y*pcy == y ) { ++ if (precno_x*pcx == x ) { ++ for (layno = 0; layno < image_info->layer; layno++) { ++ start_pos = image_info->tile[tileno].packet[pack_nb].start_pos; ++ end_pos = image_info->tile[tileno].packet[pack_nb].end_pos; ++ disto = image_info->tile[tileno].packet[pack_nb].disto; ++ fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n", ++ pack_nb, tileno, precno, compno, resno, layno, start_pos, end_pos, disto); ++ total_disto += disto; ++ pack_nb++; ++ } ++ } ++ } ++ } /* precno */ ++ } /* resno */ ++ } /* compno */ ++ } /* x = x0..x1 */ ++ } /* y = y0..y1 */ ++ } /* PCRL */ ++ else { /* CPRL */ ++ /* ++ fprintf(stream, "\npack_nb tileno compno precno resno layno start_pos end_pos disto\n"); ++ */ ++ for (compno = 0; compno < image_info->comp; compno++) { ++ /* I suppose components have same XRsiz, YRsiz */ ++ int x0 = image_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tw * image_info->tile_x; ++ int y0 = image_info->tile_Ox + (int)floor( (float)tileno/(float)image_info->tw ) * image_info->tile_y; ++ int x1 = x0 + image_info->tile_x; ++ int y1 = y0 + image_info->tile_y; ++ for(y = y0; y < y1; y++) { ++ for(x = x0; x < x1; x++) { ++ for (resno = 0; resno < image_info->decomposition + 1; resno++) { ++ int prec_max = image_info->tile[tileno].pw[resno] * image_info->tile[tileno].ph[resno]; ++ for (precno = 0; precno < prec_max; precno++) { ++ int pcnx = image_info->tile[tileno].pw[resno]; ++ int pcx = (int) pow( 2, image_info->tile[tileno].pdx[resno] + image_info->decomposition - resno ); ++ int pcy = (int) pow( 2, image_info->tile[tileno].pdy[resno] + image_info->decomposition - resno ); ++ int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; ++ int precno_y = (int) floor( (float)precno/(float)pcnx ); ++ if (precno_y*pcy == y ) { ++ if (precno_x*pcx == x ) { ++ for (layno = 0; layno < image_info->layer; layno++) { ++ start_pos = image_info->tile[tileno].packet[pack_nb].start_pos; ++ end_pos = image_info->tile[tileno].packet[pack_nb].end_pos; ++ disto = image_info->tile[tileno].packet[pack_nb].disto; ++ fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n", ++ pack_nb, tileno, compno, precno, resno, layno, start_pos, end_pos, disto); ++ total_disto += disto; ++ pack_nb++; ++ } ++ } ++ } ++ } /* precno */ ++ } /* resno */ ++ } /* x = x0..x1 */ ++ } /* y = y0..y1 */ ++ } /* comno */ ++ } /* CPRL */ ++ } /* tileno */ ++ ++ fprintf(stream, "%8e\n", image_info->D_max); /* SE max */ ++ fprintf(stream, "%.8e\n", total_disto); /* SE totale */ ++ fclose(stream); ++ ++ return 1; ++} ++ ++bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, char *index) { ++ int tileno, compno; ++ opj_image_info_t *image_info = NULL; ++ opj_cp_t *cp = NULL; ++ ++ opj_tcd_t *tcd = NULL; /* TCD component */ ++ ++ j2k->cio = cio; ++ j2k->image = image; ++ ++ cp = j2k->cp; ++ ++ /* j2k_dump_cp(stdout, image, cp); */ ++ ++ /* INDEX >> */ ++ image_info = j2k->image_info; ++ if (image_info && cp->index_on) { ++ image_info->index_on = cp->index_on; ++ image_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tile_info_t)); ++ image_info->image_w = image->x1 - image->x0; ++ image_info->image_h = image->y1 - image->y0; ++ image_info->prog = (&cp->tcps[0])->prg; ++ image_info->tw = cp->tw; ++ image_info->th = cp->th; ++ image_info->tile_x = cp->tdx; /* new version parser */ ++ image_info->tile_y = cp->tdy; /* new version parser */ ++ image_info->tile_Ox = cp->tx0; /* new version parser */ ++ image_info->tile_Oy = cp->ty0; /* new version parser */ ++ image_info->comp = image->numcomps; ++ image_info->layer = (&cp->tcps[0])->numlayers; ++ image_info->decomposition = (&cp->tcps[0])->tccps->numresolutions - 1; ++ image_info->D_max = 0; /* ADD Marcela */ ++ } ++ /* << INDEX */ ++ ++ j2k_write_soc(j2k); ++ j2k_write_siz(j2k); ++/* UniPG>> */ ++#ifdef USE_JPWL ++ /** THIS CODE IS NOT USED */ ++ //if(image_info && image_info->index_on && cp->epc_on) ++ // j2k_write_epc(j2k); ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ j2k_write_cod(j2k); ++ j2k_write_qcd(j2k); ++ for (compno = 0; compno < image->numcomps; compno++) { ++ opj_tcp_t *tcp = &cp->tcps[0]; ++ if (tcp->tccps[compno].roishift) ++ j2k_write_rgn(j2k, compno, 0); ++ } ++ if (cp->comment != NULL) { ++ j2k_write_com(j2k); ++ } ++ /* INDEX >> */ ++ if(image_info && image_info->index_on) { ++ image_info->main_head_end = cio_tell(cio) - 1; ++ } ++ /* << INDEX */ ++ ++ /* create the tile encoder */ ++ tcd = tcd_create(j2k->cinfo); ++ ++ /* encode each tile */ ++ ++ for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { ++ opj_event_msg(j2k->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th); ++ ++ j2k->curtileno = tileno; ++ ++ /* initialisation before tile encoding */ ++ if (tileno == 0) { ++ tcd_malloc_encode(tcd, image, cp, j2k->curtileno); ++ } else { ++ tcd_init_encode(tcd, image, cp, j2k->curtileno); ++ } ++ ++ /* INDEX >> */ ++ if(image_info && image_info->index_on) { ++ image_info->tile[j2k->curtileno].num_tile = j2k->curtileno; ++ image_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction; ++ } ++ /* << INDEX */ ++ ++ j2k_write_sot(j2k); ++ ++ for (compno = 1; compno < image->numcomps; compno++) { ++ j2k_write_coc(j2k, compno); ++ j2k_write_qcc(j2k, compno); ++ } ++ if (cp->tcps[tileno].numpocs) { ++ j2k_write_poc(j2k); ++ } ++ ++ j2k_write_sod(j2k, tcd); ++ ++ /* INDEX >> */ ++ if(image_info && image_info->index_on) { ++ image_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->pos_correction - 1; ++ } ++ /* << INDEX */ ++ ++ ++ /* ++ if (tile->PPT) { // BAD PPT !!! ++ FILE *PPT_file; ++ int i; ++ PPT_file=fopen("PPT","rb"); ++ fprintf(stderr,"%c%c%c%c",255,97,tile->len_ppt/256,tile->len_ppt%256); ++ for (i=0;i<tile->len_ppt;i++) { ++ unsigned char elmt; ++ fread(&elmt, 1, 1, PPT_file); ++ fwrite(&elmt,1,1,f); ++ } ++ fclose(PPT_file); ++ unlink("PPT"); ++ } ++ */ ++ ++ } ++ ++ /* destroy the tile encoder */ ++ tcd_free_encode(tcd); ++ tcd_destroy(tcd); ++ ++ j2k_write_eoc(j2k); ++ ++ /* Creation of the index file */ ++ if(image_info && image_info->index_on) { ++ if(!j2k_create_index(j2k, cio, image_info, index)) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to create index file %s\n", index); ++ return false; ++ } ++ } ++ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ /* ++ preparation of JPWL marker segments: can be finalized only when the whole ++ codestream is known ++ */ ++ if(image_info && image_info->index_on && cp->epc_on) { ++ ++ /* let's begin creating a marker list, according to user wishes */ ++ jpwl_prepare_marks(j2k, cio, image); ++ ++ /* now we dump the JPWL markers on the codestream */ ++ jpwl_dump_marks(j2k, cio, image); ++ ++ /* do not know exactly what is this for, ++ but it gets called during index creation */ ++ j2k->pos_correction = 0; ++ ++ /* Re-creation of the index file, with updated info */ ++ if(image_info && image_info->index_on) { ++ if(!j2k_create_index(j2k, cio, image_info, index)) { ++ opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to re-create index file %s\n", index); ++ return false; ++ } ++ } ++ ++ /* now we finalize the marker contents */ ++ /*jpwl_finalize_marks(j2k, cio, image);*/ ++ ++ } ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ ++ return true; ++} ++ +diff -Naur OpenJPEG/libopenjpeg/j2k.c.rej OpenJPEG-patched/libopenjpeg/j2k.c.rej +--- OpenJPEG/libopenjpeg/j2k.c.rej 1970-01-01 01:00:00.000000000 +0100 ++++ OpenJPEG-patched/libopenjpeg/j2k.c.rej 2007-03-17 14:18:44.000000000 +0100 +@@ -0,0 +1,16 @@ ++*************** ++*** 1522,1527 **** ++ opj_cp_t *cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t)); ++ cp->reduce = parameters->cp_reduce; ++ cp->layer = parameters->cp_layer; ++ /* UniPG>> */ ++ #ifdef USE_JPWL ++ cp->correct = parameters->jpwl_correct; ++--- 1524,1530 ---- ++ opj_cp_t *cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t)); ++ cp->reduce = parameters->cp_reduce; ++ cp->layer = parameters->cp_layer; +++ cp->limit_tags = parameters->cp_limit_tags; ++ /* UniPG>> */ ++ #ifdef USE_JPWL ++ cp->correct = parameters->jpwl_correct; +diff -Naur OpenJPEG/libopenjpeg/j2k.h OpenJPEG-patched/libopenjpeg/j2k.h +--- OpenJPEG/libopenjpeg/j2k.h 2007-02-19 10:59:29.000000000 +0100 ++++ OpenJPEG-patched/libopenjpeg/j2k.h 2007-03-17 14:20:28.000000000 +0100 +@@ -200,6 +200,8 @@ + /** if == NO_LIMITATION, decode entire codestream; if == LIMIT_TO_MAIN_HEADER then only decode the main header */ + OPJ_LIMIT_DECODING limit_decoding; + /** 0 = no index || 1 = index */ ++ /** if != 0, then only decode specific tags, abort on any other; if == 0 decode all tags */ ++ OPJ_LIMIT_TAGS limit_tags; + int index_on; + /** XTOsiz */ + int tx0; +diff -Naur OpenJPEG/libopenjpeg/j2k.h.orig OpenJPEG-patched/libopenjpeg/j2k.h.orig +--- OpenJPEG/libopenjpeg/j2k.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ OpenJPEG-patched/libopenjpeg/j2k.h.orig 2007-02-19 10:59:29.000000000 +0100 +@@ -0,0 +1,484 @@ ++/* ++ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium ++ * Copyright (c) 2002-2007, Professor Benoit Macq ++ * Copyright (c) 2001-2003, David Janssens ++ * Copyright (c) 2002-2003, Yannick Verschueren ++ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe ++ * Copyright (c) 2005, Herve Drolon, FreeImage Team ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef __J2K_H ++#define __J2K_H ++/** ++@file j2k.h ++@brief The JPEG-2000 Codestream Reader/Writer (J2K) ++ ++The functions in J2K.C have for goal to read/write the several parts of the codestream: markers and data. ++*/ ++ ++/** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */ ++/*@{*/ ++ ++#define J2K_CP_CSTY_PRT 0x01 ++#define J2K_CP_CSTY_SOP 0x02 ++#define J2K_CP_CSTY_EPH 0x04 ++#define J2K_CCP_CSTY_PRT 0x01 ++#define J2K_CCP_CBLKSTY_LAZY 0x01 ++#define J2K_CCP_CBLKSTY_RESET 0x02 ++#define J2K_CCP_CBLKSTY_TERMALL 0x04 ++#define J2K_CCP_CBLKSTY_VSC 0x08 ++#define J2K_CCP_CBLKSTY_PTERM 0x10 ++#define J2K_CCP_CBLKSTY_SEGSYM 0x20 ++#define J2K_CCP_QNTSTY_NOQNT 0 ++#define J2K_CCP_QNTSTY_SIQNT 1 ++#define J2K_CCP_QNTSTY_SEQNT 2 ++ ++/* ----------------------------------------------------------------------- */ ++ ++#define J2K_MS_SOC 0xff4f /**< SOC marker value */ ++#define J2K_MS_SOT 0xff90 /**< SOT marker value */ ++#define J2K_MS_SOD 0xff93 /**< SOD marker value */ ++#define J2K_MS_EOC 0xffd9 /**< EOC marker value */ ++#define J2K_MS_SIZ 0xff51 /**< SIZ marker value */ ++#define J2K_MS_COD 0xff52 /**< COD marker value */ ++#define J2K_MS_COC 0xff53 /**< COC marker value */ ++#define J2K_MS_RGN 0xff5e /**< RGN marker value */ ++#define J2K_MS_QCD 0xff5c /**< QCD marker value */ ++#define J2K_MS_QCC 0xff5d /**< QCC marker value */ ++#define J2K_MS_POC 0xff5f /**< POC marker value */ ++#define J2K_MS_TLM 0xff55 /**< TLM marker value */ ++#define J2K_MS_PLM 0xff57 /**< PLM marker value */ ++#define J2K_MS_PLT 0xff58 /**< PLT marker value */ ++#define J2K_MS_PPM 0xff60 /**< PPM marker value */ ++#define J2K_MS_PPT 0xff61 /**< PPT marker value */ ++#define J2K_MS_SOP 0xff91 /**< SOP marker value */ ++#define J2K_MS_EPH 0xff92 /**< EPH marker value */ ++#define J2K_MS_CRG 0xff63 /**< CRG marker value */ ++#define J2K_MS_COM 0xff64 /**< COM marker value */ ++/* UniPG>> */ ++#ifdef USE_JPWL ++#define J2K_MS_EPC 0xff68 /**< EPC marker value (Part11) */ ++#define J2K_MS_EPB 0xff66 /**< EPB marker value (Part11) */ ++#define J2K_MS_ESD 0xff67 /**< ESD marker value (Part11) */ ++#define J2K_MS_RED 0xff69 /**< RED marker value (Part11) */ ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ ++/* ----------------------------------------------------------------------- */ ++ ++/** ++Values that specify the status of the decoding process when decoding the main header. ++These values may be combined with a | operator. ++*/ ++typedef enum J2K_STATUS { ++ J2K_STATE_MHSOC = 0x0001, /**< a SOC marker is expected */ ++ J2K_STATE_MHSIZ = 0x0002, /**< a SIZ marker is expected */ ++ J2K_STATE_MH = 0x0004, /**< the decoding process is in the main header */ ++ J2K_STATE_TPHSOT = 0x0008, /**< the decoding process is in a tile part header and expects a SOT marker */ ++ J2K_STATE_TPH = 0x0010, /**< the decoding process is in a tile part header */ ++ J2K_STATE_MT = 0x0020, /**< the EOC marker has just been read */ ++ J2K_STATE_NEOC = 0x0040 /**< the decoding process must not expect a EOC marker because the codestream is truncated */ ++} J2K_STATUS; ++ ++/* ----------------------------------------------------------------------- */ ++ ++/** ++Quantization stepsize ++*/ ++typedef struct opj_stepsize { ++ /** exponent */ ++ int expn; ++ /** mantissa */ ++ int mant; ++} opj_stepsize_t; ++ ++/** ++Tile-component coding parameters ++*/ ++typedef struct opj_tccp { ++ /** coding style */ ++ int csty; ++ /** number of resolutions */ ++ int numresolutions; ++ /** code-blocks width */ ++ int cblkw; ++ /** code-blocks height */ ++ int cblkh; ++ /** code-block coding style */ ++ int cblksty; ++ /** discrete wavelet transform identifier */ ++ int qmfbid; ++ /** quantisation style */ ++ int qntsty; ++ /** stepsizes used for quantization */ ++ opj_stepsize_t stepsizes[J2K_MAXBANDS]; ++ /** number of guard bits */ ++ int numgbits; ++ /** Region Of Interest shift */ ++ int roishift; ++ /** precinct width */ ++ int prcw[J2K_MAXRLVLS]; ++ /** precinct height */ ++ int prch[J2K_MAXRLVLS]; ++} opj_tccp_t; ++ ++/** ++Tile coding parameters : ++this structure is used to store coding/decoding parameters common to all ++tiles (information like COD, COC in main header) ++*/ ++typedef struct opj_tcp { ++ /** 1 : first part-tile of a tile */ ++ int first; ++ /** coding style */ ++ int csty; ++ /** progression order */ ++ OPJ_PROG_ORDER prg; ++ /** number of layers */ ++ int numlayers; ++ /** multi-component transform identifier */ ++ int mct; ++ /** rates of layers */ ++ float rates[100]; ++ /** number of progression order changes */ ++ int numpocs; ++ /** indicates if a POC marker has been used O:NO, 1:YES */ ++ int POC; ++ /** progression order changes */ ++ opj_poc_t pocs[32]; ++ /** packet header store there for futur use in t2_decode_packet */ ++ unsigned char *ppt_data; ++ /** pointer remaining on the first byte of the first header if ppt is used */ ++ unsigned char *ppt_data_first; ++ /** If ppt == 1 --> there was a PPT marker for the present tile */ ++ int ppt; ++ /** used in case of multiple marker PPT (number of info already stored) */ ++ int ppt_store; ++ /** ppmbug1 */ ++ int ppt_len; ++ /** add fixed_quality */ ++ float distoratio[100]; ++ /** tile-component coding parameters */ ++ opj_tccp_t *tccps; ++} opj_tcp_t; ++ ++/** ++Coding parameters ++*/ ++typedef struct opj_cp { ++ /** allocation by rate/distortion */ ++ int disto_alloc; ++ /** allocation by fixed layer */ ++ int fixed_alloc; ++ /** add fixed_quality */ ++ int fixed_quality; ++ /** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, image is decoded to the full resolution */ ++ int reduce; ++ /** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */ ++ int layer; ++ /** if == NO_LIMITATION, decode entire codestream; if == LIMIT_TO_MAIN_HEADER then only decode the main header */ ++ OPJ_LIMIT_DECODING limit_decoding; ++ /** 0 = no index || 1 = index */ ++ int index_on; ++ /** XTOsiz */ ++ int tx0; ++ /** YTOsiz */ ++ int ty0; ++ /** XTsiz */ ++ int tdx; ++ /** YTsiz */ ++ int tdy; ++ /** comment for coding */ ++ char *comment; ++ /** number of tiles in width */ ++ int tw; ++ /** number of tiles in heigth */ ++ int th; ++ /** ID number of the tiles present in the codestream */ ++ int *tileno; ++ /** size of the vector tileno */ ++ int tileno_size; ++ /** packet header store there for futur use in t2_decode_packet */ ++ unsigned char *ppm_data; ++ /** pointer remaining on the first byte of the first header if ppm is used */ ++ unsigned char *ppm_data_first; ++ /** if ppm == 1 --> there was a PPM marker for the present tile */ ++ int ppm; ++ /** use in case of multiple marker PPM (number of info already store) */ ++ int ppm_store; ++ /** use in case of multiple marker PPM (case on non-finished previous info) */ ++ int ppm_previous; ++ /** ppmbug1 */ ++ int ppm_len; ++ /** tile coding parameters */ ++ opj_tcp_t *tcps; ++ /** fixed layer */ ++ int *matrice; ++/* UniPG>> */ ++#ifdef USE_JPWL ++ /** enables writing of EPC in MH, thus activating JPWL */ ++ bool epc_on; ++ /** enables writing of EPB, in case of activated JPWL */ ++ bool epb_on; ++ /** enables writing of ESD, in case of activated JPWL */ ++ bool esd_on; ++ /** enables writing of informative techniques of ESD, in case of activated JPWL */ ++ bool info_on; ++ /** enables writing of RED, in case of activated JPWL */ ++ bool red_on; ++ /** error protection method for MH (0,1,16,32,37-128) */ ++ int hprot_MH; ++ /** tile number of header protection specification (>=0) */ ++ int hprot_TPH_tileno[JPWL_MAX_NO_TILESPECS]; ++ /** error protection methods for TPHs (0,1,16,32,37-128) */ ++ int hprot_TPH[JPWL_MAX_NO_TILESPECS]; ++ /** tile number of packet protection specification (>=0) */ ++ int pprot_tileno[JPWL_MAX_NO_PACKSPECS]; ++ /** packet number of packet protection specification (>=0) */ ++ int pprot_packno[JPWL_MAX_NO_PACKSPECS]; ++ /** error protection methods for packets (0,1,16,32,37-128) */ ++ int pprot[JPWL_MAX_NO_PACKSPECS]; ++ /** enables writing of ESD, (0/2/4 bytes) */ ++ int sens_size; ++ /** sensitivity addressing size (0=auto/2/4 bytes) */ ++ int sens_addr; ++ /** sensitivity range (0-3) */ ++ int sens_range; ++ /** sensitivity method for MH (-1,0-7) */ ++ int sens_MH; ++ /** tile number of sensitivity specification (>=0) */ ++ int sens_TPH_tileno[JPWL_MAX_NO_TILESPECS]; ++ /** sensitivity methods for TPHs (-1,0-7) */ ++ int sens_TPH[JPWL_MAX_NO_TILESPECS]; ++ /** enables JPWL correction at the decoder */ ++ bool correct; ++ /** expected number of components at the decoder */ ++ int exp_comps; ++ /** maximum number of tiles at the decoder */ ++ int max_tiles; ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++} opj_cp_t; ++ ++/** ++Information concerning a packet inside tile ++*/ ++typedef struct opj_packet_info { ++ /** start position */ ++ int start_pos; ++ /** end position */ ++ int end_pos; ++ /** ADD for Marcela */ ++ double disto; ++} opj_packet_info_t; ++ ++/** ++Index structure : information regarding tiles inside image ++*/ ++typedef struct opj_tile_info { ++ /** value of thresh for each layer by tile cfr. Marcela */ ++ double *thresh; ++ /** number of tile */ ++ int num_tile; ++ /** start position */ ++ int start_pos; ++ /** end position of the header */ ++ int end_header; ++ /** end position */ ++ int end_pos; ++ /** precinct number for each resolution level (width) */ ++ int pw[33]; ++ /** precinct number for each resolution level (height) */ ++ int ph[33]; ++ /** precinct size (in power of 2), in X for each resolution level */ ++ int pdx[33]; ++ /** precinct size (in power of 2), in Y for each resolution level */ ++ int pdy[33]; ++ /** information concerning packets inside tile */ ++ opj_packet_info_t *packet; ++ /** add fixed_quality */ ++ int nbpix; ++ /** add fixed_quality */ ++ double distotile; ++} opj_tile_info_t; ++ ++/** ++Index structure ++*/ ++typedef struct opj_image_info { ++ /** 0 = no index || 1 = index */ ++ int index_on; ++ /** maximum distortion reduction on the whole image (add for Marcela) */ ++ double D_max; ++ /** packet number */ ++ int num; ++ /** writing the packet in the index with t2_encode_packets */ ++ int index_write; ++ /** image width */ ++ int image_w; ++ /** image height */ ++ int image_h; ++ /** progression order */ ++ OPJ_PROG_ORDER prog; ++ /** tile size in x */ ++ int tile_x; ++ /** tile size in y */ ++ int tile_y; ++ /** */ ++ int tile_Ox; ++ /** */ ++ int tile_Oy; ++ /** number of tiles in X */ ++ int tw; ++ /** number of tiles in Y */ ++ int th; ++ /** component numbers */ ++ int comp; ++ /** number of layer */ ++ int layer; ++ /** number of decomposition */ ++ int decomposition; ++ /** main header position */ ++ int main_head_end; ++ /** codestream's size */ ++ int codestream_size; ++ /** information regarding tiles inside image */ ++ opj_tile_info_t *tile; ++} opj_image_info_t; ++ ++/** ++JPEG-2000 codestream reader/writer ++*/ ++typedef struct opj_j2k { ++ /** codec context */ ++ opj_common_ptr cinfo; ++ ++ /** locate in which part of the codestream the decoder is (main header, tile header, end) */ ++ int state; ++ /** number of the tile curently concern by coding/decoding */ ++ int curtileno; ++ /** ++ locate the position of the end of the tile in the codestream, ++ used to detect a truncated codestream (in j2k_read_sod) ++ */ ++ unsigned char *eot; ++ /** ++ locate the start position of the SOT marker of the current coded tile: ++ after encoding the tile, a jump (in j2k_write_sod) is done to the SOT marker to store the value of its length. ++ */ ++ int sot_start; ++ int sod_start; ++ /** ++ as the J2K-file is written in several parts during encoding, ++ it enables to make the right correction in position return by cio_tell ++ */ ++ int pos_correction; ++ /** array used to store the data of each tile */ ++ unsigned char **tile_data; ++ /** array used to store the length of each tile */ ++ int *tile_len; ++ /** ++ decompression only : ++ store decoding parameters common to all tiles (information like COD, COC in main header) ++ */ ++ opj_tcp_t *default_tcp; ++ /** pointer to the encoded / decoded image */ ++ opj_image_t *image; ++ /** pointer to the coding parameters */ ++ opj_cp_t *cp; ++ /** helper used to write the index file */ ++ opj_image_info_t *image_info; ++ /** pointer to the byte i/o stream */ ++ opj_cio_t *cio; ++} opj_j2k_t; ++ ++/** @name Exported functions */ ++/*@{*/ ++/* ----------------------------------------------------------------------- */ ++/** ++Creates a J2K decompression structure ++@param cinfo Codec context info ++@return Returns a handle to a J2K decompressor if successful, returns NULL otherwise ++*/ ++opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo); ++/** ++Destroy a J2K decompressor handle ++@param j2k J2K decompressor handle to destroy ++*/ ++void j2k_destroy_decompress(opj_j2k_t *j2k); ++/** ++Setup the decoder decoding parameters using user parameters. ++Decoding parameters are returned in j2k->cp. ++@param j2k J2K decompressor handle ++@param parameters decompression parameters ++*/ ++void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters); ++/** ++Decode an image from a JPEG-2000 codestream ++@param j2k J2K decompressor handle ++@param cio Input buffer stream ++@return Returns a decoded image if successful, returns NULL otherwise ++*/ ++opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio); ++/** ++Decode an image form a JPT-stream (JPEG 2000, JPIP) ++@param j2k J2K decompressor handle ++@param cio Input buffer stream ++@return Returns a decoded image if successful, returns NULL otherwise ++*/ ++opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio); ++/** ++Creates a J2K compression structure ++@param cinfo Codec context info ++@return Returns a handle to a J2K compressor if successful, returns NULL otherwise ++*/ ++opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo); ++/** ++Destroy a J2K compressor handle ++@param j2k J2K compressor handle to destroy ++*/ ++void j2k_destroy_compress(opj_j2k_t *j2k); ++/** ++Setup the encoder parameters using the current image and using user parameters. ++Coding parameters are returned in j2k->cp. ++@param j2k J2K compressor handle ++@param parameters compression parameters ++@param image input filled image ++*/ ++void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image); ++/** ++Encode an image into a JPEG-2000 codestream ++@param j2k J2K compressor handle ++@param cio Output buffer stream ++@param image Image to encode ++@param index Name of the index file if required, NULL otherwise ++@return Returns true if successful, returns false otherwise ++*/ ++bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, char *index); ++/* ----------------------------------------------------------------------- */ ++/*@}*/ ++ ++/*@}*/ ++ ++#endif /* __J2K_H */ +diff -Naur OpenJPEG/libopenjpeg/openjpeg.h OpenJPEG-patched/libopenjpeg/openjpeg.h +--- OpenJPEG/libopenjpeg/openjpeg.h 2007-02-23 11:48:11.000000000 +0100 ++++ OpenJPEG-patched/libopenjpeg/openjpeg.h 2007-03-17 14:18:28.000000000 +0100 +@@ -319,6 +319,41 @@ + + } opj_cparameters_t; + ++/** Stop after tags. */ ++typedef enum LIMIT_TAGS { ++ OPJ_TAG_SOC = 0x000001, /**< start of codestream */ ++ OPJ_TAG_SOT = 0x000002, /**< start of tile-part*/ ++ OPJ_TAG_SOD = 0x000004, /**< start of data */ ++ OPJ_TAG_EOC = 0x000008, /**< end of codestream */ ++ OPJ_TAG_SIZ = 0x000010, /**< image and tile size */ ++ OPJ_TAG_COD = 0x000020, /**< coding style default */ ++ OPJ_TAG_COC = 0x000040, /**< coding style component */ ++ OPJ_TAG_RGN = 0x000080, /**< region-of-interest */ ++ OPJ_TAG_QCD = 0x000100, /**< quantization default */ ++ OPJ_TAG_QCC = 0x000200, /**< quantization component */ ++ OPJ_TAG_POC = 0x000400, /**< progression order change */ ++ OPJ_TAG_TLM = 0x000800, /**< tile-part lengths */ ++ OPJ_TAG_PLM = 0x001000, /**< packet length, main header */ ++ OPJ_TAG_PLT = 0x002000, /**< packet length, tile-part header */ ++ OPJ_TAG_PPM = 0x004000, /**< packet packet headers, main header */ ++ OPJ_TAG_PPT = 0x008000, /**< packet packet headers, tile-part header */ ++ OPJ_TAG_SOP = 0x010000, /**< SOP marker value */ ++ OPJ_TAG_EPH = 0x020000, /**< EPH marker value */ ++ OPJ_TAG_CRG = 0x040000, /**< component registration */ ++ OPJ_TAG_COM = 0x080000, /**< comment */ ++#ifdef USE_JPWL ++/* UniPG>> */ ++ OPJ_TAG_EPC = 0x100000, /**< EPC marker value (Part11) */ ++ OPJ_TAG_EPB = 0x200000, /**< EPB marker value (Part11) */ ++ OPJ_TAG_ESD = 0x400000, /**< ESD marker value (Part11) */ ++ OPJ_TAG_RED = 0x800000, /**< RED marker value (Part11) */ ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++} OPJ_LIMIT_TAGS; ++ ++/** The needed tags to decode just the size of the image. */ ++#define OPJ_LIMIT_FOR_SIZE (OPJ_LIMIT_TAGS)(OPJ_TAG_SOC | OPJ_TAG_SIZ ) ++ + /** + Decompression parameters + */ +@@ -338,6 +373,15 @@ + if == 0 or not used, all the quality layers are decoded + */ + int cp_layer; ++ /** ++ Limits the tags that are decoded. ++ This is a bitwise OR of the tags to be decoded. If a tag is ++ encountered that isn't in the list decoding ceases and the function ++ returns. ++ if != 0 only the given tags are decoded. ++ if == 0 all tags are decoded. ++ */ ++ OPJ_LIMIT_TAGS cp_limit_tags; + + /** + Specify whether the decoding should be done on the entire codestream, or be limited to the main header +diff -Naur OpenJPEG/libopenjpeg/openjpeg.h.orig OpenJPEG-patched/libopenjpeg/openjpeg.h.orig +--- OpenJPEG/libopenjpeg/openjpeg.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ OpenJPEG-patched/libopenjpeg/openjpeg.h.orig 2007-02-23 11:48:11.000000000 +0100 +@@ -0,0 +1,704 @@ ++ /* ++ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium ++ * Copyright (c) 2002-2007, Professor Benoit Macq ++ * Copyright (c) 2001-2003, David Janssens ++ * Copyright (c) 2002-2003, Yannick Verschueren ++ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe ++ * Copyright (c) 2005, Herve Drolon, FreeImage Team ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' ++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ++ * POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef OPENJPEG_H ++#define OPENJPEG_H ++ ++#define OPENJPEG_VERSION "1.1.1" ++ ++/* ++========================================================== ++ Compiler directives ++========================================================== ++*/ ++ ++#if defined(OPJ_STATIC) || !(defined(WIN32) || defined(__WIN32__)) ++#define OPJ_API ++#define OPJ_CALLCONV ++#else ++#define OPJ_CALLCONV __stdcall ++/* ++The following ifdef block is the standard way of creating macros which make exporting ++from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS ++symbol defined on the command line. this symbol should not be defined on any project ++that uses this DLL. This way any other project whose source files include this file see ++OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols ++defined with this macro as being exported. ++*/ ++#ifdef OPJ_EXPORTS ++#define OPJ_API __declspec(dllexport) ++#else ++#define OPJ_API __declspec(dllimport) ++#endif /* OPJ_EXPORTS */ ++#endif /* !OPJ_STATIC || !WIN32 */ ++ ++#ifndef __cplusplus ++#if defined(HAVE_STDBOOL_H) ++/* ++The C language implementation does correctly provide the standard header ++file "stdbool.h". ++ */ ++#include <stdbool.h> ++#else ++/* ++The C language implementation does not provide the standard header file ++"stdbool.h" as required by ISO/IEC 9899:1999. Try to compensate for this ++braindamage below. ++*/ ++#if !defined(bool) ++#define bool int ++#endif ++#if !defined(true) ++#define true 1 ++#endif ++#if !defined(false) ++#define false 0 ++#endif ++#endif ++#endif /* __cplusplus */ ++ ++/* ++========================================================== ++ Useful constant definitions ++========================================================== ++*/ ++ ++#define OPJ_PATH_LEN 4096 /**< Maximum allowed size for filenames */ ++ ++#define J2K_MAXRLVLS 33 /**< Number of maximum resolution level authorized */ ++#define J2K_MAXBANDS (3*J2K_MAXRLVLS-2) /**< Number of maximum sub-band linked to number of resolution level */ ++ ++/* UniPG>> */ ++#ifdef USE_JPWL ++#define JPWL_MAX_NO_TILESPECS 16 /**< Maximum number of tile parts expected by JPWL: increase at your will */ ++#define JPWL_MAX_NO_PACKSPECS 16 /**< Maximum number of packet parts expected by JPWL: increase at your will */ ++#define JPWL_MAX_NO_MARKERS 512 /**< Maximum number of JPWL markers: increase at your will */ ++#define JPWL_PRIVATEINDEX_NAME "jpwl_index_privatefilename" /**< index file name used when JPWL is on */ ++#define JPWL_EXPECTED_COMPONENTS 3 /**< Expect this number of components, so you'll find better the first EPB */ ++#define JPWL_MAXIMUM_TILES 8192 /**< Expect this maximum number of tiles, to avoid some crashes */ ++#define JPWL_MAXIMUM_HAMMING 2 /**< Expect this maximum number of bit errors in marker id's */ ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ ++/* ++========================================================== ++ enum definitions ++========================================================== ++*/ ++ ++/** Progression order */ ++typedef enum PROG_ORDER { ++ PROG_UNKNOWN = -1, /**< place-holder */ ++ LRCP = 0, /**< layer-resolution-component-precinct order */ ++ RLCP = 1, /**< resolution-layer-component-precinct order */ ++ RPCL = 2, /**< resolution-precinct-component-layer order */ ++ PCRL = 3, /**< precinct-component-resolution-layer order */ ++ CPRL = 4 /**< component-precinct-resolution-layer order */ ++} OPJ_PROG_ORDER; ++ ++/** ++Supported image color spaces ++*/ ++typedef enum COLOR_SPACE { ++ CLRSPC_UNKNOWN = -1, /**< place-holder */ ++ CLRSPC_SRGB = 1, /**< sRGB */ ++ CLRSPC_GRAY = 2, /**< grayscale */ ++ CLRSPC_SYCC = 3 /**< YUV */ ++} OPJ_COLOR_SPACE; ++ ++/** ++Supported codec ++*/ ++typedef enum CODEC_FORMAT { ++ CODEC_UNKNOWN = -1, /**< place-holder */ ++ CODEC_J2K = 0, /**< JPEG-2000 codestream : read/write */ ++ CODEC_JPT = 1, /**< JPT-stream (JPEG 2000, JPIP) : read only */ ++ CODEC_JP2 = 2 /**< JPEG-2000 file format : read/write */ ++} OPJ_CODEC_FORMAT; ++ ++/** ++Limit decoding to certain portions of the codestream. ++*/ ++typedef enum LIMIT_DECODING { ++ NO_LIMITATION = 0, /**< No limitation for the decoding. The entire codestream will de decoded */ ++ LIMIT_TO_MAIN_HEADER = 1 /**< The decoding is limited to the Main Header */ ++} OPJ_LIMIT_DECODING; ++ ++/* ++========================================================== ++ event manager typedef definitions ++========================================================== ++*/ ++ ++/** ++Callback function prototype for events ++@param msg Event message ++@param client_data ++*/ ++typedef void (*opj_msg_callback) (const char *msg, void *client_data); ++ ++/** ++Message handler object ++used for ++<ul> ++<li>Error messages ++<li>Warning messages ++<li>Debugging messages ++</ul> ++*/ ++typedef struct opj_event_mgr { ++ /** Error message callback if available, NULL otherwise */ ++ opj_msg_callback error_handler; ++ /** Warning message callback if available, NULL otherwise */ ++ opj_msg_callback warning_handler; ++ /** Debug message callback if available, NULL otherwise */ ++ opj_msg_callback info_handler; ++} opj_event_mgr_t; ++ ++ ++/* ++========================================================== ++ codec typedef definitions ++========================================================== ++*/ ++ ++/** ++Progression order changes ++*/ ++typedef struct opj_poc { ++ int resno0, compno0; ++ int layno1, resno1, compno1; ++ OPJ_PROG_ORDER prg; ++ int tile; ++ char progorder[4]; ++} opj_poc_t; ++ ++/** ++Compression parameters ++*/ ++typedef struct opj_cparameters { ++ /** size of tile: tile_size_on = false (not in argument) or = true (in argument) */ ++ bool tile_size_on; ++ /** XTOsiz */ ++ int cp_tx0; ++ /** YTOsiz */ ++ int cp_ty0; ++ /** XTsiz */ ++ int cp_tdx; ++ /** YTsiz */ ++ int cp_tdy; ++ /** allocation by rate/distortion */ ++ int cp_disto_alloc; ++ /** allocation by fixed layer */ ++ int cp_fixed_alloc; ++ /** add fixed_quality */ ++ int cp_fixed_quality; ++ /** fixed layer */ ++ int *cp_matrice; ++ /** comment for coding */ ++ char *cp_comment; ++ /** csty : coding style */ ++ int csty; ++ /** progression order (default LRCP) */ ++ OPJ_PROG_ORDER prog_order; ++ /** progression order changes */ ++ opj_poc_t POC[32]; ++ /** number of progression order changes (POC), default to 0 */ ++ int numpocs; ++ /** number of layers */ ++ int tcp_numlayers; ++ /** rates of layers */ ++ float tcp_rates[100]; ++ /** different psnr for successive layers */ ++ float tcp_distoratio[100]; ++ /** number of resolutions */ ++ int numresolution; ++ /** initial code block width, default to 64 */ ++ int cblockw_init; ++ /** initial code block height, default to 64 */ ++ int cblockh_init; ++ /** mode switch (cblk_style) */ ++ int mode; ++ /** 1 : use the irreversible DWT 9-7, 0 : use lossless compression (default) */ ++ int irreversible; ++ /** region of interest: affected component in [0..3], -1 means no ROI */ ++ int roi_compno; ++ /** region of interest: upshift value */ ++ int roi_shift; ++ /* number of precinct size specifications */ ++ int res_spec; ++ /** initial precinct width */ ++ int prcw_init[J2K_MAXRLVLS]; ++ /** initial precinct height */ ++ int prch_init[J2K_MAXRLVLS]; ++ ++ /**@name command line encoder parameters (not used inside the library) */ ++ /*@{*/ ++ /** input file name */ ++ char infile[OPJ_PATH_LEN]; ++ /** output file name */ ++ char outfile[OPJ_PATH_LEN]; ++ /** creation of an index file, default to 0 (false) */ ++ int index_on; ++ /** index file name */ ++ char index[OPJ_PATH_LEN]; ++ /** subimage encoding: origin image offset in x direction */ ++ int image_offset_x0; ++ /** subimage encoding: origin image offset in y direction */ ++ int image_offset_y0; ++ /** subsampling value for dx */ ++ int subsampling_dx; ++ /** subsampling value for dy */ ++ int subsampling_dy; ++ /** input file format 0: PGX, 1: PxM, 2: BMP */ ++ int decod_format; ++ /** output file format 0: J2K, 1: JP2, 2: JPT */ ++ int cod_format; ++ /*@}*/ ++ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ /**@name JPWL encoding parameters */ ++ /*@{*/ ++ /** enables writing of EPC in MH, thus activating JPWL */ ++ bool jpwl_epc_on; ++ /** error protection method for MH (0,1,16,32,37-128) */ ++ int jpwl_hprot_MH; ++ /** tile number of header protection specification (>=0) */ ++ int jpwl_hprot_TPH_tileno[JPWL_MAX_NO_TILESPECS]; ++ /** error protection methods for TPHs (0,1,16,32,37-128) */ ++ int jpwl_hprot_TPH[JPWL_MAX_NO_TILESPECS]; ++ /** tile number of packet protection specification (>=0) */ ++ int jpwl_pprot_tileno[JPWL_MAX_NO_PACKSPECS]; ++ /** packet number of packet protection specification (>=0) */ ++ int jpwl_pprot_packno[JPWL_MAX_NO_PACKSPECS]; ++ /** error protection methods for packets (0,1,16,32,37-128) */ ++ int jpwl_pprot[JPWL_MAX_NO_PACKSPECS]; ++ /** enables writing of ESD, (0=no/1/2 bytes) */ ++ int jpwl_sens_size; ++ /** sensitivity addressing size (0=auto/2/4 bytes) */ ++ int jpwl_sens_addr; ++ /** sensitivity range (0-3) */ ++ int jpwl_sens_range; ++ /** sensitivity method for MH (-1=no,0-7) */ ++ int jpwl_sens_MH; ++ /** tile number of sensitivity specification (>=0) */ ++ int jpwl_sens_TPH_tileno[JPWL_MAX_NO_TILESPECS]; ++ /** sensitivity methods for TPHs (-1=no,0-7) */ ++ int jpwl_sens_TPH[JPWL_MAX_NO_TILESPECS]; ++ /*@}*/ ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++ ++} opj_cparameters_t; ++ ++/** ++Decompression parameters ++*/ ++typedef struct opj_dparameters { ++ /** ++ Set the number of highest resolution levels to be discarded. ++ The image resolution is effectively divided by 2 to the power of the number of discarded levels. ++ The reduce factor is limited by the smallest total number of decomposition levels among tiles. ++ if != 0, then original dimension divided by 2^(reduce); ++ if == 0 or not used, image is decoded to the full resolution ++ */ ++ int cp_reduce; ++ /** ++ Set the maximum number of quality layers to decode. ++ If there are less quality layers than the specified number, all the quality layers are decoded. ++ if != 0, then only the first "layer" layers are decoded; ++ if == 0 or not used, all the quality layers are decoded ++ */ ++ int cp_layer; ++ ++ /** ++ Specify whether the decoding should be done on the entire codestream, or be limited to the main header ++ Limiting the decoding to the main header makes it possible to extract the characteristics of the codestream ++ if == NO_LIMITATION, the entire codestream is decoded; ++ if == LIMIT_TO_MAIN_HEADER, only the main header is decoded; ++ */ ++ OPJ_LIMIT_DECODING cp_limit_decoding; ++ ++ /**@name command line encoder parameters (not used inside the library) */ ++ /*@{*/ ++ /** input file name */ ++ char infile[OPJ_PATH_LEN]; ++ /** output file name */ ++ char outfile[OPJ_PATH_LEN]; ++ /** input file format 0: J2K, 1: JP2, 2: JPT */ ++ int decod_format; ++ /** output file format 0: PGX, 1: PxM, 2: BMP */ ++ int cod_format; ++ /*@}*/ ++ ++/* UniPG>> */ ++#ifdef USE_JPWL ++ /**@name JPWL decoding parameters */ ++ /*@{*/ ++ /** activates the JPWL correction capabilities */ ++ bool jpwl_correct; ++ /** expected number of components */ ++ int jpwl_exp_comps; ++ /** maximum number of tiles */ ++ int jpwl_max_tiles; ++ /*@}*/ ++#endif /* USE_JPWL */ ++/* <<UniPG */ ++} opj_dparameters_t; ++ ++/** Common fields between JPEG-2000 compression and decompression master structs. */ ++ ++#define opj_common_fields \ ++ opj_event_mgr_t *event_mgr; /**< pointer to the event manager */\ ++ void * client_data; /**< Available for use by application */\ ++ bool is_decompressor; /**< So common code can tell which is which */\ ++ OPJ_CODEC_FORMAT codec_format; /**< selected codec */\ ++ void *j2k_handle; /**< pointer to the J2K codec */\ ++ void *jp2_handle /**< pointer to the JP2 codec */ ++ ++/* Routines that are to be used by both halves of the library are declared ++ * to receive a pointer to this structure. There are no actual instances of ++ * opj_common_struct_t, only of opj_cinfo_t and opj_dinfo_t. ++ */ ++typedef struct opj_common_struct { ++ opj_common_fields; /* Fields common to both master struct types */ ++ /* Additional fields follow in an actual opj_cinfo_t or ++ * opj_dinfo_t. All three structs must agree on these ++ * initial fields! (This would be a lot cleaner in C++.) ++ */ ++} opj_common_struct_t; ++ ++typedef opj_common_struct_t * opj_common_ptr; ++ ++/** ++Compression context info ++*/ ++typedef struct opj_cinfo { ++ /** Fields shared with opj_dinfo_t */ ++ opj_common_fields; ++ /* other specific fields go here */ ++} opj_cinfo_t; ++ ++/** ++Decompression context info ++*/ ++typedef struct opj_dinfo { ++ /** Fields shared with opj_cinfo_t */ ++ opj_common_fields; ++ /* other specific fields go here */ ++} opj_dinfo_t; ++ ++/* ++========================================================== ++ I/O stream typedef definitions ++========================================================== ++*/ ++ ++/* ++ * Stream open flags. ++ */ ++/** The stream was opened for reading. */ ++#define OPJ_STREAM_READ 0x0001 ++/** The stream was opened for writing. */ ++#define OPJ_STREAM_WRITE 0x0002 ++ ++/** ++Byte input-output stream (CIO) ++*/ ++typedef struct opj_cio { ++ /** codec context */ ++ opj_common_ptr cinfo; ++ ++ /** open mode (read/write) either OPJ_STREAM_READ or OPJ_STREAM_WRITE */ ++ int openmode; ++ /** pointer to the start of the buffer */ ++ unsigned char *buffer; ++ /** buffer size in bytes */ ++ int length; ++ ++ /** pointer to the start of the stream */ ++ unsigned char *start; ++ /** pointer to the end of the stream */ ++ unsigned char *end; ++ /** pointer to the current position */ ++ unsigned char *bp; ++} opj_cio_t; ++ ++/* ++========================================================== ++ image typedef definitions ++========================================================== ++*/ ++ ++/** ++Defines a single image component ++*/ ++typedef struct opj_image_comp { ++ /** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */ ++ int dx; ++ /** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */ ++ int dy; ++ /** data width */ ++ int w; ++ /** data height */ ++ int h; ++ /** x component offset compared to the whole image */ ++ int x0; ++ /** y component offset compared to the whole image */ ++ int y0; ++ /** precision */ ++ int prec; ++ /** image depth in bits */ ++ int bpp; ++ /** signed (1) / unsigned (0) */ ++ int sgnd; ++ /** number of decoded resolution */ ++ int resno_decoded; ++ /** number of division by 2 of the out image compared to the original size of image */ ++ int factor; ++ /** image component data */ ++ int *data; ++} opj_image_comp_t; ++ ++/** ++Defines image data and characteristics ++*/ ++typedef struct opj_image { ++ /** XOsiz: horizontal offset from the origin of the reference grid to the left side of the image area */ ++ int x0; ++ /** YOsiz: vertical offset from the origin of the reference grid to the top side of the image area */ ++ int y0; ++ /** Xsiz: width of the reference grid */ ++ int x1; ++ /** Ysiz: height of the reference grid */ ++ int y1; ++ /** number of components in the image */ ++ int numcomps; ++ /** color space: sRGB, Greyscale or YUV */ ++ OPJ_COLOR_SPACE color_space; ++ /** image components */ ++ opj_image_comp_t *comps; ++} opj_image_t; ++ ++/** ++Component parameters structure used by the opj_image_create function ++*/ ++typedef struct opj_image_comptparm { ++ /** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */ ++ int dx; ++ /** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */ ++ int dy; ++ /** data width */ ++ int w; ++ /** data height */ ++ int h; ++ /** x component offset compared to the whole image */ ++ int x0; ++ /** y component offset compared to the whole image */ ++ int y0; ++ /** precision */ ++ int prec; ++ /** image depth in bits */ ++ int bpp; ++ /** signed (1) / unsigned (0) */ ++ int sgnd; ++} opj_image_cmptparm_t; ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++/* ++========================================================== ++ openjpeg version ++========================================================== ++*/ ++ ++OPJ_API const char * OPJ_CALLCONV opj_version(); ++ ++/* ++========================================================== ++ image functions definitions ++========================================================== ++*/ ++ ++/** ++Create an image ++@param numcmpts number of components ++@param cmptparms components parameters ++@param clrspc image color space ++@return returns a new image structure if successful, returns NULL otherwise ++*/ ++OPJ_API opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc); ++ ++/** ++Deallocate any resources associated with an image ++@param image image to be destroyed ++*/ ++OPJ_API void OPJ_CALLCONV opj_image_destroy(opj_image_t *image); ++ ++/* ++========================================================== ++ stream functions definitions ++========================================================== ++*/ ++ ++/** ++Open and allocate a memory stream for read / write. ++On reading, the user must provide a buffer containing encoded data. The buffer will be ++wrapped by the returned CIO handle. ++On writing, buffer parameters must be set to 0: a buffer will be allocated by the library ++to contain encoded data. ++@param cinfo Codec context info ++@param buffer Reading: buffer address. Writing: NULL ++@param length Reading: buffer length. Writing: 0 ++@return Returns a CIO handle if successful, returns NULL otherwise ++*/ ++OPJ_API opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length); ++ ++/** ++Close and free a CIO handle ++@param cio CIO handle to free ++*/ ++OPJ_API void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio); ++ ++/** ++Get position in byte stream ++@param cio CIO handle ++@return Returns the position in bytes ++*/ ++OPJ_API int OPJ_CALLCONV cio_tell(opj_cio_t *cio); ++/** ++Set position in byte stream ++@param cio CIO handle ++@param pos Position, in number of bytes, from the beginning of the stream ++*/ ++OPJ_API void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos); ++ ++/* ++========================================================== ++ event manager functions definitions ++========================================================== ++*/ ++ ++OPJ_API opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context); ++ ++/* ++========================================================== ++ codec functions definitions ++========================================================== ++*/ ++/** ++Creates a J2K/JPT/JP2 decompression structure ++@param format Decoder to select ++@return Returns a handle to a decompressor if successful, returns NULL otherwise ++*/ ++OPJ_API opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format); ++/** ++Destroy a decompressor handle ++@param dinfo decompressor handle to destroy ++*/ ++OPJ_API void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo); ++/** ++Set decoding parameters to default values ++@param parameters Decompression parameters ++*/ ++OPJ_API void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters); ++/** ++Setup the decoder decoding parameters using user parameters. ++Decoding parameters are returned in j2k->cp. ++@param dinfo decompressor handle ++@param parameters decompression parameters ++*/ ++OPJ_API void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters); ++/** ++Decode an image from a JPEG-2000 codestream ++@param dinfo decompressor handle ++@param cio Input buffer stream ++@return Returns a decoded image if successful, returns NULL otherwise ++*/ ++OPJ_API opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio); ++/** ++Creates a J2K/JP2 compression structure ++@param format Coder to select ++@return Returns a handle to a compressor if successful, returns NULL otherwise ++*/ ++OPJ_API opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format); ++/** ++Destroy a compressor handle ++@param cinfo compressor handle to destroy ++*/ ++OPJ_API void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo); ++/** ++Set encoding parameters to default values, that means : ++<ul> ++<li>Lossless ++<li>1 tile ++<li>Size of precinct : 2^15 x 2^15 (means 1 precinct) ++<li>Size of code-block : 64 x 64 ++<li>Number of resolutions: 6 ++<li>No SOP marker in the codestream ++<li>No EPH marker in the codestream ++<li>No sub-sampling in x or y direction ++<li>No mode switch activated ++<li>Progression order: LRCP ++<li>No index file ++<li>No ROI upshifted ++<li>No offset of the origin of the image ++<li>No offset of the origin of the tiles ++<li>Reversible DWT 5-3 ++</ul> ++@param parameters Compression parameters ++*/ ++OPJ_API void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters); ++/** ++Setup the encoder parameters using the current image and using user parameters. ++@param cinfo compressor handle ++@param parameters compression parameters ++@param image input filled image ++*/ ++OPJ_API void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image); ++/** ++Encode an image into a JPEG-2000 codestream ++@param cinfo compressor handle ++@param cio Output buffer stream ++@param image Image to encode ++@param index Name of the index file if required, NULL otherwise ++@return Returns true if successful, returns false otherwise ++*/ ++OPJ_API bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index); ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* OPENJPEG_H */ |