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
12 * Redistribution and use in source and binary forms, with or without
\r
13 * modification, are permitted provided that the following conditions
\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
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
39 #include "openjpeg.h"
\r
41 #include "convert.h"
\r
44 #include "org_openJpeg_OpenJPEGJavaEncoder.h"
\r
47 #define stricmp strcasecmp
\r
48 #define strnicmp strncasecmp
\r
51 #include "format_defs.h"
\r
53 #define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/
\r
54 #define CINEMA_48_CS 651041 /*Codestream length for 48fps*/
\r
55 #define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/
\r
56 #define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/
\r
58 extern int get_file_format(char *filename);
\r
59 extern void error_callback(const char *msg, void *client_data);
\r
60 extern warning_callback(const char *msg, void *client_data);
\r
61 extern void info_callback(const char *msg, void *client_data);
\r
63 typedef struct callback_variables {
\r
65 /** 'jclass' object used to call a Java method from the C */
\r
67 /** 'jclass' object used to call a Java method from the C */
\r
68 jmethodID message_mid;
\r
69 jmethodID error_mid;
\r
70 } callback_variables_t;
\r
72 typedef struct dircnt{
\r
73 /** Buffer for holding images read from Directory*/
\r
75 /** Pointer to the buffer*/
\r
79 typedef struct img_folder{
\r
80 /** The directory path of the folder containing input images*/
\r
86 /** Enable Cod Format for output*/
\r
87 char set_out_format;
\r
88 /** User specified rate stored in case of cinema option*/
\r
92 void encode_help_display() {
\r
93 fprintf(stdout,"HELP\n----\n\n");
\r
94 fprintf(stdout,"- the -h option displays this help information on screen\n\n");
\r
97 fprintf(stdout,"List of parameters for the JPEG 2000 "
\r
100 #endif /* USE_JPWL */
\r
103 fprintf(stdout,"\n");
\r
104 fprintf(stdout,"REMARKS:\n");
\r
105 fprintf(stdout,"---------\n");
\r
106 fprintf(stdout,"\n");
\r
107 fprintf(stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n");
\r
108 fprintf(stdout,"COD and QCD never appear in the tile_header.\n");
\r
109 fprintf(stdout,"\n");
\r
110 fprintf(stdout,"- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n");
\r
111 fprintf(stdout,"color image. You need enough disk space memory (twice the original) to encode \n");
\r
112 fprintf(stdout,"the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n");
\r
113 fprintf(stdout,"\n");
\r
114 fprintf(stdout,"By default:\n");
\r
115 fprintf(stdout,"------------\n");
\r
116 fprintf(stdout,"\n");
\r
117 fprintf(stdout," * Lossless\n");
\r
118 fprintf(stdout," * 1 tile\n");
\r
119 fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");
\r
120 fprintf(stdout," * Size of code-block : 64 x 64\n");
\r
121 fprintf(stdout," * Number of resolutions: 6\n");
\r
122 fprintf(stdout," * No SOP marker in the codestream\n");
\r
123 fprintf(stdout," * No EPH marker in the codestream\n");
\r
124 fprintf(stdout," * No sub-sampling in x or y direction\n");
\r
125 fprintf(stdout," * No mode switch activated\n");
\r
126 fprintf(stdout," * Progression order: LRCP\n");
\r
127 fprintf(stdout," * No index file\n");
\r
128 fprintf(stdout," * No ROI upshifted\n");
\r
129 fprintf(stdout," * No offset of the origin of the image\n");
\r
130 fprintf(stdout," * No offset of the origin of the tiles\n");
\r
131 fprintf(stdout," * Reversible DWT 5-3\n");
\r
134 fprintf(stdout," * No JPWL protection\n");
\r
135 #endif /* USE_JPWL */
\r
137 fprintf(stdout,"\n");
\r
138 fprintf(stdout,"Parameters:\n");
\r
139 fprintf(stdout,"------------\n");
\r
140 fprintf(stdout,"\n");
\r
141 fprintf(stdout,"Required Parameters (except with -h):\n");
\r
142 fprintf(stdout,"One of the two options -ImgDir or -i must be used\n");
\r
143 fprintf(stdout,"\n");
\r
144 fprintf(stdout,"-ImgDir : Image file Directory path (example ../Images) \n");
\r
145 fprintf(stdout," When using this option -OutFor must be used\n");
\r
146 fprintf(stdout,"\n");
\r
147 fprintf(stdout,"-OutFor \n");
\r
148 fprintf(stdout," REQUIRED only if -ImgDir is used\n");
\r
149 fprintf(stdout," Need to specify only format without filename <BMP> \n");
\r
150 fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA formats\n");
\r
151 fprintf(stdout,"\n");
\r
152 fprintf(stdout,"-i : source file (-i source.pnm also *.pgm, *.ppm, *.bmp, *.tif, *.raw, *.tga) \n");
\r
153 fprintf(stdout," When using this option -o must be used\n");
\r
154 fprintf(stdout,"\n");
\r
155 fprintf(stdout,"-o : destination file (-o dest.j2k or .jp2) \n");
\r
156 fprintf(stdout,"\n");
\r
157 fprintf(stdout,"Optional Parameters:\n");
\r
158 fprintf(stdout,"\n");
\r
159 fprintf(stdout,"-h : display the help information \n ");
\r
160 fprintf(stdout,"\n");
\r
161 fprintf(stdout,"-cinema2K : Digital Cinema 2K profile compliant codestream for 2K resolution.(-cinema2k 24 or 48) \n");
\r
162 fprintf(stdout," Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n");
\r
163 fprintf(stdout,"\n");
\r
164 fprintf(stdout,"-cinema4K : Digital Cinema 4K profile compliant codestream for 4K resolution \n");
\r
165 fprintf(stdout," Frames per second not required. Default value is 24fps\n");
\r
166 fprintf(stdout,"\n");
\r
167 fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n ");
\r
168 fprintf(stdout," - The rate specified for each quality level is the desired \n");
\r
169 fprintf(stdout," compression factor.\n");
\r
170 fprintf(stdout," Example: -r 20,10,1 means quality 1: compress 20x, \n");
\r
171 fprintf(stdout," quality 2: compress 10x and quality 3: compress lossless\n");
\r
172 fprintf(stdout,"\n");
\r
173 fprintf(stdout," (options -r and -q cannot be used together)\n ");
\r
174 fprintf(stdout,"\n");
\r
176 fprintf(stdout,"-q : different psnr for successive layers (-q 30,40,50) \n ");
\r
178 fprintf(stdout," (options -r and -q cannot be used together)\n ");
\r
180 fprintf(stdout,"\n");
\r
181 fprintf(stdout,"-n : number of resolutions (-n 3) \n");
\r
182 fprintf(stdout,"\n");
\r
183 fprintf(stdout,"-b : size of code block (-b 32,32) \n");
\r
184 fprintf(stdout,"\n");
\r
185 fprintf(stdout,"-c : size of precinct (-c 128,128) \n");
\r
186 fprintf(stdout,"\n");
\r
187 fprintf(stdout,"-t : size of tile (-t 512,512) \n");
\r
188 fprintf(stdout,"\n");
\r
189 fprintf(stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
\r
190 fprintf(stdout,"\n");
\r
191 fprintf(stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n");
\r
192 fprintf(stdout," Remark: subsampling bigger than 2 can produce error\n");
\r
193 fprintf(stdout,"\n");
\r
194 fprintf(stdout,"-POC : Progression order change (-POC T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL) \n");
\r
195 fprintf(stdout," Example: T1=0,0,1,5,3,CPRL \n");
\r
196 fprintf(stdout," : Ttilenumber=Resolution num start,Component num start,Layer num end,Resolution num end,Component num end,Progression order\n");
\r
197 fprintf(stdout,"\n");
\r
198 fprintf(stdout,"-SOP : write SOP marker before each packet \n");
\r
199 fprintf(stdout,"\n");
\r
200 fprintf(stdout,"-EPH : write EPH marker after each header packet \n");
\r
201 fprintf(stdout,"\n");
\r
202 fprintf(stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
\r
203 fprintf(stdout," 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");
\r
204 fprintf(stdout," Indicate multiple modes by adding their values. \n");
\r
205 fprintf(stdout," ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
\r
206 fprintf(stdout,"\n");
\r
207 fprintf(stdout,"-x : create an index file *.Idx (-x index_name.Idx) \n");
\r
208 fprintf(stdout,"\n");
\r
209 fprintf(stdout,"-ROI : c=%%d,U=%%d : quantization indices upshifted \n");
\r
210 fprintf(stdout," for component c=%%d [%%d = 0,1,2]\n");
\r
211 fprintf(stdout," with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI c=0,U=25) \n");
\r
212 fprintf(stdout,"\n");
\r
213 fprintf(stdout,"-d : offset of the origin of the image (-d 150,300) \n");
\r
214 fprintf(stdout,"\n");
\r
215 fprintf(stdout,"-T : offset of the origin of the tiles (-T 100,75) \n");
\r
216 fprintf(stdout,"\n");
\r
217 fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n");
\r
218 fprintf(stdout,"\n");
\r
221 fprintf(stdout,"-W : adoption of JPWL (Part 11) capabilities (-W params)\n");
\r
222 fprintf(stdout," The parameters can be written and repeated in any order:\n");
\r
223 fprintf(stdout," [h<tilepart><=type>,s<tilepart><=method>,a=<addr>,...\n");
\r
224 fprintf(stdout," ...,z=<size>,g=<range>,p<tilepart:pack><=type>]\n");
\r
225 fprintf(stdout,"\n");
\r
226 fprintf(stdout," h selects the header error protection (EPB): 'type' can be\n");
\r
227 fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
\r
228 fprintf(stdout," if 'tilepart' is absent, it is for main and tile headers\n");
\r
229 fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");
\r
230 fprintf(stdout," onwards, up to the next h<> spec, or to the last tilepart\n");
\r
231 fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);
\r
232 fprintf(stdout,"\n");
\r
233 fprintf(stdout," p selects the packet error protection (EEP/UEP with EPBs)\n");
\r
234 fprintf(stdout," to be applied to raw data: 'type' can be\n");
\r
235 fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
\r
236 fprintf(stdout," if 'tilepart:pack' is absent, it is from tile 0, packet 0\n");
\r
237 fprintf(stdout," if 'tilepart:pack' is present, it applies from that tile\n");
\r
238 fprintf(stdout," and that packet onwards, up to the next packet spec\n");
\r
239 fprintf(stdout," or to the last packet in the last tilepart in the stream\n");
\r
240 fprintf(stdout," (max. %d specs)\n", JPWL_MAX_NO_PACKSPECS);
\r
241 fprintf(stdout,"\n");
\r
242 fprintf(stdout," s enables sensitivity data insertion (ESD): 'method' can be\n");
\r
243 fprintf(stdout," [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n");
\r
244 fprintf(stdout," 4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n");
\r
245 fprintf(stdout," if 'tilepart' is absent, it is for main header only\n");
\r
246 fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");
\r
247 fprintf(stdout," onwards, up to the next s<> spec, or to the last tilepart\n");
\r
248 fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);
\r
249 fprintf(stdout,"\n");
\r
250 fprintf(stdout," g determines the addressing mode: <range> can be\n");
\r
251 fprintf(stdout," [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n");
\r
252 fprintf(stdout,"\n");
\r
253 fprintf(stdout," a determines the size of data addressing: <addr> can be\n");
\r
254 fprintf(stdout," 2/4 bytes (small/large codestreams). If not set, auto-mode\n");
\r
255 fprintf(stdout,"\n");
\r
256 fprintf(stdout," z determines the size of sensitivity values: <size> can be\n");
\r
257 fprintf(stdout," 1/2 bytes, for the transformed pseudo-floating point value\n");
\r
258 fprintf(stdout,"\n");
\r
259 fprintf(stdout," ex.:\n");
\r
260 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
261 fprintf(stdout," s0=6,s3=-1,a=0,g=1,z=1\n");
\r
262 fprintf(stdout," means\n");
\r
263 fprintf(stdout," predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n");
\r
264 fprintf(stdout," CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n");
\r
265 fprintf(stdout," UEP rs(78,32) for packets 0 to 23 of tile 0,\n");
\r
266 fprintf(stdout," UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n");
\r
267 fprintf(stdout," UEP rs default for packets of tilepart 1,\n");
\r
268 fprintf(stdout," no UEP for packets 0 to 19 of tilepart 3,\n");
\r
269 fprintf(stdout," UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n");
\r
270 fprintf(stdout," relative sensitivity ESD for MH,\n");
\r
271 fprintf(stdout," TSE ESD from TPH 0 to TPH 2, byte range with automatic\n");
\r
272 fprintf(stdout," size of addresses and 1 byte for each sensitivity value\n");
\r
273 fprintf(stdout,"\n");
\r
274 fprintf(stdout," ex.:\n");
\r
275 fprintf(stdout," h,s,p\n");
\r
276 fprintf(stdout," means\n");
\r
277 fprintf(stdout," default protection to headers (MH and TPHs) as well as\n");
\r
278 fprintf(stdout," data packets, one ESD in MH\n");
\r
279 fprintf(stdout,"\n");
\r
280 fprintf(stdout," N.B.: use the following recommendations when specifying\n");
\r
281 fprintf(stdout," the JPWL parameters list\n");
\r
282 fprintf(stdout," - when you use UEP, always pair the 'p' option with 'h'\n");
\r
283 fprintf(stdout," \n");
\r
284 #endif /* USE_JPWL */
\r
286 fprintf(stdout,"IMPORTANT:\n");
\r
287 fprintf(stdout,"-----------\n");
\r
288 fprintf(stdout,"\n");
\r
289 fprintf(stdout,"The index file has the structure below:\n");
\r
290 fprintf(stdout,"---------------------------------------\n");
\r
291 fprintf(stdout,"\n");
\r
292 fprintf(stdout,"Image_height Image_width\n");
\r
293 fprintf(stdout,"progression order\n");
\r
294 fprintf(stdout,"Tiles_size_X Tiles_size_Y\n");
\r
295 fprintf(stdout,"Tiles_nb_X Tiles_nb_Y\n");
\r
296 fprintf(stdout,"Components_nb\n");
\r
297 fprintf(stdout,"Layers_nb\n");
\r
298 fprintf(stdout,"decomposition_levels\n");
\r
299 fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");
\r
300 fprintf(stdout," [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");
\r
301 fprintf(stdout,"Main_header_start_position\n");
\r
302 fprintf(stdout,"Main_header_end_position\n");
\r
303 fprintf(stdout,"Codestream_size\n");
\r
304 fprintf(stdout,"\n");
\r
305 fprintf(stdout,"INFO ON TILES\n");
\r
306 fprintf(stdout,"tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n");
\r
307 fprintf(stdout,"Tile_0 start_pos end_Theader end_pos NumParts TotalDisto NumPix MaxMSE\n");
\r
308 fprintf(stdout,"Tile_1 '' '' '' '' '' '' ''\n");
\r
309 fprintf(stdout,"...\n");
\r
310 fprintf(stdout,"Tile_Nt '' '' '' '' '' '' ''\n");
\r
311 fprintf(stdout,"...\n");
\r
312 fprintf(stdout,"TILE 0 DETAILS\n");
\r
313 fprintf(stdout,"part_nb tileno num_packs start_pos end_tph_pos end_pos\n");
\r
314 fprintf(stdout,"...\n");
\r
315 fprintf(stdout,"Progression_string\n");
\r
316 fprintf(stdout,"pack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n");
\r
317 fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");
\r
318 fprintf(stdout,"...\n");
\r
319 fprintf(stdout,"Tpacket_Np '' '' '' '' '' '' '' ''\n");
\r
321 fprintf(stdout,"MaxDisto\n");
\r
323 fprintf(stdout,"TotalDisto\n\n");
\r
327 OPJ_PROG_ORDER give_progression(char progression[4]) {
\r
328 if(strncmp(progression, "LRCP", 4) == 0) {
\r
331 if(strncmp(progression, "RLCP", 4) == 0) {
\r
334 if(strncmp(progression, "RPCL", 4) == 0) {
\r
337 if(strncmp(progression, "PCRL", 4) == 0) {
\r
340 if(strncmp(progression, "CPRL", 4) == 0) {
\r
344 return PROG_UNKNOWN;
\r
349 /// Get logarithm of an integer and round downwards.
\r
351 int int_floorlog2(int a) {
\r
353 for (l=0; a>1; l++) {
\r
359 static int initialise_4K_poc(opj_poc_t *POC, int numres){
\r
361 POC[0].resno0 = 0;
\r
362 POC[0].compno0 = 0;
\r
364 POC[0].resno1 = numres-1;
\r
365 POC[0].compno1 = 3;
\r
366 POC[0].prg1 = CPRL;
\r
368 POC[1].resno0 = numres-1;
\r
369 POC[1].compno0 = 0;
\r
371 POC[1].resno1 = numres;
\r
372 POC[1].compno1 = 3;
\r
373 POC[1].prg1 = CPRL;
\r
377 void cinema_parameters(opj_cparameters_t *parameters){
\r
378 parameters->tile_size_on = false;
\r
379 parameters->cp_tdx=1;
\r
380 parameters->cp_tdy=1;
\r
383 parameters->tp_flag = 'C';
\r
384 parameters->tp_on = 1;
\r
386 /*Tile and Image shall be at (0,0)*/
\r
387 parameters->cp_tx0 = 0;
\r
388 parameters->cp_ty0 = 0;
\r
389 parameters->image_offset_x0 = 0;
\r
390 parameters->image_offset_y0 = 0;
\r
392 /*Codeblock size= 32*32*/
\r
393 parameters->cblockw_init = 32;
\r
394 parameters->cblockh_init = 32;
\r
395 parameters->csty |= 0x01;
\r
397 /*The progression order shall be CPRL*/
\r
398 parameters->prog_order = CPRL;
\r
401 parameters->roi_compno = -1;
\r
403 parameters->subsampling_dx = 1; parameters->subsampling_dy = 1;
\r
405 /* 9-7 transform */
\r
406 parameters->irreversible = 1;
\r
410 void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){
\r
413 opj_poc_t *POC = NULL;
\r
415 switch (parameters->cp_cinema){
\r
418 if(parameters->numresolution > 6){
\r
419 parameters->numresolution = 6;
\r
421 if (!((image->comps[0].w == 2048) | (image->comps[0].h == 1080))){
\r
422 fprintf(stdout,"Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3"
\r
423 "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
\r
424 image->comps[0].w,image->comps[0].h);
\r
425 parameters->cp_rsiz = STD_RSIZ;
\r
430 if(parameters->numresolution < 1){
\r
431 parameters->numresolution = 1;
\r
432 }else if(parameters->numresolution > 7){
\r
433 parameters->numresolution = 7;
\r
435 if (!((image->comps[0].w == 4096) | (image->comps[0].h == 2160))){
\r
436 fprintf(stdout,"Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4"
\r
437 "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
\r
438 image->comps[0].w,image->comps[0].h);
\r
439 parameters->cp_rsiz = STD_RSIZ;
\r
441 parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution);
\r
445 switch (parameters->cp_cinema){
\r
448 for(i=0 ; i<parameters->tcp_numlayers ; i++){
\r
450 if (img_fol->rates[i]== 0){
\r
451 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
452 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
454 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
455 (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
\r
456 if (temp_rate > CINEMA_24_CS ){
\r
457 parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
458 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
460 parameters->tcp_rates[i]= img_fol->rates[i];
\r
464 parameters->max_comp_size = COMP_24_CS;
\r
468 for(i=0 ; i<parameters->tcp_numlayers ; i++){
\r
470 if (img_fol->rates[i]== 0){
\r
471 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
472 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
474 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
475 (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
\r
476 if (temp_rate > CINEMA_48_CS ){
\r
477 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
478 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
480 parameters->tcp_rates[i]= img_fol->rates[i];
\r
484 parameters->max_comp_size = COMP_48_CS;
\r
487 parameters->cp_disto_alloc = 1;
\r
491 /* ------------------------------------------------------------------------------------ */
\r
492 int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
\r
493 img_fol_t *img_fol, char *indexfilename) {
\r
495 option_t long_option[]={
\r
496 {"cinema2K",REQ_ARG, NULL ,'w'},
\r
497 {"cinema4K",NO_ARG, NULL ,'y'},
\r
498 {"ImgDir",REQ_ARG, NULL ,'z'},
\r
499 {"TP",REQ_ARG, NULL ,'v'},
\r
500 {"SOP",NO_ARG, NULL ,'S'},
\r
501 {"EPH",NO_ARG, NULL ,'E'},
\r
502 {"OutFor",REQ_ARG, NULL ,'O'},
\r
503 {"POC",REQ_ARG, NULL ,'P'},
\r
504 {"ROI",REQ_ARG, NULL ,'R'},
\r
507 /* parse the command line */
\r
509 const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:"
\r
512 #endif /* USE_JPWL */
\r
515 /*printf("C: parse_cmdline_encoder:");
\r
516 for (i=0; i<argc; i++) {
\r
517 printf("[%s]",argv[i]);
\r
521 totlen=sizeof(long_option);
\r
522 img_fol->set_out_format=0;
\r
523 reset_options_reading();
\r
526 int c = getopt_long(argc, argv, optlist,long_option,totlen);
\r
531 /* ----------------------------------------------------- */
\r
533 case 'o': /* output file */
\r
535 char *outfile = optarg;
\r
536 parameters->cod_format = get_file_format(outfile);
\r
537 switch(parameters->cod_format) {
\r
542 fprintf(stderr, "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile);
\r
545 strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);
\r
549 /* ----------------------------------------------------- */
\r
550 case 'O': /* output format */
\r
552 char outformat[50];
\r
554 sprintf(outformat,".%s",of);
\r
555 img_fol->set_out_format = 1;
\r
556 parameters->cod_format = get_file_format(outformat);
\r
557 switch(parameters->cod_format) {
\r
560 img_fol->out_format = optarg;
\r
563 fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n");
\r
570 /* ----------------------------------------------------- */
\r
573 case 'r': /* rates rates/distorsion */
\r
576 while (sscanf(s, "%f", ¶meters->tcp_rates[parameters->tcp_numlayers]) == 1) {
\r
577 parameters->tcp_numlayers++;
\r
578 while (*s && *s != ',') {
\r
585 parameters->cp_disto_alloc = 1;
\r
589 /* ----------------------------------------------------- */
\r
591 case 'q': /* add fixed_quality */
\r
594 while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers]) == 1) {
\r
595 parameters->tcp_numlayers++;
\r
596 while (*s && *s != ',') {
\r
603 parameters->cp_fixed_quality = 1;
\r
608 /* ----------------------------------------------------- */
\r
610 case 'f': /* mod fixed_quality (before : -q) */
\r
612 int *row = NULL, *col = NULL;
\r
613 int numlayers = 0, numresolution = 0, matrix_width = 0;
\r
616 sscanf(s, "%d", &numlayers);
\r
621 parameters->tcp_numlayers = numlayers;
\r
622 numresolution = parameters->numresolution;
\r
623 matrix_width = numresolution * 3;
\r
624 parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int));
\r
627 for (i = 0; i < numlayers; i++) {
\r
628 row = ¶meters->cp_matrice[i * matrix_width];
\r
630 parameters->tcp_rates[i] = 1;
\r
631 sscanf(s, "%d,", &col[0]);
\r
637 for (j = 1; j < numresolution; j++) {
\r
639 sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);
\r
648 if (i < numlayers - 1)
\r
651 parameters->cp_fixed_alloc = 1;
\r
655 /* ----------------------------------------------------- */
\r
657 case 't': /* tiles */
\r
659 sscanf(optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy);
\r
660 parameters->tile_size_on = true;
\r
664 /* ----------------------------------------------------- */
\r
666 case 'n': /* resolution */
\r
668 sscanf(optarg, "%d", ¶meters->numresolution);
\r
672 /* ----------------------------------------------------- */
\r
673 case 'c': /* precinct dimension */
\r
681 sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec],
\r
682 ¶meters->prch_init[res_spec], &sep);
\r
683 parameters->csty |= 0x01;
\r
685 s = strpbrk(s, "]") + 2;
\r
687 while (sep == ',');
\r
688 parameters->res_spec = res_spec;
\r
692 /* ----------------------------------------------------- */
\r
694 case 'b': /* code-block dimension */
\r
696 int cblockw_init = 0, cblockh_init = 0;
\r
697 sscanf(optarg, "%d,%d", &cblockw_init, &cblockh_init);
\r
698 if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
\r
699 || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
\r
701 "!! Size of code_block error (option -b) !!\n\nRestriction :\n"
\r
702 " * width*height<=4096\n * 4<=width,height<= 1024\n\n");
\r
705 parameters->cblockw_init = cblockw_init;
\r
706 parameters->cblockh_init = cblockh_init;
\r
710 /* ----------------------------------------------------- */
\r
712 case 'x': /* creation of index file */
\r
714 char *index = optarg;
\r
715 strncpy(indexfilename, index, OPJ_PATH_LEN);
\r
719 /* ----------------------------------------------------- */
\r
721 case 'p': /* progression order */
\r
723 char progression[4];
\r
725 strncpy(progression, optarg, 4);
\r
726 parameters->prog_order = give_progression(progression);
\r
727 if (parameters->prog_order == -1) {
\r
728 fprintf(stderr, "Unrecognized progression order "
\r
729 "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
\r
735 /* ----------------------------------------------------- */
\r
737 case 's': /* subsampling factor */
\r
739 if (sscanf(optarg, "%d,%d", ¶meters->subsampling_dx,
\r
740 ¶meters->subsampling_dy) != 2) {
\r
741 fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n");
\r
747 /* ----------------------------------------------------- */
\r
749 case 'd': /* coordonnate of the reference grid */
\r
751 if (sscanf(optarg, "%d,%d", ¶meters->image_offset_x0,
\r
752 ¶meters->image_offset_y0) != 2) {
\r
753 fprintf(stderr, "-d 'coordonnate of the reference grid' argument "
\r
754 "error !! [-d x0,y0]\n");
\r
760 /* ----------------------------------------------------- */
\r
762 case 'h': /* display an help description */
\r
763 encode_help_display();
\r
766 /* ----------------------------------------------------- */
\r
768 case 'P': /* POC */
\r
770 int numpocs = 0; /* number of progression order change (POC) default 0 */
\r
771 opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */
\r
774 POC = parameters->POC;
\r
776 while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,
\r
777 &POC[numpocs].resno0, &POC[numpocs].compno0,
\r
778 &POC[numpocs].layno1, &POC[numpocs].resno1,
\r
779 &POC[numpocs].compno1, &POC[numpocs].progorder) == 7) {
\r
780 POC[numpocs].prg1 = give_progression(POC[numpocs].progorder);
\r
782 while (*s && *s != '/') {
\r
790 parameters->numpocs = numpocs;
\r
794 /* ------------------------------------------------------ */
\r
796 case 'S': /* SOP marker */
\r
798 parameters->csty |= 0x02;
\r
802 /* ------------------------------------------------------ */
\r
804 case 'E': /* EPH marker */
\r
806 parameters->csty |= 0x04;
\r
810 /* ------------------------------------------------------ */
\r
812 case 'M': /* Mode switch pas tous au point !! */
\r
815 if (sscanf(optarg, "%d", &value) == 1) {
\r
816 for (i = 0; i <= 5; i++) {
\r
817 int cache = value & (1 << i);
\r
819 parameters->mode |= (1 << i);
\r
825 /* ------------------------------------------------------ */
\r
827 case 'R': /* ROI */
\r
829 if (sscanf(optarg, "c=%d,U=%d", ¶meters->roi_compno,
\r
830 ¶meters->roi_shift) != 2) {
\r
831 fprintf(stderr, "ROI error !! [-ROI c='compno',U='shift']\n");
\r
837 /* ------------------------------------------------------ */
\r
839 case 'T': /* Tile offset */
\r
841 if (sscanf(optarg, "%d,%d", ¶meters->cp_tx0, ¶meters->cp_ty0) != 2) {
\r
842 fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");
\r
848 /* ------------------------------------------------------ */
\r
850 case 'C': /* add a comment */
\r
852 parameters->cp_comment = (char*)malloc(strlen(optarg) + 1);
\r
853 if(parameters->cp_comment) {
\r
854 strcpy(parameters->cp_comment, optarg);
\r
860 /* ------------------------------------------------------ */
\r
862 case 'I': /* reversible or not */
\r
864 parameters->irreversible = 1;
\r
868 /* ------------------------------------------------------ */
\r
870 case 'v': /* Tile part generation*/
\r
872 parameters->tp_flag = optarg[0];
\r
873 parameters->tp_on = 1;
\r
877 /* ------------------------------------------------------ */
\r
879 case 'z': /* Image Directory path */
\r
881 img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1);
\r
882 strcpy(img_fol->imgdirpath,optarg);
\r
883 img_fol->set_imgdir=1;
\r
887 /* ------------------------------------------------------ */
\r
889 case 'w': /* Digital Cinema 2K profile compliance*/
\r
892 sscanf(optarg,"%d",&fps);
\r
894 parameters->cp_cinema = CINEMA2K_24;
\r
895 }else if(fps == 48 ){
\r
896 parameters->cp_cinema = CINEMA2K_48;
\r
898 fprintf(stderr,"Incorrect value!! must be 24 or 48\n");
\r
901 fprintf(stdout,"CINEMA 2K compliant codestream\n");
\r
902 parameters->cp_rsiz = CINEMA2K;
\r
907 /* ------------------------------------------------------ */
\r
909 case 'y': /* Digital Cinema 4K profile compliance*/
\r
911 parameters->cp_cinema = CINEMA4K_24;
\r
912 fprintf(stdout,"CINEMA 4K compliant codestream\n");
\r
913 parameters->cp_rsiz = CINEMA4K;
\r
917 /* ------------------------------------------------------ */
\r
921 /* ------------------------------------------------------ */
\r
923 case 'W': /* JPWL capabilities switched on */
\r
925 char *token = NULL;
\r
926 int hprot, pprot, sens, addr, size, range;
\r
928 /* we need to enable indexing */
\r
929 if (!indexfilename) {
\r
930 strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN);
\r
933 /* search for different protection methods */
\r
935 /* break the option in comma points and parse the result */
\r
936 token = strtok(optarg, ",");
\r
937 while(token != NULL) {
\r
939 /* search header error protection method */
\r
940 if (*token == 'h') {
\r
942 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
944 hprot = 1; /* predefined method */
\r
946 if(sscanf(token, "h=%d", &hprot) == 1) {
\r
947 /* Main header, specified */
\r
948 if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
\r
949 ((hprot >= 37) && (hprot <= 128)))) {
\r
950 fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n", hprot);
\r
953 parameters->jpwl_hprot_MH = hprot;
\r
955 } else if(sscanf(token, "h%d=%d", &tile, &hprot) == 2) {
\r
956 /* Tile part header, specified */
\r
957 if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
\r
958 ((hprot >= 37) && (hprot <= 128)))) {
\r
959 fprintf(stderr, "ERROR -> invalid tile part header protection method h = %d\n", hprot);
\r
963 fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);
\r
966 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
967 parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
\r
968 parameters->jpwl_hprot_TPH[tilespec++] = hprot;
\r
971 } else if(sscanf(token, "h%d", &tile) == 1) {
\r
972 /* Tile part header, unspecified */
\r
974 fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);
\r
977 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
978 parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
\r
979 parameters->jpwl_hprot_TPH[tilespec++] = hprot;
\r
983 } else if (!strcmp(token, "h")) {
\r
984 /* Main header, unspecified */
\r
985 parameters->jpwl_hprot_MH = hprot;
\r
988 fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
\r
994 /* search packet error protection method */
\r
995 if (*token == 'p') {
\r
997 static int pack = 0, tile = 0, packspec = 0, lastpackno = 0;
\r
999 pprot = 1; /* predefined method */
\r
1001 if (sscanf(token, "p=%d", &pprot) == 1) {
\r
1002 /* Method for all tiles and all packets */
\r
1003 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1004 ((pprot >= 37) && (pprot <= 128)))) {
\r
1005 fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n", pprot);
\r
1008 parameters->jpwl_pprot_tileno[0] = 0;
\r
1009 parameters->jpwl_pprot_packno[0] = 0;
\r
1010 parameters->jpwl_pprot[0] = pprot;
\r
1012 } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) {
\r
1013 /* method specified from that tile on */
\r
1014 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1015 ((pprot >= 37) && (pprot <= 128)))) {
\r
1016 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1020 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1023 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1024 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1025 parameters->jpwl_pprot_packno[packspec] = 0;
\r
1026 parameters->jpwl_pprot[packspec++] = pprot;
\r
1029 } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) {
\r
1030 /* method fully specified from that tile and that packet on */
\r
1031 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1032 ((pprot >= 37) && (pprot <= 128)))) {
\r
1033 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1037 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1041 fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);
\r
1044 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1045 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1046 parameters->jpwl_pprot_packno[packspec] = pack;
\r
1047 parameters->jpwl_pprot[packspec++] = pprot;
\r
1050 } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) {
\r
1051 /* default method from that tile and that packet on */
\r
1052 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1053 ((pprot >= 37) && (pprot <= 128)))) {
\r
1054 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1058 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1062 fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);
\r
1065 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1066 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1067 parameters->jpwl_pprot_packno[packspec] = pack;
\r
1068 parameters->jpwl_pprot[packspec++] = pprot;
\r
1071 } else if (sscanf(token, "p%d", &tile) == 1) {
\r
1072 /* default from a tile on */
\r
1074 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1077 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1078 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1079 parameters->jpwl_pprot_packno[packspec] = 0;
\r
1080 parameters->jpwl_pprot[packspec++] = pprot;
\r
1084 } else if (!strcmp(token, "p")) {
\r
1086 parameters->jpwl_pprot_tileno[0] = 0;
\r
1087 parameters->jpwl_pprot_packno[0] = 0;
\r
1088 parameters->jpwl_pprot[0] = pprot;
\r
1091 fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
\r
1097 /* search sensitivity method */
\r
1098 if (*token == 's') {
\r
1100 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1102 sens = 0; /* predefined: relative error */
\r
1104 if(sscanf(token, "s=%d", &sens) == 1) {
\r
1105 /* Main header, specified */
\r
1106 if ((sens < -1) || (sens > 7)) {
\r
1107 fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n", sens);
\r
1110 parameters->jpwl_sens_MH = sens;
\r
1112 } else if(sscanf(token, "s%d=%d", &tile, &sens) == 2) {
\r
1113 /* Tile part header, specified */
\r
1114 if ((sens < -1) || (sens > 7)) {
\r
1115 fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n", sens);
\r
1119 fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
\r
1122 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
1123 parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
\r
1124 parameters->jpwl_sens_TPH[tilespec++] = sens;
\r
1127 } else if(sscanf(token, "s%d", &tile) == 1) {
\r
1128 /* Tile part header, unspecified */
\r
1130 fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
\r
1133 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
1134 parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
\r
1135 parameters->jpwl_sens_TPH[tilespec++] = hprot;
\r
1138 } else if (!strcmp(token, "s")) {
\r
1139 /* Main header, unspecified */
\r
1140 parameters->jpwl_sens_MH = sens;
\r
1143 fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token);
\r
1147 parameters->jpwl_sens_size = 2; /* 2 bytes for default size */
\r
1150 /* search addressing size */
\r
1151 if (*token == 'a') {
\r
1153 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1155 addr = 0; /* predefined: auto */
\r
1157 if(sscanf(token, "a=%d", &addr) == 1) {
\r
1159 if ((addr != 0) && (addr != 2) && (addr != 4)) {
\r
1160 fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr);
\r
1163 parameters->jpwl_sens_addr = addr;
\r
1165 } else if (!strcmp(token, "a")) {
\r
1167 parameters->jpwl_sens_addr = addr; /* auto for default size */
\r
1170 fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token);
\r
1176 /* search sensitivity size */
\r
1177 if (*token == 'z') {
\r
1179 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1181 size = 1; /* predefined: 1 byte */
\r
1183 if(sscanf(token, "z=%d", &size) == 1) {
\r
1185 if ((size != 0) && (size != 1) && (size != 2)) {
\r
1186 fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size);
\r
1189 parameters->jpwl_sens_size = size;
\r
1191 } else if (!strcmp(token, "a")) {
\r
1193 parameters->jpwl_sens_size = size; /* 1 for default size */
\r
1196 fprintf(stderr, "ERROR -> invalid size selection = %s\n", token);
\r
1202 /* search range method */
\r
1203 if (*token == 'g') {
\r
1205 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1207 range = 0; /* predefined: 0 (packet) */
\r
1209 if(sscanf(token, "g=%d", &range) == 1) {
\r
1211 if ((range < 0) || (range > 3)) {
\r
1212 fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range);
\r
1215 parameters->jpwl_sens_range = range;
\r
1217 } else if (!strcmp(token, "g")) {
\r
1219 parameters->jpwl_sens_range = range;
\r
1222 fprintf(stderr, "ERROR -> invalid range selection = %s\n", token);
\r
1228 /* next token or bust */
\r
1229 token = strtok(NULL, ",");
\r
1234 fprintf(stdout, "Info: JPWL capabilities enabled\n");
\r
1235 parameters->jpwl_epc_on = true;
\r
1239 #endif /* USE_JPWL */
\r
1242 /* ------------------------------------------------------ */
\r
1245 fprintf(stderr, "ERROR -> Command line not valid\n");
\r
1250 /* check for possible errors */
\r
1251 if (parameters->cp_cinema){
\r
1252 if(parameters->tcp_numlayers > 1){
\r
1253 parameters->cp_rsiz = STD_RSIZ;
\r
1254 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
1258 if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality)
\r
1259 && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ parameters->cp_fixed_quality))) {
\r
1260 fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");
\r
1262 } /* mod fixed_quality */
\r
1264 /* if no rate entered, lossless by default */
\r
1265 if (parameters->tcp_numlayers == 0) {
\r
1266 parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */
\r
1267 parameters->tcp_numlayers++;
\r
1268 parameters->cp_disto_alloc = 1;
\r
1271 if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) {
\r
1273 "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
\r
1274 parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0);
\r
1278 for (i = 0; i < parameters->numpocs; i++) {
\r
1279 if (parameters->POC[i].prg == -1) {
\r
1281 "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
\r
1290 /** 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
1291 @param buffer_size, increased by the length of the compressed index, in number of bytes
\r
1292 @return a pointer to a char[]
\r
1293 Syntax of the index:
\r
1294 one char for the version number (1): one byte because no problem with little endian, big endian etc.
\r
1295 one int for each of the following informations:
\r
1298 progression order
\r
1305 Nb of resolutions
\r
1307 for each resolution:
\r
1311 End main header position
\r
1316 tile start pos in codestream
\r
1317 tile header end position
\r
1318 tile end position in codestream
\r
1320 For each LRCP, RLCP etc.:
\r
1327 start position in the codestream
\r
1328 end position of this packet
\r
1330 char* create_index_into_byte_array(opj_codestream_info_t *cstr_info, int* buffer_size) {
\r
1331 int tileno, compno, layno, resno, precno, pack_nb, x, y;
\r
1332 char* buffer = NULL;
\r
1333 int buffer_pos = 0;
\r
1337 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1338 for (resno = 0; resno < cstr_info->numdecompos[0] + 1; resno++) {
\r
1339 prec_max = max(prec_max,cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]);
\r
1343 // Compute the size of the index buffer, in number of bytes*/
\r
1346 + (10 /* image_w until decomposition */
\r
1347 + (cstr_info->numdecompos[0]+1) * 2 /* pdx size for each tile */
\r
1348 + 2 /* main_head_end + codestream_size */
\r
1349 + cstr_info->tw * cstr_info->th * 4 /* tile info, without distorsion info */
\r
1350 + cstr_info->tw*cstr_info->th * cstr_info->numlayers * (cstr_info->numdecompos[0] + 1) * cstr_info->numcomps * prec_max *8
\r
1352 //printf("C: index buffer size = %d bytes\n", *buffer_size);
\r
1353 buffer = (char*) malloc(*buffer_size);
\r
1356 //opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to allocate index buffer for writing %d int\n", *buffer_size);
\r
1357 fprintf(stderr, "failed to allocate index buffer for writing %d int\n", *buffer_size);
\r
1361 buffer[0] = 1; // Version stored on a byte
\r
1363 // Remaining informations are stored on a int.
\r
1364 ((int*)buffer)[buffer_pos++] = cstr_info->image_w;
\r
1365 ((int*)buffer)[buffer_pos++] = cstr_info->image_h;
\r
1366 ((int*)buffer)[buffer_pos++] = cstr_info->prog;
\r
1367 ((int*)buffer)[buffer_pos++] = cstr_info->tile_x;
\r
1368 ((int*)buffer)[buffer_pos++] = cstr_info->tile_y;
\r
1369 ((int*)buffer)[buffer_pos++] = cstr_info->tw;
\r
1370 ((int*)buffer)[buffer_pos++] = cstr_info->th;
\r
1371 ((int*)buffer)[buffer_pos++] = cstr_info->numcomps;
\r
1372 ((int*)buffer)[buffer_pos++] = cstr_info->numlayers;
\r
1373 ((int*)buffer)[buffer_pos++] = cstr_info->numdecompos[0];
\r
1375 for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
\r
1376 /* based on tile 0 */
\r
1377 ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
\r
1378 ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
\r
1380 ((int*)buffer)[buffer_pos++] = cstr_info->main_head_end;
\r
1381 ((int*)buffer)[buffer_pos++] = cstr_info->codestream_size;
\r
1383 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1384 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].tileno;
\r
1385 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].start_pos;
\r
1386 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_header;
\r
1387 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_pos;
\r
1390 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1391 int start_pos, end_pos;
\r
1392 int max_numdecompos = 0;
\r
1395 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1396 if (max_numdecompos < cstr_info->numdecompos[compno])
\r
1397 max_numdecompos = cstr_info->numdecompos[compno];
\r
1400 if (cstr_info->prog == LRCP) { /* LRCP */
\r
1402 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1403 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1404 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1406 if (resno > cstr_info->numdecompos[compno])
\r
1408 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1409 for (precno = 0; precno < prec_max; precno++) {
\r
1410 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1411 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1412 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1413 ((int*)buffer)[buffer_pos++] = tileno;
\r
1414 ((int*)buffer)[buffer_pos++] = layno;
\r
1415 ((int*)buffer)[buffer_pos++] = resno;
\r
1416 ((int*)buffer)[buffer_pos++] = compno;
\r
1417 ((int*)buffer)[buffer_pos++] = precno;
\r
1418 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1419 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1426 else if (cstr_info->prog == RLCP) { /* RLCP */
\r
1428 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1429 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1430 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1432 if (resno > cstr_info->numdecompos[compno])
\r
1434 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1435 for (precno = 0; precno < prec_max; precno++) {
\r
1436 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1437 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1438 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1439 ((int*)buffer)[buffer_pos++] = tileno;
\r
1440 ((int*)buffer)[buffer_pos++] = resno;
\r
1441 ((int*)buffer)[buffer_pos++] = layno;
\r
1442 ((int*)buffer)[buffer_pos++] = compno;
\r
1443 ((int*)buffer)[buffer_pos++] = precno;
\r
1444 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1445 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1452 else if (cstr_info->prog == RPCL) { /* RPCL */
\r
1454 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1455 /* I suppose components have same XRsiz, YRsiz */
\r
1456 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1457 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1458 int x1 = x0 + cstr_info->tile_x;
\r
1459 int y1 = y0 + cstr_info->tile_y;
\r
1460 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1462 if (resno > cstr_info->numdecompos[compno])
\r
1464 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1465 for (precno = 0; precno < prec_max; precno++) {
\r
1466 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1467 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1468 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1469 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1470 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1471 for(y = y0; y < y1; y++) {
\r
1472 if (precno_y*pcy == y ) {
\r
1473 for (x = x0; x < x1; x++) {
\r
1474 if (precno_x*pcx == x ) {
\r
1475 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1476 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1477 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1478 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1479 ((int*)buffer)[buffer_pos++] = tileno;
\r
1480 ((int*)buffer)[buffer_pos++] = resno;
\r
1481 ((int*)buffer)[buffer_pos++] = precno;
\r
1482 ((int*)buffer)[buffer_pos++] = compno;
\r
1483 ((int*)buffer)[buffer_pos++] = layno;
\r
1484 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1485 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1491 } /* y = y0..y1 */
\r
1496 else if (cstr_info->prog == PCRL) { /* PCRL */
\r
1497 /* I suppose components have same XRsiz, YRsiz */
\r
1498 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1499 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1500 int x1 = x0 + cstr_info->tile_x;
\r
1501 int y1 = y0 + cstr_info->tile_y;
\r
1503 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1504 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1506 if (resno > cstr_info->numdecompos[compno])
\r
1508 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1509 for (precno = 0; precno < prec_max; precno++) {
\r
1510 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1511 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1512 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1513 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1514 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1515 for(y = y0; y < y1; y++) {
\r
1516 if (precno_y*pcy == y ) {
\r
1517 for (x = x0; x < x1; x++) {
\r
1518 if (precno_x*pcx == x ) {
\r
1519 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1520 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1521 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1522 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1523 ((int*)buffer)[buffer_pos++] = tileno;
\r
1524 ((int*)buffer)[buffer_pos++] = precno;
\r
1525 ((int*)buffer)[buffer_pos++] = compno;
\r
1526 ((int*)buffer)[buffer_pos++] = resno;
\r
1527 ((int*)buffer)[buffer_pos++] = layno;
\r
1528 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1529 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1535 } /* y = y0..y1 */
\r
1542 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1543 /* I suppose components have same XRsiz, YRsiz */
\r
1544 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1545 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1546 int x1 = x0 + cstr_info->tile_x;
\r
1547 int y1 = y0 + cstr_info->tile_y;
\r
1549 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1551 if (resno > cstr_info->numdecompos[compno])
\r
1553 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1554 for (precno = 0; precno < prec_max; precno++) {
\r
1555 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1556 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1557 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1558 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1559 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1560 for(y = y0; y < y1; y++) {
\r
1561 if (precno_y*pcy == y ) {
\r
1562 for (x = x0; x < x1; x++) {
\r
1563 if (precno_x*pcx == x ) {
\r
1564 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1565 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1566 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1567 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1568 ((int*)buffer)[buffer_pos++] = tileno;
\r
1569 ((int*)buffer)[buffer_pos++] = compno;
\r
1570 ((int*)buffer)[buffer_pos++] = precno;
\r
1571 ((int*)buffer)[buffer_pos++] = resno;
\r
1572 ((int*)buffer)[buffer_pos++] = layno;
\r
1573 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1574 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1580 } /* y = y0..y1 */
\r
1587 if (buffer_pos > *buffer_size) {
\r
1588 //opj_event_msg(j2k->cinfo, EVT_ERROR, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);
\r
1589 fprintf(stderr, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);
\r
1599 /* --------------------------------------------------------------------------
\r
1600 ------------ Get the image byte[] from the Java object -------------------*/
\r
1602 opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env, jobject obj, jclass cls) {
\r
1603 int i,max,shift,w,h,depth;
\r
1604 opj_image_t * img = NULL;
\r
1605 int compno, numcomps;
\r
1606 opj_image_t * image = NULL;
\r
1607 opj_image_comp_t *comp;
\r
1608 opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
\r
1609 OPJ_COLOR_SPACE color_space;
\r
1621 // Image width, height and depth
\r
1622 fid = (*env)->GetFieldID(env, cls,"width", "I");
\r
1623 ji = (*env)->GetIntField(env, obj, fid);
\r
1626 fid = (*env)->GetFieldID(env, cls,"height", "I");
\r
1627 ji = (*env)->GetIntField(env, obj, fid);
\r
1630 fid = (*env)->GetFieldID(env, cls,"depth", "I");
\r
1631 ji = (*env)->GetIntField(env, obj, fid);
\r
1637 color_space = CLRSPC_GRAY;
\r
1640 color_space = CLRSPC_SRGB;
\r
1642 memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
\r
1644 if (numcomps == 1) {
\r
1645 cmptparm[0].x0 = parameters->image_offset_x0;
\r
1646 cmptparm[0].y0 = parameters->image_offset_y0;
\r
1647 cmptparm[0].w = !cmptparm[0].x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm[0].x0 + (w - 1) * parameters->subsampling_dx + 1;
\r
1648 cmptparm[0].h = !cmptparm[0].y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm[0].y0 + (h - 1) * parameters->subsampling_dy + 1;
\r
1649 // Java types are always signed but we use them as unsigned types (shift of the negative part of
\r
1650 // the pixels of the images in Telemis before entering the encoder).
\r
1651 cmptparm[0].sgnd = 0;
\r
1653 cmptparm[0].prec=depth;
\r
1655 cmptparm[0].prec = 8;
\r
1656 cmptparm[0].bpp = cmptparm[0].prec;
\r
1657 cmptparm[0].dx = parameters->subsampling_dx;
\r
1658 cmptparm[0].dy = parameters->subsampling_dy;
\r
1659 /*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
1660 cmptparm[0].h, cmptparm[0].sgnd, cmptparm[0].bpp, cmptparm[0].dx, cmptparm[0].dy, color_space);*/
\r
1662 for(i = 0; i < numcomps; i++) {
\r
1663 cmptparm[i].prec = 8;
\r
1664 cmptparm[i].bpp = 8;
\r
1665 cmptparm[i].sgnd = 0;
\r
1666 cmptparm[i].dx = parameters->subsampling_dx;
\r
1667 cmptparm[i].dy = parameters->subsampling_dy;
\r
1668 cmptparm[i].w = w;
\r
1669 cmptparm[i].h = h;
\r
1673 /* create the image */
\r
1674 image = opj_image_create(numcomps, &cmptparm[0], color_space);
\r
1680 image->numcomps=1;
\r
1682 image->numcomps = 3;
\r
1685 /* set image offset and reference grid */
\r
1686 image->x0 = cmptparm[0].x0;
\r
1687 image->y0 = cmptparm[0].x0;
\r
1688 image->x1 = cmptparm[0].w;
\r
1689 image->y1 = cmptparm[0].h;
\r
1691 /* set image data */
\r
1692 for (compno=0; compno<numcomps; compno++) {
\r
1693 comp = &image->comps[compno];
\r
1696 fid = (*env)->GetFieldID(env, cls,"image8", "[B"); // byteArray []
\r
1697 jba = (*env)->GetObjectField(env, obj, fid);
\r
1698 len = (*env)->GetArrayLength(env, jba);
\r
1700 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, &isCopy);
\r
1701 //printf("C: before transfering 8 bpp image\n");
\r
1703 for(i=0; i< len;i++) {
\r
1704 comp->data[i] = (char) jbBody[i];
\r
1705 if (comp->data[i] > max) max = comp->data[i];
\r
1708 for(i=0; i< len;i++) {
\r
1709 comp->data[i] = (unsigned char) jbBody[i];
\r
1710 if (comp->data[i] > max) max = comp->data[i];
\r
1713 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1714 } else if(depth == 16) {
\r
1715 fid = (*env)->GetFieldID(env, cls,"image16", "[S"); // shortArray []
\r
1716 jsa = (*env)->GetObjectField(env, obj, fid);
\r
1717 len = (*env)->GetArrayLength(env, jsa);
\r
1719 jsBody = (*env)->GetPrimitiveArrayCritical(env, jsa, &isCopy);
\r
1720 //printf("C: before transfering 16 bpp image\n");
\r
1721 if (comp->sgnd) { // Special behaviour to deal with signed elements ??
\r
1722 comp->data[i] = (short) jsBody[i];
\r
1723 for(i=0; i< len;i++) {
\r
1724 if (comp->data[i] > max) max = comp->data[i];
\r
1727 for(i=0; i< len;i++) {
\r
1728 comp->data[i] = (unsigned short) jsBody[i];
\r
1729 if (comp->data[i] > max) max = comp->data[i];
\r
1732 (*env)->ReleasePrimitiveArrayCritical(env, jsa, jsBody, 0);
\r
1733 } else if (depth == 24) {
\r
1734 fid = (*env)->GetFieldID(env, cls,"image24", "[I"); // intArray []
\r
1735 jia = (*env)->GetObjectField(env, obj, fid);
\r
1736 len = (*env)->GetArrayLength(env, jia);
\r
1739 jiBody = (*env)->GetPrimitiveArrayCritical(env, jia, &isCopy);
\r
1740 //printf("C: before transfering 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);
\r
1741 if (comp->sgnd) { // Special behaviour to deal with signed elements ?? XXXXX
\r
1742 for(i=0; i< len;i++) {
\r
1743 comp->data[i] = ( ((int) jiBody[i]) & (0xFF << shift) ) >> shift;
\r
1744 if (comp->data[i] > max) max = comp->data[i];
\r
1747 for(i=0; i< len;i++) {
\r
1748 comp->data[i] = ( ((unsigned int) jiBody[i]) & (0xFF << shift) ) >> shift;
\r
1749 if (comp->data[i] > max) max = comp->data[i];
\r
1752 (*env)->ReleasePrimitiveArrayCritical(env, jia, jiBody, 0);
\r
1754 comp->bpp = int_floorlog2(max)+1;
\r
1755 comp->prec = comp->bpp;
\r
1756 //printf("C: component %d: max %d, real bpp = %d\n", compno, max, comp->bpp);
\r
1762 /* --------------------------------------------------------------------------
\r
1763 -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/
\r
1764 JNIEXPORT jlong JNICALL Java_org_openJpeg_OpenJPEGJavaEncoder_internalEncodeImageToJ2K(JNIEnv *env, jobject obj, jobjectArray javaParameters) {
\r
1765 int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */
\r
1766 char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */
\r
1768 opj_cparameters_t parameters; /* compression parameters */
\r
1769 img_fol_t img_fol;
\r
1770 opj_event_mgr_t event_mgr; /* event manager */
\r
1771 opj_image_t *image = NULL;
\r
1772 int i,j,num_images;
\r
1774 opj_codestream_info_t cstr_info; /* Codestream information structure */
\r
1775 char indexfilename[OPJ_PATH_LEN]; /* index file name */
\r
1777 int* compressed_index = NULL;
\r
1778 int compressed_index_size=-1;
\r
1779 // ==> Access variables to the Java member variables
\r
1787 callback_variables_t msgErrorCallback_vars;
\r
1788 // <== access variable to the Java member variables.
\r
1790 // For the encoding and storage into the file
\r
1791 opj_cinfo_t* cinfo;
\r
1792 int codestream_length;
\r
1793 opj_cio_t *cio = NULL;
\r
1796 // JNI reference to the calling class
\r
1797 cls = (*env)->GetObjectClass(env, obj);
\r
1799 // Pointers to be able to call a Java method for all the info and error messages
\r
1800 msgErrorCallback_vars.env = env;
\r
1801 msgErrorCallback_vars.jobj = &obj;
\r
1802 msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V");
\r
1803 msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V");
\r
1805 arraySize = (*env)->GetArrayLength(env, javaParameters);
\r
1806 argc = (int) arraySize +1;
\r
1807 argv = malloc(argc*sizeof(char*));
\r
1808 argv[0] = "ProgramName.exe"; // The program name: useless
\r
1810 for (i=1; i<argc; i++) {
\r
1811 object = (*env)->GetObjectArrayElement(env, javaParameters, i-1);
\r
1812 argv[i] = (*env)->GetStringUTFChars(env, object, &isCopy);
\r
1816 for (i=0; i<argc; i++) {
\r
1817 printf("[%s]",argv[i]);
\r
1822 configure the event callbacks
\r
1824 memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
\r
1825 event_mgr.error_handler = error_callback;
\r
1826 event_mgr.warning_handler = warning_callback;
\r
1827 event_mgr.info_handler = info_callback;
\r
1829 /* set encoding parameters to default values */
\r
1830 opj_set_default_encoder_parameters(¶meters);
\r
1831 parameters.cod_format = J2K_CFMT;
\r
1832 //parameters.index_on = 1;
\r
1834 /* Initialize indexfilename and img_fol */
\r
1835 *indexfilename = 0;
\r
1836 memset(&img_fol,0,sizeof(img_fol_t));
\r
1838 /* parse input and get user encoding parameters */
\r
1839 if (parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) {
\r
1840 // Release the Java arguments array
\r
1841 for (i=1; i<argc; i++)
\r
1842 (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
\r
1846 // Release the Java arguments array
\r
1847 for (i=1; i<argc; i++)
\r
1848 (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
\r
1850 if (parameters.cp_cinema){
\r
1851 cinema_parameters(¶meters);
\r
1855 /* Create comment for codestream */
\r
1856 if(parameters.cp_comment == NULL) {
\r
1857 const char comment[] = "Created by JavaOpenJPEG version ";
\r
1858 const size_t clen = strlen(comment);
\r
1859 const char *version = opj_version();
\r
1862 parameters.cp_comment = (char*)malloc(clen+strlen(version)+11);
\r
1863 sprintf(parameters.cp_comment,"%s%s with JPWL", comment, version);
\r
1865 parameters.cp_comment = (char*)malloc(clen+strlen(version)+1);
\r
1866 sprintf(parameters.cp_comment,"%s%s", comment, version);
\r
1872 /* Read directory if necessary */
\r
1875 /*Encoding image one by one*/
\r
1876 for(imageno=0;imageno<num_images;imageno++)
\r
1879 fprintf(stderr,"\n");
\r
1881 image = loadImage(¶meters, env, obj, cls);
\r
1882 //printf("C: after load image: image = %d\n", image);
\r
1884 fprintf(stderr, "Unable to load image\n");
\r
1888 /* Decide if MCT should be used */
\r
1889 parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
\r
1891 if(parameters.cp_cinema){
\r
1892 cinema_setup_encoder(¶meters,image,&img_fol);
\r
1895 /* encode the destination image */
\r
1896 /* ---------------------------- */
\r
1897 /* get a J2K compressor handle */
\r
1898 if (parameters.cod_format == J2K_CFMT) { /* J2K format output */
\r
1899 cinfo = opj_create_compress(CODEC_J2K);
\r
1900 } else { /* JP2 format output */
\r
1901 cinfo = opj_create_compress(CODEC_JP2);
\r
1903 /* catch events using our callbacks and give a local context */
\r
1904 opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, &msgErrorCallback_vars);
\r
1906 /* setup the encoder parameters using the current image and user parameters */
\r
1907 opj_setup_encoder(cinfo, ¶meters, image);
\r
1909 /* open a byte stream for writing */
\r
1910 /* allocate memory for all tiles */
\r
1911 cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
\r
1913 /* encode the image */
\r
1914 bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);
\r
1915 printf("C: after opj_encode_with_info\n");
\r
1917 opj_cio_close(cio);
\r
1918 fprintf(stderr, "failed to encode image\n");
\r
1921 codestream_length = cio_tell(cio);
\r
1923 /* write the index on disk, if needed (-x 'filename') */
\r
1924 if (*indexfilename) {
\r
1925 bSuccess = write_index_file(&cstr_info, indexfilename);
\r
1927 fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename);
\r
1931 compressed_index = create_index_into_byte_array(&cstr_info, &compressed_index_size);
\r
1932 /* Allocates the Java compressedIndex byte[] and sends this index into the Java object */
\r
1933 fid = (*env)->GetFieldID(env, cls,"compressedIndex", "[B");
\r
1934 jba = (*env)->NewByteArray(env, compressed_index_size+1);
\r
1935 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
\r
1936 memcpy(jbBody, compressed_index, compressed_index_size);
\r
1937 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1938 (*env)->SetObjectField(env, obj, fid, jba);
\r
1939 free(compressed_index);
\r
1941 /* write the generated codestream to disk ? */
\r
1942 if (parameters.outfile[0]!='\0') {
\r
1943 f = fopen(parameters.outfile, "wb");
\r
1945 fprintf(stderr, "failed to open [%s] for writing\n", parameters.outfile);
\r
1948 fwrite(cio->buffer, 1, codestream_length, f);
\r
1950 fprintf(stdout,"Generated outfile [%s]\n",parameters.outfile);
\r
1953 /* Write the generated codestream to the Java pre-allocated compressedStream byte[] */
\r
1954 fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");
\r
1955 jba = (*env)->GetObjectField(env, obj, fid);
\r
1956 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
\r
1957 memcpy(jbBody, cio->buffer, codestream_length);
\r
1958 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1960 /* close and free the byte stream */
\r
1961 opj_cio_close(cio);
\r
1963 /* free remaining compression structures */
\r
1964 opj_destroy_compress(cinfo);
\r
1965 opj_destroy_cstr_info(&cstr_info);
\r
1967 /* free image data */
\r
1968 opj_image_destroy(image);
\r
1971 /* free user parameters structure */
\r
1972 if(parameters.cp_comment) free(parameters.cp_comment);
\r
1973 if(parameters.cp_matrice) free(parameters.cp_matrice);
\r
1975 return codestream_length;
\r