diff --git a/indexer_JPIP/Makefile b/indexer_JPIP/Makefile new file mode 100644 index 00000000..40c049ea --- /dev/null +++ b/indexer_JPIP/Makefile @@ -0,0 +1,23 @@ +CC = gcc + +LDFLAGS = -lm +CFLAGS = -Wall + +all: index_create + + +bio.o : bio.c bio.h +cio.o : cio.c cio.h +int.o : int.c +pi.o : pi.c pi.h int.h +index_create.o : index_create.c j2k.h cio.h tcd.h int.h +t2.o : t2.c t2.h tcd.h bio.h j2k.h pi.h tgt.h int.h cio.h +tgt.o : tgt.c bio.h tgt.h +tcd.o : tcd.c tcd.h t2.h int.h +jpip.o : jpip.c j2k.h cio.h tcd.h int.h +jp2.o : jp2.c j2k.h cio.h tcd.h int.h + +index_create : bio.o cio.o int.o pi.o t2.o tgt.o tcd.o index_create.o jpip.o jp2.o + +clean: + rm -rf *.o *.*~ *~ core.* diff --git a/indexer_JPIP/bio.c b/indexer_JPIP/bio.c new file mode 100644 index 00000000..17078cef --- /dev/null +++ b/indexer_JPIP/bio.c @@ -0,0 +1,163 @@ +/* + * 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 "bio.h" +#include + +static unsigned char *bio_start, *bio_end, *bio_bp; +static unsigned int bio_buf; +static int bio_ct; + +extern jmp_buf j2k_error; + +/// +/// Number of bytes written. +/// +int bio_numbytes() { + return bio_bp-bio_start; +} + +/// +/// Init encoder. +/// +/// Output buffer +/// Output buffer length +void bio_init_enc(unsigned char *bp, int len) { + bio_start=bp; + bio_end=bp+len; + bio_bp=bp; + bio_buf=0; + bio_ct=8; +} + +/// +/// Init decoder. +/// +/// Input buffer +/// Input buffer length +void bio_init_dec(unsigned char *bp, int len) { + bio_start=bp; + bio_end=bp+len; + bio_bp=bp; + bio_buf=0; + bio_ct=0; +} + +/// +/// Write byte. +/// +int bio_byteout() { + bio_buf=(bio_buf<<8)&0xffff; + bio_ct=bio_buf==0xff00?7:8; + if (bio_bp>=bio_end) return 1; //longjmp(j2k_error, 1); + *bio_bp++=bio_buf>>8; + return 0; +} + +/// +/// Read byte. +/// +int bio_bytein() { + bio_buf=(bio_buf<<8)&0xffff; + bio_ct=bio_buf==0xff00?7:8; + if (bio_bp>=bio_end) return 1; //longjmp(j2k_error, 1); + bio_buf|=*bio_bp++; + return 0; +} + +/// +/// Write bit. +/// +/// Bit to write (0 or 1) +void bio_putbit(int b) { + if (bio_ct==0) { + bio_byteout(); + } + bio_ct--; + bio_buf|=b< +/// Read bit. +/// +int bio_getbit() { + if (bio_ct==0) { + bio_bytein(); + } + bio_ct--; + return (bio_buf>>bio_ct)&1; +} + +/// +/// Write bits. +/// +/// Value of bits +/// Number of bits to write +void bio_write(int v, int n) { + int i; + for (i=n-1; i>=0; i--) { + bio_putbit((v>>i)&1); + } +} + +/// +/// Read bits. +/// +/// Number of bits to read +int bio_read(int n) { + int i, v; + v=0; + for (i=n-1; i>=0; i--) { + v+=bio_getbit()< +/// Flush bits. +/// +int bio_flush() { + bio_ct=0; + bio_byteout(); + if (bio_ct==7) { + bio_ct=0; + if ( bio_byteout()) return 1;; + } + return 0; +} + +/// +/// +int bio_inalign() { + bio_ct=0; + if ((bio_buf&0xff)==0xff) { + if( bio_bytein()) return 1; + bio_ct=0; + } + return 0; +} diff --git a/indexer_JPIP/bio.h b/indexer_JPIP/bio.h new file mode 100644 index 00000000..ed412bdc --- /dev/null +++ b/indexer_JPIP/bio.h @@ -0,0 +1,40 @@ +/* + * 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. + */ + +#ifndef __BIO_H +#define __BIO_H + +int bio_numbytes(); +void bio_init_enc(unsigned char *bp, int len); +void bio_init_dec(unsigned char *bp, int len); +void bio_write(int v, int n); +int bio_read(int n); +int bio_flush(); +int bio_inalign(); + +#endif diff --git a/indexer_JPIP/cio.c b/indexer_JPIP/cio.c new file mode 100644 index 00000000..208fe24e --- /dev/null +++ b/indexer_JPIP/cio.c @@ -0,0 +1,127 @@ +/* + * 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 "cio.h" +#include + +static unsigned char *cio_start, *cio_end, *cio_bp; + +extern jmp_buf j2k_error; + +/// +/// Number of bytes written. +/// +int cio_numbytes() { + return cio_bp-cio_start; +} + +/// +/// Get position in byte stream. +/// +int cio_tell() { + return cio_bp-cio_start; +} + +/// +/// Set position in byte stream. +/// +void cio_seek(int pos) { + cio_bp=cio_start+pos; +} + +/// +/// Number of bytes left before the end of the stream. +/// +int cio_numbytesleft() { + return cio_end-cio_bp; +} + +/// +/// Get pointer to the current position in the stream. +/// +unsigned char *cio_getbp() { + return cio_bp; +} + +/// +/// Initialize byte IO. +/// +void cio_init(unsigned char *bp, int len) { + cio_start=bp; + cio_end=bp+len; + cio_bp=bp; +} + +/// +/// Write a byte. +/// +void cio_byteout(unsigned char v) { + if (cio_bp>=cio_end) longjmp(j2k_error, 1); + *cio_bp++=v; + +} + +/// +/// Read a byte. +/// +unsigned char cio_bytein() { + if (cio_bp>=cio_end) longjmp(j2k_error, 1); + return *cio_bp++; +} + +/// +/// Write a byte. +/// +//void cio_write(unsigned int v, int n) { +void cio_write(long long v, int n) { + int i; + for (i=n-1; i>=0; i--) + { + cio_byteout((unsigned char)((v>>(i<<3))&0xff)); + } +} + +/// +/// Read some bytes. +/// +unsigned int cio_read(int n) { + int i; + unsigned int v; + v=0; + for (i=n-1; i>=0; i--) { + v+=cio_bytein()<<(i<<3); + } + return v; +} + +/// +/// Write some bytes. +/// +void cio_skip(int n) { + cio_bp+=n; +} diff --git a/indexer_JPIP/cio.h b/indexer_JPIP/cio.h new file mode 100644 index 00000000..2e351c08 --- /dev/null +++ b/indexer_JPIP/cio.h @@ -0,0 +1,43 @@ +/* + * 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. + */ + +#ifndef __CIO_H +#define __CIO_H + +int cio_tell(); +void cio_seek(int pos); +int cio_numbytes(); +int cio_numbytesleft(); +unsigned char *cio_getbp(); +void cio_init(unsigned char *bp, int len); +//void cio_write(unsigned int v, int n); +void cio_write(long long v, int n); +unsigned int cio_read(int n); +void cio_skip(int n); + +#endif diff --git a/indexer_JPIP/fix.c b/indexer_JPIP/fix.c new file mode 100644 index 00000000..9699bf6b --- /dev/null +++ b/indexer_JPIP/fix.c @@ -0,0 +1,42 @@ +/* + * 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 "fix.h" + +#ifdef WIN32 +#define int64 __int64 +#else +#define int64 long long +#endif + +/// +/// Multiply two fixed-precision rational numbers. +/// +int fix_mul(int a, int b) { + return (int)((int64)a*(int64)b>>13); +} diff --git a/indexer_JPIP/fix.h b/indexer_JPIP/fix.h new file mode 100644 index 00000000..4b6e1b54 --- /dev/null +++ b/indexer_JPIP/fix.h @@ -0,0 +1,34 @@ +/* + * 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. + */ + +#ifndef __FIX_H +#define __FIX_H + +int fix_mul(int a, int b); + +#endif diff --git a/indexer_JPIP/index_create.c b/indexer_JPIP/index_create.c new file mode 100644 index 00000000..03f5332c --- /dev/null +++ b/indexer_JPIP/index_create.c @@ -0,0 +1,765 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "j2k.h" +#include "cio.h" +#include "tcd.h" +#include "int.h" +#include "jpip.h" +#include "jp2.h" + +#define J2K_MS_SOC 0xff4f +#define J2K_MS_SOT 0xff90 +#define J2K_MS_SOD 0xff93 +#define J2K_MS_EOC 0xffd9 +#define J2K_MS_SIZ 0xff51 +#define J2K_MS_COD 0xff52 +#define J2K_MS_COC 0xff53 +#define J2K_MS_RGN 0xff5e +#define J2K_MS_QCD 0xff5c +#define J2K_MS_QCC 0xff5d +#define J2K_MS_POC 0xff5f +#define J2K_MS_TLM 0xff55 +#define J2K_MS_PLM 0xff57 +#define J2K_MS_PLT 0xff58 +#define J2K_MS_PPM 0xff60 +#define J2K_MS_PPT 0xff61 +#define J2K_MS_SOP 0xff91 +#define J2K_MS_EPH 0xff92 +#define J2K_MS_CRG 0xff63 +#define J2K_MS_COM 0xff64 + +#define J2K_STATE_MHSOC 0x0001 +#define J2K_STATE_MHSIZ 0x0002 +#define J2K_STATE_MH 0x0004 +#define J2K_STATE_TPHSOT 0x0008 +#define J2K_STATE_TPH 0x0010 +#define J2K_STATE_MT 0x0020 + +jmp_buf j2k_error; + +static int j2k_state; +static int j2k_curtileno; +static j2k_tcp_t j2k_default_tcp; +static unsigned char *j2k_eot; + +static j2k_image_t *j2k_img; +static j2k_cp_t *j2k_cp; + +static unsigned char **j2k_tile_data; +static int *j2k_tile_len; + +static info_image_t img; + +void j2k_clean() { + int tileno = 0; + int compno, resno, precno; + + tcd_free(j2k_img,j2k_cp); + + for (tileno=0;tilenotw*j2k_cp->th;tileno++) { + info_tile_t *tile_Idx = &img.tile[tileno]; + + for (compno=0;compnocompo[compno]; + + for(resno=0;resnoreso[resno]; + for (precno=0;precnoprec[precno]; + free(prec_Idx->layer); + } + free(reso_Idx->prec); + } + free(compo_Idx->reso); + } + free(tile_Idx->compo); + } + free(img.tile); + free(img.marker); +} + +void j2k_read_soc() { + j2k_state=J2K_STATE_MHSIZ; +} + +void j2k_read_siz() { + int len, i; + len=cio_read(2); + + // + img.marker[img.num_marker].type=J2K_MS_SIZ; + img.marker[img.num_marker].start_pos=cio_tell()-2; + img.marker[img.num_marker].len=len; + img.num_marker++; + // + + + cio_read(2); // Rsiz (capabilities) + j2k_img->x1=cio_read(4); // Xsiz + j2k_img->y1=cio_read(4); // Ysiz + j2k_img->x0=cio_read(4); // X0siz + j2k_img->y0=cio_read(4); // Y0siz + j2k_cp->tdx=cio_read(4); // XTsiz + j2k_cp->tdy=cio_read(4); // YTsiz + j2k_cp->tx0=cio_read(4); // XT0siz + j2k_cp->ty0=cio_read(4); // YTOsiz + j2k_img->numcomps=cio_read(2); // Csiz + j2k_img->comps=(j2k_comp_t*)malloc(j2k_img->numcomps*sizeof(j2k_comp_t)); + for (i=0; inumcomps; i++) { + int tmp, w, h; + tmp=cio_read(1); + j2k_img->comps[i].prec=(tmp&0x7f)+1; + j2k_img->comps[i].sgnd=tmp>>7; + j2k_img->comps[i].dx=cio_read(1); + j2k_img->comps[i].dy=cio_read(1); + w=int_ceildiv(j2k_img->x1-j2k_img->x0, j2k_img->comps[i].dx); + h=int_ceildiv(j2k_img->y1-j2k_img->y0, j2k_img->comps[i].dy); + j2k_img->comps[i].data=(int*)malloc(sizeof(int)*w*h); + } + j2k_cp->tw=int_ceildiv(j2k_img->x1-j2k_img->x0, j2k_cp->tdx); + j2k_cp->th=int_ceildiv(j2k_img->y1-j2k_img->y0, j2k_cp->tdy); + + j2k_cp->tcps=(j2k_tcp_t*)calloc(sizeof(j2k_tcp_t), j2k_cp->tw*j2k_cp->th); + j2k_default_tcp.tccps=(j2k_tccp_t*)calloc(sizeof(j2k_tccp_t), j2k_img->numcomps); + for (i=0; itw*j2k_cp->th; i++) { + j2k_cp->tcps[i].tccps=(j2k_tccp_t*)calloc(sizeof(j2k_tccp_t), j2k_img->numcomps); + } + j2k_tile_data=(unsigned char**)calloc(j2k_cp->tw*j2k_cp->th, sizeof(char*)); + j2k_tile_len=(int*)calloc(j2k_cp->tw*j2k_cp->th, sizeof(int)); + j2k_state=J2K_STATE_MH; + + // + img.Im_w=j2k_img->x1-j2k_img->x0; + img.Im_h=j2k_img->y1-j2k_img->y0; + img.Tile_x=j2k_cp->tdx; + img.Tile_y=j2k_cp->tdy; + img.Comp=j2k_img->numcomps; + img.tw=j2k_cp->tw; + img.th=j2k_cp->th; + img.tile=(info_tile_t*)malloc((img.tw*img.th)*sizeof(info_tile_t)); + // + + + } + +void j2k_read_com() { + int len; + len=cio_read(2); + + // + if (j2k_state==J2K_STATE_MH) + { + if (!img.marker_mul.num_COM) + img.marker_mul.COM=(info_marker_t*)malloc(sizeof(info_marker_t)); + else + img.marker_mul.COM=realloc(img.marker_mul.COM,(1+img.marker_mul.num_COM)*sizeof(info_marker_t)); + img.marker_mul.COM[img.marker_mul.num_COM].type=J2K_MS_COM; + img.marker_mul.COM[img.marker_mul.num_COM].start_pos=cio_tell()-2; + img.marker_mul.COM[img.marker_mul.num_COM].len=len; + img.marker_mul.num_COM++; + } + // + + cio_skip(len-2); +} + +void j2k_read_cox(int compno) { + int i; + j2k_tcp_t *tcp; + j2k_tccp_t *tccp; + tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp; + tccp=&tcp->tccps[compno]; + tccp->numresolutions=cio_read(1)+1; + + img.Decomposition=tccp->numresolutions-1; // + + tccp->cblkw=cio_read(1)+2; + tccp->cblkh=cio_read(1)+2; + tccp->cblksty=cio_read(1); + tccp->qmfbid=cio_read(1); + if (tccp->csty&J2K_CP_CSTY_PRT) { + for (i=0; inumresolutions; i++) { + int tmp=cio_read(1); + tccp->prcw[i]=tmp&0xf; + tccp->prch[i]=tmp>>4; + } + } +} + +void j2k_read_cod() { + int len, i, pos; + j2k_tcp_t *tcp; + tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp; + len=cio_read(2); + + // + if (j2k_state==J2K_STATE_MH) + { + if (!img.marker_mul.num_COD) + img.marker_mul.COD=(info_marker_t*)malloc(sizeof(info_marker_t)); + else + img.marker_mul.COD=realloc(img.marker_mul.COD,(1+img.marker_mul.num_COD)*sizeof(info_marker_t)); + img.marker_mul.COD[img.marker_mul.num_COD].type=J2K_MS_COD; + img.marker_mul.COD[img.marker_mul.num_COD].start_pos=cio_tell()-2; + img.marker_mul.COD[img.marker_mul.num_COD].len=len; + img.marker_mul.num_COD++; + } + // + + + tcp->csty=cio_read(1); + tcp->prg=cio_read(1); + tcp->numlayers=cio_read(2); + tcp->mct=cio_read(1); + pos=cio_tell(); + for (i=0; inumcomps; i++) { + tcp->tccps[i].csty=tcp->csty&J2K_CP_CSTY_PRT; + cio_seek(pos); + j2k_read_cox(i); + } + // + img.Prog=tcp->prg; + img.Layer=tcp->numlayers; + // +} + +void j2k_read_coc() { + int len, compno; + j2k_tcp_t *tcp; + tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp; + len=cio_read(2); + // + if (j2k_state==J2K_STATE_MH) + { + if (!img.marker_mul.num_COC) + img.marker_mul.COC=(info_marker_t*)malloc(sizeof(info_marker_t)); + else + img.marker_mul.COC=realloc(img.marker_mul.COC,(1+img.marker_mul.num_COC)*sizeof(info_marker_t)); + img.marker_mul.COC[img.marker_mul.num_COC].type=J2K_MS_COC; + img.marker_mul.COC[img.marker_mul.num_COC].start_pos=cio_tell()-2; + img.marker_mul.COC[img.marker_mul.num_COC].len=len; + img.marker_mul.num_COC++; + } + // + + + compno=cio_read(j2k_img->numcomps<=256?1:2); + tcp->tccps[compno].csty=cio_read(1); + j2k_read_cox(compno); +} + +void j2k_read_qcx(int compno, int len) { + int tmp; + j2k_tcp_t *tcp; + j2k_tccp_t *tccp; + int bandno, numbands; + tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp; + tccp=&tcp->tccps[compno]; + tmp=cio_read(1); + 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); + for (bandno=0; bandnoqntsty==J2K_CCP_QNTSTY_NOQNT) { // WHY STEPSIZES WHEN NOQNT ? + expn=cio_read(1)>>3; + mant=0; + } else { + tmp=cio_read(2); + expn=tmp>>11; + mant=tmp&0x7ff; + } + tccp->stepsizes[bandno].expn=expn; + tccp->stepsizes[bandno].mant=mant; + } +} + +void j2k_read_qcd() { + int len, i, pos; + len=cio_read(2); + + // + if (j2k_state==J2K_STATE_MH) + { + img.marker[img.num_marker].type=J2K_MS_QCD; + img.marker[img.num_marker].start_pos=cio_tell()-2; + img.marker[img.num_marker].len=len; + img.num_marker++; + } + // + + + pos=cio_tell(); + for (i=0; inumcomps; i++) { + cio_seek(pos); + j2k_read_qcx(i, len-2); + } +} + +void j2k_read_qcc() { + int len, compno; + len=cio_read(2); + + // + if (j2k_state==J2K_STATE_MH) + { + if (!img.marker_mul.num_QCC) + img.marker_mul.QCC=(info_marker_t*)malloc(sizeof(info_marker_t)); + else + img.marker_mul.QCC=realloc(img.marker_mul.QCC,(1+img.marker_mul.num_QCC)*sizeof(info_marker_t)); + img.marker_mul.QCC[img.marker_mul.num_QCC].type=J2K_MS_QCC; + img.marker_mul.QCC[img.marker_mul.num_QCC].start_pos=cio_tell()-2; + img.marker_mul.QCC[img.marker_mul.num_QCC].len=len; + img.marker_mul.num_QCC++; + } + // + + + compno=cio_read(j2k_img->numcomps<=256?1:2); + j2k_read_qcx(compno, len-2-(j2k_img->numcomps<=256?1:2)); +} + +void j2k_read_poc() { + int len, numpchgs, i; + j2k_tcp_t *tcp; + fprintf(stderr, "WARNING: POC marker segment processing not fully implemented\n"); + tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp; + len=cio_read(2); + + // + if (j2k_state==J2K_STATE_MH) + { + img.marker[img.num_marker].type=J2K_MS_POC; + img.marker[img.num_marker].start_pos=cio_tell()-2; + img.marker[img.num_marker].len=len; + img.num_marker++; + } + // + + + numpchgs=(len-2)/(5+2*(j2k_img->numcomps<=256?1:2)); + for (i=0; ipocs[i]; + poc->resno0=cio_read(1); + poc->compno0=cio_read(j2k_img->numcomps<=256?1:2); + poc->layno1=cio_read(2); + poc->resno1=cio_read(1); + poc->compno1=cio_read(j2k_img->numcomps<=256?1:2); + poc->prg=cio_read(1); + } +} + +void j2k_read_crg() { + int len; + len=cio_read(2); + + // + if (j2k_state==J2K_STATE_MH) + { + img.marker[img.num_marker].type=J2K_MS_CRG; + img.marker[img.num_marker].start_pos=cio_tell()-2; + img.marker[img.num_marker].len=len; + img.num_marker++; + } + // + + fprintf(stderr, "WARNING: CRG marker segment processing not implemented\n"); + cio_skip(len-2); +} + +void j2k_read_tlm() { + int len; + len=cio_read(2); + + // + if (j2k_state==J2K_STATE_MH) + { + if (!img.marker_mul.num_TLM) + img.marker_mul.TLM=(info_marker_t*)malloc(sizeof(info_marker_t)); + else + img.marker_mul.TLM=realloc(img.marker_mul.TLM,(1+img.marker_mul.num_TLM)*sizeof(info_marker_t)); + img.marker_mul.TLM[img.marker_mul.num_TLM].type=J2K_MS_TLM; + img.marker_mul.TLM[img.marker_mul.num_TLM].start_pos=cio_tell()-2; + img.marker_mul.TLM[img.marker_mul.num_TLM].len=len; + img.marker_mul.num_TLM++; + } + // + + fprintf(stderr, "WARNING: TLM marker segment processing not implemented\n"); + cio_skip(len-2); +} + +void j2k_read_plm() { + int len; + len=cio_read(2); + + // + if (j2k_state==J2K_STATE_MH) + { + if (!img.marker_mul.num_PLM) + img.marker_mul.PLM=(info_marker_t*)malloc(sizeof(info_marker_t)); + else + img.marker_mul.PLM=realloc(img.marker_mul.PLM,(1+img.marker_mul.num_PLM)*sizeof(info_marker_t)); + img.marker_mul.PLM[img.marker_mul.num_PLM].type=J2K_MS_PLM; + img.marker_mul.PLM[img.marker_mul.num_PLM].start_pos=cio_tell()-2; + img.marker_mul.PLM[img.marker_mul.num_PLM].len=len; + img.marker_mul.num_PLM++; + } + // + + fprintf(stderr, "WARNING: PLM marker segment processing not implemented\n"); + cio_skip(len-2); +} + +void j2k_read_plt() { + int len; + len=cio_read(2); + fprintf(stderr, "WARNING: PLT marker segment processing not implemented\n"); + cio_skip(len-2); +} + +void j2k_read_ppm() { + int len; + len=cio_read(2); + // + if (j2k_state==J2K_STATE_MH) + { + img.marker[img.num_marker].type=J2K_MS_PPM; + img.marker[img.num_marker].start_pos=cio_tell()-2; + img.marker[img.num_marker].len=len; + img.num_marker++; + } + // + + fprintf(stderr, "WARNING: PPM marker segment processing not implemented\n"); + cio_skip(len-2); +} + +void j2k_read_ppt() { + int len; + len=cio_read(2); + fprintf(stderr, "WARNING: PPT marker segment processing not implemented\n"); + cio_skip(len-2); +} + +void j2k_read_sot() { + int len, tileno, totlen, partno, numparts, i; + j2k_tcp_t *tcp; + j2k_tccp_t *tmp; + len=cio_read(2); + tileno=cio_read(2); + // + if (!tileno) img.Main_head_end=cio_tell()-6; // Correction End = First byte of first SOT + img.tile[tileno].start_pos=cio_tell()-6; + img.tile[tileno].num_tile=tileno; + // + totlen=cio_read(4); + if (!totlen) totlen = cio_numbytesleft() + 8; + + img.tile[tileno].end_pos=totlen+img.tile[tileno].start_pos; // + + partno=cio_read(1); + numparts=cio_read(1); + j2k_curtileno=tileno; + j2k_eot=cio_getbp()-12+totlen; + j2k_state=J2K_STATE_TPH; + tcp=&j2k_cp->tcps[j2k_curtileno]; + tmp=tcp->tccps; + *tcp=j2k_default_tcp; + tcp->tccps=tmp; + for (i=0; inumcomps; i++) { + tcp->tccps[i]=j2k_default_tcp.tccps[i]; + } +} + +void j2k_read_sod() { + int len; + unsigned char *data; + img.tile[j2k_curtileno].end_header=cio_tell()-1; // + len=int_min(j2k_eot-cio_getbp(), cio_numbytesleft()); + j2k_tile_len[j2k_curtileno]+=len; + data=(unsigned char*)realloc(j2k_tile_data[j2k_curtileno], j2k_tile_len[j2k_curtileno]); + memcpy(data, cio_getbp(), len); + j2k_tile_data[j2k_curtileno]=data; + cio_skip(len); + j2k_state=J2K_STATE_TPHSOT; + +} + +void j2k_read_rgn() { + int len, compno, roisty; + j2k_tcp_t *tcp; + tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp; + len=cio_read(2); + + // + if (j2k_state==J2K_STATE_MH) + { + if (!img.marker_mul.num_RGN) + img.marker_mul.RGN=(info_marker_t*)malloc(sizeof(info_marker_t)); + else + img.marker_mul.RGN=realloc(img.marker_mul.RGN,(1+img.marker_mul.num_RGN)*sizeof(info_marker_t)); + img.marker_mul.RGN[img.marker_mul.num_RGN].type=J2K_MS_RGN; + img.marker_mul.RGN[img.marker_mul.num_RGN].start_pos=cio_tell()-2; + img.marker_mul.RGN[img.marker_mul.num_RGN].len=len; + img.marker_mul.num_RGN++; + } + // + + + compno=cio_read(j2k_img->numcomps<=256?1:2); + roisty=cio_read(1); + tcp->tccps[compno].roishift=cio_read(1); +} + +void j2k_read_eoc() { + int tileno; + tcd_init(j2k_img, j2k_cp, &img); + for (tileno=0; tilenotw*j2k_cp->th; tileno++) { + tcd_decode_tile(j2k_tile_data[tileno], j2k_tile_len[tileno], tileno, &img); + } + + j2k_state=J2K_STATE_MT; + longjmp(j2k_error, 1); + +} + +void j2k_read_unk() { + fprintf(stderr, "warning: unknown marker\n"); +} + +int j2k_index_JPIP(char *Idx_file, char *J2K_file, int len){ + FILE *dest; + char *index; + int pos_iptr, end_pos; + int len_cidx, pos_cidx; + int len_jp2c, pos_jp2c; + int len_fidx, pos_fidx; + + dest=fopen(Idx_file, "wb"); + if (!dest) { + fprintf(stderr,"Failed to open %s for reading !!\n",Idx_file); + return 0; + } + + // INDEX MODE JPIP + index=(char*)malloc(len); + cio_init(index, len); + jp2_write_jp(); + jp2_write_ftyp(); + + jp2_write_jp2h(j2k_img); + jp2_write_dbtl(Idx_file); + + pos_iptr=cio_tell(); + cio_skip(24); // IPTR further ! + + pos_jp2c=cio_tell(); + len_jp2c=jp2_write_jp2c(J2K_file); + + pos_cidx=cio_tell(); + len_cidx=jpip_write_cidx(pos_jp2c+8,img, j2k_cp); // Correction len_jp2C --> pos_jp2c+8 + + pos_fidx=cio_tell(); + len_fidx=jpip_write_fidx(pos_jp2c, len_jp2c, pos_cidx, len_cidx); + + end_pos=cio_tell(); + cio_seek(pos_iptr); + jpip_write_iptr(pos_fidx,len_fidx); + cio_seek(end_pos); + + fwrite(index, 1, cio_tell(), dest); + free(index); + + fclose(dest); + return 1; +} + + + +typedef struct { + int id; + int states; + void (*handler)(); +} j2k_dec_mstabent_t; + +j2k_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}, + {0, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_unk} +}; + +j2k_dec_mstabent_t *j2k_dec_mstab_lookup(int id) { + j2k_dec_mstabent_t *e; + for (e=j2k_dec_mstab; e->id!=0; e++) { + if (e->id==id) { + break; + } + } + return e; +} + +LIBJ2K_API int j2k_decode(unsigned char *src, int len, j2k_image_t **image, j2k_cp_t **cp) { + if (setjmp(j2k_error)) { + if (j2k_state!=J2K_STATE_MT) { + fprintf(stderr, "WARNING: incomplete bitstream\n"); + return 0; + } + return cio_numbytes(); + } + j2k_img=(j2k_image_t*)malloc(sizeof(j2k_image_t)); + j2k_cp=(j2k_cp_t*)malloc(sizeof(j2k_cp_t)); + *image=j2k_img; + *cp=j2k_cp; + j2k_state=J2K_STATE_MHSOC; + cio_init(src, len); + for (;;) { + j2k_dec_mstabent_t *e; + int id=cio_read(2); + if (id>>8!=0xff) { + fprintf(stderr, "%.8x: expected a marker instead of %x\n", cio_tell()-2, id); + return 0; + } + e=j2k_dec_mstab_lookup(id); + if (!(j2k_state & e->states)) { + fprintf(stderr, "%.8x: unexpected marker %x\n", cio_tell()-2, id); + return 0; + } + if (e->handler) { + (*e->handler)(); + } + } + +} + +#ifdef WIN32 +#include + +BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + + +extern info_image_t img; + + +int main(int argc, char **argv) +{ + FILE *src; + int totlen; + char *j2kfile; + j2k_image_t *imgg; + j2k_cp_t *cp; + + if (argc!=3) + { + fprintf(stderr,"\nERROR in entry : index_create J2K-file Idx-file\n\n"); + return 0; + } + + src=fopen(argv[1], "rb"); + if (!src) { + fprintf(stderr,"Failed to open %s for reading !!\n",argv[1]); + return 0; + } + + // length of the codestream + fseek(src, 0, SEEK_END); + totlen=ftell(src); + fseek(src, 0, SEEK_SET); + + j2kfile=(char*)malloc(totlen); + fread(j2kfile, 1, totlen, src); + + img.marker=(info_marker_t*)malloc(32*sizeof(info_marker_t)); + img.num_marker=0; + img.marker_mul.num_COD=0; + img.marker_mul.num_COC=0; + img.marker_mul.num_RGN=0; + img.marker_mul.num_QCC=0; + img.marker_mul.num_TLM=0; + img.marker_mul.num_PLM=0; + img.marker_mul.num_COM=0; + + // decode + + if (!j2k_decode(j2kfile, totlen, &imgg, &cp)) { + fprintf(stderr, "Index_creator: failed to decode image!\n"); + return 1; + } + + free(j2kfile); + + fseek(src, 0, SEEK_SET); + img.codestream_size=totlen; + + j2k_index_JPIP(argv[2],argv[1],totlen*2>30000?totlen*2:30000); + + fclose(src); + + j2k_clean(); + return 1; +} diff --git a/indexer_JPIP/int.c b/indexer_JPIP/int.c new file mode 100644 index 00000000..b7a368f4 --- /dev/null +++ b/indexer_JPIP/int.c @@ -0,0 +1,89 @@ +/* + * 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. + */ + +/// +/// Get the minimum of two integers. +/// +int int_min(int a, int b) { + return a +/// Get the maximum of two integers. +/// +int int_max(int a, int b) { + return a>b?a:b; +} + +/// +/// Clamp an integer inside an interval. +/// +int int_clamp(int a, int min, int max) { + if (amax) return max; + return a; +} + +/// +/// Get absolute value of integer. +/// +int int_abs(int a) { + return a<0?-a:a; +} + +/// +/// Divide an integer and round upwards. +/// +int int_ceildiv(int a, int b) { + return (a+b-1)/b; +} + +/// +/// Divide an integer by a power of 2 and round upwards. +/// +int int_ceildivpow2(int a, int b) { + return (a+(1<>b; +} + +/// +/// Divide an integer by a power of 2 and round downwards. +/// +int int_floordivpow2(int a, int b) { + return a>>b; +} + +/// +/// Get logarithm of an integer and round downwards. +/// +int int_floorlog2(int a) { + int l; + for (l=0; a>1; l++) { + a>>=1; + } + return l; +} diff --git a/indexer_JPIP/int.h b/indexer_JPIP/int.h new file mode 100644 index 00000000..5a1bfd4a --- /dev/null +++ b/indexer_JPIP/int.h @@ -0,0 +1,41 @@ +/* + * 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. + */ + +#ifndef __INT_H +#define __INT_H + +int int_min(int a, int b); +int int_max(int a, int b); +int int_clamp(int a, int min, int max); +int int_abs(int a); +int int_ceildiv(int a, int b); +int int_ceildivpow2(int a, int b); +int int_floordivpow2(int a, int b); +int int_floorlog2(int a); + +#endif diff --git a/indexer_JPIP/j2k.h b/indexer_JPIP/j2k.h new file mode 100644 index 00000000..e899fae3 --- /dev/null +++ b/indexer_JPIP/j2k.h @@ -0,0 +1,222 @@ +/* + * 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. + */ + +#define VERSION "0.0.8" + +#ifdef WIN32 +#ifdef LIBJ2K_EXPORTS +#define LIBJ2K_API __declspec(dllexport) +#else +#define LIBJ2K_API __declspec(dllimport) +#endif +#else +#define LIBJ2K_API +#endif + +#ifndef __J2K_H +#define __J2K_H + +#define J2K_MAXRLVLS 33 +#define J2K_MAXBANDS (3*J2K_MAXRLVLS+1) + +#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 + +typedef struct +{ + int dx, dy; // XRsiz, YRsiz + int prec; // precision + int bpp; // deapth of image in bits + int sgnd; // signed + int *data; // image-component data +} j2k_comp_t; + +typedef struct { + int x0, y0; // XOsiz, YOsiz + int x1, y1; // Xsiz, Ysiz + int numcomps; // number of components + int index_on; // 0 = no index || 1 = index + //int PPT; + j2k_comp_t *comps; // image-components +} j2k_image_t; + +typedef struct { + int expn; // exponent + int mant; // mantissa +} j2k_stepsize_t; + +typedef struct { + int csty; // coding style + int numresolutions; // number of resolutions + int cblkw; // width of code-blocks + int cblkh; // height of code-blocks + int cblksty; // code-block coding style + int qmfbid; // discrete wavelet transform identifier + int qntsty; // quantisation style + j2k_stepsize_t stepsizes[J2K_MAXBANDS]; // stepsizes used for quantisation + int numgbits; // number of guard bits + int roishift; // Region Of Interest shift + int prcw[J2K_MAXRLVLS]; // Precinct width + int prch[J2K_MAXRLVLS]; // Precinct height +} j2k_tccp_t; + +typedef struct { + int resno0, compno0; + int layno1, resno1, compno1; + int prg; + int tile; + char progorder[4]; +} j2k_poc_t; + +typedef struct { + int csty; // coding style + int prg; // progression order + int numlayers; // number of layers + int mct; // multi-component transform identifier + int rates[100]; // rates of layers + int numpocs; // number of progression order changes + j2k_poc_t pocs[32]; // progression order changes + j2k_tccp_t *tccps; // tile-component coding parameters +} j2k_tcp_t; + +typedef struct { + int tx0, ty0; // XTOsiz, YTOsiz + int tdx, tdy; // XTsiz, YTsiz + int tw, th; + j2k_tcp_t *tcps; // tile coding parameters +} j2k_cp_t; + +typedef struct { + int len; + int len_header; + int offset; +} info_layer_t; + +typedef struct { + info_layer_t *layer; +} info_prec_t; + +typedef struct { + info_prec_t *prec; +} info_reso_t; + +typedef struct { + info_reso_t *reso; +} info_compo_t; + +typedef struct { + int num_tile; // Number of Tile + int start_pos; // Start position + int end_header; // End position of the header + int end_pos; // End position + int pw, ph; // number of precinct by tile + int num_packet; // number of packet in the tile + info_compo_t *compo; // component [packet] +} info_tile_t; // index struct + +typedef struct { + int type; // type of marker [SIZ, QCD, POC, PPM, CRG] appearing only once + int start_pos; // Start position of the marker + int len; // Length of the marker +} info_marker_t; // index struct + +typedef struct{ + info_marker_t *COD; + int num_COD; + info_marker_t *COC; + int num_COC; + info_marker_t *RGN; + int num_RGN; + info_marker_t *QCC; + int num_QCC; + info_marker_t *TLM; + int num_TLM; + info_marker_t *PLM; + int num_PLM; + info_marker_t *PPM; + int num_PPM; + info_marker_t *COM; + int num_COM; +} info_marker_mul_t; // index struct + +typedef struct { + int index_on; + int num; // numero of packet + int index_write; // writing the packet inthe index with t2_encode_packets + int Im_w, Im_h; // Image width and Height + int Prog; // progression order + int Tile_x, Tile_y; // Number of Tile in X and Y + int tw, th; + int Comp; // Component numbers + int Layer; // number of layer + int Decomposition; // number of decomposition + int pw, ph; // nombre precinct in X and Y + int pdx, pdy; // size of precinct in X and Y + int Main_head_end; // Main header position + int codestream_size; // codestream's size + info_tile_t *tile; // information concerning tiles inside image + info_marker_t *marker; // information concerning markers inside image [only one apparition] + info_marker_mul_t marker_mul; // information concerning markers inside image [multiple apparition] + int num_marker; // number of marker + int num_packet_max; // MAximum number of packet +} info_image_t; // index struct + + + +/* + * Encode an image into a JPEG-2000 codestream + * i: image to encode + * cp: coding parameters + * dest: destination buffer + * len: length of destination buffer + * index : index file name + */ +LIBJ2K_API int j2k_encode(j2k_image_t *i, j2k_cp_t *cp,char *outfile, int len,char *index); + +//LIBJ2K_API int j2k_encode(j2k_image_t *i, j2k_cp_t *cp,unsigned char *dest, int len); +/* + * Decode an image from a JPEG-2000 codestream + * src: source buffer + * len: length of source buffer + * i: decode image + * cp: coding parameters that were used to encode the image + */ +LIBJ2K_API int j2k_decode(unsigned char *src, int len, j2k_image_t **i, j2k_cp_t **cp); + +#endif diff --git a/indexer_JPIP/jp2.c b/indexer_JPIP/jp2.c new file mode 100644 index 00000000..5588c868 --- /dev/null +++ b/indexer_JPIP/jp2.c @@ -0,0 +1,259 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "j2k.h" +#include "cio.h" +#include "tcd.h" +#include "int.h" + +#define JPIP_JPIP 0x6a706970 + +#define JP2_JP 0x6a502020 +#define JP2_FTYP 0x66747970 +#define JP2_JP2H 0x6a703268 +#define JP2_IHDR 0x69686472 +#define JP2_COLR 0x636f6c72 +#define JP2_JP2C 0x6a703263 +#define JP2_URL 0x75726c20 +#define JP2_DBTL 0x6474626c +#define JP2_BPCC 0x62706363 +#define JP2 0x6a703220 + + +void jp2_write_url(char *Idx_file) +{ + int len, lenp, i; + char str[256]; + + sprintf(str, "%s", Idx_file); + lenp=cio_tell(); + cio_skip(4); + cio_write(JP2_URL, 4); // DBTL + cio_write(0,1); // VERS + cio_write(0,3); // FLAG + + for (i=0; iy1-j2k_img->x0,4); // HEIGHT + cio_write(j2k_img->x1-j2k_img->x0,4); // WIDTH + cio_write(j2k_img->numcomps,2); // NC + + depth_0=j2k_img->comps[0].prec-1; + sign=j2k_img->comps[0].sgnd; + + for(i=1;inumcomps;i++) + { + depth=j2k_img->comps[i].prec-1; + sign=j2k_img->comps[i].sgnd; + if(depth_0!=depth) BPC_ok=0; + } + + if (BPC_ok) + cio_write(depth_0+(sign<<7),1); + else + cio_write(255,1); + + cio_write(7,1); // C : Always 7 + cio_write(1,1); // UnkC, colorspace unknow + cio_write(0,1); // IPR, no intellectual property + + len=cio_tell()-lenp; + cio_seek(lenp); + cio_write(len,4); // L + cio_seek(lenp+len); + + return BPC_ok; +} + +void jp2_write_bpcc(j2k_image_t *j2k_img) +{ + int len, lenp, i; + + lenp=cio_tell(); + cio_skip(4); + cio_write(JP2_BPCC, 4); // BPCC + + for(i=0;inumcomps;i++) + cio_write(j2k_img->comps[i].prec-1+(j2k_img->comps[i].sgnd<<7),1); + + len=cio_tell()-lenp; + cio_seek(lenp); + cio_write(len,4); // L + cio_seek(lenp+len); +} + +void jp2_write_colr(int BPC_ok, j2k_image_t *j2k_img) +{ + int len, lenp, meth; + + lenp=cio_tell(); + cio_skip(4); + cio_write(JP2_COLR, 4); // COLR + + if ((j2k_img->numcomps==1 || j2k_img->numcomps==3) && (BPC_ok && j2k_img->comps[0].prec==8)) + meth=1; + else + meth=2; + + cio_write(meth,1); // METH + cio_write(0,1); // PREC + cio_write(0,1); // APPROX + + if (meth==1) + cio_write(j2k_img->numcomps>1?16:17,4); // EnumCS + + if (meth==2) + cio_write(0,1); // PROFILE (??) + + len=cio_tell()-lenp; + cio_seek(lenp); + cio_write(len,4); // L + cio_seek(lenp+len); +} + +void jp2_write_jp2h(j2k_image_t *j2k_img) +{ + int len, lenp, BPC_ok; + + lenp=cio_tell(); + cio_skip(4); + cio_write(JP2_JP2H, 4); // JP2H + + BPC_ok=jp2_write_ihdr(j2k_img); + + if (!BPC_ok) + jp2_write_bpcc(j2k_img); + jp2_write_colr(BPC_ok, j2k_img); + + len=cio_tell()-lenp; + cio_seek(lenp); + cio_write(len,4); // L + cio_seek(lenp+len); +} + +void jp2_write_ftyp() +{ + int len, lenp; + + lenp=cio_tell(); + cio_skip(4); + cio_write(JP2_FTYP, 4); // FTYP + + cio_write(JP2,4); // BR + cio_write(0,4); // MinV + cio_write(JP2,4); // CL0 : JP2 + cio_write(JPIP_JPIP,4); // CL1 : JPIP + + len=cio_tell()-lenp; + cio_seek(lenp); + cio_write(len,4); // L + cio_seek(lenp+len); +} + +int jp2_write_jp2c(char *J2K_file) +{ + int len, lenp, totlen, i; + FILE *src; + char *j2kfile; + + lenp=cio_tell(); + cio_skip(4); + cio_write(JP2_JP2C, 4); // JP2C + + src=fopen(J2K_file, "rb"); + fseek(src, 0, SEEK_END); + totlen=ftell(src); + fseek(src, 0, SEEK_SET); + + j2kfile=(char*)malloc(totlen); + fread(j2kfile, 1, totlen, src); + fclose(src); + + for (i=0;i +#include +#include +#include +#include +#include + +#include "j2k.h" +#include "cio.h" +#include "tcd.h" +#include "int.h" + +#define JPIP_CIDX 0x63696478 +#define JPIP_CPTR 0x63707472 +#define JPIP_MANF 0x6d616e66 +#define JPIP_FAIX 0x66616978 +#define JPIP_MHIX 0x6d686978 +#define JPIP_TPIX 0x74706978 +#define JPIP_THIX 0x74686978 +#define JPIP_PPIX 0x70706978 +#define JPIP_PHIX 0x70686978 +#define JPIP_FIDX 0x66696478 +#define JPIP_FPTR 0x66707472 +#define JPIP_PRXY 0x70727879 +#define JPIP_IPTR 0x69707472 + +#define JP2C 0x6a703263 + +static info_marker_t marker_jpip[32], marker_local_jpip[32]; // SIZE to precise ! +static int num_marker_jpip, num_marker_local_jpip; + +void jpip_write_cptr(int offset, info_image_t img) // Codestream finder box (box) +{ + int len, lenp; + + lenp=cio_tell(); + cio_skip(4); // L [at the end] + cio_write(JPIP_CPTR,4); // T + cio_write(0,2); // DR A PRECISER !! + cio_write(0,2); // CONT + cio_write(offset,8); // COFF A PRECISER !! + cio_write(img.codestream_size,8); // CLEN + len=cio_tell()-lenp; + cio_seek(lenp); + cio_write(len, 4); // L + cio_seek(lenp+len); +} + +void jpip_write_manf(int second, int v, info_marker_t *marker) // Manifest box (box) +{ + int len, lenp, i; + lenp=cio_tell(); + cio_skip(4); // L [at the end] + cio_write(JPIP_MANF,4); // T + + if (second) // Write only during the second pass + { + for(i=0;i=0;i--) // COD + { + cio_write(img.marker_mul.COD[i].type,2); + cio_write(i,2); + cio_write(img.marker_mul.COD[i].start_pos,8); + cio_write(img.marker_mul.COD[i].len,2); + } + + for(i=img.marker_mul.num_COC-1;i>=0;i--) // COC + { + cio_write(img.marker_mul.COC[i].type,2); + cio_write(i,2); + cio_write(img.marker_mul.COC[i].start_pos,8); + cio_write(img.marker_mul.COC[i].len,2); + } + + for(i=img.marker_mul.num_RGN-1;i>=0;i--) // RGN + { + cio_write(img.marker_mul.RGN[i].type,2); + cio_write(i,2); + cio_write(img.marker_mul.RGN[i].start_pos,8); + cio_write(img.marker_mul.RGN[i].len,2); + } + + for(i=img.marker_mul.num_QCC-1;i>=0;i--) // QCC + { + cio_write(img.marker_mul.QCC[i].type,2); + cio_write(i,2); + cio_write(img.marker_mul.QCC[i].start_pos,8); + cio_write(img.marker_mul.QCC[i].len,2); + } + + for(i=img.marker_mul.num_TLM-1;i>=0;i--) // TLM + { + cio_write(img.marker_mul.TLM[i].type,2); + cio_write(i,2); + cio_write(img.marker_mul.TLM[i].start_pos,8); + cio_write(img.marker_mul.TLM[i].len,2); + } + + for(i=img.marker_mul.num_PLM-1;i>=0;i--) // PLM + { + cio_write(img.marker_mul.PLM[i].type,2); + cio_write(i,2); + cio_write(img.marker_mul.PLM[i].start_pos,8); + cio_write(img.marker_mul.PLM[i].len,2); + } + + for(i=img.marker_mul.num_COM-1;i>=0;i--) // COM + { + cio_write(img.marker_mul.COM[i].type,2); + cio_write(i,2); + cio_write(img.marker_mul.COM[i].start_pos,8); + cio_write(img.marker_mul.COM[i].len,2); + } + + len=cio_tell()-lenp; + cio_seek(lenp); + cio_write(len, 4); // L + cio_seek(lenp+len); + + return len; +} + +int jpip_write_faix(int v, int compno, info_image_t img, j2k_cp_t *j2k_cp) // Fragment array Index box +{ + int len, lenp, i; + int version = 0; + int tileno, resno, precno, layno, num_packet=0; + + lenp=cio_tell(); + cio_skip(4); // L [at the end] + cio_write(JPIP_FAIX, 4); // MHIX + cio_write(version,1); // Version 0 = 4 bytes + + switch(v) + { + case 0: // TPIX + cio_write(1,version?8:4); // NMAX + cio_write(img.tw*img.th,version?8:4); // M + for (i=0;icompo[compno]; + int correction; + if(j2k_cp->tcps[tileno].csty&J2K_CP_CSTY_EPH) + correction=3; + else + correction=1; + for(resno=0;resnoreso[resno]; + for (precno=0;precnoprec[precno]; + for(layno=0;laynolayer[layno]; + cio_write(layer_Idx->offset,version?8:4); + cio_write((layer_Idx->len_header-correction)?0:layer_Idx->len,version?8:4); + num_packet++; + } + } + } + } + // PADDING + while (num_packetcompo[compno]; + int correction; + if(j2k_cp->tcps[tileno].csty&J2K_CP_CSTY_EPH) + correction=3; + else + correction=1; + for(resno=0;resnoreso[resno]; + for (precno=0;precnoprec[precno]; + for(layno=0;laynolayer[layno]; + cio_write(layer_Idx->offset,version?8:4); + cio_write((layer_Idx->len_header-correction)?0:layer_Idx->len_header,version?8:4); + num_packet++; + } + } + } + } + // PADDING + while (num_packet +#include + + +/// +/// Create a packet iterator. +/// +pi_iterator_t *pi_create(j2k_image_t *img, j2k_cp_t *cp, int tileno) { + int p, q; + int compno, resno,pino, layno, precno; + int maxres=0; + pi_iterator_t *pi; + j2k_tcp_t *tcp; + j2k_tccp_t *tccp; + + tcp=&cp->tcps[tileno]; + pi=(pi_iterator_t*)malloc((tcp->numpocs+1)*sizeof(pi_iterator_t)); + + for (pino=0;pinonumpocs+1;pino++) // change + { + p=tileno%cp->tw; + q=tileno/cp->tw; + + pi[pino].tx0=int_max(cp->tx0+p*cp->tdx, img->x0); + pi[pino].ty0=int_max(cp->ty0+q*cp->tdy, img->y0); + pi[pino].tx1=int_min(cp->tx0+(p+1)*cp->tdx, img->x1); + pi[pino].ty1=int_min(cp->ty0+(q+1)*cp->tdy, img->y1); + pi[pino].numcomps=img->numcomps; + pi[pino].comps=(pi_comp_t*)malloc(img->numcomps*sizeof(pi_comp_t)); + + for (compno=0; compnonumcomps; compno++) + { + int tcx0, tcy0, tcx1, tcy1; + pi_comp_t *comp=&pi[pino].comps[compno]; + + tccp=&tcp->tccps[compno]; + comp->dx=img->comps[compno].dx; + comp->dy=img->comps[compno].dy; + comp->numresolutions=tccp->numresolutions; + comp->resolutions=(pi_resolution_t*)malloc(comp->numresolutions*sizeof(pi_resolution_t)); + tcx0=int_ceildiv(pi->tx0, comp->dx); + tcy0=int_ceildiv(pi->ty0, comp->dy); + tcx1=int_ceildiv(pi->tx1, comp->dx); + tcy1=int_ceildiv(pi->ty1, comp->dy); + if (comp->numresolutions>maxres) { + maxres=comp->numresolutions; + } + for (resno=0; resnonumresolutions; resno++) + { + int levelno; + int rx0, ry0, rx1, ry1; + int px0, py0, px1, py1; + pi_resolution_t *res=&comp->resolutions[resno]; + if (tccp->csty&J2K_CCP_CSTY_PRT) { + res->pdx=tccp->prcw[resno]; + res->pdy=tccp->prch[resno]; + } else { + res->pdx=15; + res->pdy=15; + } + levelno=comp->numresolutions-1-resno; + rx0=int_ceildivpow2(tcx0, levelno); + ry0=int_ceildivpow2(tcy0, levelno); + rx1=int_ceildivpow2(tcx1, levelno); + ry1=int_ceildivpow2(tcy1, levelno); + px0=int_floordivpow2(rx0, res->pdx)<pdx; + py0=int_floordivpow2(ry0, res->pdy)<pdy; + px1=int_ceildivpow2(rx1, res->pdx)<pdx; + py1=int_ceildivpow2(ry1, res->pdy)<pdy; + res->pw=(px1-px0)>>res->pdx; + res->ph=(py1-py0)>>res->pdy; + } + } + + for (layno=0; layno<10; layno++) + { + for (resno=0; resno<10; resno++) + { + for (compno=0; compno<3; compno++) + { + for (precno=0; precno<99; precno++) + { + pi[pino].include[layno][resno][compno][precno]=0; + } + } + } + } + + if (pino==tcp->numpocs) + { + pi[pino].first=1; + pi[pino].poc.resno0=0; + pi[pino].poc.compno0=0; + pi[pino].poc.layno1=tcp->numlayers; + pi[pino].poc.resno1=maxres; + pi[pino].poc.compno1=img->numcomps; + pi[pino].poc.prg=tcp->prg; + } else + { + pi[pino].first=1; + pi[pino].poc.resno0=tcp->pocs[pino].resno0; + pi[pino].poc.compno0=tcp->pocs[pino].compno0; + pi[pino].poc.layno1=tcp->pocs[pino].layno1; + pi[pino].poc.resno1=tcp->pocs[pino].resno1; + pi[pino].poc.compno1=tcp->pocs[pino].compno1; + pi[pino].poc.prg=tcp->pocs[pino].prg; + } + } + return pi; +} + +/// +/// Get next packet in layer=resolution-component-precinct order. +/// +int pi_next_lrcp(pi_iterator_t *pi) { + pi_comp_t *comp; + pi_resolution_t *res; + + if (!pi->first) + { + comp=&pi->comps[pi->compno]; + res=&comp->resolutions[pi->resno]; + goto skip; + } else { + pi->first=0; + } + for (pi->layno=0; pi->laynopoc.layno1; pi->layno++) + { + for (pi->resno=pi->poc.resno0; pi->resnopoc.resno1; pi->resno++) + { + for (pi->compno=pi->poc.compno0; pi->compnopoc.compno1; pi->compno++) + { + + comp=&pi->comps[pi->compno]; + if (pi->resno>=comp->numresolutions) + { + + continue; + } + res=&comp->resolutions[pi->resno]; + + for (pi->precno=0; pi->precnopw*res->ph; pi->precno++) + { + + if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno]) + { + pi->include[pi->layno][pi->resno][pi->compno][pi->precno]=1; + return 1; + } + skip: ; + } + } + } + } + return 0; +} + +/// +/// Get next packet in resolution-layer-component-precinct order. +/// +int pi_next_rlcp(pi_iterator_t *pi) { + pi_comp_t *comp; + pi_resolution_t *res; + if (!pi->first) { + comp=&pi->comps[pi->compno]; + res=&comp->resolutions[pi->resno]; + goto skip; + } else { + pi->first=0; + } + for (pi->resno=pi->poc.resno0; pi->resnopoc.resno1; pi->resno++) { + for (pi->layno=0; pi->laynopoc.layno1; pi->layno++) { + for (pi->compno=pi->poc.compno0; pi->compnopoc.compno1; pi->compno++) { + comp=&pi->comps[pi->compno]; + if (pi->resno>=comp->numresolutions) { + continue; + } + res=&comp->resolutions[pi->resno]; + for (pi->precno=0; pi->precnopw*res->ph; pi->precno++) { + if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno]) + { + pi->include[pi->layno][pi->resno][pi->compno][pi->precno]=1; + return 1; + } + skip: ; + } + } + } + } + return 0; +} + +/// +/// Get next packet in resolution-precinct-component-layer order. +/// +int pi_next_rpcl(pi_iterator_t *pi) { + pi_comp_t *comp; + pi_resolution_t *res; + if (!pi->first) { + goto skip; + } else { + int compno, resno; + pi->first=0; + pi->dx=0; + pi->dy=0; + for (compno=0; compnonumcomps; compno++) { + comp=&pi->comps[compno]; + for (resno=0; resnonumresolutions; resno++) { + int dx, dy; + res=&comp->resolutions[resno]; + dx=comp->dx*(1<<(res->pdx+comp->numresolutions-1-resno)); + dy=comp->dy*(1<<(res->pdy+comp->numresolutions-1-resno)); + pi->dx=!pi->dx?dx:int_min(pi->dx, dx); + pi->dy=!pi->dy?dy:int_min(pi->dy, dy); + } + } + } + for (pi->resno=pi->poc.resno0; pi->resnopoc.resno1; pi->resno++) { + for (pi->y=pi->ty0; pi->yty1; pi->y+=pi->dy-(pi->y%pi->dy)) { + for (pi->x=pi->tx0; pi->xtx1; pi->x+=pi->dx-(pi->x%pi->dx)) { + for (pi->compno=pi->poc.compno0; pi->compnopoc.compno1; pi->compno++) { + int levelno; + int trx0, try0; + int rpx, rpy; + int prci, prcj; + comp=&pi->comps[pi->compno]; + if (pi->resno>=comp->numresolutions) { + continue; + } + res=&comp->resolutions[pi->resno]; + levelno=comp->numresolutions-1-pi->resno; + trx0=int_ceildiv(pi->tx0, comp->dx<ty0, comp->dy<pdx+levelno; + rpy=res->pdy+levelno; + if (!(pi->x%(comp->dx<x==pi->tx0&&(trx0<y%(comp->dy<y==pi->ty0&&(try0<x, comp->dx<pdx)-int_floordivpow2(trx0, res->pdx); + prcj=int_floordivpow2(int_ceildiv(pi->y, comp->dy<pdy)-int_floordivpow2(try0, res->pdy); + pi->precno=prci+prcj*res->pw; + for (pi->layno=0; pi->laynopoc.layno1; pi->layno++) { + if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno]) + { + pi->include[pi->layno][pi->resno][pi->compno][pi->precno]=1; + return 1; + } + skip: ; + } + } + } + } + } + return 0; +} + +/// +/// Get next packet in precinct-component-resolution-layer order. +/// +int pi_next_pcrl(pi_iterator_t *pi) { + pi_comp_t *comp; + pi_resolution_t *res; + if (!pi->first) { + comp=&pi->comps[pi->compno]; + goto skip; + } else { + int compno, resno; + pi->first=0; + pi->dx=0; + pi->dy=0; + for (compno=0; compnonumcomps; compno++) { + comp=&pi->comps[compno]; + for (resno=0; resnonumresolutions; resno++) { + int dx, dy; + res=&comp->resolutions[resno]; + dx=comp->dx*(1<<(res->pdx+comp->numresolutions-1-resno)); + dy=comp->dy*(1<<(res->pdy+comp->numresolutions-1-resno)); + pi->dx=!pi->dx?dx:int_min(pi->dx, dx); + pi->dy=!pi->dy?dy:int_min(pi->dy, dy); + } + } + } + for (pi->y=pi->ty0; pi->yty1; pi->y+=pi->dy-(pi->y%pi->dy)) { + for (pi->x=pi->tx0; pi->xtx1; pi->x+=pi->dx-(pi->x%pi->dx)) { + for (pi->compno=pi->poc.compno0; pi->compnopoc.compno1; pi->compno++) { + comp=&pi->comps[pi->compno]; + for (pi->resno=pi->poc.resno0; pi->resnopoc.resno1, comp->numresolutions); pi->resno++) { + int levelno; + int trx0, try0; + int rpx, rpy; + int prci, prcj; + res=&comp->resolutions[pi->resno]; + levelno=comp->numresolutions-1-pi->resno; + trx0=int_ceildiv(pi->tx0, comp->dx<ty0, comp->dy<pdx+levelno; + rpy=res->pdy+levelno; + if (!(pi->x%(comp->dx<x==pi->tx0&&(trx0<y%(comp->dy<y==pi->ty0&&(try0<x, comp->dx<pdx)-int_floordivpow2(trx0, res->pdx); + prcj=int_floordivpow2(int_ceildiv(pi->y, comp->dy<pdy)-int_floordivpow2(try0, res->pdy); + pi->precno=prci+prcj*res->pw; + for (pi->layno=0; pi->laynopoc.layno1; pi->layno++) { + if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno]) + { + pi->include[pi->layno][pi->resno][pi->compno][pi->precno]=1; + return 1; + } + skip: ; + } + } + } + } + } + return 0; +} + +/// +/// Get next packet in component-precinct-resolution-layer order. +/// +int pi_next_cprl(pi_iterator_t *pi) { + pi_comp_t *comp; + pi_resolution_t *res; + if (!pi->first) { + comp=&pi->comps[pi->compno]; + goto skip; + } else { + pi->first=0; + } + for (pi->compno=pi->poc.compno0; pi->compnopoc.compno1; pi->compno++) { + int resno; + comp=&pi->comps[pi->compno]; + pi->dx=0; + pi->dy=0; + for (resno=0; resnonumresolutions; resno++) { + int dx, dy; + res=&comp->resolutions[resno]; + dx=comp->dx*(1<<(res->pdx+comp->numresolutions-1-resno)); + dy=comp->dy*(1<<(res->pdy+comp->numresolutions-1-resno)); + pi->dx=!pi->dx?dx:int_min(pi->dx, dx); + pi->dy=!pi->dy?dy:int_min(pi->dy, dy); + } + for (pi->y=pi->ty0; pi->yty1; pi->y+=pi->dy-(pi->y%pi->dy)) { + for (pi->x=pi->tx0; pi->xtx1; pi->x+=pi->dx-(pi->x%pi->dx)) { + for (pi->resno=pi->poc.resno0; pi->resnopoc.resno1, comp->numresolutions); pi->resno++) { + int levelno; + int trx0, try0; + int rpx, rpy; + int prci, prcj; + res=&comp->resolutions[pi->resno]; + levelno=comp->numresolutions-1-pi->resno; + trx0=int_ceildiv(pi->tx0, comp->dx<ty0, comp->dy<pdx+levelno; + rpy=res->pdy+levelno; + if (!(pi->x%(comp->dx<x==pi->tx0&&(trx0<y%(comp->dy<y==pi->ty0&&(try0<x, comp->dx<pdx)-int_floordivpow2(trx0, res->pdx); + prcj=int_floordivpow2(int_ceildiv(pi->y, comp->dy<pdy)-int_floordivpow2(try0, res->pdy); + pi->precno=prci+prcj*res->pw; + for (pi->layno=0; pi->laynopoc.layno1; pi->layno++) { + if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno]) + { + pi->include[pi->layno][pi->resno][pi->compno][pi->precno]=1; + return 1; + } + skip: ; + } + } + } + } + } + return 0; +} + +/// +/// Get next packet. +/// +int pi_next(pi_iterator_t *pi) { + switch (pi->poc.prg) { + case 0: + return pi_next_lrcp(pi); + case 1: + return pi_next_rlcp(pi); + case 2: + return pi_next_rpcl(pi); + case 3: + return pi_next_pcrl(pi); + case 4: + return pi_next_cprl(pi); + } + return 0; +} diff --git a/indexer_JPIP/pi.h b/indexer_JPIP/pi.h new file mode 100644 index 00000000..fbe822d2 --- /dev/null +++ b/indexer_JPIP/pi.h @@ -0,0 +1,73 @@ +/* + * 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. + */ + +#ifndef __PI_H +#define __PI_H + +#include "j2k.h" +#include "tcd.h" + +typedef struct { + int pdx, pdy; + int pw, ph; +} pi_resolution_t; + +typedef struct { + int dx, dy; + int numresolutions; + pi_resolution_t *resolutions; +} pi_comp_t; + +typedef struct { + int include[10][10][3][99]; + int compno, resno, precno, layno; // component, resolution, precinct and layer that indentify the packet + int first; + j2k_poc_t poc; + int numcomps; + pi_comp_t *comps; + int tx0, ty0, tx1, ty1; + int x, y, dx, dy; +} pi_iterator_t; // packet iterator + +/* + * Create a packet iterator + * img: raw image for which the packets will be listed + * cp: coding paremeters + * tileno: number that identifies the tile for which to list the packets + * return value: returns a packet iterator that points to the first packet of the tile + */ +pi_iterator_t *pi_create(j2k_image_t *img, j2k_cp_t *cp, int tileno); + +/* + * Modify the packet iterator to point to the next packet + * pi: packet iterator to modify + * return value: returns 0 if pi pointed to the last packet or else returns 1 + */ +int pi_next(pi_iterator_t *pi); + +#endif diff --git a/indexer_JPIP/t2.c b/indexer_JPIP/t2.c new file mode 100644 index 00000000..466b4095 --- /dev/null +++ b/indexer_JPIP/t2.c @@ -0,0 +1,254 @@ +/* + * 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 "t2.h" +#include "tcd.h" +#include "bio.h" +#include "j2k.h" +#include "pi.h" +#include "tgt.h" +#include "int.h" +#include "cio.h" +#include +#include +#include +#include + +#define RESTART 0x04 + +extern jmp_buf j2k_error; + +int t2_getcommacode() { + int n; + for (n=0; bio_read(1); n++) {} + return n; +} + +int t2_getnumpasses() +{ + int n; + if (!bio_read(1)) return 1; + if (!bio_read(1)) return 2; + if ((n=bio_read(2))!=3) return 3+n; + if ((n=bio_read(5))!=31) return 6+n; + return 37+bio_read(7); +} + +void t2_init_seg(tcd_seg_t *seg, int cblksty) { + seg->numpasses=0; + seg->len=0; + seg->maxpasses=cblksty&J2K_CCP_CBLKSTY_TERMALL?1:100; +} + +int t2_decode_packet(unsigned char *src, int len, tcd_tile_t *tile, j2k_tcp_t *tcp, int compno, int resno, int precno, int layno, info_layer_t *layer_Idx) { + int bandno, cblkno; + tcd_tilecomp_t *tilec=&tile->comps[compno]; + tcd_resolution_t *res=&tilec->resolutions[resno]; + unsigned char *c=src; + unsigned char *d=c; + int e; + int present; + + if (layno==0) { + for (bandno=0; bandnonumbands; bandno++) { + tcd_band_t *band=&res->bands[bandno]; + tcd_precinct_t *prc=&band->precincts[precno]; + tgt_reset(prc->incltree); + tgt_reset(prc->imsbtree); + for (cblkno=0; cblknocw*prc->ch; cblkno++) { + tcd_cblk_t *cblk=&prc->cblks[cblkno]; + cblk->numsegs=0; + } + } + } + + if (tcp->csty&J2K_CP_CSTY_SOP) { + c+=6; + } + bio_init_dec(c, src+len-c); + present=bio_read(1); + if (!present) { + bio_inalign(); + c+=bio_numbytes(); + return c-src; + } + for (bandno=0; bandnonumbands; bandno++) { + tcd_band_t *band=&res->bands[bandno]; + tcd_precinct_t *prc=&band->precincts[precno]; + for (cblkno=0; cblknocw*prc->ch; cblkno++) { + int included, increment, n; + tcd_cblk_t *cblk=&prc->cblks[cblkno]; + tcd_seg_t *seg; + if (!cblk->numsegs) { + included=tgt_decode(prc->incltree, cblkno, layno+1); + } else { + included=bio_read(1); + } + if (!included) { + cblk->numnewpasses=0; + continue; + } + if (!cblk->numsegs) { + int i, numimsbs; + for (i=0; !tgt_decode(prc->imsbtree, cblkno, i); i++) {} + numimsbs=i-1; + cblk->numbps=band->numbps-numimsbs; + cblk->numlenbits=3; + } + cblk->numnewpasses=t2_getnumpasses(); + increment=t2_getcommacode(); + cblk->numlenbits+=increment; + if (!cblk->numsegs) { + seg=&cblk->segs[0]; + t2_init_seg(seg, tcp->tccps[compno].cblksty); + } else { + seg=&cblk->segs[cblk->numsegs-1]; + if (seg->numpasses==seg->maxpasses) { + t2_init_seg(++seg, tcp->tccps[compno].cblksty); + } + } + n=cblk->numnewpasses; + do { + seg->numnewpasses=int_min(seg->maxpasses-seg->numpasses, n); + seg->newlen=bio_read(cblk->numlenbits+int_floorlog2(seg->numnewpasses)); + n-=seg->numnewpasses; + if (n>0) { + t2_init_seg(++seg, tcp->tccps[compno].cblksty); + } + } while (n>0); + } + } + if(bio_inalign()) return -999; + c+=bio_numbytes(); + if (tcp->csty&J2K_CP_CSTY_EPH) { + c+=2; + } + + // INDEX + layer_Idx->len_header=c-d; + if (tcp->csty&J2K_CP_CSTY_SOP) + layer_Idx->len_header-=6; + // \INDEX --> END OF HEADER !! + + for (bandno=0; bandnonumbands; bandno++) { + tcd_band_t *band=&res->bands[bandno]; + tcd_precinct_t *prc=&band->precincts[precno]; + for (cblkno=0; cblknocw*prc->ch; cblkno++) { + tcd_cblk_t *cblk=&prc->cblks[cblkno]; + tcd_seg_t *seg; + if (!cblk->numnewpasses) continue; + if (!cblk->numsegs) { + seg=&cblk->segs[cblk->numsegs++]; + cblk->len=0; + } else { + seg=&cblk->segs[cblk->numsegs-1]; + if (seg->numpasses==seg->maxpasses) { + seg++; + cblk->numsegs++; + } + } + do { + if (c+seg->newlen>src+len) return -999; + memcpy(cblk->data+cblk->len, c, seg->newlen); + if (seg->numpasses==0) { + seg->data=cblk->data+cblk->len; + } + c+=seg->newlen; + cblk->len+=seg->newlen; + seg->len+=seg->newlen; + seg->numpasses+=seg->numnewpasses; + cblk->numnewpasses-=seg->numnewpasses; + if (cblk->numnewpasses>0) { + seg++; + cblk->numsegs++; + } + } while (cblk->numnewpasses>0); + } + } + // + e=c-d; + layer_Idx->len=e; + // + + return c-src; +} + +int t2_decode_packets(unsigned char *src, int len, j2k_image_t *img, j2k_cp_t *cp, int tileno, tcd_tile_t *tile, info_image_t *imgg) { + unsigned char *c=src; + pi_iterator_t *pi; + int pino, compno,e; + int position=imgg->tile[tileno].end_header+1; + info_tile_t *tile_Idx; + info_compo_t *compo_Idx; + info_reso_t *reso_Idx; + info_prec_t *prec_Idx; + info_layer_t *layer_Idx; + + tile_Idx=&imgg->tile[tileno]; + tile_Idx->num_packet=0; + pi=pi_create(img, cp, tileno); + + for (pino=0; pino<=cp->tcps[tileno].numpocs;pino++) + { + + while (pi_next(&pi[pino])) { + compo_Idx=&tile_Idx->compo[pi[pino].compno]; + reso_Idx=&compo_Idx->reso[pi[pino].resno]; + prec_Idx=&reso_Idx->prec[pi[pino].precno]; + layer_Idx=&prec_Idx->layer[pi[pino].layno]; + + layer_Idx->offset=position; + + e=t2_decode_packet(c, src+len-c, tile, &cp->tcps[tileno], pi[pino].compno, pi[pino].resno, pi[pino].precno, pi[pino].layno,layer_Idx); + + if (e==-999) + { + break; + } else + c+=e; + position+=e; + tile_Idx->num_packet++; + } + + // FREE space memory taken by pi + for (compno=0; compnonum_packet_max=int_max(imgg->num_packet_max,tile_Idx->num_packet); + return c-src; + } +} diff --git a/indexer_JPIP/t2.h b/indexer_JPIP/t2.h new file mode 100644 index 00000000..f4951079 --- /dev/null +++ b/indexer_JPIP/t2.h @@ -0,0 +1,46 @@ +/* + * 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. + */ + +#ifndef __T2_H +#define __T2_H + +#include "tcd.h" +#include "j2k.h" + +/* + * Decode the packets of a tile from a source buffer + * src: the source buffer + * len: length of the source buffer + * img: destination image + * cp: image coding parameters + * tileno: number that identifies the tile for which to decode the packets + * tile: tile for which to decode the packets + */ +int t2_decode_packets(unsigned char *src, int len, j2k_image_t *img, j2k_cp_t *cp, int tileno, tcd_tile_t *tile, info_image_t *imgg); + +#endif 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 +#include +#include +#include +#include +#include +#include + +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; tilenotw*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; compnonumcomps; 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; resnonumresolutions; 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)<y0, pdy)<x1, pdx)<y1, pdy)<pw=(brprcxend-tlprcxstart)>>pdx; + res->ph=(brprcyend-tlprcystart)>>pdy; + + // + 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_Idxpw*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<pdy=1< + + 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; bandnonumbands; 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<y0=int_ceildivpow2(tilec->y0-(1<x1=int_ceildivpow2(tilec->x1-(1<y1=int_ceildivpow2(tilec->y1-(1<precincts=(tcd_precinct_t*)malloc(res->pw*res->ph*sizeof(tcd_precinct_t)); + + for (precno=0; precnopw*res->ph; precno++) { + int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; + int cbgxstart=tlcbgxstart+(precno%res->pw)*(1<pw)*(1<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)<y0, cblkheightexpn)<x1, cblkwidthexpn)<y1, cblkheightexpn)<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; cblknocw*prc->ch; cblkno++) { + int cblkxstart=tlcblkxstart+(cblkno%prc->cw)*(1<cw)*(1<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; tilenotcps[curtileno]; + tcd_tile_t *tile=&tcd_image.tiles[tileno]; + for (compno=0; compnonumcomps; compno++) + { + tcd_tilecomp_t *tilec=&tile->comps[compno]; + for (resno=0; resnonumresolutions; resno++) + { + tcd_resolution_t *res=&tilec->resolutions[resno]; + for (bandno=0; bandnonumbands; bandno++) + { + tcd_band_t *band=&res->bands[bandno]; + for (precno=0; precnopw*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; +} diff --git a/indexer_JPIP/tcd.h b/indexer_JPIP/tcd.h new file mode 100644 index 00000000..9a31723b --- /dev/null +++ b/indexer_JPIP/tcd.h @@ -0,0 +1,137 @@ +/* + * 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. + */ + +#ifndef __TCD_H +#define __TCD_H + +#include "j2k.h" +#include "tgt.h" + +typedef struct { + int numpasses; + int len; + unsigned char *data; + int maxpasses; + int numnewpasses; + int newlen; +} tcd_seg_t; + +typedef struct { + int rate; + double distortiondec; +} tcd_pass_t; + +typedef struct { + int numpasses; + int len; + unsigned char *data; +} tcd_layer_t; + +typedef struct { + int x0, y0, x1, y1; + int numbps; + int numlenbits; + int len; + int numpasses; + int numnewpasses; + int numsegs; + tcd_seg_t segs[100]; + unsigned char data[8192]; + int numpassesinlayers; + tcd_layer_t layers[100]; + int totalpasses; + tcd_pass_t passes[100]; +} tcd_cblk_t; + +typedef struct { + int x0, y0, x1, y1; + int cw, ch; + tcd_cblk_t *cblks; + tgt_tree_t *incltree; + tgt_tree_t *imsbtree; +} tcd_precinct_t; + +typedef struct { + int x0, y0, x1, y1; + int bandno; + tcd_precinct_t *precincts; + int numbps; + int stepsize; +} tcd_band_t; + +typedef struct { + int x0, y0, x1, y1; + int previous_x0, previous_y0, previous_x1, previous_y1; // usefull for the DWT + int cas_col, cas_row; // usefull for the DWT + int pw, ph; + int numbands; + tcd_band_t bands[3]; +} tcd_resolution_t; + +typedef struct { + int x0, y0, x1, y1; + int previous_row, previous_col; // usefull for the DWT + int numresolutions; + tcd_resolution_t *resolutions; + int *data; +} tcd_tilecomp_t; + +typedef struct { + int x0, y0, x1, y1; + int numcomps; + //int PPT; + //int len_ppt; + tcd_tilecomp_t *comps; +} tcd_tile_t; + +typedef struct { + int tw, th; + tcd_tile_t *tiles; +} tcd_image_t; + +/* + * Initialize the tile coder/decoder + * img: raw image + * cp: coding parameters + * imgg: creation of index file + */ + +void tcd_init(j2k_image_t *img, j2k_cp_t *cp, info_image_t *imgg); + +void tcd_free(j2k_image_t *img, j2k_cp_t *cp); + +/* + * Decode a tile from a buffer into a raw image + * src: source buffer + * len: length of the source buffer + * tileno: number that identifies the tile that will be decoded + * imgg : Structure for index file + */ +int tcd_decode_tile(unsigned char *src, int len, int tileno, info_image_t *imgg); + +#endif diff --git a/indexer_JPIP/tgt.c b/indexer_JPIP/tgt.c new file mode 100644 index 00000000..4a651935 --- /dev/null +++ b/indexer_JPIP/tgt.c @@ -0,0 +1,170 @@ +/* + * 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 "tgt.h" +#include "bio.h" +#include +#include + +/// +/// Reset tag-tree. +/// +void tgt_reset(tgt_tree_t *tree) +{ + int i; + for (i=0; inumnodes; i++) { + tree->nodes[i].value=999; + tree->nodes[i].low=0; + tree->nodes[i].known=0; + } +} + +/// +/// Create tag-tree. +/// +tgt_tree_t *tgt_create(int numleafsh, int numleafsv) +{ + int nplh[32]; + int nplv[32]; + tgt_node_t *node; + tgt_node_t *parentnode; + tgt_node_t *parentnode0; + tgt_tree_t *tree; + int i, j, k; + int numlvls; + int n; + + tree=(tgt_tree_t*)malloc(sizeof(tgt_tree_t)); + tree->numleafsh=numleafsh; + tree->numleafsv=numleafsv; + + numlvls=0; + nplh[0]=numleafsh; + nplv[0]=numleafsv; + tree->numnodes=0; + do { + n=nplh[numlvls]*nplv[numlvls]; + nplh[numlvls+1]=(nplh[numlvls]+1)/2; + nplv[numlvls+1]=(nplv[numlvls]+1)/2; + tree->numnodes+=n; + ++numlvls; + } while (n>1); + + tree->nodes=(tgt_node_t*)malloc(tree->numnodes*sizeof(tgt_node_t)); + + node=tree->nodes; + parentnode=&tree->nodes[tree->numleafsh*tree->numleafsv]; + parentnode0=parentnode; + + for (i=0; i=0) { + node->parent=parentnode; + ++node; + if (--k >= 0) { + node->parent=parentnode; + ++node; + } + ++parentnode; + } + if ((j&1)||j==nplv[i]-1) { + parentnode0=parentnode; + } else { + parentnode=parentnode0; + parentnode0+=nplh[i]; + } + } + } + node->parent=0; + + tgt_reset(tree); + + return tree; +} + +/// +/// Destroy tag-tree. +/// +void tgt_destroy(tgt_tree_t *t) { + free(t->nodes); + free(t); +} + +/// +/// Set the value of a leaf of the tag-tree. +/// +void tgt_setvalue(tgt_tree_t *tree, int leafno, int value) { + tgt_node_t *node; + node=&tree->nodes[leafno]; + while (node && node->value>value) { + node->value=value; + node=node->parent; + } +} + +/// +/// Decode the value of a leaf of the tag-tree. +/// +int tgt_decode(tgt_tree_t *tree, int leafno, int threshold) +{ + tgt_node_t *stk[31]; + tgt_node_t **stkptr; + tgt_node_t *node; + int low; + + stkptr=stk; + node=&tree->nodes[leafno]; + while (node->parent) { + *stkptr++=node; + node=node->parent; + } + + low=0; + for (;;) { + if (low>node->low) { + node->low=low; + } else { + low=node->low; + } + while (lowvalue) { + if (bio_read(1)) { + node->value=low; + } else { + ++low; + } + } + node->low=low; + if (stkptr==stk) { + break; + } + node=*--stkptr; + } + + return (node->value