478f556a0a8a898ebaf90995d6a58353931fd06a
[openjpeg.git] / src / bin / jp2 / index.c
1 /*
2  * The copyright in this software is being made available under the 2-clauses 
3  * BSD License, included below. This software may be subject to other third 
4  * party and contributor rights, including patent rights, and no such rights
5  * are granted under this license.
6  *
7  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8  * Copyright (c) 2002-2014, Professor Benoit Macq
9  * Copyright (c) 2003-2007, Francois-Olivier Devaux 
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdio.h>
35 #include <math.h>
36 #include <string.h>
37 #include "openjpeg.h"
38 #include "index.h"
39 #include "opj_inttypes.h"
40
41 /* ------------------------------------------------------------------------------------ */
42
43 /**
44 Write a structured index to a file
45 @param cstr_info Codestream information 
46 @param index Index filename
47 @return Returns 0 if successful, returns 1 otherwise
48 */
49 int write_index_file(opj_codestream_info_t *cstr_info, char *index) {
50         int tileno, compno, layno, resno, precno, pack_nb, x, y;
51         FILE *stream = NULL;
52         double total_disto = 0;
53 /* UniPG>> */
54         int tilepartno;
55         char disto_on, numpix_on;
56
57 #ifdef USE_JPWL
58         if (!strcmp(index, JPWL_PRIVATEINDEX_NAME))
59                 return 0;
60 #endif /* USE_JPWL */
61 /* <<UniPG */
62
63         if (!cstr_info)         
64                 return 1;
65
66         stream = fopen(index, "w");
67         if (!stream) {
68                 fprintf(stderr, "failed to open index file [%s] for writing\n", index);
69                 return 1;
70         }
71         
72         if (cstr_info->tile[0].distotile > 0.0)
73                 disto_on = 1;
74         else 
75                 disto_on = 0;
76
77         if (cstr_info->tile[0].numpix)
78                 numpix_on = 1;
79         else 
80                 numpix_on = 0;
81
82         fprintf(stream, "%d %d\n", cstr_info->image_w, cstr_info->image_h);
83         fprintf(stream, "%d\n", cstr_info->prog);
84         fprintf(stream, "%d %d\n", cstr_info->tile_x, cstr_info->tile_y);
85         fprintf(stream, "%d %d\n", cstr_info->tw, cstr_info->th);
86         fprintf(stream, "%d\n", cstr_info->numcomps);
87         fprintf(stream, "%d\n", cstr_info->numlayers);
88         fprintf(stream, "%d\n", cstr_info->numdecompos[0]); /* based on component 0 */
89
90         for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
91                 fprintf(stream, "[%d,%d] ", 
92                         (1 << cstr_info->tile[0].pdx[resno]), (1 << cstr_info->tile[0].pdx[resno]));    /* based on tile 0 and component 0 */
93         }
94
95         fprintf(stream, "\n");
96 /* UniPG>> */
97         fprintf(stream, "%d\n", cstr_info->main_head_start);
98 /* <<UniPG */
99         fprintf(stream, "%d\n", cstr_info->main_head_end);
100         fprintf(stream, "%d\n", cstr_info->codestream_size);
101         
102         fprintf(stream, "\nINFO ON TILES\n");
103         fprintf(stream, "tileno start_pos  end_hd  end_tile   nbparts");
104         if (disto_on)
105                 fprintf(stream,"         disto");
106         if (numpix_on)
107                 fprintf(stream,"     nbpix");
108         if (disto_on && numpix_on)
109                 fprintf(stream,"  disto/nbpix");
110         fprintf(stream, "\n");
111
112         for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
113                 fprintf(stream, "%4d %9d %9d %9d %9d", 
114                         cstr_info->tile[tileno].tileno,
115                         cstr_info->tile[tileno].start_pos,
116                         cstr_info->tile[tileno].end_header,
117                         cstr_info->tile[tileno].end_pos,
118                         cstr_info->tile[tileno].num_tps);
119                 if (disto_on)
120                         fprintf(stream," %9e", cstr_info->tile[tileno].distotile);
121                 if (numpix_on)
122                         fprintf(stream," %9d", cstr_info->tile[tileno].numpix);
123                 if (disto_on && numpix_on)
124                         fprintf(stream," %9e", cstr_info->tile[tileno].distotile / cstr_info->tile[tileno].numpix);
125                 fprintf(stream, "\n");
126         }
127                 
128         for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
129                 OPJ_OFF_T start_pos, end_ph_pos, end_pos;
130                 double disto = 0;
131                 int max_numdecompos = 0;
132                 pack_nb = 0;
133
134                 for (compno = 0; compno < cstr_info->numcomps; compno++) {
135                         if (max_numdecompos < cstr_info->numdecompos[compno])
136                                 max_numdecompos = cstr_info->numdecompos[compno];
137                 }       
138
139                 fprintf(stream, "\nTILE %d DETAILS\n", tileno); 
140                 fprintf(stream, "part_nb tileno  start_pack num_packs  start_pos end_tph_pos   end_pos\n");
141                 for (tilepartno = 0; tilepartno < cstr_info->tile[tileno].num_tps; tilepartno++)
142                         fprintf(stream, "%4d %9d   %9d %9d  %9d %11d %9d\n",
143                                 tilepartno, tileno,
144                                 cstr_info->tile[tileno].tp[tilepartno].tp_start_pack,
145                                 cstr_info->tile[tileno].tp[tilepartno].tp_numpacks,
146                                 cstr_info->tile[tileno].tp[tilepartno].tp_start_pos,
147                                 cstr_info->tile[tileno].tp[tilepartno].tp_end_header,
148                                 cstr_info->tile[tileno].tp[tilepartno].tp_end_pos
149                                 );
150
151                 if (cstr_info->prog == OPJ_LRCP) {      /* LRCP */
152                         fprintf(stream, "LRCP\npack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos");
153                         if (disto_on)
154                                 fprintf(stream, " disto");
155                         fprintf(stream,"\n");
156
157                         for (layno = 0; layno < cstr_info->numlayers; layno++) {
158                                 for (resno = 0; resno < max_numdecompos + 1; resno++) {
159                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {
160                                                 int prec_max;
161                                                 if (resno > cstr_info->numdecompos[compno])
162                                                         break;
163                                                 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
164                                                 for (precno = 0; precno < prec_max; precno++) {
165                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
166                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
167                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
168                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;
169                                                         fprintf(stream, "%4d %6d %7d %5d %6d  %6d    %6" PRId64 "     %6" PRId64 " %7" PRId64,
170                                                                 pack_nb, tileno, layno, resno, compno, precno, start_pos, end_ph_pos, end_pos);
171                                                         if (disto_on)
172                                                                 fprintf(stream, " %8e", disto);
173                                                         fprintf(stream, "\n");
174                                                         total_disto += disto;
175                                                         pack_nb++;
176                                                 }
177                                         }
178                                 }
179                         }
180                 } /* LRCP */
181
182                 else if (cstr_info->prog == OPJ_RLCP) { /* RLCP */                      
183                         fprintf(stream, "RLCP\npack_nb tileno resno layno compno precno start_pos end_ph_pos end_pos\n");
184                         if (disto_on)
185                                 fprintf(stream, " disto");
186                         fprintf(stream,"\n");
187
188                         for (resno = 0; resno < max_numdecompos + 1; resno++) {
189                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
190                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {
191                                                 int prec_max; 
192                                                 if (resno > cstr_info->numdecompos[compno])
193                                                         break;
194                                                 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
195                                                 for (precno = 0; precno < prec_max; precno++) {
196                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
197                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
198                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
199                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;
200                                                         fprintf(stream, "%4d %6d %5d %7d %6d %6d %9" PRId64 "   %9" PRId64 " %7" PRId64,
201                                                                 pack_nb, tileno, resno, layno, compno, precno, start_pos, end_ph_pos, end_pos);
202                                                         if (disto_on)
203                                                                 fprintf(stream, " %8e", disto);
204                                                         fprintf(stream, "\n");
205                                                         total_disto += disto;
206                                                         pack_nb++;
207                                                 }
208                                         }
209                                 }
210                         }
211                 } /* RLCP */
212
213                 else if (cstr_info->prog == OPJ_RPCL) { /* RPCL */
214
215                         fprintf(stream, "RPCL\npack_nb tileno resno precno compno layno start_pos end_ph_pos end_pos"); 
216                         if (disto_on)
217                                 fprintf(stream, " disto");
218                         fprintf(stream,"\n");
219
220                         for (resno = 0; resno < max_numdecompos + 1; resno++) {
221                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
222                                 for (precno = 0; precno < numprec; precno++) {                                                          
223                                         /* I suppose components have same XRsiz, YRsiz */
224                                         int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
225                                         int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
226                                         int x1 = x0 + cstr_info->tile_x;
227                                         int y1 = y0 + cstr_info->tile_y;
228                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {                                      
229                                                 int pcnx = cstr_info->tile[tileno].pw[resno];
230                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
231                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
232                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
233                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );
234                                                 if (resno > cstr_info->numdecompos[compno])
235                                                         break;
236                                                 for(y = y0; y < y1; y++) {                                                      
237                                                         if (precno_y*pcy == y ) {
238                                                                 for (x = x0; x < x1; x++) {                                                                     
239                                                                         if (precno_x*pcx == x ) {
240                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
241                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
242                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
243                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
244                                                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;
245                                                                                         fprintf(stream, "%4d %6d %5d %6d %6d %7d %9" PRId64 "   %9" PRId64 " %7" PRId64,
246                                                                                                 pack_nb, tileno, resno, precno, compno, layno, start_pos, end_ph_pos, end_pos); 
247                                                                                         if (disto_on)
248                                                                                                 fprintf(stream, " %8e", disto);
249                                                                                         fprintf(stream, "\n");
250                                                                                         total_disto += disto;
251                                                                                         pack_nb++; 
252                                                                                 }
253                                                                         }
254                                                                 }/* x = x0..x1 */
255                                                         } 
256                                                 }  /* y = y0..y1 */
257                                         } /* precno */
258                                 } /* compno */
259                         } /* resno */
260                 } /* RPCL */
261
262                 else if (cstr_info->prog == OPJ_PCRL) { /* PCRL */
263                         /* I suppose components have same XRsiz, YRsiz */
264                         int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
265                         int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
266                         int x1 = x0 + cstr_info->tile_x;
267                         int y1 = y0 + cstr_info->tile_y;
268
269                         /* Count the maximum number of precincts */
270                         int max_numprec = 0;
271                         for (resno = 0; resno < max_numdecompos + 1; resno++) {
272                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
273                                 if (numprec > max_numprec)
274                                         max_numprec = numprec;
275                         }
276
277                         fprintf(stream, "PCRL\npack_nb tileno precno compno resno layno start_pos end_ph_pos end_pos"); 
278                         if (disto_on)
279                                 fprintf(stream, " disto");
280                         fprintf(stream,"\n");
281
282                         for (precno = 0; precno < max_numprec; precno++) {
283                                 for (compno = 0; compno < cstr_info->numcomps; compno++) {
284                                         for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
285                                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
286                                                 int pcnx = cstr_info->tile[tileno].pw[resno];
287                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
288                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
289                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
290                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );
291                                                 if (precno >= numprec)
292                                                         continue;
293                                                 for(y = y0; y < y1; y++) {                                                      
294                                                         if (precno_y*pcy == y ) {
295                                                                 for (x = x0; x < x1; x++) {                                                                     
296                                                                         if (precno_x*pcx == x ) {
297                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
298                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
299                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
300                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
301                                                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;
302                                                                                         fprintf(stream, "%4d %6d %6d %6d %5d %7d %9" PRId64 "   %9" PRId64 " %7" PRId64,
303                                                                                                 pack_nb, tileno, precno, compno, resno, layno, start_pos, end_ph_pos, end_pos); 
304                                                                                         if (disto_on)
305                                                                                                 fprintf(stream, " %8e", disto);
306                                                                                         fprintf(stream, "\n");
307                                                                                         total_disto += disto;
308                                                                                         pack_nb++; 
309                                                                                 }
310                                                                         }
311                                                                 }/* x = x0..x1 */
312                                                         } 
313                                                 }  /* y = y0..y1 */
314                                         } /* resno */
315                                 } /* compno */
316                         } /* precno */
317                 } /* PCRL */
318
319                 else {  /* CPRL */
320                         /* Count the maximum number of precincts */
321                         int max_numprec = 0;
322                         for (resno = 0; resno < max_numdecompos + 1; resno++) {
323                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
324                                 if (numprec > max_numprec)
325                                         max_numprec = numprec;
326                         }
327
328                         fprintf(stream, "CPRL\npack_nb tileno compno precno resno layno start_pos end_ph_pos end_pos"); 
329                         if (disto_on)
330                                 fprintf(stream, " disto");
331                         fprintf(stream,"\n");
332
333                         for (compno = 0; compno < cstr_info->numcomps; compno++) {
334                                 /* I suppose components have same XRsiz, YRsiz */
335                                 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
336                                 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
337                                 int x1 = x0 + cstr_info->tile_x;
338                                 int y1 = y0 + cstr_info->tile_y;
339
340                                 for (precno = 0; precno < max_numprec; precno++) {
341                                         for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
342                                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
343                                                 int pcnx = cstr_info->tile[tileno].pw[resno];
344                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
345                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
346                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
347                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );
348                                                 if (precno >= numprec)
349                                                         continue;
350
351                                                 for(y = y0; y < y1; y++) {
352                                                         if (precno_y*pcy == y ) {
353                                                                 for (x = x0; x < x1; x++) {
354                                                                         if (precno_x*pcx == x ) {
355                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
356                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
357                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
358                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
359                                                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;
360                                                                                         fprintf(stream, "%4d %6d %6d %6d %5d %7d %9" PRId64 "   %9" PRId64 " %7" PRId64,
361                                                                                                 pack_nb, tileno, compno, precno, resno, layno, start_pos, end_ph_pos, end_pos); 
362                                                                                         if (disto_on)
363                                                                                                 fprintf(stream, " %8e", disto);
364                                                                                         fprintf(stream, "\n");
365                                                                                         total_disto += disto;
366                                                                                         pack_nb++; 
367                                                                                 }
368                                                                         }
369                                                                 }/* x = x0..x1 */
370                                                         }
371                                                 } /* y = y0..y1 */
372                                         } /* resno */
373                                 } /* precno */
374                         } /* compno */
375                 } /* CPRL */   
376         } /* tileno */
377         
378         if (disto_on) {
379                 fprintf(stream, "%8e\n", cstr_info->D_max); /* SE max */        
380                 fprintf(stream, "%.8e\n", total_disto); /* SE totale */
381         }
382 /* UniPG>> */
383         /* print the markers' list */
384         if (cstr_info->marknum) {
385                 fprintf(stream, "\nMARKER LIST\n");
386                 fprintf(stream, "%d\n", cstr_info->marknum);
387                 fprintf(stream, "type\tstart_pos    length\n");
388                 for (x = 0; x < cstr_info->marknum; x++)
389                         fprintf(stream, "%X\t%9" PRId64 " %9d\n", cstr_info->marker[x].type, cstr_info->marker[x].pos, cstr_info->marker[x].len);
390         }
391 /* <<UniPG */
392         fclose(stream);
393
394         fprintf(stderr,"Generated index file %s\n", index);
395
396         return 0;
397 }