summaryrefslogtreecommitdiff
path: root/indexer_JPIP/tcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'indexer_JPIP/tcd.c')
-rw-r--r--indexer_JPIP/tcd.c292
1 files changed, 292 insertions, 0 deletions
diff --git a/indexer_JPIP/tcd.c b/indexer_JPIP/tcd.c
new file mode 100644
index 00000000..a8f1a805
--- /dev/null
+++ b/indexer_JPIP/tcd.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2003, Yannick Verschueren
+ * Copyright (c) 2003, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * 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 "tcd.h"
+#include "int.h"
+#include "t2.h"
+#include <setjmp.h>
+#include <float.h>
+#include <stdio.h>
+#include <time.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+static tcd_image_t tcd_image;
+
+static j2k_image_t *tcd_img;
+static j2k_cp_t *tcd_cp;
+
+static tcd_tile_t *tcd_tile;
+static j2k_tcp_t *tcd_tcp;
+static int tcd_tileno;
+
+extern jmp_buf j2k_error;
+
+void tcd_init(j2k_image_t *img, j2k_cp_t *cp, info_image_t *imgg) {
+ int tileno, compno, resno, bandno, precno, cblkno;
+ tcd_img=img;
+ tcd_cp=cp;
+ tcd_image.tw=cp->tw;
+ tcd_image.th=cp->th;
+ tcd_image.tiles=(tcd_tile_t*)malloc(cp->tw*cp->th*sizeof(tcd_tile_t));
+ for (tileno=0; tileno<cp->tw*cp->th; tileno++) {
+ j2k_tcp_t *tcp=&cp->tcps[tileno];
+ tcd_tile_t *tile=&tcd_image.tiles[tileno];
+ // cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000)
+ int p=tileno%cp->tw; // si numerotation matricielle ..
+ int q=tileno/cp->tw; // .. coordonnees de la tile (q,p) q pour ligne et p pour colonne
+ info_tile_t *tile_Idx=&imgg->tile[tileno]; // INDEX
+
+ // 4 borders of the tile rescale on the image if necessary
+ tile->x0=int_max(cp->tx0+p*cp->tdx, img->x0);
+ tile->y0=int_max(cp->ty0+q*cp->tdy, img->y0);
+ tile->x1=int_min(cp->tx0+(p+1)*cp->tdx, img->x1);
+ tile->y1=int_min(cp->ty0+(q+1)*cp->tdy, img->y1);
+
+ tile->numcomps=img->numcomps;
+ tile->comps=(tcd_tilecomp_t*)malloc(img->numcomps*sizeof(tcd_tilecomp_t));
+ tile_Idx->compo=(info_compo_t*)malloc(img->numcomps*sizeof(info_compo_t)); // INDEX
+ for (compno=0; compno<tile->numcomps; compno++) {
+ j2k_tccp_t *tccp=&tcp->tccps[compno];
+ tcd_tilecomp_t *tilec=&tile->comps[compno];
+ info_compo_t *compo_Idx=&tile_Idx->compo[compno]; // INDEX
+
+ // border of each tile component (global)
+ tilec->x0=int_ceildiv(tile->x0, img->comps[compno].dx);
+ tilec->y0=int_ceildiv(tile->y0, img->comps[compno].dy);
+ tilec->x1=int_ceildiv(tile->x1, img->comps[compno].dx);
+ tilec->y1=int_ceildiv(tile->y1, img->comps[compno].dy);
+
+ tilec->data=(int*)malloc(sizeof(int)*(tilec->x1-tilec->x0)*(tilec->y1-tilec->y0));
+ tilec->numresolutions=tccp->numresolutions;
+ tilec->resolutions=(tcd_resolution_t*)malloc(tilec->numresolutions*sizeof(tcd_resolution_t));
+ compo_Idx->reso=(info_reso_t*)malloc(tilec->numresolutions*sizeof(info_reso_t)); // INDEX
+ for (resno=0; resno<tilec->numresolutions; resno++) {
+ int pdx, pdy;
+ int levelno=tilec->numresolutions-1-resno;
+ int tlprcxstart, tlprcystart, brprcxend, brprcyend;
+ int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend;
+ int cbgwidthexpn, cbgheightexpn;
+ int cblkwidthexpn, cblkheightexpn;
+ tcd_resolution_t *res=&tilec->resolutions[resno];
+ info_reso_t *res_Idx=&compo_Idx->reso[resno]; // INDEX
+ int precno_Idx; // INDEX
+
+ // border for each resolution level (global)
+ res->x0=int_ceildivpow2(tilec->x0, levelno);
+ res->y0=int_ceildivpow2(tilec->y0, levelno);
+ res->x1=int_ceildivpow2(tilec->x1, levelno);
+ res->y1=int_ceildivpow2(tilec->y1, levelno);
+
+ res->numbands=resno==0?1:3;
+ // p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000)
+ if (tccp->csty&J2K_CCP_CSTY_PRT) {
+ pdx=tccp->prcw[resno];
+ pdy=tccp->prch[resno];
+ } else {
+ pdx=15;
+ pdy=15;
+ }
+ // p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000)
+ tlprcxstart=int_floordivpow2(res->x0, pdx)<<pdx;
+ tlprcystart=int_floordivpow2(res->y0, pdy)<<pdy;
+ brprcxend=int_ceildivpow2(res->x1, pdx)<<pdx;
+ brprcyend=int_ceildivpow2(res->y1, pdy)<<pdy;
+ res->pw=(brprcxend-tlprcxstart)>>pdx;
+ res->ph=(brprcyend-tlprcystart)>>pdy;
+
+ // <INDEX>
+ imgg->tile[tileno].pw=res->pw;
+ imgg->tile[tileno].ph=res->ph;
+
+ res_Idx->prec=(info_prec_t*)malloc(res->pw*res->ph*sizeof(info_prec_t));
+ for (precno_Idx=0;precno_Idx<res->pw*res->ph;precno_Idx++)
+ {
+ info_prec_t *prec_Idx = &res_Idx->prec[precno_Idx];
+ prec_Idx->layer=(info_layer_t*)malloc(imgg->Layer*sizeof(info_layer_t));
+ }
+
+ imgg->pw=res->pw; // old parser version
+ imgg->ph=res->ph; // old parser version
+ imgg->pdx=1<<pdx;
+ imgg->pdy=1<<pdy;
+ // </INDEX>
+
+ if (resno==0) {
+ tlcbgxstart=tlprcxstart;
+ tlcbgystart=tlprcystart;
+ brcbgxend=brprcxend;
+ brcbgyend=brprcyend;
+ cbgwidthexpn=pdx;
+ cbgheightexpn=pdy;
+ } else {
+ tlcbgxstart=int_ceildivpow2(tlprcxstart, 1);
+ tlcbgystart=int_ceildivpow2(tlprcystart, 1);
+ brcbgxend=int_ceildivpow2(brprcxend, 1);
+ brcbgyend=int_ceildivpow2(brprcyend, 1);
+ cbgwidthexpn=pdx-1;
+ cbgheightexpn=pdy-1;
+ }
+
+ cblkwidthexpn=int_min(tccp->cblkw, cbgwidthexpn);
+ cblkheightexpn=int_min(tccp->cblkh, cbgheightexpn);
+
+ for (bandno=0; bandno<res->numbands; bandno++) {
+ int x0b, y0b;
+ tcd_band_t *band=&res->bands[bandno];
+ band->bandno=resno==0?0:bandno+1;
+ x0b=(band->bandno==1)||(band->bandno==3)?1:0;
+ y0b=(band->bandno==2)||(band->bandno==3)?1:0;
+
+ if (band->bandno==0) {
+ // band border (global)
+ band->x0=int_ceildivpow2(tilec->x0, levelno);
+ band->y0=int_ceildivpow2(tilec->y0, levelno);
+ band->x1=int_ceildivpow2(tilec->x1, levelno);
+ band->y1=int_ceildivpow2(tilec->y1, levelno);
+ } else {
+ // band border (global)
+ band->x0=int_ceildivpow2(tilec->x0-(1<<levelno)*x0b, levelno+1);
+ band->y0=int_ceildivpow2(tilec->y0-(1<<levelno)*y0b, levelno+1);
+ band->x1=int_ceildivpow2(tilec->x1-(1<<levelno)*x0b, levelno+1);
+ band->y1=int_ceildivpow2(tilec->y1-(1<<levelno)*y0b, levelno+1);
+ }
+
+ band->precincts=(tcd_precinct_t*)malloc(res->pw*res->ph*sizeof(tcd_precinct_t));
+
+ for (precno=0; precno<res->pw*res->ph; precno++) {
+ int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend;
+ int cbgxstart=tlcbgxstart+(precno%res->pw)*(1<<cbgwidthexpn);
+ int cbgystart=tlcbgystart+(precno/res->pw)*(1<<cbgheightexpn);
+ int cbgxend=cbgxstart+(1<<cbgwidthexpn);
+ int cbgyend=cbgystart+(1<<cbgheightexpn);
+ tcd_precinct_t *prc=&band->precincts[precno];
+ // precinct size (global)
+ prc->x0=int_max(cbgxstart, band->x0);
+ prc->y0=int_max(cbgystart, band->y0);
+ prc->x1=int_min(cbgxend, band->x1);
+ prc->y1=int_min(cbgyend, band->y1);
+
+ tlcblkxstart=int_floordivpow2(prc->x0, cblkwidthexpn)<<cblkwidthexpn;
+ tlcblkystart=int_floordivpow2(prc->y0, cblkheightexpn)<<cblkheightexpn;
+ brcblkxend=int_ceildivpow2(prc->x1, cblkwidthexpn)<<cblkwidthexpn;
+ brcblkyend=int_ceildivpow2(prc->y1, cblkheightexpn)<<cblkheightexpn;
+ prc->cw=(brcblkxend-tlcblkxstart)>>cblkwidthexpn;
+ prc->ch=(brcblkyend-tlcblkystart)>>cblkheightexpn;
+
+ prc->cblks=(tcd_cblk_t*)malloc(prc->cw*prc->ch*sizeof(tcd_cblk_t));
+
+ prc->incltree=tgt_create(prc->cw, prc->ch);
+ prc->imsbtree=tgt_create(prc->cw, prc->ch);
+
+ for (cblkno=0; cblkno<prc->cw*prc->ch; cblkno++) {
+ int cblkxstart=tlcblkxstart+(cblkno%prc->cw)*(1<<cblkwidthexpn);
+ int cblkystart=tlcblkystart+(cblkno/prc->cw)*(1<<cblkheightexpn);
+ int cblkxend=cblkxstart+(1<<cblkwidthexpn);
+ int cblkyend=cblkystart+(1<<cblkheightexpn);
+ tcd_cblk_t *cblk=&prc->cblks[cblkno];
+ // code-block size (global)
+ cblk->x0=int_max(cblkxstart, prc->x0);
+ cblk->y0=int_max(cblkystart, prc->y0);
+ cblk->x1=int_min(cblkxend, prc->x1);
+ cblk->y1=int_min(cblkyend, prc->y1);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+void tcd_free(j2k_image_t *img, j2k_cp_t *cp) {
+ int tileno, compno, resno, bandno, precno;
+ tcd_img=img;
+ tcd_cp=cp;
+ tcd_image.tw=cp->tw;
+ tcd_image.th=cp->th;
+ for (tileno=0; tileno<tcd_image.tw*tcd_image.th; tileno++)
+ {
+ // j2k_tcp_t *tcp=&cp->tcps[curtileno];
+ tcd_tile_t *tile=&tcd_image.tiles[tileno];
+ for (compno=0; compno<tile->numcomps; compno++)
+ {
+ tcd_tilecomp_t *tilec=&tile->comps[compno];
+ for (resno=0; resno<tilec->numresolutions; resno++)
+ {
+ tcd_resolution_t *res=&tilec->resolutions[resno];
+ for (bandno=0; bandno<res->numbands; bandno++)
+ {
+ tcd_band_t *band=&res->bands[bandno];
+ for (precno=0; precno<res->pw*res->ph; precno++)
+ {
+ tcd_precinct_t *prc=&band->precincts[precno];
+
+ if (prc->incltree!=NULL)
+ tgt_destroy(prc->incltree);
+ if (prc->imsbtree!=NULL)
+ tgt_destroy(prc->imsbtree);
+ free(prc->cblks);
+ } // for (precno
+ free(band->precincts);
+ } // for (bandno
+ } // for (resno
+ free(tilec->resolutions);
+ } // for (compno
+ free(tile->comps);
+ } // for (tileno
+ free(tcd_image.tiles);
+}
+
+
+int tcd_decode_tile(unsigned char *src, int len, int tileno, info_image_t *imgg) {
+ int l;
+ int eof=0;
+
+ tcd_tile_t *tile;
+ tcd_tileno=tileno;
+ tcd_tile=&tcd_image.tiles[tileno];
+ tcd_tcp=&tcd_cp->tcps[tileno];
+ tile=tcd_tile;
+
+ l=t2_decode_packets(src, len, tcd_img, tcd_cp, tileno, tile, imgg);
+
+ if (l==-999)
+ {
+ eof=1;
+ fprintf(stderr, "tcd_decode: incomplete bistream\n");
+ }
+
+ if (eof) {
+ longjmp(j2k_error, 1);
+ }
+
+ l=1;
+ return l;
+}