]> Creatis software - gdcm.git/blob - src/gdcmopenjpeg/codec/image_to_j2k.c
af61a2fb7c681e38985cef02c8273efb4cb3c5e6
[gdcm.git] / src / gdcmopenjpeg / codec / image_to_j2k.c
1 /*\r
2  * Copyright (c) 2001-2003, David Janssens\r
3  * Copyright (c) 2002-2003, Yannick Verschueren\r
4  * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe\r
5  * Copyright (c) 2005, HervĂ© Drolon, FreeImage Team\r
6  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium\r
7  * All rights reserved.\r
8  *\r
9  * Redistribution and use in source and binary forms, with or without\r
10  * modification, are permitted provided that the following conditions\r
11  * are met:\r
12  * 1. Redistributions of source code must retain the above copyright\r
13  *    notice, this list of conditions and the following disclaimer.\r
14  * 2. Redistributions in binary form must reproduce the above copyright\r
15  *    notice, this list of conditions and the following disclaimer in the\r
16  *    documentation and/or other materials provided with the distribution.\r
17  *\r
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
28  * POSSIBILITY OF SUCH DAMAGE.\r
29  */\r
30 #include <stdio.h>\r
31 #include <string.h>\r
32 #include <stdlib.h>\r
33 \r
34 #include "openjpeg.h"\r
35 #include "compat/getopt.h"\r
36 #include "convert.h"\r
37 \r
38 #ifndef WIN32\r
39 #define stricmp strcasecmp\r
40 #define strnicmp strncasecmp\r
41 #endif\r
42 \r
43 /* ----------------------------------------------------------------------- */\r
44 \r
45 #define J2K_CFMT 0\r
46 #define JP2_CFMT 1\r
47 #define JPT_CFMT 2\r
48 #define MJ2_CFMT 3\r
49 #define PXM_DFMT 0\r
50 #define PGX_DFMT 1\r
51 #define BMP_DFMT 2\r
52 #define YUV_DFMT 3\r
53 \r
54 /* ----------------------------------------------------------------------- */\r
55 \r
56 void encode_help_display() {\r
57   fprintf(stdout,"HELP\n----\n\n");\r
58   fprintf(stdout,"- the -h option displays this help information on screen\n\n");\r
59 \r
60 \r
61   fprintf(stdout,"List of parameters for the JPEG 2000 encoder:\n");\r
62   fprintf(stdout,"\n");\r
63   fprintf(stdout,"REMARKS:\n");\r
64   fprintf(stdout,"---------\n");\r
65   fprintf(stdout,"\n");\r
66   fprintf(stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n");\r
67   fprintf(stdout,"COD and QCD never appear in the tile_header.\n");\r
68   fprintf(stdout,"\n");\r
69   fprintf(stdout,"- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n");\r
70   fprintf(stdout,"color image.  You need enough disk space memory (twice the original) to encode \n");\r
71   fprintf(stdout,"the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n");\r
72   fprintf(stdout,"\n");\r
73   fprintf(stdout,"By default:\n");\r
74   fprintf(stdout,"------------\n");\r
75   fprintf(stdout,"\n");\r
76   fprintf(stdout," * Lossless\n");\r
77   fprintf(stdout," * 1 tile\n");\r
78   fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");\r
79   fprintf(stdout," * Size of code-block : 64 x 64\n");\r
80   fprintf(stdout," * Number of resolutions: 6\n");\r
81   fprintf(stdout," * No SOP marker in the codestream\n");\r
82   fprintf(stdout," * No EPH marker in the codestream\n");\r
83   fprintf(stdout," * No sub-sampling in x or y direction\n");\r
84   fprintf(stdout," * No mode switch activated\n");\r
85   fprintf(stdout," * Progression order: LRCP\n");\r
86   fprintf(stdout," * No index file\n");\r
87   fprintf(stdout," * No ROI upshifted\n");\r
88   fprintf(stdout," * No offset of the origin of the image\n");\r
89   fprintf(stdout," * No offset of the origin of the tiles\n");\r
90   fprintf(stdout," * Reversible DWT 5-3\n");\r
91   fprintf(stdout,"\n");\r
92   fprintf(stdout,"Parameters:\n");\r
93   fprintf(stdout,"------------\n");\r
94   fprintf(stdout,"\n");\r
95   fprintf(stdout,"Required Parameters (except with -h):\n");\r
96   fprintf(stdout,"\n");\r
97   fprintf(stdout,"-i           : source file  (-i source.pnm also *.pgm, *.ppm) \n");\r
98   fprintf(stdout,"\n");\r
99   fprintf(stdout,"-o           : destination file (-o dest.j2k or .jp2) \n");\r
100   fprintf(stdout,"\n");\r
101   fprintf(stdout,"Optional Parameters:\n");\r
102   fprintf(stdout,"\n");\r
103   fprintf(stdout,"-h           : display the help information \n ");\r
104   fprintf(stdout,"\n");\r
105   fprintf(stdout,"-r           : different compression ratios for successive layers (-r 20,10,5)\n ");\r
106   fprintf(stdout,"           - The rate specified for each quality level is the desired \n");\r
107   fprintf(stdout,"             compression factor.\n");\r
108   fprintf(stdout,"       Example: -r 20,10,1 means quality 1: compress 20x, \n");\r
109   fprintf(stdout,"         quality 2: compress 10x and quality 3: compress lossless\n");\r
110   fprintf(stdout,"\n");\r
111   fprintf(stdout,"               (options -r and -q cannot be used together)\n ");\r
112   fprintf(stdout,"\n");\r
113 \r
114   fprintf(stdout,"-q           : different psnr for successive layers (-q 30,40,50) \n ");\r
115 \r
116   fprintf(stdout,"               (options -r and -q cannot be used together)\n ");\r
117 \r
118   fprintf(stdout,"\n");\r
119   fprintf(stdout,"-n           : number of resolutions (-n 3) \n");\r
120   fprintf(stdout,"\n");\r
121   fprintf(stdout,"-b           : size of code block (-b 32,32) \n");\r
122   fprintf(stdout,"\n");\r
123   fprintf(stdout,"-c           : size of precinct (-c 128,128) \n");\r
124   fprintf(stdout,"\n");\r
125   fprintf(stdout,"-t           : size of tile (-t 512,512) \n");\r
126   fprintf(stdout,"\n");\r
127   fprintf(stdout,"-p           : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");\r
128   fprintf(stdout,"\n");\r
129   fprintf(stdout,"-s           : subsampling factor (-s 2,2) [-s X,Y] \n");\r
130   fprintf(stdout,"       Remark: subsampling bigger than 2 can produce error\n");\r
131   fprintf(stdout,"\n");\r
132   fprintf(stdout,"-SOP         : write SOP marker before each packet \n");\r
133   fprintf(stdout,"\n");\r
134   fprintf(stdout,"-EPH         : write EPH marker after each header packet \n");\r
135   fprintf(stdout,"\n");\r
136   fprintf(stdout,"-M           : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");\r
137   fprintf(stdout,"                 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");\r
138   fprintf(stdout,"                 Indicate multiple modes by adding their values. \n");\r
139   fprintf(stdout,"                 ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");\r
140   fprintf(stdout,"\n");\r
141   fprintf(stdout,"-x           : create an index file *.Idx (-x index_name.Idx) \n");\r
142   fprintf(stdout,"\n");\r
143   fprintf(stdout,"-ROI         : c=%%d,U=%%d : quantization indices upshifted \n");\r
144   fprintf(stdout,"               for component c=%%d [%%d = 0,1,2]\n");\r
145   fprintf(stdout,"               with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) \n");\r
146   fprintf(stdout,"\n");\r
147   fprintf(stdout,"-d           : offset of the origin of the image (-d 150,300) \n");\r
148   fprintf(stdout,"\n");\r
149   fprintf(stdout,"-T           : offset of the origin of the tiles (-T 100,75) \n");\r
150   fprintf(stdout,"\n");\r
151   fprintf(stdout,"-I           : use the irreversible DWT 9-7 (-I) \n");\r
152   fprintf(stdout,"\n");\r
153   fprintf(stdout,"IMPORTANT:\n");\r
154   fprintf(stdout,"-----------\n");\r
155   fprintf(stdout,"\n");\r
156   fprintf(stdout,"The index file has the structure below:\n");\r
157   fprintf(stdout,"---------------------------------------\n");\r
158   fprintf(stdout,"\n");\r
159   fprintf(stdout,"Image_height Image_width\n");\r
160   fprintf(stdout,"progression order\n");\r
161   fprintf(stdout,"Tiles_size_X Tiles_size_Y\n");\r
162   fprintf(stdout,"Components_nb\n");\r
163   fprintf(stdout,"Layers_nb\n");\r
164   fprintf(stdout,"decomposition_levels\n");\r
165   fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");\r
166   fprintf(stdout,"   [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");\r
167   fprintf(stdout,"Main_header_end_position\n");\r
168   fprintf(stdout,"Codestream_size\n");\r
169   fprintf(stdout,"Tile_0 start_pos end_Theader end_pos TotalDisto NumPix MaxMSE\n");\r
170   fprintf(stdout,"Tile_1   ''           ''        ''        ''       ''    ''\n");\r
171   fprintf(stdout,"...\n");\r
172   fprintf(stdout,"Tile_Nt   ''           ''        ''        ''       ''    ''\n");\r
173   fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");\r
174   fprintf(stdout,"...\n");\r
175   fprintf(stdout,"Tpacket_Np ''   ''    ''   ''    ''       ''       ''     ''\n");\r
176 \r
177   fprintf(stdout,"MaxDisto\n");\r
178 \r
179   fprintf(stdout,"TotalDisto\n\n");\r
180 }\r
181 \r
182 OPJ_PROG_ORDER give_progression(char progression[4]) {\r
183   if(strncmp(progression, "LRCP", 4) == 0) {\r
184     return LRCP;\r
185   }\r
186   if(strncmp(progression, "RLCP", 4) == 0) {\r
187     return RLCP;\r
188   }\r
189   if(strncmp(progression, "RPCL", 4) == 0) {\r
190     return RPCL;\r
191   }\r
192   if(strncmp(progression, "PCRL", 4) == 0) {\r
193     return PCRL;\r
194   }\r
195   if(strncmp(progression, "CPRL", 4) == 0) {\r
196     return CPRL;\r
197   }\r
198 \r
199   return PROG_UNKNOWN;\r
200 }\r
201 \r
202 int get_file_format(char *filename) {\r
203   unsigned int i;\r
204   static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp", "j2k", "jp2" };\r
205   static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, J2K_CFMT, JP2_CFMT };\r
206   char * ext = strrchr(filename, '.') + 1;\r
207   for(i = 0; i < sizeof(format); i++) {\r
208     if(strnicmp(ext, extension[i], 3) == 0) {\r
209       return format[i];\r
210     }\r
211   }\r
212 \r
213   return -1;\r
214 }\r
215 \r
216 /* ------------------------------------------------------------------------------------ */\r
217 \r
218 int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters) {\r
219   int i, j;\r
220 \r
221   /* parse the command line */\r
222 \r
223   while (1) {\r
224     int c = getopt(argc, argv, "i:o:r:q:f:t:n:c:b:x:p:s:d:h:P:S:E:M:R:T:C:I");\r
225     if (c == -1)\r
226       break;\r
227     switch (c) {\r
228       case 'i':      /* input file */\r
229       {\r
230         char *infile = optarg;\r
231         parameters->decod_format = get_file_format(infile);\r
232         switch(parameters->decod_format) {\r
233           case PGX_DFMT:\r
234           case PXM_DFMT:\r
235           case BMP_DFMT:\r
236             break;\r
237           default:\r
238             fprintf(stderr, \r
239               "!! Unrecognized format for infile : %s [accept only *.pnm, *.pgm, *.ppm, *.pgx or *.bmp] !!\n\n", \r
240               infile);\r
241             return 1;\r
242             break;\r
243         }\r
244         strncpy(parameters->infile, infile, MAX_PATH);\r
245       }\r
246       break;\r
247         \r
248         /* ----------------------------------------------------- */\r
249 \r
250       case 'o':      /* output file */\r
251       {\r
252         char *outfile = optarg;\r
253         parameters->cod_format = get_file_format(outfile);\r
254         switch(parameters->cod_format) {\r
255           case J2K_CFMT:\r
256           case JP2_CFMT:\r
257             break;\r
258           default:\r
259             fprintf(stderr, "Unknown output format image %s [only *.j2k, *.jp2]!! \n", outfile);\r
260             return 1;\r
261             break;\r
262         }\r
263         strncpy(parameters->outfile, outfile, MAX_PATH);\r
264       }\r
265       break;\r
266 \r
267         /* ----------------------------------------------------- */\r
268       \r
269       case 'r':      /* rates rates/distorsion */\r
270       {\r
271         char *s = optarg;\r
272         while (sscanf(s, "%d", &parameters->tcp_rates[parameters->tcp_numlayers]) == 1) {\r
273           parameters->tcp_numlayers++;\r
274           while (*s && *s != ',') {\r
275             s++;\r
276           }\r
277           if (!*s)\r
278             break;\r
279           s++;\r
280         }\r
281         parameters->cp_disto_alloc = 1;\r
282       }\r
283       break;\r
284         \r
285         /* ----------------------------------------------------- */\r
286       \r
287       case 'q':      /* add fixed_quality */\r
288       {\r
289         char *s = optarg;\r
290         while (sscanf(s, "%f", &parameters->tcp_distoratio[parameters->tcp_numlayers]) == 1) {\r
291           parameters->tcp_numlayers++;\r
292           while (*s && *s != ',') {\r
293             s++;\r
294           }\r
295           if (!*s)\r
296             break;\r
297           s++;\r
298         }\r
299         parameters->cp_fixed_quality = 1;\r
300       }\r
301       break;\r
302         \r
303         /* dda */\r
304         /* ----------------------------------------------------- */\r
305 \r
306       case 'f':      /* mod fixed_quality (before : -q) */\r
307       {\r
308         int *row = NULL, *col = NULL;\r
309         int numlayers = 0, numresolution = 0, matrix_width = 0;\r
310 \r
311         char *s = optarg;\r
312         sscanf(s, "%d", &numlayers);\r
313         s++;\r
314         if (numlayers > 9)\r
315           s++;\r
316 \r
317         parameters->tcp_numlayers = numlayers;\r
318         numresolution = parameters->numresolution;\r
319         matrix_width = numresolution * 3;\r
320         parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int));\r
321         s = s + 2;\r
322 \r
323         for (i = 0; i < numlayers; i++) {\r
324           row = &parameters->cp_matrice[i * matrix_width];\r
325           col = row;\r
326           parameters->tcp_rates[i] = 1;\r
327           sscanf(s, "%d,", &col[0]);\r
328           s += 2;\r
329           if (col[0] > 9)\r
330             s++;\r
331           col[1] = 0;\r
332           col[2] = 0;\r
333           for (j = 1; j < numresolution; j++) {\r
334             col += 3;\r
335             sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);\r
336             s += 6;\r
337             if (col[0] > 9)\r
338               s++;\r
339             if (col[1] > 9)\r
340               s++;\r
341             if (col[2] > 9)\r
342               s++;\r
343           }\r
344           if (i < numlayers - 1)\r
345             s++;\r
346         }\r
347         parameters->cp_fixed_alloc = 1;\r
348       }\r
349       break;\r
350         \r
351         /* ----------------------------------------------------- */\r
352 \r
353       case 't':      /* tiles */\r
354       {\r
355         sscanf(optarg, "%d,%d", &parameters->cp_tdx, &parameters->cp_tdy);\r
356         parameters->tile_size_on = true;\r
357       }\r
358       break;\r
359         \r
360         /* ----------------------------------------------------- */\r
361       \r
362       case 'n':      /* resolution */\r
363       {\r
364         sscanf(optarg, "%d", &parameters->numresolution);\r
365       }\r
366       break;\r
367         \r
368         /* ----------------------------------------------------- */\r
369       case 'c':      /* precinct dimension */\r
370       {\r
371         char sep;\r
372         int res_spec = 0;\r
373 \r
374         char *s = optarg;\r
375         do {\r
376           sep = 0;\r
377           sscanf(s, "[%d,%d]%c", &parameters->prcw_init[res_spec], &parameters->prch_init[res_spec], &sep);\r
378           parameters->csty |= 0x01;\r
379           res_spec++;\r
380           s = strpbrk(s, "]") + 2;\r
381         }\r
382         while (sep == ',');\r
383         parameters->res_spec = res_spec;\r
384       }\r
385       break;\r
386         \r
387         /* ----------------------------------------------------- */\r
388       \r
389       case 'b':      /* code-block dimension */\r
390       {\r
391         int cblockw_init = 0, cblockh_init = 0;\r
392         sscanf(optarg, "%d,%d", &cblockw_init, &cblockh_init);\r
393         if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024\r
394           || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {\r
395           fprintf(stderr,\r
396             "!! Size of code_block error (option -b) !!\n\nRestriction :\n    * width*height<=4096\n    * 4<=width,height<= 1024\n\n");\r
397           return 1;\r
398         }\r
399         parameters->cblockw_init = cblockw_init;\r
400         parameters->cblockh_init = cblockh_init;\r
401       }\r
402       break;\r
403         \r
404         /* ----------------------------------------------------- */\r
405       \r
406       case 'x':      /* creation of index file */\r
407       {\r
408         char *index = optarg;\r
409         strncpy(parameters->index, index, MAX_PATH);\r
410         parameters->index_on = 1;\r
411       }\r
412       break;\r
413         \r
414         /* ----------------------------------------------------- */\r
415       \r
416       case 'p':      /* progression order */\r
417       {\r
418         char progression[4];\r
419 \r
420         strncpy(progression, optarg, 4);\r
421         parameters->prog_order = give_progression(progression);\r
422         if (parameters->prog_order == -1) {\r
423           fprintf(stderr, "Unrecognized progression order [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");\r
424           return 1;\r
425         }\r
426       }\r
427       break;\r
428         \r
429         /* ----------------------------------------------------- */\r
430       \r
431       case 's':      /* subsampling factor */\r
432       {\r
433         if (sscanf(optarg, "%d,%d", &parameters->subsampling_dx, &parameters->subsampling_dy) != 2) {\r
434           fprintf(stderr,  "'-s' sub-sampling argument error !  [-s dx,dy]\n");\r
435           return 1;\r
436         }\r
437       }\r
438       break;\r
439         \r
440         /* ----------------------------------------------------- */\r
441       \r
442       case 'd':      /* coordonnate of the reference grid */\r
443       {\r
444         if (sscanf(optarg, "%d,%d", &parameters->image_offset_x0, &parameters->image_offset_y0) != 2) {\r
445           fprintf(stderr,  "-d 'coordonnate of the reference grid' argument error !! [-d x0,y0]\n");\r
446           return 1;\r
447         }\r
448       }\r
449       break;\r
450         \r
451         /* ----------------------------------------------------- */\r
452       \r
453       case 'h':      /* display an help description */\r
454       {\r
455         encode_help_display();\r
456         return 1;\r
457       }\r
458       break;\r
459         \r
460         /* ----------------------------------------------------- */\r
461 \r
462       case 'P':      /* POC */\r
463       {\r
464         int numpocs = 0;    /* number of progression order change (POC) default 0 */\r
465         opj_poc_t *POC = NULL;  /* POC : used in case of Progression order change */\r
466 \r
467         char *s = optarg;\r
468         POC = parameters->POC;\r
469 \r
470         fprintf(stderr, "/----------------------------------\\\n");\r
471         fprintf(stderr, "|  POC option not fully tested !!  |\n");\r
472         fprintf(stderr, "\\----------------------------------/\n");\r
473         \r
474         while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%s", &POC[numpocs].tile,\r
475           &POC[numpocs].resno0, &POC[numpocs].compno0,\r
476           &POC[numpocs].layno1, &POC[numpocs].resno1,\r
477           &POC[numpocs].compno1, POC[numpocs].progorder) == 7) {\r
478           POC[numpocs].prg = give_progression(POC[numpocs].progorder);\r
479           /* POC[numpocs].tile; */\r
480           numpocs++;\r
481           while (*s && *s != '/') {\r
482             s++;\r
483           }\r
484           if (!*s) {\r
485             break;\r
486           }\r
487           s++;\r
488         }\r
489         parameters->numpocs = numpocs;\r
490       }\r
491       break;\r
492         \r
493         /* ------------------------------------------------------ */\r
494         \r
495       case 'S':      /* SOP marker */\r
496       {\r
497         parameters->csty |= 0x02;\r
498       }\r
499       break;\r
500         \r
501         /* ------------------------------------------------------ */\r
502       \r
503       case 'E':      /* EPH marker */\r
504       {\r
505         parameters->csty |= 0x04;\r
506       }\r
507       break;\r
508         \r
509         /* ------------------------------------------------------ */\r
510       \r
511       case 'M':      /* Mode switch pas tous au point !! */\r
512       {\r
513         int value = 0;\r
514         if (sscanf(optarg, "%d", &value) == 1) {\r
515           for (i = 0; i <= 5; i++) {\r
516             int cache = value & (1 << i);\r
517             if (cache)\r
518               parameters->mode |= (1 << i);\r
519           }\r
520         }\r
521       }\r
522       break;\r
523         \r
524         /* ------------------------------------------------------ */\r
525       \r
526       case 'R':      /* ROI */\r
527       {\r
528         if (sscanf(optarg, "OI:c=%d,U=%d", &parameters->roi_compno, &parameters->roi_shift) != 2) {\r
529           fprintf(stderr, "ROI error !! [-ROI:c='compno',U='shift']\n");\r
530           return 1;\r
531         }\r
532       }\r
533       break;\r
534         \r
535         /* ------------------------------------------------------ */\r
536       \r
537       case 'T':      /* Tile offset */\r
538       {\r
539         if (sscanf(optarg, "%d,%d", &parameters->cp_tx0, &parameters->cp_ty0) != 2) {\r
540           fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");\r
541           return 1;\r
542         }\r
543       }\r
544       break;\r
545         \r
546         /* ------------------------------------------------------ */\r
547         \r
548       case 'C':      /* add a comment */\r
549       {\r
550         parameters->cp_comment = (char*)malloc(strlen(optarg) + 1);\r
551         if(parameters->cp_comment) {\r
552           strcpy(parameters->cp_comment, optarg);\r
553         }\r
554       }\r
555       break;\r
556         \r
557         /* ------------------------------------------------------ */\r
558       \r
559       case 'I':      /* reversible or not */\r
560       {\r
561         parameters->irreversible = 1;\r
562       }\r
563       break;\r
564         \r
565         /* ------------------------------------------------------ */\r
566       \r
567       default:\r
568         fprintf(stderr, "ERROR -> this option is not valid \"-%c %s\"\n", c, optarg);\r
569         return 1;\r
570     }\r
571   }\r
572 \r
573   /* check for possible errors */\r
574 \r
575   if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) {\r
576     fprintf(stderr, "usage: image_to_j2k -i image-file -o j2k/jp2-file (+ options)\n");\r
577     return 1;\r
578   }\r
579 \r
580   if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality)\r
581     && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ parameters->cp_fixed_quality))) {\r
582     fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");\r
583     return 1;\r
584   }        /* mod fixed_quality */\r
585 \r
586   /* if no rate entered, lossless by default */\r
587   if (parameters->tcp_numlayers == 0) {\r
588     parameters->tcp_rates[0] = 0;  /* MOD antonin : losslessbug */\r
589     parameters->tcp_numlayers++;\r
590     parameters->cp_disto_alloc = 1;\r
591   }\r
592 \r
593   if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) {\r
594     fprintf(stderr,\r
595       "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",\r
596       parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0);\r
597     return 1;\r
598   }\r
599 \r
600   for (i = 0; i < parameters->numpocs; i++) {\r
601     if (parameters->POC[i].prg == -1) {\r
602       fprintf(stderr,\r
603         "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",\r
604         i + 1);\r
605     }\r
606   }\r
607 \r
608   return 0;\r
609 }\r
610 \r
611 /* -------------------------------------------------------------------------- */\r
612 \r
613 /**\r
614 sample error callback expecting a FILE* client object\r
615 */\r
616 void error_callback(const char *msg, void *client_data) {\r
617   FILE *stream = (FILE*)client_data;\r
618   fprintf(stream, "[ERROR] %s", msg);\r
619 }\r
620 /**\r
621 sample warning callback expecting a FILE* client object\r
622 */\r
623 void warning_callback(const char *msg, void *client_data) {\r
624   FILE *stream = (FILE*)client_data;\r
625   fprintf(stream, "[WARNING] %s", msg);\r
626 }\r
627 /**\r
628 sample debug callback expecting a FILE* client object\r
629 */\r
630 void info_callback(const char *msg, void *client_data) {\r
631   FILE *stream = (FILE*)client_data;\r
632   fprintf(stream, "[INFO] %s", msg);\r
633 }\r
634 \r
635 /* -------------------------------------------------------------------------- */\r
636 \r
637 int main(int argc, char **argv) {\r
638   bool bSuccess;\r
639   bool delete_comment = true;\r
640   opj_cparameters_t parameters;  /* compression parameters */\r
641   opj_event_mgr_t event_mgr;    /* event manager */\r
642   opj_image_t *image = NULL;\r
643 \r
644   /* \r
645   configure the event callbacks (not required)\r
646   setting of each callback is optionnal \r
647   */\r
648   memset(&event_mgr, 0, sizeof(opj_event_mgr_t));\r
649   event_mgr.error_handler = error_callback;\r
650   event_mgr.warning_handler = warning_callback;\r
651   event_mgr.info_handler = info_callback;\r
652 \r
653   /* set encoding parameters to default values */\r
654   opj_set_default_encoder_parameters(&parameters);\r
655 \r
656   /* parse input and get user encoding parameters */\r
657   if(parse_cmdline_encoder(argc, argv, &parameters) == 1) {\r
658     return 0;\r
659   }\r
660 \r
661   if(parameters.cp_comment == NULL) {\r
662     parameters.cp_comment = "Created by OpenJPEG version 0.9";\r
663     /* no need to delete parameters.cp_comment on exit */\r
664     delete_comment = false;\r
665   }\r
666 \r
667   /* decode the source image */\r
668   /* ----------------------- */\r
669 \r
670   switch (parameters.decod_format) {\r
671     case PGX_DFMT:\r
672       image = pgxtoimage(parameters.infile, &parameters);\r
673       if (!image) {\r
674         fprintf(stderr, " unable to load pgx file\n");\r
675         return 1;\r
676       }\r
677       break;\r
678     \r
679     case PXM_DFMT:\r
680       image = pnmtoimage(parameters.infile, &parameters);\r
681       if (!image) {\r
682         fprintf(stderr, " not a pnm file\n");\r
683         return 1;\r
684       }\r
685       break;\r
686 \r
687     case BMP_DFMT:\r
688       image = bmptoimage(parameters.infile, &parameters);\r
689       if (!image) {\r
690         fprintf(stderr, " not a bmp file\n");\r
691         return 1;\r
692       }\r
693       break;\r
694   }\r
695 \r
696   /* encode the destination image */\r
697   /* ---------------------------- */\r
698 \r
699   if (parameters.cod_format == J2K_CFMT) {  /* J2K format output */\r
700     int codestream_length;\r
701     opj_cio_t *cio = NULL;\r
702     FILE *f = NULL;\r
703 \r
704     /* get a J2K compressor handle */\r
705     opj_cinfo_t* cinfo = opj_create_compress(CODEC_J2K);\r
706 \r
707     /* catch events using our callbacks and give a local context */\r
708     opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);      \r
709 \r
710     /* setup the encoder parameters using the current image and using user parameters */\r
711     opj_setup_encoder(cinfo, &parameters, image);\r
712 \r
713     /* open a byte stream for writing */\r
714     /* allocate memory for all tiles */\r
715     cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);\r
716 \r
717     /* encode the image */\r
718     bSuccess = opj_encode(cinfo, cio, image, parameters.index);\r
719     if (!bSuccess) {\r
720       opj_cio_close(cio);\r
721       fprintf(stderr, "failed to encode image\n");\r
722       return 1;\r
723     }\r
724     codestream_length = cio_tell(cio);\r
725 \r
726     /* write the buffer to disk */\r
727     f = fopen(parameters.outfile, "wb");\r
728     if (!f) {\r
729       fprintf(stderr, "failed to open %s for writing\n", parameters.outfile);\r
730       return 1;\r
731     }\r
732     fwrite(cio->buffer, 1, codestream_length, f);\r
733     fclose(f);\r
734 \r
735     /* close and free the byte stream */\r
736     opj_cio_close(cio);\r
737 \r
738     /* free remaining compression structures */\r
739     opj_destroy_compress(cinfo);\r
740 \r
741   } else {      /* JP2 format output */\r
742     int codestream_length;\r
743     opj_cio_t *cio = NULL;\r
744     FILE *f = NULL;\r
745 \r
746     /* get a JP2 compressor handle */\r
747     opj_cinfo_t* cinfo = opj_create_compress(CODEC_JP2);\r
748 \r
749     /* catch events using our callbacks and give a local context */\r
750     opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);      \r
751 \r
752     /* setup the encoder parameters using the current image and using user parameters */\r
753     opj_setup_encoder(cinfo, &parameters, image);\r
754 \r
755     /* open a byte stream for writing */\r
756     /* allocate memory for all tiles */\r
757     cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);\r
758 \r
759     /* encode the image */\r
760     bSuccess = opj_encode(cinfo, cio, image, parameters.index);\r
761     if (!bSuccess) {\r
762       opj_cio_close(cio);\r
763       fprintf(stderr, "failed to encode image\n");\r
764       return 1;\r
765     }\r
766     codestream_length = cio_tell(cio);\r
767 \r
768     /* write the buffer to disk */\r
769     f = fopen(parameters.outfile, "wb");\r
770     if (!f) {\r
771       fprintf(stderr, "failed to open %s for writing\n", parameters.outfile);\r
772       return 1;\r
773     }\r
774     fwrite(cio->buffer, 1, codestream_length, f);\r
775     fclose(f);\r
776 \r
777     /* close and free the byte stream */\r
778     opj_cio_close(cio);\r
779 \r
780     /* free remaining compression structures */\r
781     opj_destroy_compress(cinfo);\r
782 \r
783   }\r
784 \r
785   /* free user parameters structure */\r
786   if(delete_comment) {\r
787     if(parameters.cp_comment) free(parameters.cp_comment);\r
788   }\r
789   if(parameters.cp_matrice) free(parameters.cp_matrice);\r
790 \r
791   /* free image data */\r
792   opj_image_destroy(image);\r
793 \r
794   return 0;\r
795 }\r
796 \r