Update for version 0.8
[openjpeg.git] / codec / image_to_j2k.c
1 /*
2  * Copyright (c) 2001-2003, David Janssens
3  * Copyright (c) 2002-2003, Yannick Verschueren
4  * Copyright (c) 2002-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 #include <openjpeg.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <math.h>
33 #include <string.h>
34 #ifndef DONT_HAVE_GETOPT
35 #include <getopt.h>
36 #else
37 #include "compat/getopt.h"
38 #endif
39 #include "convert.h"
40
41 void help_display()
42 {
43         printf("HELP\n----\n\n");
44         printf
45                 ("- the option -help displays the readme.txt file on screen\n\n");
46
47
48         printf("List of parameters for the coder JPEG 2000 :\n");
49         printf("\n");
50         printf
51                 ("- The markers COD and QCD are writed both of two in the main_header and never appear in the tile_header.  The markers in the main header are : SOC SIZ COD QCD COM.\n");
52         printf("\n");
53         printf
54                 ("- This coder can encode mega image, a test was made on a 24000x24000 pixels color image.  You need enough disk space memory (twice the original) to encode the image. (i.e. for a 1.5 Gb image you need a minimum of 3Gb of disk memory)\n");
55         printf("\n");
56         printf("REMARKS :\n");
57         printf("---------\n");
58         printf("\n");
59         printf
60                 ("* the value of rate enter in the code line is the compression factor !\n");
61         printf("exemple :\n");
62         printf("\n");
63         printf
64                 ("-r 20,10,1 means quality 1 : compress 20x, quality 2 : compress 10x and quality 3 : compress 1x = lossless\n");
65         printf("\n");
66         printf("By default :\n");
67         printf("------------\n");
68         printf("\n");
69         printf(" * lossless\n");
70         printf(" * 1 tile\n");
71         printf(" * size of precinct 2^15 x 2^15 (means 1 precinct)\n");
72         printf(" * size of code-block 64 x 64\n");
73         printf(" * Number of resolution : 6\n");
74         printf(" * No SOP marker in the codestream\n");
75         printf(" * No EPH marker in the codestream\n");
76         printf(" * No sub-sampling in x and y direction\n");
77         printf(" * No mode switch activated\n");
78         printf(" * progression order : LRCP\n");
79         printf(" * No index file\n");
80         printf(" * No ROI upshifted\n");
81         printf(" * No offset of the origin of the image\n");
82         printf(" * No offset of the origin of the tiles\n");
83         printf(" * Reversible DWT 5-3\n");
84         printf("\n");
85         printf("Parameters :\n");
86         printf("------------\n");
87         printf("\n");
88         printf
89                 ("-i             : source file  (-i source.pnm also *.pgm, *.ppm) required\n");
90         printf("\n");
91         printf
92                 ("-o             : destination file (-o dest.j2k) required\n");
93         printf("\n");
94         printf
95                 ("-help          : Display the help information optional\n ");
96         printf("\n");
97         printf
98                 ("-r             : different rates (-r 20,10,5) optional\n ");
99         printf("\n");
100         printf
101                 ("-n             : Number of resolution (-n 3) optional\n");
102         printf("\n");
103         printf
104                 ("-b             : size of code block (-b 32,32) optional\n");
105         printf("\n");
106         printf
107                 ("-c             : size of precinct (-c 128,128) optional\n");
108         printf("\n");
109         printf
110                 ("-t             : size of tile (-t 512,512) optional\n");
111         printf("\n");
112         printf
113                 ("-p             : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] optional\n");
114         printf("\n");
115         printf
116                 ("-s             : subsampling factor (-s 2,2) [-s X,Y] optional\n");
117         printf("\n");
118         printf
119                 ("-SOP           : write SOP marker before each packet optional\n");
120         printf("\n");
121         printf
122                 ("-EPH           : write EPH marker after each header packet optional\n");
123         printf("\n");
124         printf
125                 ("-M             : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL) 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] optional\n");
126         printf
127                 ("                    for several mode switch you have to add the value of each mode you want\n");
128         printf
129                 ("                    ex : RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
130         printf("\n");
131         printf
132                 ("-x             : Create an index file *.Idx (-x index_name.Idx) optional\n");
133         printf("\n");
134         printf
135                 ("-ROI:c=%%d,U=%%d : quantization indices upshifted for component c=%%d [\%%d = 0,1,2]\n");
136         printf
137                 ("                 with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) optional\n");
138         printf("\n");
139         printf
140                 ("-d             : offset of the origin of the image (-d 150,300) optional\n");
141         printf("\n");
142         printf
143                 ("-T             : offset of the origin of the tiles (-T 100,75) optional\n");
144         printf("\n");
145         printf
146                 ("-I             : Use the irreversible DWT 9-7 (-I) optional\n");
147         printf("\n");
148         printf("IMPORTANT :\n");
149         printf("-----------\n");
150         printf("\n");
151         printf("* subsampling bigger than 2 can produce error\n");
152         printf("\n");
153         printf
154                 ("The index file respect the structure below :\n");
155         printf
156                 ("---------------------------------------------\n");
157         printf("\n");
158         printf("Image_height Image_width\n");
159         printf("progression order\n");
160         printf("Tiles_size_X Tiles_size_Y\n");
161         printf("Components_nb\n");
162         printf("Layers_nb\n");
163         printf("decomposition_levels\n");
164         printf("Precincts_size_X Precincts_size_Y\n");
165         printf("Main_header_end_position\n");
166         printf("Codestream_size\n");
167         printf("Tile0 start_pos end_Theader end_pos\n");
168         printf("Tile1  ''           ''        ''\n");
169         printf("...\n");
170         printf("TileN  ''           ''        ''\n");
171         printf("Tpacket_0 Tile layer res. comp. prec. start_pos end_pos\n");
172         printf("...\n");
173         printf("Tpacket_M  ''    ''   ''   ''    ''       ''       ''\n");
174 }
175
176 int give_progression(char progression[4])
177 {
178   if (progression[0] == 'L' && progression[1] == 'R' && progression[2] == 'C' && progression[3] == 'P') 
179     {
180       return 0;
181     } else 
182       {
183         if (progression[0] == 'R' && progression[1] == 'L' && progression[2] == 'C' && progression[3] == 'P') 
184           {
185             return 1;
186           } else 
187             {
188               if (progression[0] == 'R' && progression[1] == 'P' && progression[2] == 'C' && progression[3] == 'L') 
189                 {
190                   return 2;
191                 } else 
192                   {
193                     if (progression[0] == 'P' && progression[1] == 'C' && progression[2] == 'R' && progression[3] == 'L') 
194                       {
195                         return 3;
196                       } else 
197                         {
198                           if (progression[0] == 'C' && progression[1] == 'P' && progression[2] == 'R' && progression[3] == 'L') 
199                             {
200                               return 4;
201                             } else 
202                               {
203                                 return -1;
204                               }
205                         }
206                   }
207             }
208       }
209 }
210
211 double dwt_norms_97[4][10] = {
212         {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
213         {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
214         {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
215         {2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
216 };
217
218 int floorlog2(int a)
219 {
220         int l;
221         for (l = 0; a > 1; l++) {
222                 a >>= 1;
223         }
224         return l;
225 }
226
227 void encode_stepsize(int stepsize, int numbps, int *expn, int *mant)
228 {
229         int p, n;
230         p = floorlog2(stepsize) - 13;
231         n = 11 - floorlog2(stepsize);
232         *mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff;
233         *expn = numbps - p;
234 }
235
236 void calc_explicit_stepsizes(j2k_tccp_t * tccp, int prec)
237 {
238         int numbands, bandno;
239         numbands = 3 * tccp->numresolutions - 2;
240         for (bandno = 0; bandno < numbands; bandno++) {
241                 double stepsize;
242
243                 int resno, level, orient, gain;
244                 resno = bandno == 0 ? 0 : (bandno - 1) / 3 + 1;
245                 orient = bandno == 0 ? 0 : (bandno - 1) % 3 + 1;
246                 level = tccp->numresolutions - 1 - resno;
247                 gain = tccp->qmfbid == 0 ? 0 : (orient == 0 ? 0 : (orient == 1 || orient == 2 ? 1 : 2));
248                 if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) {
249                         stepsize = 1.0;
250                 } else {
251                         double norm = dwt_norms_97[orient][level];
252                         stepsize = (1 << (gain + 1)) / norm;
253                 }
254                 encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno].expn,
255                                 &tccp->stepsizes[bandno].mant);
256         }
257 }
258
259 int main(int argc, char **argv)
260 {
261         int len;
262         int NumResolution, numD_min;    /*   NumResolution : number of resolution                     */
263         int Tile_arg;                   /*   Tile_arg = 0 (not in argument) ou = 1 (in argument)      */
264         int CSty;                       /*   CSty : coding style                                      */
265         int Prog_order;                 /*   progression order (default LRCP)                         */
266         char progression[4];
267         int numpocs, numpocs_tile;      /*   Number of progression order change (POC) default 0       */
268         int prcw_init, prch_init;       /*   Initialisation precincts' size                           */
269         int cblockw_init, cblockh_init; /*   Initialisation codeblocks' size                          */
270         int mode, value;                /*   Mode switch (cblk_style)                                 */
271         int subsampling_dx, subsampling_dy;     /* subsampling value for dx and dy                    */
272         int ROI_compno, ROI_shift;      /*   region of interrest                                      */
273         int Dim[2];                     /*   portion of the image coded                               */
274         int TX0, TY0;                   /*   tile off-set                                             */
275         j2k_image_t img;
276         j2k_cp_t cp, cp_init;           /*   cp_init is used to initialise in multiple tiles          */
277         j2k_tcp_t *tcp, *tcp_init;      /*   tcp_init is used to initialise in multiple tile          */
278         j2k_poc_t POC[32];              /*   POC : used in case of Progression order change           */
279         j2k_poc_t *tcp_poc;
280         j2k_tccp_t *tccp;
281         int i, tileno, j;
282         char *infile = 0;
283         char *outfile = 0;
284         char *index = 0;
285         char *s, S1, S2, S3;
286         int ir = 0;
287
288         /* default value */
289         /* ------------- */
290         NumResolution = 6;
291         CSty = 0;
292         cblockw_init = 64;
293         cblockh_init = 64;
294         cp.tw = 1;
295         cp.th = 1;
296         img.index_on = 0;
297         Prog_order = 0;
298         numpocs = 0;
299         mode = 0;
300         subsampling_dx = 1;
301         subsampling_dy = 1;
302         ROI_compno = -1;        /* no ROI */
303         ROI_shift = 0;
304         Dim[0] = 0;
305         Dim[1] = 0;
306         TX0 = 0;
307         TY0 = 0;
308         cp.comment = NULL;
309         cp.disto_alloc = 0;
310         cp.fixed_alloc = 0;
311         /* img.PPT=0; */
312
313         Tile_arg = 0;
314         cp_init.tcps = (j2k_tcp_t *) malloc(sizeof(j2k_tcp_t)); /* initialisation if only one tile */
315         tcp_init = &cp_init.tcps[0];
316         tcp_init->numlayers = 0;
317
318         while (1) {
319                 int c =
320                         getopt(argc, argv, "i:o:r:q:t:n:c:b:x:p:s:d:h:P:S:E:M:R:T:C:I");
321                 if (c == -1)
322                         break;
323                 switch (c) {
324                 case 'i':       /* IN fill */
325                         infile = optarg;
326                         s = optarg;
327                         while (*s) {
328                                 s++;
329                         }
330                         s--;
331                         S3 = *s;
332                         s--;
333                         S2 = *s;
334                         s--;
335                         S1 = *s;
336
337                         if ((S1 == 'p' && S2 == 'g' && S3 == 'x') || (S1 == 'P' && S2 == 'G' && S3 == 'X')) {
338                                 cp.image_type = 0;
339                                 break;
340                         }
341
342                         if ((S1 == 'p' && S2 == 'n' && S3 == 'm')|| (S1 == 'P' && S2 == 'N' && S3 == 'M') 
343                             || (S1 == 'p' && S2 == 'g' && S3 == 'm') || (S1 == 'P' && S2 == 'G' && S3 == 'M') 
344                             || (S1 == 'P' && S2 == 'P' && S3 == 'M') || (S1 == 'p' && S2 == 'p' && S3 == 'm')) {
345                                 cp.image_type = 1;
346                                 break;
347                         }
348
349                         if ((S1 == 'b' && S2 == 'm' && S3 == 'p') || (S1 == 'B' && S2 == 'M' && S3 == 'P')) {
350                                 cp.image_type = 2;
351                                 break;
352                         }
353                         fprintf(stderr, "!! Unrecognized format for infile : %c%c%c [accept only *.pnm, *.pgm, *.ppm, *.pgx or *.bmp] !!\n\n",S1,S2,S3);
354                         return 1;
355                         break;
356                         /* ----------------------------------------------------- */
357                 case 'o':       /* OUT fill */
358                         outfile = optarg;
359                         break;
360                         /* ----------------------------------------------------- */
361                 case 'r':       /* rates rates/distorsion*/
362                         s = optarg;
363                         while (sscanf(s, "%d", &tcp_init->rates[tcp_init->numlayers]) == 1) {
364                                 tcp_init->numlayers++;
365                                 while (*s && *s != ',') {
366                                         s++;
367                                 }
368                                 if (!*s)
369                                         break;
370                                 s++;
371                         }
372                         cp.disto_alloc = 1;
373                         cp.matrice = NULL;
374                         break;
375                         /* ----------------------------------------------------- */
376                 case 'q':       /* rates fixed */
377                   s=optarg;
378                   sscanf(s, "%d",&tcp_init->numlayers);
379                   s++;
380                   if (tcp_init->numlayers>9) s++;
381                   cp.matrice=(int*)malloc(tcp_init->numlayers*NumResolution*3*sizeof(int));
382                   s=s+2;
383                   for(i=0;i<tcp_init->numlayers;i++)
384                     {
385                       tcp_init->rates[i]=1;
386                       sscanf(s, "%d,", &cp.matrice[i*NumResolution*3]);
387                       s+=2;
388                       if (cp.matrice[i*NumResolution*3]>9) s++;
389                       cp.matrice[i*NumResolution*3+1]=0;
390                       cp.matrice[i*NumResolution*3+2]=0;
391                       for (j=1;j<NumResolution;j++)
392                         {
393                           sscanf(s, "%d,%d,%d", &cp.matrice[i*NumResolution*3+j*3+0],&cp.matrice[i*NumResolution*3+j*3+1],&cp.matrice[i*NumResolution*3+j*3+2]);
394                           s+=6;
395                           if (cp.matrice[i*NumResolution*3+j*3]>9) s++;
396                           if (cp.matrice[i*NumResolution*3+j*3+1]>9) s++;
397                           if (cp.matrice[i*NumResolution*3+j*3+2]>9) s++;  
398                         }
399                       if (i<tcp_init->numlayers-1) s++;
400                     }
401                   cp.fixed_alloc=1;
402                   break;
403                         /* ----------------------------------------------------- */
404                 case 't':       /* tiles */
405                         sscanf(optarg, "%d,%d", &cp.tdx, &cp.tdy);
406                         Tile_arg = 1;
407                         break;
408                         /* ----------------------------------------------------- */
409                 case 'n':       /* resolution */
410                         sscanf(optarg, "%d", &NumResolution);
411                         break;
412                         /* ----------------------------------------------------- */
413                 case 'c':       /* precinct dimension */
414                         sscanf(optarg, "%d,%d", &prcw_init, &prch_init);
415                         CSty |= 0x01;
416                         break;
417                         /* ----------------------------------------------------- */
418                 case 'b':       /* code-block dimension */
419                         sscanf(optarg, "%d,%d", &cblockw_init, &cblockh_init);
420                         if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
421                                         || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
422                                 fprintf(stderr,"!! Size of code_block error (option -b) !!\n\nRestriction :\n    * width*height<=4096\n    * 4<=width,height<= 1024\n\n");
423                                 return 1;
424                         }
425                         break;
426                         /* ----------------------------------------------------- */
427                 case 'x':       /* creation of index file */
428                         index = optarg;
429                         img.index_on = 1;
430                         break;
431                         /* ----------------------------------------------------- */
432                 case 'p':       /* progression order */
433                         s = optarg;
434                         for (i=0; i<4; i++)
435                           {
436                             progression[i] = *s;
437                             s++;
438                           }
439                         Prog_order = give_progression(progression);
440                         
441                         if (Prog_order == -1) {
442                           fprintf(stderr,"Unrecognized progression order [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
443                           return 1;
444                         }
445                         break;
446                         /* ----------------------------------------------------- */
447                 case 's':       /* subsampling factor */
448                         if (sscanf(optarg, "%d,%d", &subsampling_dx, &subsampling_dy) != 2) {
449                                 fprintf(stderr,"'-s' sub-sampling argument error !  [-s dx,dy]\n");
450                                 return 1;
451                         }
452                         break;
453                         /* ----------------------------------------------------- */
454                 case 'd':       /* coordonnate of the reference grid */
455                         if (sscanf(optarg, "%d,%d", &Dim[0], &Dim[1]) != 2) {
456                                 fprintf(stderr,"-d 'coordonnate of the reference grid' argument error !! [-d x0,y0]\n");
457                                 return 1;
458                         }
459                         break;
460                         /* ----------------------------------------------------- */
461                 case 'h':       /* Display an help description */
462                         help_display();
463                         return 0;
464                         break;
465                         /* ----------------------------------------------------- */
466                 case 'P':       /* POC */
467                         fprintf(stderr, "/----------------------------------\\\n");
468                         fprintf(stderr, "|  POC option not fully tested !!  |\n");
469                         fprintf(stderr, "\\----------------------------------/\n");
470
471                         s = optarg;
472                         while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%s", &POC[numpocs].tile,
473                                       &POC[numpocs].resno0, &POC[numpocs].compno0,
474                                       &POC[numpocs].layno1, &POC[numpocs].resno1,
475                                       &POC[numpocs].compno1, POC[numpocs].progorder) == 7) {
476                                 POC[numpocs].prg = give_progression(POC[numpocs].progorder);
477                                 /* POC[numpocs].tile; */
478                                 numpocs++;
479                                 while (*s && *s != '/') {
480                                         s++;
481                                 }
482                                 if (!*s)
483                                         break;
484                                 s++;
485                         }
486                         break;
487                         /* ------------------------------------------------------ */
488                 case 'S':       /* SOP marker */
489                         CSty |= 0x02;
490                         break;
491                         /* ------------------------------------------------------ */
492                 case 'E':       /* EPH marker */
493                         CSty |= 0x04;
494                         break;
495                         /* ------------------------------------------------------ */
496                 case 'M':       /* Mode switch pas tous au point !! */
497                         if (sscanf(optarg, "%d", &value) == 1) {
498                                 for (i = 0; i <= 5; i++) {
499                                         int cache = value & (1 << i);
500                                         if (cache)
501                                                 mode |= (1 << i);
502                                 }
503                         }
504                         break;
505                         /* ------------------------------------------------------ */
506                 case 'R':       /* ROI */
507                         if (sscanf(optarg, "OI:c=%d,U=%d", &ROI_compno, &ROI_shift) != 2) {
508                                 fprintf(stderr,"ROI error !! [-ROI:c='compno',U='shift']\n");
509                                 return 1;
510                         }
511                         break;
512                         /* ------------------------------------------------------ */
513                 case 'T':       /* Tile offset */
514                         if (sscanf(optarg, "%d,%d", &TX0, &TY0) != 2) {
515                                 fprintf(stderr,"-T 'tile offset' argument error !! [-T X0,Y0]");
516                                 return 1;
517                         }
518                         break;
519                         /* ------------------------------------------------------ */
520                 case 'C':       /* Add a comment */
521                         cp.comment = optarg;
522                         break;
523                         /* ------------------------------------------------------ */
524                 case 'I':       /* reversible or not */
525                         ir = 1;
526                         break;
527                         /* ------------------------------------------------------ */
528                 default:
529                         return 1;
530                 }
531         }
532
533         cp.tx0 = TX0;
534         cp.ty0 = TY0;
535
536         /* Error messages */
537         /* -------------- */
538         if (!infile || !outfile) {
539                 fprintf(stderr, "usage: pnmtoj2k -i pnm-file -o j2k-file\n");
540                 return 1;
541         }
542
543         if (cp.disto_alloc & cp.fixed_alloc) {
544                 fprintf(stderr, "Error: option -r and -q can not be used together !!\n");
545                 return 1;
546         }
547
548         /* if no rate entered, lossless by default */
549         if (tcp_init->numlayers == 0) {
550                 tcp_init->rates[tcp_init->numlayers] = 1;
551                 tcp_init->numlayers++;
552                 cp.disto_alloc = 1;
553         }
554
555         if (TX0 > Dim[0] || TY0 > Dim[1]) {
556                 fprintf(stderr, "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
557                         TX0, Dim[0], TY0, Dim[1]);
558                 return 1;
559         }
560
561         for (i = 0; i < numpocs; i++) {
562                 if (POC[i].prg == -1) {
563                         fprintf(stderr, "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
564                                 i + 1);
565                 }
566         }
567
568         switch (cp.image_type) {
569         case 0:
570                 if (Tile_arg) {
571                         if (!pgxtoimage(infile, &img, cp.tdy, subsampling_dx, subsampling_dy, Dim, cp)) {
572                                 fprintf(stderr, "not a pgx file\n");
573                                 return 1;
574                         }
575                 } else {
576                         if (!pgxtoimage(infile, &img, -1, subsampling_dx, subsampling_dy, Dim, cp)) {
577                                 fprintf(stderr, " not a pgx file\n");
578                                 return 1;
579                         }
580                 }
581                 break;
582
583         case 1:
584                 if (!pnmtoimage(infile, &img, subsampling_dx, subsampling_dy, Dim)) {
585                         fprintf(stderr, " not a pnm file\n");
586                         return 1;
587                 }
588                 break;
589
590         case 2:
591                 if (!bmptoimage(infile, &img, subsampling_dx, subsampling_dy, Dim)) {
592                         fprintf(stderr, " not a bmp file\n");
593                         return 1;
594                 }
595                 break;
596         }
597         /* to respect profile - 0 */
598         /* ---------------------- */
599         numD_min = 0;
600         /*   while (int_ceildiv(img.x1,(1<<numD_min))-int_ceildiv(img.x0,(1<<numD_min))>120 || int_ceildiv(img.y1,(1<<numD_min))-int_ceildiv(img.y0,(1<<numD_min))>160) numD_min++;
601            if ((numD_min+1)>NumResolution)
602            {
603            fprintf(stderr,"\n********************************************************************************\n\n");
604            fprintf(stderr,  "In view to respect Profile-0, the number of resolution used is %d in place of %d\n\n",numD_min+1,NumResolution);
605            fprintf(stderr,  "********************************************************************************\n\n");
606            NumResolution=numD_min+1;
607            } */
608
609         if (Tile_arg == 1) {
610                 cp.tw = int_ceildiv(img.x1 - cp.tx0, cp.tdx);
611                 cp.th = int_ceildiv(img.y1 - cp.ty0, cp.tdy);
612         } else {
613                 cp.tdx = img.x1 - cp.tx0;
614                 cp.tdy = img.y1 - cp.ty0;
615         }
616
617         /* Initialization for PPM marker */
618         cp.ppm=0;
619         cp.ppm_data=NULL;
620         cp.ppm_previous=0;
621         cp.ppm_store=0;
622
623         /* Init the mutiple tiles */
624         /* ---------------------- */
625         cp.tcps = (j2k_tcp_t *) malloc(cp.tw * cp.th * sizeof(j2k_tcp_t));
626
627         for (tileno = 0; tileno < cp.tw * cp.th; tileno++) {
628                 tcp = &cp.tcps[tileno];
629                 tcp->numlayers = tcp_init->numlayers;
630                 for (j = 0; j < tcp->numlayers; j++) {
631                         tcp->rates[j] = tcp_init->rates[j];
632                 }
633                 tcp->csty = CSty;
634                 tcp->prg = Prog_order;
635                 tcp->mct = img.numcomps == 3 ? 1 : 0;
636                 tcp->ppt = 0;
637                 tcp->ppt_data=NULL; 
638                 tcp->ppt_store=0;
639
640                 numpocs_tile = 0;
641                 tcp->POC=0;
642                 if (numpocs) {
643                   /* intialisation of POC */
644                   tcp->POC=1;
645                   for (i = 0; i < numpocs; i++) {
646                                 if (tileno == POC[i].tile - 1 || POC[i].tile == -1) {
647                                         tcp_poc = &tcp->pocs[numpocs_tile];
648                                         tcp_poc->resno0 = POC[numpocs_tile].resno0;
649                                         tcp_poc->compno0 = POC[numpocs_tile].compno0;
650                                         tcp_poc->layno1 = POC[numpocs_tile].layno1;
651                                         tcp_poc->resno1 = POC[numpocs_tile].resno1;
652                                         tcp_poc->compno1 = POC[numpocs_tile].compno1;
653                                         tcp_poc->prg = POC[numpocs_tile].prg;
654                                         tcp_poc->tile = POC[numpocs_tile].tile;
655                                         numpocs_tile++;
656                                 }
657                         }
658                 }
659                 tcp->numpocs = numpocs_tile;
660                 tcp->tccps = (j2k_tccp_t *) malloc(img.numcomps * sizeof(j2k_tccp_t));
661
662                 for (i = 0; i < img.numcomps; i++) {
663                         tccp = &tcp->tccps[i];
664                         tccp->csty = CSty & 0x01;       /* 0 => one precinct || 1 => custom precinct  */
665                         tccp->numresolutions = NumResolution;
666                         tccp->cblkw = int_floorlog2(cblockw_init);
667                         tccp->cblkh = int_floorlog2(cblockh_init);
668                         tccp->cblksty = mode;
669                         tccp->qmfbid = ir ? 0 : 1;
670                         tccp->qntsty = ir ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT;
671                         tccp->numgbits = 2;
672                         if (i == ROI_compno)
673                                 tccp->roishift = ROI_shift;
674                         else
675                                 tccp->roishift = 0;
676                         if (CSty & J2K_CCP_CSTY_PRT) {
677
678                                 for (j = 0; j < tccp->numresolutions; j++) {
679                                         int size_prcw, size_prch;
680                                         size_prcw = prcw_init >> (tccp->numresolutions - j - 1);
681                                         size_prch = prch_init >> (tccp->numresolutions - j - 1);
682                                         if (size_prcw < 1) {
683                                                 tccp->prcw[j] = 1;
684                                         } else {
685                                                 tccp->prcw[j] =
686                                                         int_floorlog2(prcw_init >> (tccp->numresolutions - j - 1));
687                                         }
688                                         if (size_prch < 1) {
689                                                 tccp->prch[j] = 1;
690                                         } else {
691                                                 tccp->prch[j] =
692                                                         int_floorlog2(prch_init >> (tccp->numresolutions - j - 1));
693                                         }
694                                 }
695                         } else {
696                                 for (j = 0; j < tccp->numresolutions; j++) {
697                                         tccp->prcw[j] = 15;
698                                         tccp->prch[j] = 15;
699                                 }
700                         }
701                         calc_explicit_stepsizes(tccp, img.comps[i].prec);
702                 }
703         }
704
705         len = j2k_encode(&img, &cp, outfile, cp.tdx * cp.tdy * 2, index);
706         if (len == 0) {
707                 fprintf(stderr, "failed to encode image\n");
708                 return 1;
709         }
710
711         /* Remove the temporary files */
712         /* -------------------------- */
713         if (cp.image_type) { /* PNM PGM PPM */
714                 for (i = 0; i < img.numcomps; i++) {
715                         char tmp;
716                         sprintf(&tmp, "Compo%d", i);
717                         if (remove(&tmp) == -1) {
718                                 fprintf(stderr, "failed to kill %s file !\n", &tmp);
719                         }
720                 }
721         } else { /* PGX */
722                 for (i = 0; i < cp.th; i++) {
723                         char tmp;
724                         sprintf(&tmp, "bandtile%d", i + 1);
725
726                         if (remove(&tmp) == -1) {
727                                 fprintf(stderr, "failed to kill %s file !\n", &tmp);
728                         }
729                 }
730         }
731
732         return 0;
733 }