openjpeg/indexer_JPIP/index_create.c

766 lines
21 KiB
C

/*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <math.h>
#include <unistd.h>
#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;tileno<j2k_cp->tw*j2k_cp->th;tileno++) {
info_tile_t *tile_Idx = &img.tile[tileno];
for (compno=0;compno<img.Comp;compno++)
{
info_compo_t *compo_Idx = &tile_Idx->compo[compno];
for(resno=0;resno<img.Decomposition+1;resno++)
{
info_reso_t *reso_Idx = &compo_Idx->reso[resno];
for (precno=0;precno<img.tile[tileno].pw*img.tile[tileno].ph;precno++)
{
info_prec_t *prec_Idx = &reso_Idx->prec[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);
// <INDEX>
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++;
// </INDEX>
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; i<j2k_img->numcomps; 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; i<j2k_cp->tw*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;
// <INDEX>
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));
//</INDEX>
}
void j2k_read_com() {
int len;
len=cio_read(2);
// <INDEX>
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++;
}
// </INDEX>
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; // <INDEX>
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; i<tccp->numresolutions; 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);
// <INDEX>
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++;
}
// </INDEX>
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; i<j2k_img->numcomps; i++) {
tcp->tccps[i].csty=tcp->csty&J2K_CP_CSTY_PRT;
cio_seek(pos);
j2k_read_cox(i);
}
//<INDEX>
img.Prog=tcp->prg;
img.Layer=tcp->numlayers;
//</INDEX>
}
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);
// <INDEX>
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++;
}
// </INDEX>
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; bandno<numbands; bandno++) {
int expn, mant;
if (tccp->qntsty==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);
// <INDEX>
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++;
}
// </INDEX>
pos=cio_tell();
for (i=0; i<j2k_img->numcomps; i++) {
cio_seek(pos);
j2k_read_qcx(i, len-2);
}
}
void j2k_read_qcc() {
int len, compno;
len=cio_read(2);
// <INDEX>
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++;
}
// </INDEX>
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);
// <INDEX>
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++;
}
// </INDEX>
numpchgs=(len-2)/(5+2*(j2k_img->numcomps<=256?1:2));
for (i=0; i<numpchgs; i++) {
j2k_poc_t *poc;
poc=&tcp->pocs[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);
// <INDEX>
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++;
}
// </INDEX>
fprintf(stderr, "WARNING: CRG marker segment processing not implemented\n");
cio_skip(len-2);
}
void j2k_read_tlm() {
int len;
len=cio_read(2);
// <INDEX>
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++;
}
// </INDEX>
fprintf(stderr, "WARNING: TLM marker segment processing not implemented\n");
cio_skip(len-2);
}
void j2k_read_plm() {
int len;
len=cio_read(2);
// <INDEX>
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++;
}
// </INDEX>
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);
// <INDEX>
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++;
}
// </INDEX>
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);
//<INDEX>
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;
// </INDEX>
totlen=cio_read(4);
if (!totlen) totlen = cio_numbytesleft() + 8;
img.tile[tileno].end_pos=totlen+img.tile[tileno].start_pos; // <INDEX>
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; i<j2k_img->numcomps; 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; //<INDEX>
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);
// <INDEX>
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++;
}
// </INDEX>
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; tileno<j2k_cp->tw*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 <windows.h>
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;
}