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