Fix some typos (found by `codespell` and `typos`)
[openjpeg.git] / wrapping / java / openjp2 / JavaOpenJPEG.c
1 /*
2  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
3  * Copyright (c) 2002-2014, Professor Benoit Macq
4  * Copyright (c) 2001-2003, David Janssens
5  * Copyright (c) 2002-2003, Yannick Verschueren
6  * Copyright (c) 2003-2007, Francois-Olivier Devaux
7  * Copyright (c) 2003-2014, Antonin Descampe
8  * Copyright (c) 2005, Herve Drolon, FreeImage Team
9  * Copyright (c) 2006-2007, Parvatha Elangovan
10  * Copyright (c) 2007, Patrick Piscaglia (Telemis)
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <jni.h>
38 #include <math.h>
39
40 #include "openjpeg.h"
41 #include "opj_includes.h"
42 #include "opj_getopt.h"
43 #include "convert.h"
44 #include "index.h"
45 #include "dirent.h"
46 #include "org_openJpeg_OpenJPEGJavaEncoder.h"
47
48 #ifndef _WIN32
49 #define stricmp strcasecmp
50 #define strnicmp strncasecmp
51 #endif
52
53 #include "format_defs.h"
54
55 #define CINEMA_24_CS 1302083    /*Codestream length for 24fps*/
56 #define CINEMA_48_CS 651041     /*Codestream length for 48fps*/
57 #define COMP_24_CS 1041666      /*Maximum size per color component for 2K & 4K @ 24fps*/
58 #define COMP_48_CS 520833       /*Maximum size per color component for 2K @ 48fps*/
59
60 extern int get_file_format(char *filename);
61 extern void error_callback(const char *msg, void *client_data);
62 extern void warning_callback(const char *msg, void *client_data);
63 extern void info_callback(const char *msg, void *client_data);
64
65 typedef struct callback_variables {
66     JNIEnv *env;
67     /** 'jclass' object used to call a Java method from the C */
68     jobject *jobj;
69     /** 'jclass' object used to call a Java method from the C */
70     jmethodID message_mid;
71     jmethodID error_mid;
72 } callback_variables_t;
73
74 typedef struct dircnt {
75     /** Buffer for holding images read from Directory*/
76     char *filename_buf;
77     /** Pointer to the buffer*/
78     char **filename;
79 } dircnt_t;
80
81 typedef struct img_folder {
82     /** The directory path of the folder containing input images*/
83     char *imgdirpath;
84     /** Output format*/
85     char *out_format;
86     /** Enable option*/
87     char set_imgdir;
88     /** Enable Cod Format for output*/
89     char set_out_format;
90     /** User specified rate stored in case of cinema option*/
91     float *rates;
92 } img_fol_t;
93
94 static void encode_help_display()
95 {
96     fprintf(stdout, "HELP\n----\n\n");
97     fprintf(stdout, "- the -h option displays this help information on screen\n\n");
98
99     /* UniPG>> */
100     fprintf(stdout, "List of parameters for the JPEG 2000 "
101 #ifdef USE_JPWL
102             "+ JPWL "
103 #endif /* USE_JPWL */
104             "encoder:\n");
105     /* <<UniPG */
106     fprintf(stdout, "\n");
107     fprintf(stdout, "REMARKS:\n");
108     fprintf(stdout, "---------\n");
109     fprintf(stdout, "\n");
110     fprintf(stdout,
111             "The markers written to the main_header are : SOC SIZ COD QCD COM.\n");
112     fprintf(stdout, "COD and QCD never appear in the tile_header.\n");
113     fprintf(stdout, "\n");
114     fprintf(stdout,
115             "- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n");
116     fprintf(stdout,
117             "color image.  You need enough disk space memory (twice the original) to encode \n");
118     fprintf(stdout,
119             "the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n");
120     fprintf(stdout, "\n");
121     fprintf(stdout, "By default:\n");
122     fprintf(stdout, "------------\n");
123     fprintf(stdout, "\n");
124     fprintf(stdout, " * Lossless\n");
125     fprintf(stdout, " * 1 tile\n");
126     fprintf(stdout, " * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");
127     fprintf(stdout, " * Size of code-block : 64 x 64\n");
128     fprintf(stdout, " * Number of resolutions: 6\n");
129     fprintf(stdout, " * No SOP marker in the codestream\n");
130     fprintf(stdout, " * No EPH marker in the codestream\n");
131     fprintf(stdout, " * No sub-sampling in x or y direction\n");
132     fprintf(stdout, " * No mode switch activated\n");
133     fprintf(stdout, " * Progression order: LRCP\n");
134     fprintf(stdout, " * No index file\n");
135     fprintf(stdout, " * No ROI upshifted\n");
136     fprintf(stdout, " * No offset of the origin of the image\n");
137     fprintf(stdout, " * No offset of the origin of the tiles\n");
138     fprintf(stdout, " * Reversible DWT 5-3\n");
139     /* UniPG>> */
140 #ifdef USE_JPWL
141     fprintf(stdout, " * No JPWL protection\n");
142 #endif /* USE_JPWL */
143     /* <<UniPG */
144     fprintf(stdout, "\n");
145     fprintf(stdout, "Parameters:\n");
146     fprintf(stdout, "------------\n");
147     fprintf(stdout, "\n");
148     fprintf(stdout, "Required Parameters (except with -h):\n");
149     fprintf(stdout, "One of the two options -ImgDir or -i must be used\n");
150     fprintf(stdout, "\n");
151     fprintf(stdout,
152             "-ImgDir      : Image file Directory path (example ../Images) \n");
153     fprintf(stdout, "    When using this option -OutFor must be used\n");
154     fprintf(stdout, "\n");
155     fprintf(stdout, "-OutFor \n");
156     fprintf(stdout, "    REQUIRED only if -ImgDir is used\n");
157     fprintf(stdout, "     Need to specify only format without filename <BMP>  \n");
158     fprintf(stdout,
159             "    Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA formats\n");
160     fprintf(stdout, "\n");
161     fprintf(stdout,
162             "-i           : source file  (-i source.pnm also *.pgm, *.ppm, *.bmp, *.tif, *.raw, *.tga) \n");
163     fprintf(stdout, "    When using this option -o must be used\n");
164     fprintf(stdout, "\n");
165     fprintf(stdout, "-o           : destination file (-o dest.j2k or .jp2) \n");
166     fprintf(stdout, "\n");
167     fprintf(stdout, "Optional Parameters:\n");
168     fprintf(stdout, "\n");
169     fprintf(stdout, "-h           : display the help information \n ");
170     fprintf(stdout, "\n");
171     fprintf(stdout,
172             "-cinema2K    : Digital Cinema 2K profile compliant codestream for 2K resolution.(-cinema2k 24 or 48) \n");
173     fprintf(stdout,
174             "     Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n");
175     fprintf(stdout, "\n");
176     fprintf(stdout,
177             "-cinema4K    : Digital Cinema 4K profile compliant codestream for 4K resolution \n");
178     fprintf(stdout, "     Frames per second not required. Default value is 24fps\n");
179     fprintf(stdout, "\n");
180     fprintf(stdout,
181             "-r           : different compression ratios for successive layers (-r 20,10,5)\n ");
182     fprintf(stdout,
183             "            - The rate specified for each quality level is the desired \n");
184     fprintf(stdout, "              compression factor.\n");
185     fprintf(stdout, "              Example: -r 20,10,1 means quality 1: compress 20x, \n");
186     fprintf(stdout,
187             "                quality 2: compress 10x and quality 3: compress lossless\n");
188     fprintf(stdout, "\n");
189     fprintf(stdout,
190             "               (options -r and -q cannot be used together)\n ");
191     fprintf(stdout, "\n");
192
193     fprintf(stdout,
194             "-q           : different psnr for successive layers (-q 30,40,50) \n ");
195
196     fprintf(stdout,
197             "               (options -r and -q cannot be used together)\n ");
198
199     fprintf(stdout, "\n");
200     fprintf(stdout, "-n           : number of resolutions (-n 3) \n");
201     fprintf(stdout, "\n");
202     fprintf(stdout, "-b           : size of code block (-b 32,32) \n");
203     fprintf(stdout, "\n");
204     fprintf(stdout, "-c           : size of precinct (-c 128,128) \n");
205     fprintf(stdout, "\n");
206     fprintf(stdout, "-t           : size of tile (-t 512,512) \n");
207     fprintf(stdout, "\n");
208     fprintf(stdout,
209             "-p           : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
210     fprintf(stdout, "\n");
211     fprintf(stdout, "-s           : subsampling factor (-s 2,2) [-s X,Y] \n");
212     fprintf(stdout, "        Remark: subsampling bigger than 2 can produce error\n");
213     fprintf(stdout, "\n");
214     fprintf(stdout,
215             "-POC         : Progression order change (-POC T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL) \n");
216     fprintf(stdout, "      Example: T1=0,0,1,5,3,CPRL \n");
217     fprintf(stdout,
218             "                    : Ttilenumber=Resolution num start,Component num start,Layer num end,Resolution num end,Component num end,Progression order\n");
219     fprintf(stdout, "\n");
220     fprintf(stdout, "-SOP         : write SOP marker before each packet \n");
221     fprintf(stdout, "\n");
222     fprintf(stdout, "-EPH         : write EPH marker after each header packet \n");
223     fprintf(stdout, "\n");
224     fprintf(stdout,
225             "-M           : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
226     fprintf(stdout,
227             "                 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");
228     fprintf(stdout,
229             "                 Indicate multiple modes by adding their values. \n");
230     fprintf(stdout,
231             "                 ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
232     fprintf(stdout, "\n");
233     fprintf(stdout,
234             "-TP          : divide packets of every tile into tile-parts (-TP R) [R, L, C]\n");
235     fprintf(stdout, "\n");
236     fprintf(stdout,
237             "-x           : create an index file *.Idx (-x index_name.Idx) \n");
238     fprintf(stdout, "\n");
239     fprintf(stdout,
240             "-ROI         : c=%%d,U=%%d : quantization indices upshifted \n");
241     fprintf(stdout, "               for component c=%%d [%%d = 0,1,2]\n");
242     fprintf(stdout,
243             "               with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI c=0,U=25) \n");
244     fprintf(stdout, "\n");
245     fprintf(stdout,
246             "-d           : offset of the origin of the image (-d 150,300) \n");
247     fprintf(stdout, "\n");
248     fprintf(stdout,
249             "-T           : offset of the origin of the tiles (-T 100,75) \n");
250     fprintf(stdout, "\n");
251     fprintf(stdout, "-I           : use the irreversible DWT 9-7 (-I) \n");
252     fprintf(stdout, "\n");
253     fprintf(stdout,
254             "-jpip        : write jpip codestream index box in JP2 output file\n");
255     fprintf(stdout, "               NOTICE: currently supports only RPCL order\n");
256     fprintf(stdout, "\n");
257     /* UniPG>> */
258 #ifdef USE_JPWL
259     fprintf(stdout,
260             "-W           : adoption of JPWL (Part 11) capabilities (-W params)\n");
261     fprintf(stdout,
262             "               The parameters can be written and repeated in any order:\n");
263     fprintf(stdout,
264             "               [h<tilepart><=type>,s<tilepart><=method>,a=<addr>,...\n");
265     fprintf(stdout,
266             "                ...,z=<size>,g=<range>,p<tilepart:pack><=type>]\n");
267     fprintf(stdout, "\n");
268     fprintf(stdout,
269             "                 h selects the header error protection (EPB): 'type' can be\n");
270     fprintf(stdout,
271             "                   [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
272     fprintf(stdout,
273             "                   if 'tilepart' is absent, it is for main and tile headers\n");
274     fprintf(stdout,
275             "                   if 'tilepart' is present, it applies from that tile\n");
276     fprintf(stdout,
277             "                     onwards, up to the next h<> spec, or to the last tilepart\n");
278     fprintf(stdout, "                     in the codestream (max. %d specs)\n",
279             JPWL_MAX_NO_TILESPECS);
280     fprintf(stdout, "\n");
281     fprintf(stdout,
282             "                 p selects the packet error protection (EEP/UEP with EPBs)\n");
283     fprintf(stdout, "                  to be applied to raw data: 'type' can be\n");
284     fprintf(stdout,
285             "                   [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
286     fprintf(stdout,
287             "                   if 'tilepart:pack' is absent, it is from tile 0, packet 0\n");
288     fprintf(stdout,
289             "                   if 'tilepart:pack' is present, it applies from that tile\n");
290     fprintf(stdout,
291             "                     and that packet onwards, up to the next packet spec\n");
292     fprintf(stdout,
293             "                     or to the last packet in the last tilepart in the stream\n");
294     fprintf(stdout, "                     (max. %d specs)\n",
295             JPWL_MAX_NO_PACKSPECS);
296     fprintf(stdout, "\n");
297     fprintf(stdout,
298             "                 s enables sensitivity data insertion (ESD): 'method' can be\n");
299     fprintf(stdout,
300             "                   [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n");
301     fprintf(stdout,
302             "                    4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n");
303     fprintf(stdout,
304             "                   if 'tilepart' is absent, it is for main header only\n");
305     fprintf(stdout,
306             "                   if 'tilepart' is present, it applies from that tile\n");
307     fprintf(stdout,
308             "                     onwards, up to the next s<> spec, or to the last tilepart\n");
309     fprintf(stdout, "                     in the codestream (max. %d specs)\n",
310             JPWL_MAX_NO_TILESPECS);
311     fprintf(stdout, "\n");
312     fprintf(stdout,
313             "                 g determines the addressing mode: <range> can be\n");
314     fprintf(stdout, "                   [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n");
315     fprintf(stdout, "\n");
316     fprintf(stdout,
317             "                 a determines the size of data addressing: <addr> can be\n");
318     fprintf(stdout,
319             "                   2/4 bytes (small/large codestreams). If not set, auto-mode\n");
320     fprintf(stdout, "\n");
321     fprintf(stdout,
322             "                 z determines the size of sensitivity values: <size> can be\n");
323     fprintf(stdout,
324             "                   1/2 bytes, for the transformed pseudo-floating point value\n");
325     fprintf(stdout, "\n");
326     fprintf(stdout, "                 ex.:\n");
327     fprintf(stdout,
328             "                   h,h0=64,h3=16,h5=32,p0=78,p0:24=56,p1,p3:0=0,p3:20=32,s=0,\n");
329     fprintf(stdout, "                     s0=6,s3=-1,a=0,g=1,z=1\n");
330     fprintf(stdout, "                 means\n");
331     fprintf(stdout,
332             "                   predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n");
333     fprintf(stdout,
334             "                   CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n");
335     fprintf(stdout,
336             "                   UEP rs(78,32) for packets 0 to 23 of tile 0,\n");
337     fprintf(stdout,
338             "                   UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n");
339     fprintf(stdout,
340             "                   UEP rs default for packets of tilepart 1,\n");
341     fprintf(stdout,
342             "                   no UEP for packets 0 to 19 of tilepart 3,\n");
343     fprintf(stdout,
344             "                   UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n");
345     fprintf(stdout, "                   relative sensitivity ESD for MH,\n");
346     fprintf(stdout,
347             "                   TSE ESD from TPH 0 to TPH 2, byte range with automatic\n");
348     fprintf(stdout,
349             "                   size of addresses and 1 byte for each sensitivity value\n");
350     fprintf(stdout, "\n");
351     fprintf(stdout, "                 ex.:\n");
352     fprintf(stdout, "                       h,s,p\n");
353     fprintf(stdout, "                 means\n");
354     fprintf(stdout,
355             "                   default protection to headers (MH and TPHs) as well as\n");
356     fprintf(stdout, "                   data packets, one ESD in MH\n");
357     fprintf(stdout, "\n");
358     fprintf(stdout,
359             "                 N.B.: use the following recommendations when specifying\n");
360     fprintf(stdout, "                       the JPWL parameters list\n");
361     fprintf(stdout,
362             "                   - when you use UEP, always pair the 'p' option with 'h'\n");
363     fprintf(stdout, "                 \n");
364 #endif /* USE_JPWL */
365     /* <<UniPG */
366     fprintf(stdout, "IMPORTANT:\n");
367     fprintf(stdout, "-----------\n");
368     fprintf(stdout, "\n");
369     fprintf(stdout, "The index file has the structure below:\n");
370     fprintf(stdout, "---------------------------------------\n");
371     fprintf(stdout, "\n");
372     fprintf(stdout, "Image_height Image_width\n");
373     fprintf(stdout, "progression order\n");
374     fprintf(stdout, "Tiles_size_X Tiles_size_Y\n");
375     fprintf(stdout, "Tiles_nb_X Tiles_nb_Y\n");
376     fprintf(stdout, "Components_nb\n");
377     fprintf(stdout, "Layers_nb\n");
378     fprintf(stdout, "decomposition_levels\n");
379     fprintf(stdout, "[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");
380     fprintf(stdout, "   [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");
381     fprintf(stdout, "Main_header_start_position\n");
382     fprintf(stdout, "Main_header_end_position\n");
383     fprintf(stdout, "Codestream_size\n");
384     fprintf(stdout, "\n");
385     fprintf(stdout, "INFO ON TILES\n");
386     fprintf(stdout,
387             "tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n");
388     fprintf(stdout,
389             "Tile_0 start_pos end_Theader end_pos NumParts TotalDisto NumPix MaxMSE\n");
390     fprintf(stdout,
391             "Tile_1   ''           ''        ''        ''       ''    ''      ''\n");
392     fprintf(stdout, "...\n");
393     fprintf(stdout,
394             "Tile_Nt   ''           ''        ''        ''       ''    ''     ''\n");
395     fprintf(stdout, "...\n");
396     fprintf(stdout, "TILE 0 DETAILS\n");
397     fprintf(stdout, "part_nb tileno num_packs start_pos end_tph_pos end_pos\n");
398     fprintf(stdout, "...\n");
399     fprintf(stdout, "Progression_string\n");
400     fprintf(stdout,
401             "pack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n");
402     fprintf(stdout,
403             "Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");
404     fprintf(stdout, "...\n");
405     fprintf(stdout,
406             "Tpacket_Np ''   ''    ''   ''    ''       ''       ''     ''\n");
407
408     fprintf(stdout, "MaxDisto\n");
409
410     fprintf(stdout, "TotalDisto\n\n");
411 }
412
413
414 static OPJ_PROG_ORDER give_progression(const char progression[4])
415 {
416     if (strncmp(progression, "LRCP", 4) == 0) {
417         return LRCP;
418     }
419     if (strncmp(progression, "RLCP", 4) == 0) {
420         return RLCP;
421     }
422     if (strncmp(progression, "RPCL", 4) == 0) {
423         return RPCL;
424     }
425     if (strncmp(progression, "PCRL", 4) == 0) {
426         return PCRL;
427     }
428     if (strncmp(progression, "CPRL", 4) == 0) {
429         return CPRL;
430     }
431
432     return PROG_UNKNOWN;
433 }
434
435 static int initialise_4K_poc(opj_poc_t *POC, int numres)
436 {
437     POC[0].tile  = 1;
438     POC[0].resno0  = 0;
439     POC[0].compno0 = 0;
440     POC[0].layno1  = 1;
441     POC[0].resno1  = numres - 1;
442     POC[0].compno1 = 3;
443     POC[0].prg1 = CPRL;
444     POC[1].tile  = 1;
445     POC[1].resno0  = numres - 1;
446     POC[1].compno0 = 0;
447     POC[1].layno1  = 1;
448     POC[1].resno1  = numres;
449     POC[1].compno1 = 3;
450     POC[1].prg1 = CPRL;
451     return 2;
452 }
453
454 static void cinema_parameters(opj_cparameters_t *parameters)
455 {
456     parameters->tile_size_on = OPJ_FALSE;
457     parameters->cp_tdx = 1;
458     parameters->cp_tdy = 1;
459
460     /*Tile part*/
461     parameters->tp_flag = 'C';
462     parameters->tp_on = 1;
463
464     /*Tile and Image shall be at (0,0)*/
465     parameters->cp_tx0 = 0;
466     parameters->cp_ty0 = 0;
467     parameters->image_offset_x0 = 0;
468     parameters->image_offset_y0 = 0;
469
470     /*Codeblock size= 32*32*/
471     parameters->cblockw_init = 32;
472     parameters->cblockh_init = 32;
473     parameters->csty |= 0x01;
474
475     /*The progression order shall be CPRL*/
476     parameters->prog_order = CPRL;
477
478     /* No ROI */
479     parameters->roi_compno = -1;
480
481     parameters->subsampling_dx = 1;
482     parameters->subsampling_dy = 1;
483
484     /* 9-7 transform */
485     parameters->irreversible = 1;
486
487 }
488
489 static void cinema_setup_encoder(opj_cparameters_t *parameters,
490                                  opj_image_t *image, img_fol_t *img_fol)
491 {
492     int i;
493     float temp_rate;
494     opj_poc_t *POC = NULL;
495
496     switch (parameters->cp_cinema) {
497     case CINEMA2K_24:
498     case CINEMA2K_48:
499         if (parameters->numresolution > 6) {
500             parameters->numresolution = 6;
501         }
502         if (!((image->comps[0].w == 2048) | (image->comps[0].h == 1080))) {
503             fprintf(stdout,
504                     "Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3"
505                     "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
506                     image->comps[0].w, image->comps[0].h);
507             parameters->cp_rsiz = STD_RSIZ;
508         }
509         break;
510
511     case CINEMA4K_24:
512         if (parameters->numresolution < 1) {
513             parameters->numresolution = 1;
514         } else if (parameters->numresolution > 7) {
515             parameters->numresolution = 7;
516         }
517         if (!((image->comps[0].w == 4096) | (image->comps[0].h == 2160))) {
518             fprintf(stdout,
519                     "Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4"
520                     "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
521                     image->comps[0].w, image->comps[0].h);
522             parameters->cp_rsiz = STD_RSIZ;
523         }
524         parameters->numpocs = initialise_4K_poc(parameters->POC,
525                                                 parameters->numresolution);
526         break;
527     }
528
529     switch (parameters->cp_cinema) {
530     case CINEMA2K_24:
531     case CINEMA4K_24:
532         for (i = 0 ; i < parameters->tcp_numlayers ; i++) {
533             temp_rate = 0 ;
534             if (img_fol->rates[i] == 0) {
535                 parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
536                                                     image->comps[0].h * image->comps[0].prec)) /
537                                            (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
538             } else {
539                 temp_rate = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h *
540                                      image->comps[0].prec)) /
541                             (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
542                 if (temp_rate > CINEMA_24_CS) {
543                     parameters->tcp_rates[i] = ((float)(image->numcomps * image->comps[0].w *
544                                                         image->comps[0].h * image->comps[0].prec)) /
545                                                (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
546                 } else {
547                     parameters->tcp_rates[i] = img_fol->rates[i];
548                 }
549             }
550         }
551         parameters->max_comp_size = COMP_24_CS;
552         break;
553
554     case CINEMA2K_48:
555         for (i = 0 ; i < parameters->tcp_numlayers ; i++) {
556             temp_rate = 0 ;
557             if (img_fol->rates[i] == 0) {
558                 parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
559                                                     image->comps[0].h * image->comps[0].prec)) /
560                                            (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
561             } else {
562                 temp_rate = ((float)(image->numcomps * image->comps[0].w * image->comps[0].h *
563                                      image->comps[0].prec)) /
564                             (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
565                 if (temp_rate > CINEMA_48_CS) {
566                     parameters->tcp_rates[0] = ((float)(image->numcomps * image->comps[0].w *
567                                                         image->comps[0].h * image->comps[0].prec)) /
568                                                (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
569                 } else {
570                     parameters->tcp_rates[i] = img_fol->rates[i];
571                 }
572             }
573         }
574         parameters->max_comp_size = COMP_48_CS;
575         break;
576     }
577     parameters->cp_disto_alloc = 1;
578 }
579
580
581 /* ------------------------------------------------------------------------------------ */
582 static int parse_cmdline_encoder(int argc, char **argv,
583                                  opj_cparameters_t *parameters,
584                                  img_fol_t *img_fol, char *indexfilename)
585 {
586     int i, j, totlen;
587     opj_option_t long_option[] = {
588         {"cinema2K", REQ_ARG, NULL, 'w'},
589         {"cinema4K", NO_ARG, NULL, 'y'},
590         {"ImgDir", REQ_ARG, NULL, 'z'},
591         {"TP", REQ_ARG, NULL, 'u'},
592         {"SOP", NO_ARG, NULL, 'S'},
593         {"EPH", NO_ARG, NULL, 'E'},
594         {"OutFor", REQ_ARG, NULL, 'O'},
595         {"POC", REQ_ARG, NULL, 'P'},
596         {"ROI", REQ_ARG, NULL, 'R'},
597         {"jpip", NO_ARG, NULL, 'J'}
598     };
599
600     /* parse the command line */
601     /* UniPG>> */
602     const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:"
603 #ifdef USE_JPWL
604                            "W:"
605 #endif /* USE_JPWL */
606                            ;
607
608     /*printf("C: parse_cmdline_encoder:");
609     for (i=0; i<argc; i++) {
610         printf("[%s]",argv[i]);
611     }
612     printf("\n");*/
613
614     totlen = sizeof(long_option);
615     img_fol->set_out_format = 0;
616     reset_options_reading();
617
618     while (1) {
619         int c = opj_getopt_long(argc, argv, optlist, long_option, totlen);
620         if (c == -1) {
621             break;
622         }
623         switch (c) {
624
625         /* ----------------------------------------------------- */
626
627         case 'o': {         /* output file */
628             char *outfile = opj_optarg;
629             parameters->cod_format = get_file_format(outfile);
630             switch (parameters->cod_format) {
631             case J2K_CFMT:
632             case JP2_CFMT:
633                 break;
634             default:
635                 fprintf(stderr,
636                         "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile);
637                 return 1;
638             }
639             strncpy(parameters->outfile, outfile, sizeof(parameters->outfile) - 1);
640         }
641         break;
642
643         /* ----------------------------------------------------- */
644         case 'O': {         /* output format */
645             char outformat[50];
646             char *of = opj_optarg;
647             sprintf(outformat, ".%s", of);
648             img_fol->set_out_format = 1;
649             parameters->cod_format = get_file_format(outformat);
650             switch (parameters->cod_format) {
651             case J2K_CFMT:
652             case JP2_CFMT:
653                 img_fol->out_format = opj_optarg;
654                 break;
655             default:
656                 fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n");
657                 return 1;
658             }
659         }
660         break;
661
662
663         /* ----------------------------------------------------- */
664
665
666         case 'r': {         /* rates rates/distortion */
667             char *s = opj_optarg;
668             while (sscanf(s, "%f", &parameters->tcp_rates[parameters->tcp_numlayers]) ==
669                     1) {
670                 parameters->tcp_numlayers++;
671                 while (*s && *s != ',') {
672                     s++;
673                 }
674                 if (!*s) {
675                     break;
676                 }
677                 s++;
678             }
679             parameters->cp_disto_alloc = 1;
680         }
681         break;
682
683         /* ----------------------------------------------------- */
684
685         case 'q': {         /* add fixed_quality */
686             char *s = opj_optarg;
687             while (sscanf(s, "%f", &parameters->tcp_distoratio[parameters->tcp_numlayers])
688                     == 1) {
689                 parameters->tcp_numlayers++;
690                 while (*s && *s != ',') {
691                     s++;
692                 }
693                 if (!*s) {
694                     break;
695                 }
696                 s++;
697             }
698             parameters->cp_fixed_quality = 1;
699         }
700         break;
701
702         /* dda */
703         /* ----------------------------------------------------- */
704
705         case 'f': {         /* mod fixed_quality (before : -q) */
706             int *row = NULL, *col = NULL;
707             int numlayers = 0, numresolution = 0, matrix_width = 0;
708
709             char *s = opj_optarg;
710             sscanf(s, "%d", &numlayers);
711             s++;
712             if (numlayers > 9) {
713                 s++;
714             }
715
716             parameters->tcp_numlayers = numlayers;
717             numresolution = parameters->numresolution;
718             matrix_width = numresolution * 3;
719             parameters->cp_matrice = (int *) opj_malloc(numlayers * matrix_width * sizeof(
720                                          int));
721             s = s + 2;
722
723             for (i = 0; i < numlayers; i++) {
724                 row = &parameters->cp_matrice[i * matrix_width];
725                 col = row;
726                 parameters->tcp_rates[i] = 1;
727                 sscanf(s, "%d,", &col[0]);
728                 s += 2;
729                 if (col[0] > 9) {
730                     s++;
731                 }
732                 col[1] = 0;
733                 col[2] = 0;
734                 for (j = 1; j < numresolution; j++) {
735                     col += 3;
736                     sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);
737                     s += 6;
738                     if (col[0] > 9) {
739                         s++;
740                     }
741                     if (col[1] > 9) {
742                         s++;
743                     }
744                     if (col[2] > 9) {
745                         s++;
746                     }
747                 }
748                 if (i < numlayers - 1) {
749                     s++;
750                 }
751             }
752             parameters->cp_fixed_alloc = 1;
753         }
754         break;
755
756         /* ----------------------------------------------------- */
757
758         case 't': {         /* tiles */
759             sscanf(opj_optarg, "%d,%d", &parameters->cp_tdx, &parameters->cp_tdy);
760             parameters->tile_size_on = OPJ_TRUE;
761         }
762         break;
763
764         /* ----------------------------------------------------- */
765
766         case 'n': {         /* resolution */
767             sscanf(opj_optarg, "%d", &parameters->numresolution);
768         }
769         break;
770
771         /* ----------------------------------------------------- */
772         case 'c': {         /* precinct dimension */
773             char sep;
774             int res_spec = 0;
775
776             char *s = opj_optarg;
777             do {
778                 sep = 0;
779                 sscanf(s, "[%d,%d]%c", &parameters->prcw_init[res_spec],
780                        &parameters->prch_init[res_spec], &sep);
781                 parameters->csty |= 0x01;
782                 res_spec++;
783                 s = strpbrk(s, "]") + 2;
784             } while (sep == ',');
785             parameters->res_spec = res_spec;
786         }
787         break;
788
789         /* ----------------------------------------------------- */
790
791         case 'b': {         /* code-block dimension */
792             int cblockw_init = 0, cblockh_init = 0;
793             sscanf(opj_optarg, "%d,%d", &cblockw_init, &cblockh_init);
794             if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
795                     || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
796                 fprintf(stderr,
797                         "!! Size of code_block error (option -b) !!\n\nRestriction :\n"
798                         "    * width*height<=4096\n    * 4<=width,height<= 1024\n\n");
799                 return 1;
800             }
801             parameters->cblockw_init = cblockw_init;
802             parameters->cblockh_init = cblockh_init;
803         }
804         break;
805
806         /* ----------------------------------------------------- */
807
808         case 'x': {         /* creation of index file */
809             char *index = opj_optarg;
810             strncpy(indexfilename, index, OPJ_PATH_LEN);
811         }
812         break;
813
814         /* ----------------------------------------------------- */
815
816         case 'p': {         /* progression order */
817             char progression[4];
818
819             strncpy(progression, opj_optarg, 4);
820             parameters->prog_order = give_progression(progression);
821             if (parameters->prog_order == -1) {
822                 fprintf(stderr, "Unrecognized progression order "
823                         "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
824                 return 1;
825             }
826         }
827         break;
828
829         /* ----------------------------------------------------- */
830
831         case 's': {         /* subsampling factor */
832             if (sscanf(opj_optarg, "%d,%d", &parameters->subsampling_dx,
833                        &parameters->subsampling_dy) != 2) {
834                 fprintf(stderr, "'-s' sub-sampling argument error !  [-s dx,dy]\n");
835                 return 1;
836             }
837         }
838         break;
839
840         /* ----------------------------------------------------- */
841
842         case 'd': {         /* coordonnate of the reference grid */
843             if (sscanf(opj_optarg, "%d,%d", &parameters->image_offset_x0,
844                        &parameters->image_offset_y0) != 2) {
845                 fprintf(stderr, "-d 'coordonnate of the reference grid' argument "
846                         "error !! [-d x0,y0]\n");
847                 return 1;
848             }
849         }
850         break;
851
852         /* ----------------------------------------------------- */
853
854         case 'h':           /* display an help description */
855             encode_help_display();
856             return 1;
857
858         /* ----------------------------------------------------- */
859
860         case 'P': {         /* POC */
861             int numpocs = 0;        /* number of progression order change (POC) default 0 */
862             opj_poc_t *POC = NULL;  /* POC : used in case of Progression order change */
863
864             char *s = opj_optarg;
865             POC = parameters->POC;
866
867             while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,
868                           &POC[numpocs].resno0, &POC[numpocs].compno0,
869                           &POC[numpocs].layno1, &POC[numpocs].resno1,
870                           &POC[numpocs].compno1, &POC[numpocs].progorder) == 7) {
871                 POC[numpocs].prg1 = give_progression(POC[numpocs].progorder);
872                 numpocs++;
873                 while (*s && *s != '/') {
874                     s++;
875                 }
876                 if (!*s) {
877                     break;
878                 }
879                 s++;
880             }
881             parameters->numpocs = numpocs;
882         }
883         break;
884
885         /* ------------------------------------------------------ */
886
887         case 'S': {         /* SOP marker */
888             parameters->csty |= 0x02;
889         }
890         break;
891
892         /* ------------------------------------------------------ */
893
894         case 'E': {         /* EPH marker */
895             parameters->csty |= 0x04;
896         }
897         break;
898
899         /* ------------------------------------------------------ */
900
901         case 'M': {         /* Mode switch pas tous au point !! */
902             int value = 0;
903             if (sscanf(opj_optarg, "%d", &value) == 1) {
904                 for (i = 0; i <= 5; i++) {
905                     int cache = value & (1 << i);
906                     if (cache) {
907                         parameters->mode |= (1 << i);
908                     }
909                 }
910             }
911         }
912         break;
913
914         /* ------------------------------------------------------ */
915
916         case 'R': {         /* ROI */
917             if (sscanf(opj_optarg, "c=%d,U=%d", &parameters->roi_compno,
918                        &parameters->roi_shift) != 2) {
919                 fprintf(stderr, "ROI error !! [-ROI c='compno',U='shift']\n");
920                 return 1;
921             }
922         }
923         break;
924
925         /* ------------------------------------------------------ */
926
927         case 'T': {         /* Tile offset */
928             if (sscanf(opj_optarg, "%d,%d", &parameters->cp_tx0,
929                        &parameters->cp_ty0) != 2) {
930                 fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");
931                 return 1;
932             }
933         }
934         break;
935
936         /* ------------------------------------------------------ */
937
938         case 'C': {         /* add a comment */
939             parameters->cp_comment = (char*)opj_malloc(strlen(opj_optarg) + 1);
940             if (parameters->cp_comment) {
941                 strcpy(parameters->cp_comment, opj_optarg);
942             }
943         }
944         break;
945
946
947         /* ------------------------------------------------------ */
948
949         case 'I': {         /* reversible or not */
950             parameters->irreversible = 1;
951         }
952         break;
953
954         /* ------------------------------------------------------ */
955
956         case 'u': {         /* Tile part generation*/
957             parameters->tp_flag = opj_optarg[0];
958             parameters->tp_on = 1;
959         }
960         break;
961
962         /* ------------------------------------------------------ */
963
964         case 'z': {         /* Image Directory path */
965             img_fol->imgdirpath = (char*)opj_malloc(strlen(opj_optarg) + 1);
966             strcpy(img_fol->imgdirpath, opj_optarg);
967             img_fol->set_imgdir = 1;
968         }
969         break;
970
971         /* ------------------------------------------------------ */
972
973         case 'w': {         /* Digital Cinema 2K profile compliance*/
974             int fps = 0;
975             sscanf(opj_optarg, "%d", &fps);
976             if (fps == 24) {
977                 parameters->cp_cinema = CINEMA2K_24;
978             } else if (fps == 48) {
979                 parameters->cp_cinema = CINEMA2K_48;
980             } else {
981                 fprintf(stderr, "Incorrect value!! must be 24 or 48\n");
982                 return 1;
983             }
984             fprintf(stdout, "CINEMA 2K compliant codestream\n");
985             parameters->cp_rsiz = CINEMA2K;
986
987         }
988         break;
989
990         /* ------------------------------------------------------ */
991
992         case 'y': {         /* Digital Cinema 4K profile compliance*/
993             parameters->cp_cinema = CINEMA4K_24;
994             fprintf(stdout, "CINEMA 4K compliant codestream\n");
995             parameters->cp_rsiz = CINEMA4K;
996         }
997         break;
998
999             /* ------------------------------------------------------ */
1000
1001             /* UniPG>> */
1002 #ifdef USE_JPWL
1003         /* ------------------------------------------------------ */
1004
1005         case 'W': {         /* JPWL capabilities switched on */
1006             char *token = NULL;
1007             int hprot, pprot, sens, addr, size, range;
1008
1009             /* we need to enable indexing */
1010             if (!indexfilename) {
1011                 strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN);
1012             }
1013
1014             /* search for different protection methods */
1015
1016             /* break the option in comma points and parse the result */
1017             token = strtok(opj_optarg, ",");
1018             while (token != NULL) {
1019
1020                 /* search header error protection method */
1021                 if (*token == 'h') {
1022
1023                     static int tile = 0, tilespec = 0, lasttileno = 0;
1024
1025                     hprot = 1; /* predefined method */
1026
1027                     if (sscanf(token, "h=%d", &hprot) == 1) {
1028                         /* Main header, specified */
1029                         if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
1030                                 ((hprot >= 37) && (hprot <= 128)))) {
1031                             fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n",
1032                                     hprot);
1033                             return 1;
1034                         }
1035                         parameters->jpwl_hprot_MH = hprot;
1036
1037                     } else if (sscanf(token, "h%d=%d", &tile, &hprot) == 2) {
1038                         /* Tile part header, specified */
1039                         if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
1040                                 ((hprot >= 37) && (hprot <= 128)))) {
1041                             fprintf(stderr, "ERROR -> invalid tile part header protection method h = %d\n",
1042                                     hprot);
1043                             return 1;
1044                         }
1045                         if (tile < 0) {
1046                             fprintf(stderr,
1047                                     "ERROR -> invalid tile part number on protection method t = %d\n", tile);
1048                             return 1;
1049                         }
1050                         if (tilespec < JPWL_MAX_NO_TILESPECS) {
1051                             parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
1052                             parameters->jpwl_hprot_TPH[tilespec++] = hprot;
1053                         }
1054
1055                     } else if (sscanf(token, "h%d", &tile) == 1) {
1056                         /* Tile part header, unspecified */
1057                         if (tile < 0) {
1058                             fprintf(stderr,
1059                                     "ERROR -> invalid tile part number on protection method t = %d\n", tile);
1060                             return 1;
1061                         }
1062                         if (tilespec < JPWL_MAX_NO_TILESPECS) {
1063                             parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
1064                             parameters->jpwl_hprot_TPH[tilespec++] = hprot;
1065                         }
1066
1067
1068                     } else if (!strcmp(token, "h")) {
1069                         /* Main header, unspecified */
1070                         parameters->jpwl_hprot_MH = hprot;
1071
1072                     } else {
1073                         fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
1074                         return 1;
1075                     };
1076
1077                 }
1078
1079                 /* search packet error protection method */
1080                 if (*token == 'p') {
1081
1082                     static int pack = 0, tile = 0, packspec = 0, lastpackno = 0;
1083
1084                     pprot = 1; /* predefined method */
1085
1086                     if (sscanf(token, "p=%d", &pprot) == 1) {
1087                         /* Method for all tiles and all packets */
1088                         if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
1089                                 ((pprot >= 37) && (pprot <= 128)))) {
1090                             fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n",
1091                                     pprot);
1092                             return 1;
1093                         }
1094                         parameters->jpwl_pprot_tileno[0] = 0;
1095                         parameters->jpwl_pprot_packno[0] = 0;
1096                         parameters->jpwl_pprot[0] = pprot;
1097
1098                     } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) {
1099                         /* method specified from that tile on */
1100                         if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
1101                                 ((pprot >= 37) && (pprot <= 128)))) {
1102                             fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
1103                             return 1;
1104                         }
1105                         if (tile < 0) {
1106                             fprintf(stderr,
1107                                     "ERROR -> invalid tile part number on protection method p = %d\n", tile);
1108                             return 1;
1109                         }
1110                         if (packspec < JPWL_MAX_NO_PACKSPECS) {
1111                             parameters->jpwl_pprot_tileno[packspec] = tile;
1112                             parameters->jpwl_pprot_packno[packspec] = 0;
1113                             parameters->jpwl_pprot[packspec++] = pprot;
1114                         }
1115
1116                     } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) {
1117                         /* method fully specified from that tile and that packet on */
1118                         if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
1119                                 ((pprot >= 37) && (pprot <= 128)))) {
1120                             fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
1121                             return 1;
1122                         }
1123                         if (tile < 0) {
1124                             fprintf(stderr,
1125                                     "ERROR -> invalid tile part number on protection method p = %d\n", tile);
1126                             return 1;
1127                         }
1128                         if (pack < 0) {
1129                             fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n",
1130                                     pack);
1131                             return 1;
1132                         }
1133                         if (packspec < JPWL_MAX_NO_PACKSPECS) {
1134                             parameters->jpwl_pprot_tileno[packspec] = tile;
1135                             parameters->jpwl_pprot_packno[packspec] = pack;
1136                             parameters->jpwl_pprot[packspec++] = pprot;
1137                         }
1138
1139                     } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) {
1140                         /* default method from that tile and that packet on */
1141                         if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
1142                                 ((pprot >= 37) && (pprot <= 128)))) {
1143                             fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
1144                             return 1;
1145                         }
1146                         if (tile < 0) {
1147                             fprintf(stderr,
1148                                     "ERROR -> invalid tile part number on protection method p = %d\n", tile);
1149                             return 1;
1150                         }
1151                         if (pack < 0) {
1152                             fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n",
1153                                     pack);
1154                             return 1;
1155                         }
1156                         if (packspec < JPWL_MAX_NO_PACKSPECS) {
1157                             parameters->jpwl_pprot_tileno[packspec] = tile;
1158                             parameters->jpwl_pprot_packno[packspec] = pack;
1159                             parameters->jpwl_pprot[packspec++] = pprot;
1160                         }
1161
1162                     } else if (sscanf(token, "p%d", &tile) == 1) {
1163                         /* default from a tile on */
1164                         if (tile < 0) {
1165                             fprintf(stderr,
1166                                     "ERROR -> invalid tile part number on protection method p = %d\n", tile);
1167                             return 1;
1168                         }
1169                         if (packspec < JPWL_MAX_NO_PACKSPECS) {
1170                             parameters->jpwl_pprot_tileno[packspec] = tile;
1171                             parameters->jpwl_pprot_packno[packspec] = 0;
1172                             parameters->jpwl_pprot[packspec++] = pprot;
1173                         }
1174
1175
1176                     } else if (!strcmp(token, "p")) {
1177                         /* all default */
1178                         parameters->jpwl_pprot_tileno[0] = 0;
1179                         parameters->jpwl_pprot_packno[0] = 0;
1180                         parameters->jpwl_pprot[0] = pprot;
1181
1182                     } else {
1183                         fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
1184                         return 1;
1185                     };
1186
1187                 }
1188
1189                 /* search sensitivity method */
1190                 if (*token == 's') {
1191
1192                     static int tile = 0, tilespec = 0, lasttileno = 0;
1193
1194                     sens = 0; /* predefined: relative error */
1195
1196                     if (sscanf(token, "s=%d", &sens) == 1) {
1197                         /* Main header, specified */
1198                         if ((sens < -1) || (sens > 7)) {
1199                             fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n",
1200                                     sens);
1201                             return 1;
1202                         }
1203                         parameters->jpwl_sens_MH = sens;
1204
1205                     } else if (sscanf(token, "s%d=%d", &tile, &sens) == 2) {
1206                         /* Tile part header, specified */
1207                         if ((sens < -1) || (sens > 7)) {
1208                             fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n",
1209                                     sens);
1210                             return 1;
1211                         }
1212                         if (tile < 0) {
1213                             fprintf(stderr,
1214                                     "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
1215                             return 1;
1216                         }
1217                         if (tilespec < JPWL_MAX_NO_TILESPECS) {
1218                             parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
1219                             parameters->jpwl_sens_TPH[tilespec++] = sens;
1220                         }
1221
1222                     } else if (sscanf(token, "s%d", &tile) == 1) {
1223                         /* Tile part header, unspecified */
1224                         if (tile < 0) {
1225                             fprintf(stderr,
1226                                     "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
1227                             return 1;
1228                         }
1229                         if (tilespec < JPWL_MAX_NO_TILESPECS) {
1230                             parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
1231                             parameters->jpwl_sens_TPH[tilespec++] = hprot;
1232                         }
1233
1234                     } else if (!strcmp(token, "s")) {
1235                         /* Main header, unspecified */
1236                         parameters->jpwl_sens_MH = sens;
1237
1238                     } else {
1239                         fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token);
1240                         return 1;
1241                     };
1242
1243                     parameters->jpwl_sens_size = 2; /* 2 bytes for default size */
1244                 }
1245
1246                 /* search addressing size */
1247                 if (*token == 'a') {
1248
1249                     static int tile = 0, tilespec = 0, lasttileno = 0;
1250
1251                     addr = 0; /* predefined: auto */
1252
1253                     if (sscanf(token, "a=%d", &addr) == 1) {
1254                         /* Specified */
1255                         if ((addr != 0) && (addr != 2) && (addr != 4)) {
1256                             fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr);
1257                             return 1;
1258                         }
1259                         parameters->jpwl_sens_addr = addr;
1260
1261                     } else if (!strcmp(token, "a")) {
1262                         /* default */
1263                         parameters->jpwl_sens_addr = addr; /* auto for default size */
1264
1265                     } else {
1266                         fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token);
1267                         return 1;
1268                     };
1269
1270                 }
1271
1272                 /* search sensitivity size */
1273                 if (*token == 'z') {
1274
1275                     static int tile = 0, tilespec = 0, lasttileno = 0;
1276
1277                     size = 1; /* predefined: 1 byte */
1278
1279                     if (sscanf(token, "z=%d", &size) == 1) {
1280                         /* Specified */
1281                         if ((size != 0) && (size != 1) && (size != 2)) {
1282                             fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size);
1283                             return 1;
1284                         }
1285                         parameters->jpwl_sens_size = size;
1286
1287                     } else if (!strcmp(token, "a")) {
1288                         /* default */
1289                         parameters->jpwl_sens_size = size; /* 1 for default size */
1290
1291                     } else {
1292                         fprintf(stderr, "ERROR -> invalid size selection = %s\n", token);
1293                         return 1;
1294                     };
1295
1296                 }
1297
1298                 /* search range method */
1299                 if (*token == 'g') {
1300
1301                     static int tile = 0, tilespec = 0, lasttileno = 0;
1302
1303                     range = 0; /* predefined: 0 (packet) */
1304
1305                     if (sscanf(token, "g=%d", &range) == 1) {
1306                         /* Specified */
1307                         if ((range < 0) || (range > 3)) {
1308                             fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range);
1309                             return 1;
1310                         }
1311                         parameters->jpwl_sens_range = range;
1312
1313                     } else if (!strcmp(token, "g")) {
1314                         /* default */
1315                         parameters->jpwl_sens_range = range;
1316
1317                     } else {
1318                         fprintf(stderr, "ERROR -> invalid range selection = %s\n", token);
1319                         return 1;
1320                     };
1321
1322                 }
1323
1324                 /* next token or bust */
1325                 token = strtok(NULL, ",");
1326             };
1327
1328
1329             /* some info */
1330             fprintf(stdout, "Info: JPWL capabilities enabled\n");
1331             parameters->jpwl_epc_on = true;
1332
1333         }
1334         break;
1335 #endif /* USE_JPWL */
1336             /* <<UniPG */
1337             /* ------------------------------------------------------ */
1338
1339         break;
1340         /* ------------------------------------------------------ */
1341
1342         default:
1343             fprintf(stderr, "ERROR -> Command line not valid\n");
1344             return 1;
1345         }
1346     }
1347
1348     /* check for possible errors */
1349     if (parameters->cp_cinema) {
1350         if (parameters->tcp_numlayers > 1) {
1351             parameters->cp_rsiz = STD_RSIZ;
1352             fprintf(stdout,
1353                     "Warning: DC profiles do not allow more than one quality layer. The codestream created will not be compliant with the DC profile\n");
1354         }
1355     }
1356
1357     if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc ||
1358             parameters->cp_fixed_quality)
1359             && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^
1360                   parameters->cp_fixed_quality))) {
1361         fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");
1362         return 1;
1363     }               /* mod fixed_quality */
1364
1365     /* if no rate entered, lossless by default */
1366     if (parameters->tcp_numlayers == 0) {
1367         parameters->tcp_rates[0] = 0;   /* MOD antonin : losslessbug */
1368         parameters->tcp_numlayers++;
1369         parameters->cp_disto_alloc = 1;
1370     }
1371
1372     if ((parameters->cp_tx0 > parameters->image_offset_x0) ||
1373             (parameters->cp_ty0 > parameters->image_offset_y0)) {
1374         fprintf(stderr,
1375                 "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
1376                 parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0,
1377                 parameters->image_offset_y0);
1378         return 1;
1379     }
1380
1381     for (i = 0; i < parameters->numpocs; i++) {
1382         if (parameters->POC[i].prg == -1) {
1383             fprintf(stderr,
1384                     "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
1385                     i + 1);
1386         }
1387     }
1388
1389     return 0;
1390 }
1391
1392
1393 /** Create the same index as j2k_create_index does, but in an int[] instead of in a file ==> easy to pass it back to Java, to transfer it etc.
1394   @param buffer_size, increased by the length of the compressed index, in number of bytes
1395   @return a pointer to a char[]
1396   Syntax of the index:
1397     one char for the version number (1): one byte because no problem with little endian, big endian etc.
1398     one int for each of the following information:
1399             Image Width
1400             Image Height
1401             progression order
1402             Tile width
1403             Tile height
1404             Nb tiles in X
1405             Nb tiles in Y
1406             Nb of components
1407             Nb of layers
1408             Nb of resolutions
1409
1410             for each resolution:
1411                 Precinct width
1412                 Precinct height
1413
1414             End main header position
1415             codestream size
1416
1417             For each tile:
1418                 tile number
1419                 tile start pos in codestream
1420                 tile header end position
1421                 tile end position in codestream
1422
1423             For each LRCP, RLCP etc.:
1424                 packet number
1425                 tile number
1426                 layer number
1427                 resolution number
1428                 component number
1429                 precinct number
1430                 start position in the codestream
1431                 end position of this packet
1432   */
1433 static char* create_index_into_byte_array(opj_codestream_info_t *cstr_info,
1434         int* buffer_size)
1435 {
1436     int tileno, compno, layno, resno, precno, pack_nb, x, y;
1437     char* buffer = NULL;
1438     int buffer_pos = 0;
1439     int prec_max = 0;
1440
1441     prec_max = 0;
1442     for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
1443         for (resno = 0; resno < cstr_info->numdecompos[0] + 1; resno++) {
1444             prec_max = int_max(prec_max,
1445                                cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]);
1446         }
1447     }
1448
1449     /* Compute the size of the index buffer, in number of bytes*/
1450     *buffer_size =
1451         1 /* version */
1452         + (10 /* image_w until decomposition */
1453            + (cstr_info->numdecompos[0] + 1) * 2 /* pdx size for each tile */
1454            + 2 /* main_head_end + codestream_size */
1455            + cstr_info->tw * cstr_info->th * 4 /* tile info, without distortion info */
1456            + cstr_info->tw * cstr_info->th * cstr_info->numlayers *
1457            (cstr_info->numdecompos[0] + 1) * cstr_info->numcomps * prec_max * 8
1458           ) * sizeof(int);
1459     /*printf("C: index buffer size = %d bytes\n", *buffer_size);*/
1460     buffer = (char*) opj_malloc(*buffer_size);
1461
1462     if (!buffer) {
1463         /*opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to allocate index buffer for writing %d int\n", *buffer_size);*/
1464         fprintf(stderr, "failed to allocate index buffer for writing %d int\n",
1465                 *buffer_size);
1466         return 0;
1467     }
1468
1469     buffer[0] = 1;  /* Version stored on a byte*/
1470     buffer++;
1471     /* Remaining information are stored on a int.*/
1472     ((int*)buffer)[buffer_pos++] = cstr_info->image_w;
1473     ((int*)buffer)[buffer_pos++] = cstr_info->image_h;
1474     ((int*)buffer)[buffer_pos++] = cstr_info->prog;
1475     ((int*)buffer)[buffer_pos++] = cstr_info->tile_x;
1476     ((int*)buffer)[buffer_pos++] = cstr_info->tile_y;
1477     ((int*)buffer)[buffer_pos++] = cstr_info->tw;
1478     ((int*)buffer)[buffer_pos++] = cstr_info->th;
1479     ((int*)buffer)[buffer_pos++] = cstr_info->numcomps;
1480     ((int*)buffer)[buffer_pos++] = cstr_info->numlayers;
1481     ((int*)buffer)[buffer_pos++] = cstr_info->numdecompos[0];
1482
1483     for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
1484         /* based on tile 0 */
1485         ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
1486         ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
1487     }
1488     ((int*)buffer)[buffer_pos++] = cstr_info->main_head_end;
1489     ((int*)buffer)[buffer_pos++] = cstr_info->codestream_size;
1490
1491     for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
1492         ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].tileno;
1493         ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].start_pos;
1494         ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_header;
1495         ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_pos;
1496     }
1497
1498     for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
1499         int start_pos, end_pos;
1500         int max_numdecompos = 0;
1501         pack_nb = 0;
1502
1503         for (compno = 0; compno < cstr_info->numcomps; compno++) {
1504             if (max_numdecompos < cstr_info->numdecompos[compno]) {
1505                 max_numdecompos = cstr_info->numdecompos[compno];
1506             }
1507         }
1508
1509         if (cstr_info->prog == LRCP) {  /* LRCP */
1510
1511             for (layno = 0; layno < cstr_info->numlayers; layno++) {
1512                 for (resno = 0; resno < max_numdecompos + 1; resno++) {
1513                     for (compno = 0; compno < cstr_info->numcomps; compno++) {
1514                         int prec_max;
1515                         if (resno > cstr_info->numdecompos[compno]) {
1516                             break;
1517                         }
1518                         prec_max = cstr_info->tile[tileno].pw[resno] *
1519                                    cstr_info->tile[tileno].ph[resno];
1520                         for (precno = 0; precno < prec_max; precno++) {
1521                             start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
1522                             end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
1523                             ((int*)buffer)[buffer_pos++] = pack_nb;
1524                             ((int*)buffer)[buffer_pos++] = tileno;
1525                             ((int*)buffer)[buffer_pos++] = layno;
1526                             ((int*)buffer)[buffer_pos++] = resno;
1527                             ((int*)buffer)[buffer_pos++] = compno;
1528                             ((int*)buffer)[buffer_pos++] = precno;
1529                             ((int*)buffer)[buffer_pos++] = start_pos;
1530                             ((int*)buffer)[buffer_pos++] = end_pos;
1531                             pack_nb++;
1532                         }
1533                     }
1534                 }
1535             }
1536         } /* LRCP */
1537         else if (cstr_info->prog == RLCP) { /* RLCP */
1538
1539             for (resno = 0; resno < max_numdecompos + 1; resno++) {
1540                 for (layno = 0; layno < cstr_info->numlayers; layno++) {
1541                     for (compno = 0; compno < cstr_info->numcomps; compno++) {
1542                         int prec_max;
1543                         if (resno > cstr_info->numdecompos[compno]) {
1544                             break;
1545                         }
1546                         prec_max = cstr_info->tile[tileno].pw[resno] *
1547                                    cstr_info->tile[tileno].ph[resno];
1548                         for (precno = 0; precno < prec_max; precno++) {
1549                             start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
1550                             end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
1551                             ((int*)buffer)[buffer_pos++] = pack_nb;
1552                             ((int*)buffer)[buffer_pos++] = tileno;
1553                             ((int*)buffer)[buffer_pos++] = resno;
1554                             ((int*)buffer)[buffer_pos++] = layno;
1555                             ((int*)buffer)[buffer_pos++] = compno;
1556                             ((int*)buffer)[buffer_pos++] = precno;
1557                             ((int*)buffer)[buffer_pos++] = start_pos;
1558                             ((int*)buffer)[buffer_pos++] = end_pos;
1559                             pack_nb++;
1560                         }
1561                     }
1562                 }
1563             }
1564         } /* RLCP */
1565         else if (cstr_info->prog == RPCL) { /* RPCL */
1566
1567             for (resno = 0; resno < max_numdecompos + 1; resno++) {
1568                 /* I suppose components have same XRsiz, YRsiz */
1569                 int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno /
1570                          (float)cstr_info->tw) * cstr_info->tw * cstr_info->tile_x;
1571                 int y0 = cstr_info->tile_Ox + (int)floor((float)tileno /
1572                          (float)cstr_info->tw) * cstr_info->tile_y;
1573                 int x1 = x0 + cstr_info->tile_x;
1574                 int y1 = y0 + cstr_info->tile_y;
1575                 for (compno = 0; compno < cstr_info->numcomps; compno++) {
1576                     int prec_max;
1577                     if (resno > cstr_info->numdecompos[compno]) {
1578                         break;
1579                     }
1580                     prec_max = cstr_info->tile[tileno].pw[resno] *
1581                                cstr_info->tile[tileno].ph[resno];
1582                     for (precno = 0; precno < prec_max; precno++) {
1583                         int pcnx = cstr_info->tile[tileno].pw[resno];
1584                         int pcx = (int) pow(2, cstr_info->tile[tileno].pdx[resno] +
1585                                             cstr_info->numdecompos[compno] - resno);
1586                         int pcy = (int) pow(2, cstr_info->tile[tileno].pdy[resno] +
1587                                             cstr_info->numdecompos[compno] - resno);
1588                         int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
1589                         int precno_y = (int) floor((float)precno / (float)pcnx);
1590                         for (y = y0; y < y1; y++) {
1591                             if (precno_y * pcy == y) {
1592                                 for (x = x0; x < x1; x++) {
1593                                     if (precno_x * pcx == x) {
1594                                         for (layno = 0; layno < cstr_info->numlayers; layno++) {
1595                                             start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
1596                                             end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
1597                                             ((int*)buffer)[buffer_pos++] = pack_nb;
1598                                             ((int*)buffer)[buffer_pos++] = tileno;
1599                                             ((int*)buffer)[buffer_pos++] = resno;
1600                                             ((int*)buffer)[buffer_pos++] = precno;
1601                                             ((int*)buffer)[buffer_pos++] = compno;
1602                                             ((int*)buffer)[buffer_pos++] = layno;
1603                                             ((int*)buffer)[buffer_pos++] = start_pos;
1604                                             ((int*)buffer)[buffer_pos++] = end_pos;
1605                                             pack_nb++;
1606                                         }
1607                                     }
1608                                 }/* x = x0..x1 */
1609                             }
1610                         }  /* y = y0..y1 */
1611                     } /* precno */
1612                 } /* compno */
1613             } /* resno */
1614         } /* RPCL */
1615         else if (cstr_info->prog == PCRL) { /* PCRL */
1616             /* I suppose components have same XRsiz, YRsiz */
1617             int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno /
1618                      (float)cstr_info->tw) * cstr_info->tw * cstr_info->tile_x;
1619             int y0 = cstr_info->tile_Ox + (int)floor((float)tileno /
1620                      (float)cstr_info->tw) * cstr_info->tile_y;
1621             int x1 = x0 + cstr_info->tile_x;
1622             int y1 = y0 + cstr_info->tile_y;
1623
1624             for (compno = 0; compno < cstr_info->numcomps; compno++) {
1625                 for (resno = 0; resno < max_numdecompos + 1; resno++) {
1626                     int prec_max;
1627                     if (resno > cstr_info->numdecompos[compno]) {
1628                         break;
1629                     }
1630                     prec_max = cstr_info->tile[tileno].pw[resno] *
1631                                cstr_info->tile[tileno].ph[resno];
1632                     for (precno = 0; precno < prec_max; precno++) {
1633                         int pcnx = cstr_info->tile[tileno].pw[resno];
1634                         int pcx = (int) pow(2, cstr_info->tile[tileno].pdx[resno] +
1635                                             cstr_info->numdecompos[compno] - resno);
1636                         int pcy = (int) pow(2, cstr_info->tile[tileno].pdy[resno] +
1637                                             cstr_info->numdecompos[compno] - resno);
1638                         int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
1639                         int precno_y = (int) floor((float)precno / (float)pcnx);
1640                         for (y = y0; y < y1; y++) {
1641                             if (precno_y * pcy == y) {
1642                                 for (x = x0; x < x1; x++) {
1643                                     if (precno_x * pcx == x) {
1644                                         for (layno = 0; layno < cstr_info->numlayers; layno++) {
1645                                             start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
1646                                             end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
1647                                             ((int*)buffer)[buffer_pos++] = pack_nb;
1648                                             ((int*)buffer)[buffer_pos++] = tileno;
1649                                             ((int*)buffer)[buffer_pos++] = precno;
1650                                             ((int*)buffer)[buffer_pos++] = compno;
1651                                             ((int*)buffer)[buffer_pos++] = resno;
1652                                             ((int*)buffer)[buffer_pos++] = layno;
1653                                             ((int*)buffer)[buffer_pos++] = start_pos;
1654                                             ((int*)buffer)[buffer_pos++] = end_pos;
1655                                             pack_nb++;
1656                                         }
1657                                     }
1658                                 }/* x = x0..x1 */
1659                             }
1660                         }  /* y = y0..y1 */
1661                     } /* precno */
1662                 } /* resno */
1663             } /* compno */
1664         } /* PCRL */
1665         else {  /* CPRL */
1666
1667             for (compno = 0; compno < cstr_info->numcomps; compno++) {
1668                 /* I suppose components have same XRsiz, YRsiz */
1669                 int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno /
1670                          (float)cstr_info->tw) * cstr_info->tw * cstr_info->tile_x;
1671                 int y0 = cstr_info->tile_Ox + (int)floor((float)tileno /
1672                          (float)cstr_info->tw) * cstr_info->tile_y;
1673                 int x1 = x0 + cstr_info->tile_x;
1674                 int y1 = y0 + cstr_info->tile_y;
1675
1676                 for (resno = 0; resno < max_numdecompos + 1; resno++) {
1677                     int prec_max;
1678                     if (resno > cstr_info->numdecompos[compno]) {
1679                         break;
1680                     }
1681                     prec_max = cstr_info->tile[tileno].pw[resno] *
1682                                cstr_info->tile[tileno].ph[resno];
1683                     for (precno = 0; precno < prec_max; precno++) {
1684                         int pcnx = cstr_info->tile[tileno].pw[resno];
1685                         int pcx = (int) pow(2, cstr_info->tile[tileno].pdx[resno] +
1686                                             cstr_info->numdecompos[compno] - resno);
1687                         int pcy = (int) pow(2, cstr_info->tile[tileno].pdy[resno] +
1688                                             cstr_info->numdecompos[compno] - resno);
1689                         int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
1690                         int precno_y = (int) floor((float)precno / (float)pcnx);
1691                         for (y = y0; y < y1; y++) {
1692                             if (precno_y * pcy == y) {
1693                                 for (x = x0; x < x1; x++) {
1694                                     if (precno_x * pcx == x) {
1695                                         for (layno = 0; layno < cstr_info->numlayers; layno++) {
1696                                             start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
1697                                             end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
1698                                             ((int*)buffer)[buffer_pos++] = pack_nb;
1699                                             ((int*)buffer)[buffer_pos++] = tileno;
1700                                             ((int*)buffer)[buffer_pos++] = compno;
1701                                             ((int*)buffer)[buffer_pos++] = precno;
1702                                             ((int*)buffer)[buffer_pos++] = resno;
1703                                             ((int*)buffer)[buffer_pos++] = layno;
1704                                             ((int*)buffer)[buffer_pos++] = start_pos;
1705                                             ((int*)buffer)[buffer_pos++] = end_pos;
1706                                             pack_nb++;
1707                                         }
1708                                     }
1709                                 }/* x = x0..x1 */
1710                             }
1711                         } /* y = y0..y1 */
1712                     } /* precno */
1713                 } /* resno */
1714             } /* compno */
1715         } /* CPRL */
1716     } /* tileno */
1717
1718     if (buffer_pos > *buffer_size) {
1719         /*opj_event_msg(j2k->cinfo, EVT_ERROR, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);*/
1720         fprintf(stderr, "index creation: buffer_pos (%d) > buffer_size (%d)!\n",
1721                 buffer_pos, *buffer_size);
1722         return 0;
1723     }
1724
1725     return --buffer;
1726 }
1727
1728
1729
1730
1731 /* --------------------------------------------------------------------------
1732    ------------ Get the image byte[] from the Java object -------------------*/
1733
1734 static opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env,
1735                               jobject obj, jclass cls)
1736 {
1737     int i, max, shift, w, h, depth;
1738     opj_image_t * img = NULL;
1739     int compno, numcomps;
1740     opj_image_t * image = NULL;
1741     opj_image_comp_t *comp;
1742     opj_image_cmptparm_t cmptparm[3];   /* maximum of 3 components */
1743     OPJ_COLOR_SPACE color_space;
1744     jfieldID    fid;
1745     jint        ji;
1746     jbyteArray  jba;
1747     jshortArray jsa;
1748     jintArray   jia;
1749     int         len;
1750     jbyte       *jbBody;
1751     jshort      *jsBody;
1752     jint        *jiBody;
1753     jboolean        isCopy;
1754
1755     /* Image width, height and depth*/
1756     fid = (*env)->GetFieldID(env, cls, "width", "I");
1757     ji = (*env)->GetIntField(env, obj, fid);
1758     w = ji;
1759
1760     fid = (*env)->GetFieldID(env, cls, "height", "I");
1761     ji = (*env)->GetIntField(env, obj, fid);
1762     h = ji;
1763
1764     fid = (*env)->GetFieldID(env, cls, "depth", "I");
1765     ji = (*env)->GetIntField(env, obj, fid);
1766     depth = ji;
1767
1768     /* Read the image*/
1769     if (depth <= 16) {
1770         numcomps = 1;
1771         color_space = CLRSPC_GRAY;
1772     } else {
1773         numcomps = 3;
1774         color_space = CLRSPC_SRGB;
1775     }
1776     memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
1777
1778     if (numcomps == 1) {
1779         cmptparm[0].x0 = parameters->image_offset_x0;
1780         cmptparm[0].y0 = parameters->image_offset_y0;
1781         cmptparm[0].w = !cmptparm[0].x0 ? (w - 1) * parameters->subsampling_dx + 1 :
1782                         cmptparm[0].x0 + (w - 1) * parameters->subsampling_dx + 1;
1783         cmptparm[0].h = !cmptparm[0].y0 ? (h - 1) * parameters->subsampling_dy + 1 :
1784                         cmptparm[0].y0 + (h - 1) * parameters->subsampling_dy + 1;
1785         /* Java types are always signed but we use them as unsigned types (shift of the negative part of
1786            the pixels of the images in Telemis before entering the encoder).*/
1787         cmptparm[0].sgnd = 0;
1788         if (depth <= 16) {
1789             cmptparm[0].prec = depth;
1790         } else {
1791             cmptparm[0].prec = 8;
1792         }
1793         cmptparm[0].bpp = cmptparm[0].prec;
1794         cmptparm[0].dx = parameters->subsampling_dx;
1795         cmptparm[0].dy = parameters->subsampling_dy;
1796         /*printf("C: component 0 initialised: x0=%d, y0=%d, w=%d, h=%d, sgnd=%d, bpp=%d, dx=%d, dy=%d, color_space=%d\n", cmptparm[0].x0, cmptparm[0].y0, cmptparm[0].w,
1797                     cmptparm[0].h, cmptparm[0].sgnd, cmptparm[0].bpp, cmptparm[0].dx, cmptparm[0].dy, color_space);*/
1798     } else {
1799         for (i = 0; i < numcomps; i++) {
1800             cmptparm[i].prec = 8;
1801             cmptparm[i].bpp = 8;
1802             cmptparm[i].sgnd = 0;
1803             cmptparm[i].dx = parameters->subsampling_dx;
1804             cmptparm[i].dy = parameters->subsampling_dy;
1805             cmptparm[i].w = w;
1806             cmptparm[i].h = h;
1807         }
1808     }
1809
1810     /* create the image */
1811     image = opj_image_create(numcomps, &cmptparm[0], color_space);
1812
1813     if (!image) {
1814         return NULL;
1815     }
1816
1817     if (depth <= 16) {
1818         image->numcomps = 1;
1819     } else {
1820         image->numcomps = 3;
1821     }
1822
1823     /* set image offset and reference grid */
1824     image->x0 = cmptparm[0].x0;
1825     image->y0 = cmptparm[0].x0;
1826     image->x1 = cmptparm[0].w;
1827     image->y1 = cmptparm[0].h;
1828
1829     /* set image data */
1830     for (compno = 0; compno < numcomps; compno++) {
1831         comp = &image->comps[compno];
1832         max = -100000;
1833         if (depth == 8) {
1834             fid = (*env)->GetFieldID(env, cls, "image8", "[B"); /* byteArray []*/
1835             jba = (*env)->GetObjectField(env, obj, fid);
1836             len = (*env)->GetArrayLength(env, jba);
1837
1838             jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, &isCopy);
1839             /*printf("C: before transferring 8 bpp image\n");*/
1840             if (comp->sgnd) {
1841                 for (i = 0; i < len; i++) {
1842                     comp->data[i] = (char) jbBody[i];
1843                     if (comp->data[i] > max) {
1844                         max = comp->data[i];
1845                     }
1846                 }
1847             } else {
1848                 for (i = 0; i < len; i++) {
1849                     comp->data[i] = (unsigned char) jbBody[i];
1850                     if (comp->data[i] > max) {
1851                         max = comp->data[i];
1852                     }
1853                 }
1854             }
1855             (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
1856         } else if (depth == 16) {
1857             fid = (*env)->GetFieldID(env, cls, "image16", "[S"); /* shortArray []*/
1858             jsa = (*env)->GetObjectField(env, obj, fid);
1859             len = (*env)->GetArrayLength(env, jsa);
1860
1861             jsBody = (*env)->GetPrimitiveArrayCritical(env, jsa, &isCopy);
1862             /*printf("C: before transferring 16 bpp image\n");*/
1863             if (comp->sgnd) {   /* Special behaviour to deal with signed elements ??*/
1864                 comp->data[i] = (short) jsBody[i];
1865                 for (i = 0; i < len; i++) {
1866                     if (comp->data[i] > max) {
1867                         max = comp->data[i];
1868                     }
1869                 }
1870             } else {
1871                 for (i = 0; i < len; i++) {
1872                     comp->data[i] = (unsigned short) jsBody[i];
1873                     if (comp->data[i] > max) {
1874                         max = comp->data[i];
1875                     }
1876                 }
1877             }
1878             (*env)->ReleasePrimitiveArrayCritical(env, jsa, jsBody, 0);
1879         } else if (depth == 24) {
1880             fid = (*env)->GetFieldID(env, cls, "image24", "[I"); /* intArray []*/
1881             jia = (*env)->GetObjectField(env, obj, fid);
1882             len = (*env)->GetArrayLength(env, jia);
1883             shift = compno * 8;
1884
1885             jiBody = (*env)->GetPrimitiveArrayCritical(env, jia, &isCopy);
1886             /*printf("C: before transferring 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);*/
1887             if (comp->sgnd) {   /* Special behaviour to deal with signed elements ?? XXXXX*/
1888                 for (i = 0; i < len; i++) {
1889                     comp->data[i] = (((int) jiBody[i]) & (0xFF << shift)) >> shift;
1890                     if (comp->data[i] > max) {
1891                         max = comp->data[i];
1892                     }
1893                 }
1894             } else {
1895                 for (i = 0; i < len; i++) {
1896                     comp->data[i] = (((unsigned int) jiBody[i]) & (0xFF << shift)) >> shift;
1897                     if (comp->data[i] > max) {
1898                         max = comp->data[i];
1899                     }
1900                 }
1901             }
1902             (*env)->ReleasePrimitiveArrayCritical(env, jia, jiBody, 0);
1903         }
1904         comp->bpp = int_floorlog2(max) + 1;
1905         comp->prec = comp->bpp;
1906         /*printf("C: component %d: max  %d, real bpp = %d\n", compno, max, comp->bpp);*/
1907     }
1908     return image;
1909 }
1910
1911
1912 /* --------------------------------------------------------------------------
1913    --------------------   MAIN METHOD, CALLED BY JAVA -----------------------*/
1914 JNIEXPORT jlong JNICALL
1915 Java_org_openJpeg_OpenJPEGJavaEncoder_internalEncodeImageToJ2K(JNIEnv *env,
1916         jobject obj, jobjectArray javaParameters)
1917 {
1918     int argc;       /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */
1919     char **argv;    /*  'parse_cmdline_decoder' method taken from the j2k_to_image project */
1920     opj_bool bSuccess;
1921     opj_cparameters_t parameters;   /* compression parameters */
1922     img_fol_t img_fol;
1923     opj_event_mgr_t event_mgr;      /* event manager */
1924     opj_image_t *image = NULL;
1925     int i, j, num_images;
1926     int imageno;
1927     opj_codestream_info_t cstr_info;        /* Codestream information structure */
1928     char indexfilename[OPJ_PATH_LEN];   /* index file name */
1929
1930     char* compressed_index = NULL;
1931     int compressed_index_size = -1;
1932     /* ==> Access variables to the Java member variables*/
1933     jsize       arraySize;
1934     jclass      cls;
1935     jobject     object;
1936     jboolean    isCopy;
1937     jfieldID    fid;
1938     jbyteArray  jba;
1939     jbyte       *jbBody;
1940     callback_variables_t msgErrorCallback_vars;
1941     /* <== access variable to the Java member variables.*/
1942
1943     /* For the encoding and storage into the file*/
1944     opj_cinfo_t* cinfo;
1945     int codestream_length;
1946     opj_cio_t *cio = NULL;
1947     FILE *f = NULL;
1948
1949     /* JNI reference to the calling class*/
1950     cls = (*env)->GetObjectClass(env, obj);
1951
1952     /* Pointers to be able to call a Java method for all the info and error messages*/
1953     msgErrorCallback_vars.env = env;
1954     msgErrorCallback_vars.jobj = &obj;
1955     msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage",
1956                                         "(Ljava/lang/String;)V");
1957     msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError",
1958                                       "(Ljava/lang/String;)V");
1959
1960     arraySize = (*env)->GetArrayLength(env, javaParameters);
1961     argc = (int) arraySize + 1;
1962     argv = opj_malloc(argc * sizeof(char*));
1963     argv[0] = "ProgramName.exe";    /* The program name: useless*/
1964     j = 0;
1965     for (i = 1; i < argc; i++) {
1966         object = (*env)->GetObjectArrayElement(env, javaParameters, i - 1);
1967         argv[i] = (char*)(*env)->GetStringUTFChars(env, object, &isCopy);
1968     }
1969
1970     /*printf("C: ");
1971     for (i=0; i<argc; i++) {
1972         printf("[%s]",argv[i]);
1973     }
1974     printf("\n");*/
1975
1976     /*
1977     configure the event callbacks
1978     */
1979     memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
1980     event_mgr.error_handler = error_callback;
1981     event_mgr.warning_handler = warning_callback;
1982     event_mgr.info_handler = info_callback;
1983
1984     /* set encoding parameters to default values */
1985     opj_set_default_encoder_parameters(&parameters);
1986     parameters.cod_format = J2K_CFMT;
1987     /*parameters.index_on = 1;*/
1988
1989     /* Initialize indexfilename and img_fol */
1990     *indexfilename = 0;
1991     memset(&img_fol, 0, sizeof(img_fol_t));
1992
1993     /* parse input and get user encoding parameters */
1994     if (parse_cmdline_encoder(argc, argv, &parameters, &img_fol,
1995                               indexfilename) == 1) {
1996         /* Release the Java arguments array*/
1997         for (i = 1; i < argc; i++) {
1998             (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env,
1999                                           javaParameters, i - 1), argv[i]);
2000         }
2001         return -1;
2002     }
2003
2004     /* Release the Java arguments array*/
2005     for (i = 1; i < argc; i++) {
2006         (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env,
2007                                       javaParameters, i - 1), argv[i]);
2008     }
2009
2010     if (parameters.cp_cinema) {
2011         cinema_parameters(&parameters);
2012     }
2013
2014
2015     /* Create comment for codestream */
2016     if (parameters.cp_comment == NULL) {
2017         const char comment[] = "Created by JavaOpenJPEG version ";
2018         const size_t clen = strlen(comment);
2019         const char *version = opj_version();
2020         /* UniPG>> */
2021 #ifdef USE_JPWL
2022         parameters.cp_comment = (char*)opj_malloc(clen + strlen(version) + 11);
2023         sprintf(parameters.cp_comment, "%s%s with JPWL", comment, version);
2024 #else
2025         parameters.cp_comment = (char*)opj_malloc(clen + strlen(version) + 1);
2026         sprintf(parameters.cp_comment, "%s%s", comment, version);
2027 #endif
2028         /* <<UniPG */
2029
2030     }
2031
2032     /* Read directory if necessary */
2033     num_images = 1;
2034
2035     /*Encoding image one by one*/
2036     for (imageno = 0; imageno < num_images; imageno++) {
2037         image = NULL;
2038         fprintf(stderr, "\n");
2039
2040         image = loadImage(&parameters, env, obj, cls);
2041         /*printf("C: after load image: image = %d\n", image);*/
2042         if (!image) {
2043             fprintf(stderr, "Unable to load image\n");
2044             return -1;
2045         }
2046
2047         /* Decide if MCT should be used */
2048         parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
2049
2050         if (parameters.cp_cinema) {
2051             cinema_setup_encoder(&parameters, image, &img_fol);
2052         }
2053
2054         /* encode the destination image */
2055         /* ---------------------------- */
2056         /* get a J2K compressor handle */
2057         if (parameters.cod_format == J2K_CFMT) {    /* J2K format output */
2058             cinfo = opj_create_compress(CODEC_J2K);
2059         } else {                                    /* JP2 format output */
2060             cinfo = opj_create_compress(CODEC_JP2);
2061         }
2062         /* catch events using our callbacks and give a local context */
2063         opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, &msgErrorCallback_vars);
2064
2065         /* setup the encoder parameters using the current image and user parameters */
2066         opj_setup_encoder(cinfo, &parameters, image);
2067
2068         /* open a byte stream for writing */
2069         /* allocate memory for all tiles */
2070         cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
2071
2072         /* encode the image */
2073         bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);
2074         printf("C: after opj_encode_with_info\n");
2075         if (!bSuccess) {
2076             opj_cio_close(cio);
2077             fprintf(stderr, "failed to encode image\n");
2078             return -1;
2079         }
2080         codestream_length = cio_tell(cio);
2081
2082         /* write the index on disk, if needed (-x 'filename') */
2083         if (*indexfilename) {
2084             bSuccess = write_index_file(&cstr_info, indexfilename);
2085             if (bSuccess) {
2086                 fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename);
2087             }
2088         }
2089
2090         compressed_index = create_index_into_byte_array(&cstr_info,
2091                            &compressed_index_size);
2092         /* Allocates the Java compressedIndex byte[] and sends this index into the Java object */
2093         fid = (*env)->GetFieldID(env, cls, "compressedIndex", "[B");
2094         jba = (*env)->NewByteArray(env, compressed_index_size + 1);
2095         jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
2096         memcpy(jbBody, compressed_index, compressed_index_size);
2097         (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
2098         (*env)->SetObjectField(env, obj, fid, jba);
2099         opj_free(compressed_index);
2100
2101         /* write the generated codestream to disk ? */
2102         if (parameters.outfile[0] != '\0') {
2103             f = fopen(parameters.outfile, "wb");
2104             if (!f) {
2105                 fprintf(stderr, "failed to open [%s] for writing\n", parameters.outfile);
2106                 return -1;
2107             }
2108             fwrite(cio->buffer, 1, codestream_length, f);
2109             fclose(f);
2110             fprintf(stdout, "Generated outfile [%s]\n", parameters.outfile);
2111         }
2112
2113         /* Write the generated codestream to the Java pre-allocated compressedStream byte[] */
2114         fid = (*env)->GetFieldID(env, cls, "compressedStream", "[B");
2115         jba = (*env)->GetObjectField(env, obj, fid);
2116         jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
2117         memcpy(jbBody, cio->buffer, codestream_length);
2118         (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
2119
2120         /* close and free the byte stream */
2121         opj_cio_close(cio);
2122
2123         /* free remaining compression structures */
2124         opj_destroy_compress(cinfo);
2125         opj_destroy_cstr_info(&cstr_info);
2126
2127         /* free image data */
2128         opj_image_destroy(image);
2129     }
2130
2131     /* free user parameters structure */
2132     if (parameters.cp_comment) {
2133         opj_free(parameters.cp_comment);
2134     }
2135     if (parameters.cp_matrice) {
2136         opj_free(parameters.cp_matrice);
2137     }
2138
2139     return codestream_length;
2140 }
2141