Update for version 1.0
[openjpeg.git] / indexer_JPIP / index_create.c
1 /*
2  * Copyright (c) 2001-2002, David Janssens
3  * Copyright (c) 2003, Yannick Verschueren
4  * Copyright (c) 2003,  Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <setjmp.h>
34 #include <math.h>
35 #include <unistd.h>
36
37 #include "j2k.h"
38 #include "cio.h"
39 #include "tcd.h"
40 #include "int.h"
41 #include "jpip.h"
42 #include "jp2.h"
43
44 #define J2K_MS_SOC 0xff4f
45 #define J2K_MS_SOT 0xff90
46 #define J2K_MS_SOD 0xff93
47 #define J2K_MS_EOC 0xffd9
48 #define J2K_MS_SIZ 0xff51
49 #define J2K_MS_COD 0xff52
50 #define J2K_MS_COC 0xff53
51 #define J2K_MS_RGN 0xff5e
52 #define J2K_MS_QCD 0xff5c
53 #define J2K_MS_QCC 0xff5d
54 #define J2K_MS_POC 0xff5f
55 #define J2K_MS_TLM 0xff55
56 #define J2K_MS_PLM 0xff57
57 #define J2K_MS_PLT 0xff58
58 #define J2K_MS_PPM 0xff60
59 #define J2K_MS_PPT 0xff61
60 #define J2K_MS_SOP 0xff91
61 #define J2K_MS_EPH 0xff92
62 #define J2K_MS_CRG 0xff63
63 #define J2K_MS_COM 0xff64
64
65 #define J2K_STATE_MHSOC 0x0001
66 #define J2K_STATE_MHSIZ 0x0002
67 #define J2K_STATE_MH 0x0004
68 #define J2K_STATE_TPHSOT 0x0008
69 #define J2K_STATE_TPH 0x0010
70 #define J2K_STATE_MT 0x0020
71
72 jmp_buf j2k_error;
73
74 static int j2k_state;
75 static int j2k_curtileno;
76 static j2k_tcp_t j2k_default_tcp;
77 static unsigned char *j2k_eot;
78
79 static j2k_image_t *j2k_img;
80 static j2k_cp_t *j2k_cp;
81
82 static unsigned char **j2k_tile_data;
83 static int *j2k_tile_len;
84
85 static info_image_t img;
86
87 void j2k_clean() {
88   int tileno = 0;
89   int compno, resno, precno;
90   
91   tcd_free(j2k_img,j2k_cp);
92   
93   for (tileno=0;tileno<j2k_cp->tw*j2k_cp->th;tileno++) {
94     info_tile_t *tile_Idx = &img.tile[tileno];
95     
96     for (compno=0;compno<img.Comp;compno++)
97       {
98         info_compo_t *compo_Idx = &tile_Idx->compo[compno];
99         
100         for(resno=0;resno<img.Decomposition+1;resno++)
101           {
102             info_reso_t *reso_Idx = &compo_Idx->reso[resno];
103             for (precno=0;precno<img.tile[tileno].pw*img.tile[tileno].ph;precno++)
104               {
105                 info_prec_t *prec_Idx = &reso_Idx->prec[precno];
106                 free(prec_Idx->layer);
107               }
108             free(reso_Idx->prec);
109           }
110         free(compo_Idx->reso);
111       }
112     free(tile_Idx->compo);
113   }
114   free(img.tile);
115   free(img.marker);
116 }
117
118 void j2k_read_soc() {
119     j2k_state=J2K_STATE_MHSIZ;
120 }
121
122 void j2k_read_siz() {
123     int len, i;
124     len=cio_read(2);
125
126     // <INDEX>
127     img.marker[img.num_marker].type=J2K_MS_SIZ;
128     img.marker[img.num_marker].start_pos=cio_tell()-2;
129     img.marker[img.num_marker].len=len;
130     img.num_marker++;
131     // </INDEX>
132
133     
134     cio_read(2);              // Rsiz (capabilities)
135     j2k_img->x1=cio_read(4);  // Xsiz
136     j2k_img->y1=cio_read(4);  // Ysiz
137     j2k_img->x0=cio_read(4);  // X0siz
138     j2k_img->y0=cio_read(4);  // Y0siz
139     j2k_cp->tdx=cio_read(4);  // XTsiz
140     j2k_cp->tdy=cio_read(4);  // YTsiz
141     j2k_cp->tx0=cio_read(4);  // XT0siz
142     j2k_cp->ty0=cio_read(4);  // YTOsiz
143     j2k_img->numcomps=cio_read(2);  // Csiz
144     j2k_img->comps=(j2k_comp_t*)malloc(j2k_img->numcomps*sizeof(j2k_comp_t));
145     for (i=0; i<j2k_img->numcomps; i++) {
146         int tmp, w, h;
147         tmp=cio_read(1);
148         j2k_img->comps[i].prec=(tmp&0x7f)+1;
149         j2k_img->comps[i].sgnd=tmp>>7;
150         j2k_img->comps[i].dx=cio_read(1);
151         j2k_img->comps[i].dy=cio_read(1);
152         w=int_ceildiv(j2k_img->x1-j2k_img->x0, j2k_img->comps[i].dx);
153         h=int_ceildiv(j2k_img->y1-j2k_img->y0, j2k_img->comps[i].dy);
154         j2k_img->comps[i].data=(int*)malloc(sizeof(int)*w*h);
155     }
156     j2k_cp->tw=int_ceildiv(j2k_img->x1-j2k_img->x0, j2k_cp->tdx);
157     j2k_cp->th=int_ceildiv(j2k_img->y1-j2k_img->y0, j2k_cp->tdy);
158
159     j2k_cp->tcps=(j2k_tcp_t*)calloc(sizeof(j2k_tcp_t), j2k_cp->tw*j2k_cp->th);
160     j2k_default_tcp.tccps=(j2k_tccp_t*)calloc(sizeof(j2k_tccp_t), j2k_img->numcomps);
161     for (i=0; i<j2k_cp->tw*j2k_cp->th; i++) {
162         j2k_cp->tcps[i].tccps=(j2k_tccp_t*)calloc(sizeof(j2k_tccp_t), j2k_img->numcomps);
163     }
164     j2k_tile_data=(unsigned char**)calloc(j2k_cp->tw*j2k_cp->th, sizeof(char*));
165     j2k_tile_len=(int*)calloc(j2k_cp->tw*j2k_cp->th, sizeof(int));
166     j2k_state=J2K_STATE_MH;
167
168     // <INDEX>
169     img.Im_w=j2k_img->x1-j2k_img->x0;
170     img.Im_h=j2k_img->y1-j2k_img->y0;
171     img.Tile_x=j2k_cp->tdx;
172     img.Tile_y=j2k_cp->tdy;
173     img.Comp=j2k_img->numcomps;
174     img.tw=j2k_cp->tw;
175     img.th=j2k_cp->th;
176     img.tile=(info_tile_t*)malloc((img.tw*img.th)*sizeof(info_tile_t));
177     //</INDEX>
178
179
180  }
181
182 void j2k_read_com() {
183     int len;
184     len=cio_read(2);
185
186     // <INDEX>
187     if (j2k_state==J2K_STATE_MH)
188       {
189         if (!img.marker_mul.num_COM)
190           img.marker_mul.COM=(info_marker_t*)malloc(sizeof(info_marker_t));
191         else
192           img.marker_mul.COM=realloc(img.marker_mul.COM,(1+img.marker_mul.num_COM)*sizeof(info_marker_t));
193         img.marker_mul.COM[img.marker_mul.num_COM].type=J2K_MS_COM;
194         img.marker_mul.COM[img.marker_mul.num_COM].start_pos=cio_tell()-2;
195         img.marker_mul.COM[img.marker_mul.num_COM].len=len;
196         img.marker_mul.num_COM++;
197       }
198     // </INDEX>
199
200     cio_skip(len-2);
201 }
202
203 void j2k_read_cox(int compno) {
204     int i;
205     j2k_tcp_t *tcp;
206     j2k_tccp_t *tccp;
207     tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp;
208     tccp=&tcp->tccps[compno];
209     tccp->numresolutions=cio_read(1)+1;
210
211     img.Decomposition=tccp->numresolutions-1; // <INDEX>
212
213     tccp->cblkw=cio_read(1)+2;
214     tccp->cblkh=cio_read(1)+2;
215     tccp->cblksty=cio_read(1);
216     tccp->qmfbid=cio_read(1);
217     if (tccp->csty&J2K_CP_CSTY_PRT) {
218         for (i=0; i<tccp->numresolutions; i++) {
219             int tmp=cio_read(1);
220             tccp->prcw[i]=tmp&0xf;
221             tccp->prch[i]=tmp>>4; 
222         }
223     }
224 }
225
226 void j2k_read_cod() {
227     int len, i, pos;
228     j2k_tcp_t *tcp;
229     tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp;
230     len=cio_read(2);
231
232     // <INDEX>
233     if (j2k_state==J2K_STATE_MH)
234       {
235         if (!img.marker_mul.num_COD)
236           img.marker_mul.COD=(info_marker_t*)malloc(sizeof(info_marker_t));
237         else
238           img.marker_mul.COD=realloc(img.marker_mul.COD,(1+img.marker_mul.num_COD)*sizeof(info_marker_t));
239         img.marker_mul.COD[img.marker_mul.num_COD].type=J2K_MS_COD;
240         img.marker_mul.COD[img.marker_mul.num_COD].start_pos=cio_tell()-2;
241         img.marker_mul.COD[img.marker_mul.num_COD].len=len;
242         img.marker_mul.num_COD++;
243       }
244     // </INDEX>
245     
246     
247     tcp->csty=cio_read(1);
248     tcp->prg=cio_read(1);
249     tcp->numlayers=cio_read(2);
250     tcp->mct=cio_read(1);
251     pos=cio_tell();
252     for (i=0; i<j2k_img->numcomps; i++) {
253         tcp->tccps[i].csty=tcp->csty&J2K_CP_CSTY_PRT;
254         cio_seek(pos);
255         j2k_read_cox(i);
256     }
257     //<INDEX>
258     img.Prog=tcp->prg;
259     img.Layer=tcp->numlayers;
260     //</INDEX>
261 }
262
263 void j2k_read_coc() {
264     int len, compno;
265     j2k_tcp_t *tcp;
266     tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp;
267     len=cio_read(2);
268     // <INDEX>
269     if (j2k_state==J2K_STATE_MH)
270       {
271         if (!img.marker_mul.num_COC)
272           img.marker_mul.COC=(info_marker_t*)malloc(sizeof(info_marker_t));
273         else
274           img.marker_mul.COC=realloc(img.marker_mul.COC,(1+img.marker_mul.num_COC)*sizeof(info_marker_t));
275         img.marker_mul.COC[img.marker_mul.num_COC].type=J2K_MS_COC;
276         img.marker_mul.COC[img.marker_mul.num_COC].start_pos=cio_tell()-2;
277         img.marker_mul.COC[img.marker_mul.num_COC].len=len;
278         img.marker_mul.num_COC++;
279       }
280     // </INDEX>
281
282     
283     compno=cio_read(j2k_img->numcomps<=256?1:2);
284     tcp->tccps[compno].csty=cio_read(1);
285     j2k_read_cox(compno);
286 }
287
288 void j2k_read_qcx(int compno, int len) {
289     int tmp;
290     j2k_tcp_t *tcp;
291     j2k_tccp_t *tccp;
292     int bandno, numbands;
293     tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp;
294     tccp=&tcp->tccps[compno];
295     tmp=cio_read(1);
296     tccp->qntsty=tmp&0x1f;
297     tccp->numgbits=tmp>>5;
298     numbands=tccp->qntsty==J2K_CCP_QNTSTY_SIQNT?1:(tccp->qntsty==J2K_CCP_QNTSTY_NOQNT?len-1:(len-1)/2);
299     for (bandno=0; bandno<numbands; bandno++) {
300         int expn, mant;
301         if (tccp->qntsty==J2K_CCP_QNTSTY_NOQNT) { // WHY STEPSIZES WHEN NOQNT ?
302             expn=cio_read(1)>>3;
303             mant=0;
304         } else {
305             tmp=cio_read(2);
306             expn=tmp>>11;
307             mant=tmp&0x7ff;
308         }
309         tccp->stepsizes[bandno].expn=expn;
310         tccp->stepsizes[bandno].mant=mant;
311     }
312 }
313
314 void j2k_read_qcd() {
315     int len, i, pos;
316     len=cio_read(2);    
317
318     // <INDEX>
319     if (j2k_state==J2K_STATE_MH)
320       {
321         img.marker[img.num_marker].type=J2K_MS_QCD;
322         img.marker[img.num_marker].start_pos=cio_tell()-2;
323         img.marker[img.num_marker].len=len;
324         img.num_marker++;
325       }
326     // </INDEX>
327     
328     
329     pos=cio_tell();
330     for (i=0; i<j2k_img->numcomps; i++) {
331         cio_seek(pos);
332         j2k_read_qcx(i, len-2);
333     }
334 }
335
336 void j2k_read_qcc() {
337   int len, compno;
338   len=cio_read(2);  
339
340   // <INDEX>
341   if (j2k_state==J2K_STATE_MH)
342     {
343       if (!img.marker_mul.num_QCC)
344         img.marker_mul.QCC=(info_marker_t*)malloc(sizeof(info_marker_t));
345       else
346         img.marker_mul.QCC=realloc(img.marker_mul.QCC,(1+img.marker_mul.num_QCC)*sizeof(info_marker_t));
347       img.marker_mul.QCC[img.marker_mul.num_QCC].type=J2K_MS_QCC;
348       img.marker_mul.QCC[img.marker_mul.num_QCC].start_pos=cio_tell()-2;
349       img.marker_mul.QCC[img.marker_mul.num_QCC].len=len;
350       img.marker_mul.num_QCC++;
351     }
352   // </INDEX>
353   
354   
355   compno=cio_read(j2k_img->numcomps<=256?1:2);
356   j2k_read_qcx(compno, len-2-(j2k_img->numcomps<=256?1:2));
357 }
358
359 void j2k_read_poc() {
360   int len, numpchgs, i;
361   j2k_tcp_t *tcp;
362   fprintf(stderr, "WARNING: POC marker segment processing not fully implemented\n");
363   tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp;
364   len=cio_read(2);
365   
366   // <INDEX>
367   if (j2k_state==J2K_STATE_MH)
368     {
369       img.marker[img.num_marker].type=J2K_MS_POC;
370       img.marker[img.num_marker].start_pos=cio_tell()-2;
371       img.marker[img.num_marker].len=len;
372       img.num_marker++;
373     }
374   // </INDEX>
375   
376
377   numpchgs=(len-2)/(5+2*(j2k_img->numcomps<=256?1:2));
378   for (i=0; i<numpchgs; i++) {
379     j2k_poc_t *poc;
380     poc=&tcp->pocs[i];
381     poc->resno0=cio_read(1);
382     poc->compno0=cio_read(j2k_img->numcomps<=256?1:2);
383     poc->layno1=cio_read(2);
384     poc->resno1=cio_read(1);
385     poc->compno1=cio_read(j2k_img->numcomps<=256?1:2);
386     poc->prg=cio_read(1);
387   }
388 }
389
390 void j2k_read_crg() {
391     int len;
392     len=cio_read(2);
393
394     // <INDEX>
395     if (j2k_state==J2K_STATE_MH)
396       {
397         img.marker[img.num_marker].type=J2K_MS_CRG;
398         img.marker[img.num_marker].start_pos=cio_tell()-2;
399         img.marker[img.num_marker].len=len;
400         img.num_marker++;
401       }
402     // </INDEX>
403
404     fprintf(stderr, "WARNING: CRG marker segment processing not implemented\n");
405     cio_skip(len-2);
406 }
407
408 void j2k_read_tlm() {
409     int len;
410     len=cio_read(2);
411
412     // <INDEX>
413     if (j2k_state==J2K_STATE_MH)
414       {
415         if (!img.marker_mul.num_TLM)
416           img.marker_mul.TLM=(info_marker_t*)malloc(sizeof(info_marker_t));
417         else
418           img.marker_mul.TLM=realloc(img.marker_mul.TLM,(1+img.marker_mul.num_TLM)*sizeof(info_marker_t));
419         img.marker_mul.TLM[img.marker_mul.num_TLM].type=J2K_MS_TLM;
420         img.marker_mul.TLM[img.marker_mul.num_TLM].start_pos=cio_tell()-2;
421         img.marker_mul.TLM[img.marker_mul.num_TLM].len=len;
422         img.marker_mul.num_TLM++;
423       }
424     // </INDEX>
425     
426     fprintf(stderr, "WARNING: TLM marker segment processing not implemented\n");
427     cio_skip(len-2);
428 }
429
430 void j2k_read_plm() {
431     int len;
432     len=cio_read(2);
433
434     // <INDEX>
435     if (j2k_state==J2K_STATE_MH)
436       {
437         if (!img.marker_mul.num_PLM)
438           img.marker_mul.PLM=(info_marker_t*)malloc(sizeof(info_marker_t));
439         else
440           img.marker_mul.PLM=realloc(img.marker_mul.PLM,(1+img.marker_mul.num_PLM)*sizeof(info_marker_t));
441         img.marker_mul.PLM[img.marker_mul.num_PLM].type=J2K_MS_PLM;
442         img.marker_mul.PLM[img.marker_mul.num_PLM].start_pos=cio_tell()-2;
443         img.marker_mul.PLM[img.marker_mul.num_PLM].len=len;
444         img.marker_mul.num_PLM++;
445       }
446     // </INDEX>
447     
448     fprintf(stderr, "WARNING: PLM marker segment processing not implemented\n");
449     cio_skip(len-2);
450 }
451
452 void j2k_read_plt() {
453     int len;
454     len=cio_read(2);
455     fprintf(stderr, "WARNING: PLT marker segment processing not implemented\n");
456     cio_skip(len-2);
457 }
458
459 void j2k_read_ppm() {
460     int len;
461     len=cio_read(2);
462     // <INDEX>
463     if (j2k_state==J2K_STATE_MH)
464       {
465         img.marker[img.num_marker].type=J2K_MS_PPM;
466         img.marker[img.num_marker].start_pos=cio_tell()-2;
467         img.marker[img.num_marker].len=len;
468         img.num_marker++;
469       }
470     // </INDEX>
471     
472     fprintf(stderr, "WARNING: PPM marker segment processing not implemented\n");
473     cio_skip(len-2);
474 }
475
476 void j2k_read_ppt() {
477     int len;
478     len=cio_read(2);
479     fprintf(stderr, "WARNING: PPT marker segment processing not implemented\n");
480     cio_skip(len-2);
481 }
482
483 void j2k_read_sot() {
484     int len, tileno, totlen, partno, numparts, i;
485     j2k_tcp_t *tcp;
486     j2k_tccp_t *tmp;
487     len=cio_read(2);
488     tileno=cio_read(2);
489     //<INDEX>
490     if (!tileno) img.Main_head_end=cio_tell()-6;  // Correction End = First byte of first SOT
491     img.tile[tileno].start_pos=cio_tell()-6;
492     img.tile[tileno].num_tile=tileno;
493     // </INDEX>
494     totlen=cio_read(4); 
495     if (!totlen) totlen = cio_numbytesleft() + 8;
496
497     img.tile[tileno].end_pos=totlen+img.tile[tileno].start_pos; // <INDEX>
498
499     partno=cio_read(1);
500     numparts=cio_read(1);
501     j2k_curtileno=tileno;
502     j2k_eot=cio_getbp()-12+totlen;
503     j2k_state=J2K_STATE_TPH;
504     tcp=&j2k_cp->tcps[j2k_curtileno];
505     tmp=tcp->tccps;
506     *tcp=j2k_default_tcp;
507     tcp->tccps=tmp;
508     for (i=0; i<j2k_img->numcomps; i++) {
509         tcp->tccps[i]=j2k_default_tcp.tccps[i];
510     }
511 }
512
513 void j2k_read_sod() {
514     int len;
515     unsigned char *data;
516     img.tile[j2k_curtileno].end_header=cio_tell()-1;  //<INDEX>
517     len=int_min(j2k_eot-cio_getbp(), cio_numbytesleft());
518     j2k_tile_len[j2k_curtileno]+=len;
519     data=(unsigned char*)realloc(j2k_tile_data[j2k_curtileno], j2k_tile_len[j2k_curtileno]);
520     memcpy(data, cio_getbp(), len);
521     j2k_tile_data[j2k_curtileno]=data;
522     cio_skip(len);
523     j2k_state=J2K_STATE_TPHSOT;
524    
525 }
526
527 void j2k_read_rgn() {
528     int len, compno, roisty;
529     j2k_tcp_t *tcp;
530     tcp=j2k_state==J2K_STATE_TPH?&j2k_cp->tcps[j2k_curtileno]:&j2k_default_tcp;
531     len=cio_read(2);
532
533     // <INDEX>
534     if (j2k_state==J2K_STATE_MH)
535       {
536         if (!img.marker_mul.num_RGN)
537           img.marker_mul.RGN=(info_marker_t*)malloc(sizeof(info_marker_t));
538         else
539           img.marker_mul.RGN=realloc(img.marker_mul.RGN,(1+img.marker_mul.num_RGN)*sizeof(info_marker_t));
540         img.marker_mul.RGN[img.marker_mul.num_RGN].type=J2K_MS_RGN;
541         img.marker_mul.RGN[img.marker_mul.num_RGN].start_pos=cio_tell()-2;
542         img.marker_mul.RGN[img.marker_mul.num_RGN].len=len;
543         img.marker_mul.num_RGN++;
544       }
545     // </INDEX>
546
547     
548     compno=cio_read(j2k_img->numcomps<=256?1:2);
549     roisty=cio_read(1);
550     tcp->tccps[compno].roishift=cio_read(1);
551 }
552
553 void j2k_read_eoc() {
554     int tileno;
555     tcd_init(j2k_img, j2k_cp, &img);
556     for (tileno=0; tileno<j2k_cp->tw*j2k_cp->th; tileno++) {
557         tcd_decode_tile(j2k_tile_data[tileno], j2k_tile_len[tileno], tileno, &img);
558     }
559
560     j2k_state=J2K_STATE_MT;
561      longjmp(j2k_error, 1);
562
563 }
564
565 void j2k_read_unk() {
566     fprintf(stderr, "warning: unknown marker\n");
567 }
568
569 int j2k_index_JPIP(char *Idx_file, char *J2K_file, int len){
570   FILE *dest;
571   char *index;
572   int pos_iptr, end_pos;
573   int len_cidx, pos_cidx;
574   int len_jp2c, pos_jp2c;
575   int len_fidx, pos_fidx;
576
577   dest=fopen(Idx_file, "wb");
578   if (!dest) {
579     fprintf(stderr,"Failed to open %s for reading !!\n",Idx_file);
580     return 0;
581   }
582
583  // INDEX MODE JPIP
584  index=(char*)malloc(len); 
585  cio_init(index, len);
586  jp2_write_jp();
587  jp2_write_ftyp();
588  
589  jp2_write_jp2h(j2k_img);
590  jp2_write_dbtl(Idx_file);
591
592  pos_iptr=cio_tell();
593  cio_skip(24); // IPTR further !
594  
595  pos_jp2c=cio_tell();
596  len_jp2c=jp2_write_jp2c(J2K_file);
597   
598  pos_cidx=cio_tell();
599  len_cidx=jpip_write_cidx(pos_jp2c+8,img, j2k_cp); // Correction len_jp2C --> pos_jp2c+8  
600  
601  pos_fidx=cio_tell();
602  len_fidx=jpip_write_fidx(pos_jp2c, len_jp2c, pos_cidx, len_cidx);
603  
604  end_pos=cio_tell();
605  cio_seek(pos_iptr);
606  jpip_write_iptr(pos_fidx,len_fidx);
607  cio_seek(end_pos);
608
609  fwrite(index, 1, cio_tell(), dest);
610  free(index);
611
612  fclose(dest);
613  return 1;
614 }
615
616
617
618 typedef struct {
619   int id;
620     int states;
621     void (*handler)();
622 } j2k_dec_mstabent_t;
623
624 j2k_dec_mstabent_t j2k_dec_mstab[]={
625     {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc},
626     {J2K_MS_SOT, J2K_STATE_MH|J2K_STATE_TPHSOT, j2k_read_sot},
627     {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod},
628     {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc},
629     {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz},
630     {J2K_MS_COD, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_cod},
631     {J2K_MS_COC, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_coc},
632     {J2K_MS_RGN, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_rgn},
633     {J2K_MS_QCD, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_qcd},
634     {J2K_MS_QCC, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_qcc},
635     {J2K_MS_POC, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_poc},
636     {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm},
637     {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm},
638     {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt},
639     {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm},
640     {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt},
641     {J2K_MS_SOP, 0, 0},
642     {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg},
643     {J2K_MS_COM, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_com},
644     {0, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_unk}
645 };
646
647 j2k_dec_mstabent_t *j2k_dec_mstab_lookup(int id) {
648     j2k_dec_mstabent_t *e;
649     for (e=j2k_dec_mstab; e->id!=0; e++) {
650         if (e->id==id) {
651             break;
652         }
653     }
654     return e;
655 }
656
657 LIBJ2K_API int j2k_decode(unsigned char *src, int len, j2k_image_t **image, j2k_cp_t **cp) {
658     if (setjmp(j2k_error)) {
659         if (j2k_state!=J2K_STATE_MT) {
660             fprintf(stderr, "WARNING: incomplete bitstream\n");
661             return 0;
662         }
663         return cio_numbytes();
664     }
665     j2k_img=(j2k_image_t*)malloc(sizeof(j2k_image_t));
666     j2k_cp=(j2k_cp_t*)malloc(sizeof(j2k_cp_t));
667     *image=j2k_img;
668     *cp=j2k_cp;
669     j2k_state=J2K_STATE_MHSOC;
670     cio_init(src, len);
671     for (;;) {
672         j2k_dec_mstabent_t *e;
673         int id=cio_read(2);
674         if (id>>8!=0xff) {
675             fprintf(stderr, "%.8x: expected a marker instead of %x\n", cio_tell()-2, id);
676             return 0;
677         }
678         e=j2k_dec_mstab_lookup(id);
679         if (!(j2k_state & e->states)) {
680             fprintf(stderr, "%.8x: unexpected marker %x\n", cio_tell()-2, id);
681             return 0;
682         }
683         if (e->handler) {
684             (*e->handler)();
685         }
686     }
687
688 }
689
690 #ifdef WIN32
691 #include <windows.h>
692
693 BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
694     switch (ul_reason_for_call) {
695                 case DLL_PROCESS_ATTACH:
696                 case DLL_THREAD_ATTACH:
697                 case DLL_THREAD_DETACH:
698                 case DLL_PROCESS_DETACH:
699                         break;
700     }
701     return TRUE;
702 }
703 #endif
704
705
706 extern info_image_t img;
707
708
709 int main(int argc, char **argv)
710 {  
711   FILE *src;
712   int totlen;
713   char *j2kfile;
714   j2k_image_t *imgg;
715   j2k_cp_t *cp;
716
717   if (argc!=3)
718     {
719       fprintf(stderr,"\nERROR in entry : index_create J2K-file Idx-file\n\n");
720       return 0;
721     }
722
723   src=fopen(argv[1], "rb");
724   if (!src) {
725     fprintf(stderr,"Failed to open %s for reading !!\n",argv[1]);
726     return 0;
727   }
728
729   // length of the codestream
730   fseek(src, 0, SEEK_END);
731   totlen=ftell(src);
732   fseek(src, 0, SEEK_SET);
733   
734   j2kfile=(char*)malloc(totlen);
735   fread(j2kfile, 1, totlen, src);
736   
737   img.marker=(info_marker_t*)malloc(32*sizeof(info_marker_t));
738   img.num_marker=0;
739   img.marker_mul.num_COD=0;
740   img.marker_mul.num_COC=0;
741   img.marker_mul.num_RGN=0;
742   img.marker_mul.num_QCC=0;
743   img.marker_mul.num_TLM=0;
744   img.marker_mul.num_PLM=0;
745   img.marker_mul.num_COM=0;
746
747   // decode  
748
749   if (!j2k_decode(j2kfile, totlen, &imgg, &cp)) {
750     fprintf(stderr, "Index_creator: failed to decode image!\n");
751     return 1;
752   }
753
754   free(j2kfile);
755
756   fseek(src, 0, SEEK_SET);
757   img.codestream_size=totlen;
758
759   j2k_index_JPIP(argv[2],argv[1],totlen*2>30000?totlen*2:30000);
760
761   fclose(src);
762
763   j2k_clean();
764   return 1;
765 }