[trunk] use hidden visibility for static library (fixes issue 354)
[openjpeg.git] / src / bin / jpwl / 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
40 /* ------------------------------------------------------------------------------------ */
41
42 /**
43 Write a structured index to a file
44 @param cstr_info Codestream information 
45 @param index Index filename
46 @return Returns 0 if successful, returns 1 otherwise
47 */
48 int write_index_file(opj_codestream_info_t *cstr_info, char *index) {
49         int tileno, compno, layno, resno, precno, pack_nb, x, y;
50         FILE *stream = NULL;
51         double total_disto = 0;
52 /* UniPG>> */
53         int tilepartno;
54         char disto_on, numpix_on;
55
56 #ifdef USE_JPWL
57         if (!strcmp(index, JPWL_PRIVATEINDEX_NAME))
58                 return 0;
59 #endif /* USE_JPWL */
60 /* <<UniPG */
61
62         if (!cstr_info)         
63                 return 1;
64
65         stream = fopen(index, "w");
66         if (!stream) {
67                 fprintf(stderr, "failed to open index file [%s] for writing\n", index);
68                 return 1;
69         }
70         
71         if (cstr_info->tile[0].distotile)
72                 disto_on = 1;
73         else 
74                 disto_on = 0;
75
76         if (cstr_info->tile[0].numpix)
77                 numpix_on = 1;
78         else 
79                 numpix_on = 0;
80
81         fprintf(stream, "%d %d\n", cstr_info->image_w, cstr_info->image_h);
82         fprintf(stream, "%d\n", cstr_info->prog);
83         fprintf(stream, "%d %d\n", cstr_info->tile_x, cstr_info->tile_y);
84         fprintf(stream, "%d %d\n", cstr_info->tw, cstr_info->th);
85         fprintf(stream, "%d\n", cstr_info->numcomps);
86         fprintf(stream, "%d\n", cstr_info->numlayers);
87         fprintf(stream, "%d\n", cstr_info->numdecompos[0]); /* based on component 0 */
88
89         for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
90                 fprintf(stream, "[%d,%d] ", 
91                         (1 << cstr_info->tile[0].pdx[resno]), (1 << cstr_info->tile[0].pdx[resno]));    /* based on tile 0 and component 0 */
92         }
93
94         fprintf(stream, "\n");
95 /* UniPG>> */
96         fprintf(stream, "%d\n", cstr_info->main_head_start);
97 /* <<UniPG */
98         fprintf(stream, "%d\n", cstr_info->main_head_end);
99         fprintf(stream, "%d\n", cstr_info->codestream_size);
100         
101         fprintf(stream, "\nINFO ON TILES\n");
102         fprintf(stream, "tileno start_pos  end_hd  end_tile   nbparts");
103         if (disto_on)
104                 fprintf(stream,"         disto");
105         if (numpix_on)
106                 fprintf(stream,"     nbpix");
107         if (disto_on && numpix_on)
108                 fprintf(stream,"  disto/nbpix");
109         fprintf(stream, "\n");
110
111         for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
112                 fprintf(stream, "%4d %9d %9d %9d %9d", 
113                         cstr_info->tile[tileno].tileno,
114                         cstr_info->tile[tileno].start_pos,
115                         cstr_info->tile[tileno].end_header,
116                         cstr_info->tile[tileno].end_pos,
117                         cstr_info->tile[tileno].num_tps);
118                 if (disto_on)
119                         fprintf(stream," %9e", cstr_info->tile[tileno].distotile);
120                 if (numpix_on)
121                         fprintf(stream," %9d", cstr_info->tile[tileno].numpix);
122                 if (disto_on && numpix_on)
123                         fprintf(stream," %9e", cstr_info->tile[tileno].distotile / cstr_info->tile[tileno].numpix);
124                 fprintf(stream, "\n");
125         }
126                 
127         for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
128                 int start_pos, end_ph_pos, end_pos;
129                 double disto = 0;
130                 int max_numdecompos = 0;
131                 pack_nb = 0;
132
133                 for (compno = 0; compno < cstr_info->numcomps; compno++) {
134                         if (max_numdecompos < cstr_info->numdecompos[compno])
135                                 max_numdecompos = cstr_info->numdecompos[compno];
136                 }       
137
138                 fprintf(stream, "\nTILE %d DETAILS\n", tileno); 
139                 fprintf(stream, "part_nb tileno  start_pack num_packs  start_pos end_tph_pos   end_pos\n");
140                 for (tilepartno = 0; tilepartno < cstr_info->tile[tileno].num_tps; tilepartno++)
141                         fprintf(stream, "%4d %9d   %9d %9d  %9d %11d %9d\n",
142                                 tilepartno, tileno,
143                                 cstr_info->tile[tileno].tp[tilepartno].tp_start_pack,
144                                 cstr_info->tile[tileno].tp[tilepartno].tp_numpacks,
145                                 cstr_info->tile[tileno].tp[tilepartno].tp_start_pos,
146                                 cstr_info->tile[tileno].tp[tilepartno].tp_end_header,
147                                 cstr_info->tile[tileno].tp[tilepartno].tp_end_pos
148                                 );
149
150                 if (cstr_info->prog == LRCP) {  /* LRCP */
151                         fprintf(stream, "LRCP\npack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos");
152                         if (disto_on)
153                                 fprintf(stream, " disto");
154                         fprintf(stream,"\n");
155
156                         for (layno = 0; layno < cstr_info->numlayers; layno++) {
157                                 for (resno = 0; resno < max_numdecompos + 1; resno++) {
158                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {
159                                                 int prec_max;
160                                                 if (resno > cstr_info->numdecompos[compno])
161                                                         break;
162                                                 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
163                                                 for (precno = 0; precno < prec_max; precno++) {
164                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
165                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
166                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
167                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;
168                                                         fprintf(stream, "%4d %6d %7d %5d %6d  %6d    %6d     %6d %7d",
169                                                                 pack_nb, tileno, layno, resno, compno, precno, start_pos, end_ph_pos, end_pos);
170                                                         if (disto_on)
171                                                                 fprintf(stream, " %8e", disto);
172                                                         fprintf(stream, "\n");
173                                                         total_disto += disto;
174                                                         pack_nb++;
175                                                 }
176                                         }
177                                 }
178                         }
179                 } /* LRCP */
180
181                 else if (cstr_info->prog == RLCP) {     /* RLCP */                      
182                         fprintf(stream, "RLCP\npack_nb tileno resno layno compno precno start_pos end_ph_pos end_pos\n");
183                         if (disto_on)
184                                 fprintf(stream, " disto");
185                         fprintf(stream,"\n");
186
187                         for (resno = 0; resno < max_numdecompos + 1; resno++) {
188                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
189                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {
190                                                 int prec_max; 
191                                                 if (resno > cstr_info->numdecompos[compno])
192                                                         break;
193                                                 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
194                                                 for (precno = 0; precno < prec_max; precno++) {
195                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
196                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
197                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
198                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;
199                                                         fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d   %9d %7d",
200                                                                 pack_nb, tileno, resno, layno, compno, precno, start_pos, end_ph_pos, end_pos);
201                                                         if (disto_on)
202                                                                 fprintf(stream, " %8e", disto);
203                                                         fprintf(stream, "\n");
204                                                         total_disto += disto;
205                                                         pack_nb++;
206                                                 }
207                                         }
208                                 }
209                         }
210                 } /* RLCP */
211
212                 else if (cstr_info->prog == RPCL) {     /* RPCL */
213
214                         fprintf(stream, "RPCL\npack_nb tileno resno precno compno layno start_pos end_ph_pos end_pos"); 
215                         if (disto_on)
216                                 fprintf(stream, " disto");
217                         fprintf(stream,"\n");
218
219                         for (resno = 0; resno < max_numdecompos + 1; resno++) {
220                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
221                                 for (precno = 0; precno < numprec; precno++) {                                                          
222                                         /* I suppose components have same XRsiz, YRsiz */
223                                         int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
224                                         int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
225                                         int x1 = x0 + cstr_info->tile_x;
226                                         int y1 = y0 + cstr_info->tile_y;
227                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {                                      
228                                                 int pcnx = cstr_info->tile[tileno].pw[resno];
229                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
230                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
231                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
232                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );
233                                                 if (resno > cstr_info->numdecompos[compno])
234                                                         break;
235                                                 for(y = y0; y < y1; y++) {                                                      
236                                                         if (precno_y*pcy == y ) {
237                                                                 for (x = x0; x < x1; x++) {                                                                     
238                                                                         if (precno_x*pcx == x ) {
239                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
240                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
241                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
242                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
243                                                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;
244                                                                                         fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d   %9d %7d",
245                                                                                                 pack_nb, tileno, resno, precno, compno, layno, start_pos, end_ph_pos, end_pos); 
246                                                                                         if (disto_on)
247                                                                                                 fprintf(stream, " %8e", disto);
248                                                                                         fprintf(stream, "\n");
249                                                                                         total_disto += disto;
250                                                                                         pack_nb++; 
251                                                                                 }
252                                                                         }
253                                                                 }/* x = x0..x1 */
254                                                         } 
255                                                 }  /* y = y0..y1 */
256                                         } /* precno */
257                                 } /* compno */
258                         } /* resno */
259                 } /* RPCL */
260
261                 else if (cstr_info->prog == PCRL) {     /* PCRL */
262                         /* I suppose components have same XRsiz, YRsiz */
263                         int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
264                         int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
265                         int x1 = x0 + cstr_info->tile_x;
266                         int y1 = y0 + cstr_info->tile_y;
267
268                         /* Count the maximum number of precincts */
269                         int max_numprec = 0;
270                         for (resno = 0; resno < max_numdecompos + 1; resno++) {
271                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
272                                 if (numprec > max_numprec)
273                                         max_numprec = numprec;
274                         }
275
276                         fprintf(stream, "PCRL\npack_nb tileno precno compno resno layno start_pos end_ph_pos end_pos"); 
277                         if (disto_on)
278                                 fprintf(stream, " disto");
279                         fprintf(stream,"\n");
280
281                         for (precno = 0; precno < max_numprec; precno++) {
282                                 for (compno = 0; compno < cstr_info->numcomps; compno++) {
283                                         for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
284                                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
285                                                 int pcnx = cstr_info->tile[tileno].pw[resno];
286                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
287                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
288                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
289                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );
290                                                 if (precno >= numprec)
291                                                         continue;
292                                                 for(y = y0; y < y1; y++) {                                                      
293                                                         if (precno_y*pcy == y ) {
294                                                                 for (x = x0; x < x1; x++) {                                                                     
295                                                                         if (precno_x*pcx == x ) {
296                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
297                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
298                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
299                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
300                                                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;
301                                                                                         fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d   %9d %7d",
302                                                                                                 pack_nb, tileno, precno, compno, resno, layno, start_pos, end_ph_pos, end_pos); 
303                                                                                         if (disto_on)
304                                                                                                 fprintf(stream, " %8e", disto);
305                                                                                         fprintf(stream, "\n");
306                                                                                         total_disto += disto;
307                                                                                         pack_nb++; 
308                                                                                 }
309                                                                         }
310                                                                 }/* x = x0..x1 */
311                                                         } 
312                                                 }  /* y = y0..y1 */
313                                         } /* resno */
314                                 } /* compno */
315                         } /* precno */
316                 } /* PCRL */
317
318                 else {  /* CPRL */
319                         /* Count the maximum number of precincts */
320                         int max_numprec = 0;
321                         for (resno = 0; resno < max_numdecompos + 1; resno++) {
322                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
323                                 if (numprec > max_numprec)
324                                         max_numprec = numprec;
325                         }
326
327                         fprintf(stream, "CPRL\npack_nb tileno compno precno resno layno start_pos end_ph_pos end_pos"); 
328                         if (disto_on)
329                                 fprintf(stream, " disto");
330                         fprintf(stream,"\n");
331
332                         for (compno = 0; compno < cstr_info->numcomps; compno++) {
333                                 /* I suppose components have same XRsiz, YRsiz */
334                                 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
335                                 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
336                                 int x1 = x0 + cstr_info->tile_x;
337                                 int y1 = y0 + cstr_info->tile_y;
338
339                                 for (precno = 0; precno < max_numprec; precno++) {
340                                         for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
341                                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
342                                                 int pcnx = cstr_info->tile[tileno].pw[resno];
343                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
344                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
345                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
346                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );
347                                                 if (precno >= numprec)
348                                                         continue;
349
350                                                 for(y = y0; y < y1; y++) {
351                                                         if (precno_y*pcy == y ) {
352                                                                 for (x = x0; x < x1; x++) {
353                                                                         if (precno_x*pcx == x ) {
354                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
355                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
356                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
357                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
358                                                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;
359                                                                                         fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d   %9d %7d",
360                                                                                                 pack_nb, tileno, compno, precno, resno, layno, start_pos, end_ph_pos, end_pos); 
361                                                                                         if (disto_on)
362                                                                                                 fprintf(stream, " %8e", disto);
363                                                                                         fprintf(stream, "\n");
364                                                                                         total_disto += disto;
365                                                                                         pack_nb++; 
366                                                                                 }
367                                                                         }
368                                                                 }/* x = x0..x1 */
369                                                         }
370                                                 } /* y = y0..y1 */
371                                         } /* resno */
372                                 } /* precno */
373                         } /* compno */
374                 } /* CPRL */   
375         } /* tileno */
376         
377         if (disto_on) {
378                 fprintf(stream, "%8e\n", cstr_info->D_max); /* SE max */        
379                 fprintf(stream, "%.8e\n", total_disto); /* SE totale */
380         }
381 /* UniPG>> */
382         /* print the markers' list */
383         if (cstr_info->marknum) {
384                 fprintf(stream, "\nMARKER LIST\n");
385                 fprintf(stream, "%d\n", cstr_info->marknum);
386                 fprintf(stream, "type\tstart_pos    length\n");
387                 for (x = 0; x < cstr_info->marknum; x++)
388                         fprintf(stream, "%X\t%9d %9d\n", cstr_info->marker[x].type, cstr_info->marker[x].pos, cstr_info->marker[x].len);
389         }
390 /* <<UniPG */
391         fclose(stream);
392
393         fprintf(stderr,"Generated index file %s\n", index);
394
395         return 0;
396 }