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