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
40 #include "opj_getopt.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
219 fprintf(stdout,"-jpip : write jpip codestream index box in JP2 output file\n");
\r
220 fprintf(stdout," NOTICE: currently supports only RPCL order\n");
\r
221 fprintf(stdout,"\n");
\r
224 fprintf(stdout,"-W : adoption of JPWL (Part 11) capabilities (-W params)\n");
\r
225 fprintf(stdout," The parameters can be written and repeated in any order:\n");
\r
226 fprintf(stdout," [h<tilepart><=type>,s<tilepart><=method>,a=<addr>,...\n");
\r
227 fprintf(stdout," ...,z=<size>,g=<range>,p<tilepart:pack><=type>]\n");
\r
228 fprintf(stdout,"\n");
\r
229 fprintf(stdout," h selects the header error protection (EPB): 'type' can be\n");
\r
230 fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
\r
231 fprintf(stdout," if 'tilepart' is absent, it is for main and tile headers\n");
\r
232 fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");
\r
233 fprintf(stdout," onwards, up to the next h<> spec, or to the last tilepart\n");
\r
234 fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);
\r
235 fprintf(stdout,"\n");
\r
236 fprintf(stdout," p selects the packet error protection (EEP/UEP with EPBs)\n");
\r
237 fprintf(stdout," to be applied to raw data: 'type' can be\n");
\r
238 fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
\r
239 fprintf(stdout," if 'tilepart:pack' is absent, it is from tile 0, packet 0\n");
\r
240 fprintf(stdout," if 'tilepart:pack' is present, it applies from that tile\n");
\r
241 fprintf(stdout," and that packet onwards, up to the next packet spec\n");
\r
242 fprintf(stdout," or to the last packet in the last tilepart in the stream\n");
\r
243 fprintf(stdout," (max. %d specs)\n", JPWL_MAX_NO_PACKSPECS);
\r
244 fprintf(stdout,"\n");
\r
245 fprintf(stdout," s enables sensitivity data insertion (ESD): 'method' can be\n");
\r
246 fprintf(stdout," [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n");
\r
247 fprintf(stdout," 4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n");
\r
248 fprintf(stdout," if 'tilepart' is absent, it is for main header only\n");
\r
249 fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");
\r
250 fprintf(stdout," onwards, up to the next s<> spec, or to the last tilepart\n");
\r
251 fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);
\r
252 fprintf(stdout,"\n");
\r
253 fprintf(stdout," g determines the addressing mode: <range> can be\n");
\r
254 fprintf(stdout," [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n");
\r
255 fprintf(stdout,"\n");
\r
256 fprintf(stdout," a determines the size of data addressing: <addr> can be\n");
\r
257 fprintf(stdout," 2/4 bytes (small/large codestreams). If not set, auto-mode\n");
\r
258 fprintf(stdout,"\n");
\r
259 fprintf(stdout," z determines the size of sensitivity values: <size> can be\n");
\r
260 fprintf(stdout," 1/2 bytes, for the transformed pseudo-floating point value\n");
\r
261 fprintf(stdout,"\n");
\r
262 fprintf(stdout," ex.:\n");
\r
263 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
264 fprintf(stdout," s0=6,s3=-1,a=0,g=1,z=1\n");
\r
265 fprintf(stdout," means\n");
\r
266 fprintf(stdout," predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n");
\r
267 fprintf(stdout," CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n");
\r
268 fprintf(stdout," UEP rs(78,32) for packets 0 to 23 of tile 0,\n");
\r
269 fprintf(stdout," UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n");
\r
270 fprintf(stdout," UEP rs default for packets of tilepart 1,\n");
\r
271 fprintf(stdout," no UEP for packets 0 to 19 of tilepart 3,\n");
\r
272 fprintf(stdout," UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n");
\r
273 fprintf(stdout," relative sensitivity ESD for MH,\n");
\r
274 fprintf(stdout," TSE ESD from TPH 0 to TPH 2, byte range with automatic\n");
\r
275 fprintf(stdout," size of addresses and 1 byte for each sensitivity value\n");
\r
276 fprintf(stdout,"\n");
\r
277 fprintf(stdout," ex.:\n");
\r
278 fprintf(stdout," h,s,p\n");
\r
279 fprintf(stdout," means\n");
\r
280 fprintf(stdout," default protection to headers (MH and TPHs) as well as\n");
\r
281 fprintf(stdout," data packets, one ESD in MH\n");
\r
282 fprintf(stdout,"\n");
\r
283 fprintf(stdout," N.B.: use the following recommendations when specifying\n");
\r
284 fprintf(stdout," the JPWL parameters list\n");
\r
285 fprintf(stdout," - when you use UEP, always pair the 'p' option with 'h'\n");
\r
286 fprintf(stdout," \n");
\r
287 #endif /* USE_JPWL */
\r
289 fprintf(stdout,"IMPORTANT:\n");
\r
290 fprintf(stdout,"-----------\n");
\r
291 fprintf(stdout,"\n");
\r
292 fprintf(stdout,"The index file has the structure below:\n");
\r
293 fprintf(stdout,"---------------------------------------\n");
\r
294 fprintf(stdout,"\n");
\r
295 fprintf(stdout,"Image_height Image_width\n");
\r
296 fprintf(stdout,"progression order\n");
\r
297 fprintf(stdout,"Tiles_size_X Tiles_size_Y\n");
\r
298 fprintf(stdout,"Tiles_nb_X Tiles_nb_Y\n");
\r
299 fprintf(stdout,"Components_nb\n");
\r
300 fprintf(stdout,"Layers_nb\n");
\r
301 fprintf(stdout,"decomposition_levels\n");
\r
302 fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");
\r
303 fprintf(stdout," [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");
\r
304 fprintf(stdout,"Main_header_start_position\n");
\r
305 fprintf(stdout,"Main_header_end_position\n");
\r
306 fprintf(stdout,"Codestream_size\n");
\r
307 fprintf(stdout,"\n");
\r
308 fprintf(stdout,"INFO ON TILES\n");
\r
309 fprintf(stdout,"tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n");
\r
310 fprintf(stdout,"Tile_0 start_pos end_Theader end_pos NumParts TotalDisto NumPix MaxMSE\n");
\r
311 fprintf(stdout,"Tile_1 '' '' '' '' '' '' ''\n");
\r
312 fprintf(stdout,"...\n");
\r
313 fprintf(stdout,"Tile_Nt '' '' '' '' '' '' ''\n");
\r
314 fprintf(stdout,"...\n");
\r
315 fprintf(stdout,"TILE 0 DETAILS\n");
\r
316 fprintf(stdout,"part_nb tileno num_packs start_pos end_tph_pos end_pos\n");
\r
317 fprintf(stdout,"...\n");
\r
318 fprintf(stdout,"Progression_string\n");
\r
319 fprintf(stdout,"pack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n");
\r
320 fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");
\r
321 fprintf(stdout,"...\n");
\r
322 fprintf(stdout,"Tpacket_Np '' '' '' '' '' '' '' ''\n");
\r
324 fprintf(stdout,"MaxDisto\n");
\r
326 fprintf(stdout,"TotalDisto\n\n");
\r
330 OPJ_PROG_ORDER give_progression(char progression[4]) {
\r
331 if(strncmp(progression, "LRCP", 4) == 0) {
\r
334 if(strncmp(progression, "RLCP", 4) == 0) {
\r
337 if(strncmp(progression, "RPCL", 4) == 0) {
\r
340 if(strncmp(progression, "PCRL", 4) == 0) {
\r
343 if(strncmp(progression, "CPRL", 4) == 0) {
\r
347 return PROG_UNKNOWN;
\r
352 /// Get logarithm of an integer and round downwards.
\r
354 int int_floorlog2(int a) {
\r
356 for (l=0; a>1; l++) {
\r
362 static int initialise_4K_poc(opj_poc_t *POC, int numres){
\r
364 POC[0].resno0 = 0;
\r
365 POC[0].compno0 = 0;
\r
367 POC[0].resno1 = numres-1;
\r
368 POC[0].compno1 = 3;
\r
369 POC[0].prg1 = CPRL;
\r
371 POC[1].resno0 = numres-1;
\r
372 POC[1].compno0 = 0;
\r
374 POC[1].resno1 = numres;
\r
375 POC[1].compno1 = 3;
\r
376 POC[1].prg1 = CPRL;
\r
380 void cinema_parameters(opj_cparameters_t *parameters){
\r
381 parameters->tile_size_on = false;
\r
382 parameters->cp_tdx=1;
\r
383 parameters->cp_tdy=1;
\r
386 parameters->tp_flag = 'C';
\r
387 parameters->tp_on = 1;
\r
389 /*Tile and Image shall be at (0,0)*/
\r
390 parameters->cp_tx0 = 0;
\r
391 parameters->cp_ty0 = 0;
\r
392 parameters->image_offset_x0 = 0;
\r
393 parameters->image_offset_y0 = 0;
\r
395 /*Codeblock size= 32*32*/
\r
396 parameters->cblockw_init = 32;
\r
397 parameters->cblockh_init = 32;
\r
398 parameters->csty |= 0x01;
\r
400 /*The progression order shall be CPRL*/
\r
401 parameters->prog_order = CPRL;
\r
404 parameters->roi_compno = -1;
\r
406 parameters->subsampling_dx = 1; parameters->subsampling_dy = 1;
\r
408 /* 9-7 transform */
\r
409 parameters->irreversible = 1;
\r
413 void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){
\r
416 opj_poc_t *POC = NULL;
\r
418 switch (parameters->cp_cinema){
\r
421 if(parameters->numresolution > 6){
\r
422 parameters->numresolution = 6;
\r
424 if (!((image->comps[0].w == 2048) | (image->comps[0].h == 1080))){
\r
425 fprintf(stdout,"Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3"
\r
426 "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
\r
427 image->comps[0].w,image->comps[0].h);
\r
428 parameters->cp_rsiz = STD_RSIZ;
\r
433 if(parameters->numresolution < 1){
\r
434 parameters->numresolution = 1;
\r
435 }else if(parameters->numresolution > 7){
\r
436 parameters->numresolution = 7;
\r
438 if (!((image->comps[0].w == 4096) | (image->comps[0].h == 2160))){
\r
439 fprintf(stdout,"Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4"
\r
440 "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
\r
441 image->comps[0].w,image->comps[0].h);
\r
442 parameters->cp_rsiz = STD_RSIZ;
\r
444 parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution);
\r
448 switch (parameters->cp_cinema){
\r
451 for(i=0 ; i<parameters->tcp_numlayers ; i++){
\r
453 if (img_fol->rates[i]== 0){
\r
454 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
455 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
457 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
458 (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
\r
459 if (temp_rate > CINEMA_24_CS ){
\r
460 parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
461 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
463 parameters->tcp_rates[i]= img_fol->rates[i];
\r
467 parameters->max_comp_size = COMP_24_CS;
\r
471 for(i=0 ; i<parameters->tcp_numlayers ; i++){
\r
473 if (img_fol->rates[i]== 0){
\r
474 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
475 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
477 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
478 (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
\r
479 if (temp_rate > CINEMA_48_CS ){
\r
480 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
481 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
483 parameters->tcp_rates[i]= img_fol->rates[i];
\r
487 parameters->max_comp_size = COMP_48_CS;
\r
490 parameters->cp_disto_alloc = 1;
\r
494 /* ------------------------------------------------------------------------------------ */
\r
495 int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
\r
496 img_fol_t *img_fol, char *indexfilename) {
\r
498 opj_option_t long_option[]={
\r
499 {"cinema2K",REQ_ARG, NULL ,'w'},
\r
500 {"cinema4K",NO_ARG, NULL ,'y'},
\r
501 {"ImgDir",REQ_ARG, NULL ,'z'},
\r
502 {"TP",REQ_ARG, NULL ,'v'},
\r
503 {"SOP",NO_ARG, NULL ,'S'},
\r
504 {"EPH",NO_ARG, NULL ,'E'},
\r
505 {"OutFor",REQ_ARG, NULL ,'O'},
\r
506 {"POC",REQ_ARG, NULL ,'P'},
\r
507 {"ROI",REQ_ARG, NULL ,'R'},
\r
508 {"jpip",NO_ARG, NULL, 'J'}
\r
511 /* parse the command line */
\r
513 const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:"
\r
516 #endif /* USE_JPWL */
\r
519 /*printf("C: parse_cmdline_encoder:");
\r
520 for (i=0; i<argc; i++) {
\r
521 printf("[%s]",argv[i]);
\r
525 totlen=sizeof(long_option);
\r
526 img_fol->set_out_format=0;
\r
527 reset_options_reading();
\r
530 int c = opj_getopt_long(argc, argv, optlist,long_option,totlen);
\r
535 /* ----------------------------------------------------- */
\r
537 case 'o': /* output file */
\r
539 char *outfile = opj_optarg;
\r
540 parameters->cod_format = get_file_format(outfile);
\r
541 switch(parameters->cod_format) {
\r
546 fprintf(stderr, "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile);
\r
549 strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);
\r
553 /* ----------------------------------------------------- */
\r
554 case 'O': /* output format */
\r
556 char outformat[50];
\r
557 char *of = opj_optarg;
\r
558 sprintf(outformat,".%s",of);
\r
559 img_fol->set_out_format = 1;
\r
560 parameters->cod_format = get_file_format(outformat);
\r
561 switch(parameters->cod_format) {
\r
564 img_fol->out_format = opj_optarg;
\r
567 fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n");
\r
574 /* ----------------------------------------------------- */
\r
577 case 'r': /* rates rates/distorsion */
\r
579 char *s = opj_optarg;
\r
580 while (sscanf(s, "%f", ¶meters->tcp_rates[parameters->tcp_numlayers]) == 1) {
\r
581 parameters->tcp_numlayers++;
\r
582 while (*s && *s != ',') {
\r
589 parameters->cp_disto_alloc = 1;
\r
593 /* ----------------------------------------------------- */
\r
595 case 'q': /* add fixed_quality */
\r
597 char *s = opj_optarg;
\r
598 while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers]) == 1) {
\r
599 parameters->tcp_numlayers++;
\r
600 while (*s && *s != ',') {
\r
607 parameters->cp_fixed_quality = 1;
\r
612 /* ----------------------------------------------------- */
\r
614 case 'f': /* mod fixed_quality (before : -q) */
\r
616 int *row = NULL, *col = NULL;
\r
617 int numlayers = 0, numresolution = 0, matrix_width = 0;
\r
619 char *s = opj_optarg;
\r
620 sscanf(s, "%d", &numlayers);
\r
625 parameters->tcp_numlayers = numlayers;
\r
626 numresolution = parameters->numresolution;
\r
627 matrix_width = numresolution * 3;
\r
628 parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int));
\r
631 for (i = 0; i < numlayers; i++) {
\r
632 row = ¶meters->cp_matrice[i * matrix_width];
\r
634 parameters->tcp_rates[i] = 1;
\r
635 sscanf(s, "%d,", &col[0]);
\r
641 for (j = 1; j < numresolution; j++) {
\r
643 sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);
\r
652 if (i < numlayers - 1)
\r
655 parameters->cp_fixed_alloc = 1;
\r
659 /* ----------------------------------------------------- */
\r
661 case 't': /* tiles */
\r
663 sscanf(opj_optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy);
\r
664 parameters->tile_size_on = true;
\r
668 /* ----------------------------------------------------- */
\r
670 case 'n': /* resolution */
\r
672 sscanf(opj_optarg, "%d", ¶meters->numresolution);
\r
676 /* ----------------------------------------------------- */
\r
677 case 'c': /* precinct dimension */
\r
682 char *s = opj_optarg;
\r
685 sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec],
\r
686 ¶meters->prch_init[res_spec], &sep);
\r
687 parameters->csty |= 0x01;
\r
689 s = strpbrk(s, "]") + 2;
\r
691 while (sep == ',');
\r
692 parameters->res_spec = res_spec;
\r
696 /* ----------------------------------------------------- */
\r
698 case 'b': /* code-block dimension */
\r
700 int cblockw_init = 0, cblockh_init = 0;
\r
701 sscanf(opj_optarg, "%d,%d", &cblockw_init, &cblockh_init);
\r
702 if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
\r
703 || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
\r
705 "!! Size of code_block error (option -b) !!\n\nRestriction :\n"
\r
706 " * width*height<=4096\n * 4<=width,height<= 1024\n\n");
\r
709 parameters->cblockw_init = cblockw_init;
\r
710 parameters->cblockh_init = cblockh_init;
\r
714 /* ----------------------------------------------------- */
\r
716 case 'x': /* creation of index file */
\r
718 char *index = opj_optarg;
\r
719 strncpy(indexfilename, index, OPJ_PATH_LEN);
\r
723 /* ----------------------------------------------------- */
\r
725 case 'p': /* progression order */
\r
727 char progression[4];
\r
729 strncpy(progression, opj_optarg, 4);
\r
730 parameters->prog_order = give_progression(progression);
\r
731 if (parameters->prog_order == -1) {
\r
732 fprintf(stderr, "Unrecognized progression order "
\r
733 "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
\r
739 /* ----------------------------------------------------- */
\r
741 case 's': /* subsampling factor */
\r
743 if (sscanf(opj_optarg, "%d,%d", ¶meters->subsampling_dx,
\r
744 ¶meters->subsampling_dy) != 2) {
\r
745 fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n");
\r
751 /* ----------------------------------------------------- */
\r
753 case 'd': /* coordonnate of the reference grid */
\r
755 if (sscanf(opj_optarg, "%d,%d", ¶meters->image_offset_x0,
\r
756 ¶meters->image_offset_y0) != 2) {
\r
757 fprintf(stderr, "-d 'coordonnate of the reference grid' argument "
\r
758 "error !! [-d x0,y0]\n");
\r
764 /* ----------------------------------------------------- */
\r
766 case 'h': /* display an help description */
\r
767 encode_help_display();
\r
770 /* ----------------------------------------------------- */
\r
772 case 'P': /* POC */
\r
774 int numpocs = 0; /* number of progression order change (POC) default 0 */
\r
775 opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */
\r
777 char *s = opj_optarg;
\r
778 POC = parameters->POC;
\r
780 while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,
\r
781 &POC[numpocs].resno0, &POC[numpocs].compno0,
\r
782 &POC[numpocs].layno1, &POC[numpocs].resno1,
\r
783 &POC[numpocs].compno1, &POC[numpocs].progorder) == 7) {
\r
784 POC[numpocs].prg1 = give_progression(POC[numpocs].progorder);
\r
786 while (*s && *s != '/') {
\r
794 parameters->numpocs = numpocs;
\r
798 /* ------------------------------------------------------ */
\r
800 case 'S': /* SOP marker */
\r
802 parameters->csty |= 0x02;
\r
806 /* ------------------------------------------------------ */
\r
808 case 'E': /* EPH marker */
\r
810 parameters->csty |= 0x04;
\r
814 /* ------------------------------------------------------ */
\r
816 case 'M': /* Mode switch pas tous au point !! */
\r
819 if (sscanf(opj_optarg, "%d", &value) == 1) {
\r
820 for (i = 0; i <= 5; i++) {
\r
821 int cache = value & (1 << i);
\r
823 parameters->mode |= (1 << i);
\r
829 /* ------------------------------------------------------ */
\r
831 case 'R': /* ROI */
\r
833 if (sscanf(opj_optarg, "c=%d,U=%d", ¶meters->roi_compno,
\r
834 ¶meters->roi_shift) != 2) {
\r
835 fprintf(stderr, "ROI error !! [-ROI c='compno',U='shift']\n");
\r
841 /* ------------------------------------------------------ */
\r
843 case 'T': /* Tile offset */
\r
845 if (sscanf(opj_optarg, "%d,%d", ¶meters->cp_tx0, ¶meters->cp_ty0) != 2) {
\r
846 fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");
\r
852 /* ------------------------------------------------------ */
\r
854 case 'C': /* add a comment */
\r
856 parameters->cp_comment = (char*)malloc(strlen(opj_optarg) + 1);
\r
857 if(parameters->cp_comment) {
\r
858 strcpy(parameters->cp_comment, opj_optarg);
\r
864 /* ------------------------------------------------------ */
\r
866 case 'I': /* reversible or not */
\r
868 parameters->irreversible = 1;
\r
872 /* ------------------------------------------------------ */
\r
874 case 'v': /* Tile part generation*/
\r
876 parameters->tp_flag = opj_optarg[0];
\r
877 parameters->tp_on = 1;
\r
881 /* ------------------------------------------------------ */
\r
883 case 'z': /* Image Directory path */
\r
885 img_fol->imgdirpath = (char*)malloc(strlen(opj_optarg) + 1);
\r
886 strcpy(img_fol->imgdirpath,opj_optarg);
\r
887 img_fol->set_imgdir=1;
\r
891 /* ------------------------------------------------------ */
\r
893 case 'w': /* Digital Cinema 2K profile compliance*/
\r
896 sscanf(opj_optarg,"%d",&fps);
\r
898 parameters->cp_cinema = CINEMA2K_24;
\r
899 }else if(fps == 48 ){
\r
900 parameters->cp_cinema = CINEMA2K_48;
\r
902 fprintf(stderr,"Incorrect value!! must be 24 or 48\n");
\r
905 fprintf(stdout,"CINEMA 2K compliant codestream\n");
\r
906 parameters->cp_rsiz = CINEMA2K;
\r
911 /* ------------------------------------------------------ */
\r
913 case 'y': /* Digital Cinema 4K profile compliance*/
\r
915 parameters->cp_cinema = CINEMA4K_24;
\r
916 fprintf(stdout,"CINEMA 4K compliant codestream\n");
\r
917 parameters->cp_rsiz = CINEMA4K;
\r
921 /* ------------------------------------------------------ */
\r
925 /* ------------------------------------------------------ */
\r
927 case 'W': /* JPWL capabilities switched on */
\r
929 char *token = NULL;
\r
930 int hprot, pprot, sens, addr, size, range;
\r
932 /* we need to enable indexing */
\r
933 if (!indexfilename) {
\r
934 strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN);
\r
937 /* search for different protection methods */
\r
939 /* break the option in comma points and parse the result */
\r
940 token = strtok(opj_optarg, ",");
\r
941 while(token != NULL) {
\r
943 /* search header error protection method */
\r
944 if (*token == 'h') {
\r
946 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
948 hprot = 1; /* predefined method */
\r
950 if(sscanf(token, "h=%d", &hprot) == 1) {
\r
951 /* Main header, specified */
\r
952 if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
\r
953 ((hprot >= 37) && (hprot <= 128)))) {
\r
954 fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n", hprot);
\r
957 parameters->jpwl_hprot_MH = hprot;
\r
959 } else if(sscanf(token, "h%d=%d", &tile, &hprot) == 2) {
\r
960 /* Tile part 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 tile part header protection method h = %d\n", hprot);
\r
967 fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);
\r
970 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
971 parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
\r
972 parameters->jpwl_hprot_TPH[tilespec++] = hprot;
\r
975 } else if(sscanf(token, "h%d", &tile) == 1) {
\r
976 /* Tile part header, unspecified */
\r
978 fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);
\r
981 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
982 parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
\r
983 parameters->jpwl_hprot_TPH[tilespec++] = hprot;
\r
987 } else if (!strcmp(token, "h")) {
\r
988 /* Main header, unspecified */
\r
989 parameters->jpwl_hprot_MH = hprot;
\r
992 fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
\r
998 /* search packet error protection method */
\r
999 if (*token == 'p') {
\r
1001 static int pack = 0, tile = 0, packspec = 0, lastpackno = 0;
\r
1003 pprot = 1; /* predefined method */
\r
1005 if (sscanf(token, "p=%d", &pprot) == 1) {
\r
1006 /* Method for all tiles and all packets */
\r
1007 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1008 ((pprot >= 37) && (pprot <= 128)))) {
\r
1009 fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n", pprot);
\r
1012 parameters->jpwl_pprot_tileno[0] = 0;
\r
1013 parameters->jpwl_pprot_packno[0] = 0;
\r
1014 parameters->jpwl_pprot[0] = pprot;
\r
1016 } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) {
\r
1017 /* method specified from that tile on */
\r
1018 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1019 ((pprot >= 37) && (pprot <= 128)))) {
\r
1020 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1024 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1027 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1028 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1029 parameters->jpwl_pprot_packno[packspec] = 0;
\r
1030 parameters->jpwl_pprot[packspec++] = pprot;
\r
1033 } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) {
\r
1034 /* method fully specified from that tile and that packet on */
\r
1035 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1036 ((pprot >= 37) && (pprot <= 128)))) {
\r
1037 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1041 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1045 fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);
\r
1048 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1049 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1050 parameters->jpwl_pprot_packno[packspec] = pack;
\r
1051 parameters->jpwl_pprot[packspec++] = pprot;
\r
1054 } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) {
\r
1055 /* default method from that tile and that packet on */
\r
1056 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1057 ((pprot >= 37) && (pprot <= 128)))) {
\r
1058 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1062 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1066 fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);
\r
1069 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1070 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1071 parameters->jpwl_pprot_packno[packspec] = pack;
\r
1072 parameters->jpwl_pprot[packspec++] = pprot;
\r
1075 } else if (sscanf(token, "p%d", &tile) == 1) {
\r
1076 /* default from a tile on */
\r
1078 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1081 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1082 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1083 parameters->jpwl_pprot_packno[packspec] = 0;
\r
1084 parameters->jpwl_pprot[packspec++] = pprot;
\r
1088 } else if (!strcmp(token, "p")) {
\r
1090 parameters->jpwl_pprot_tileno[0] = 0;
\r
1091 parameters->jpwl_pprot_packno[0] = 0;
\r
1092 parameters->jpwl_pprot[0] = pprot;
\r
1095 fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
\r
1101 /* search sensitivity method */
\r
1102 if (*token == 's') {
\r
1104 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1106 sens = 0; /* predefined: relative error */
\r
1108 if(sscanf(token, "s=%d", &sens) == 1) {
\r
1109 /* Main header, specified */
\r
1110 if ((sens < -1) || (sens > 7)) {
\r
1111 fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n", sens);
\r
1114 parameters->jpwl_sens_MH = sens;
\r
1116 } else if(sscanf(token, "s%d=%d", &tile, &sens) == 2) {
\r
1117 /* Tile part header, specified */
\r
1118 if ((sens < -1) || (sens > 7)) {
\r
1119 fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n", sens);
\r
1123 fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
\r
1126 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
1127 parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
\r
1128 parameters->jpwl_sens_TPH[tilespec++] = sens;
\r
1131 } else if(sscanf(token, "s%d", &tile) == 1) {
\r
1132 /* Tile part header, unspecified */
\r
1134 fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
\r
1137 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
1138 parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
\r
1139 parameters->jpwl_sens_TPH[tilespec++] = hprot;
\r
1142 } else if (!strcmp(token, "s")) {
\r
1143 /* Main header, unspecified */
\r
1144 parameters->jpwl_sens_MH = sens;
\r
1147 fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token);
\r
1151 parameters->jpwl_sens_size = 2; /* 2 bytes for default size */
\r
1154 /* search addressing size */
\r
1155 if (*token == 'a') {
\r
1157 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1159 addr = 0; /* predefined: auto */
\r
1161 if(sscanf(token, "a=%d", &addr) == 1) {
\r
1163 if ((addr != 0) && (addr != 2) && (addr != 4)) {
\r
1164 fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr);
\r
1167 parameters->jpwl_sens_addr = addr;
\r
1169 } else if (!strcmp(token, "a")) {
\r
1171 parameters->jpwl_sens_addr = addr; /* auto for default size */
\r
1174 fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token);
\r
1180 /* search sensitivity size */
\r
1181 if (*token == 'z') {
\r
1183 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1185 size = 1; /* predefined: 1 byte */
\r
1187 if(sscanf(token, "z=%d", &size) == 1) {
\r
1189 if ((size != 0) && (size != 1) && (size != 2)) {
\r
1190 fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size);
\r
1193 parameters->jpwl_sens_size = size;
\r
1195 } else if (!strcmp(token, "a")) {
\r
1197 parameters->jpwl_sens_size = size; /* 1 for default size */
\r
1200 fprintf(stderr, "ERROR -> invalid size selection = %s\n", token);
\r
1206 /* search range method */
\r
1207 if (*token == 'g') {
\r
1209 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1211 range = 0; /* predefined: 0 (packet) */
\r
1213 if(sscanf(token, "g=%d", &range) == 1) {
\r
1215 if ((range < 0) || (range > 3)) {
\r
1216 fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range);
\r
1219 parameters->jpwl_sens_range = range;
\r
1221 } else if (!strcmp(token, "g")) {
\r
1223 parameters->jpwl_sens_range = range;
\r
1226 fprintf(stderr, "ERROR -> invalid range selection = %s\n", token);
\r
1232 /* next token or bust */
\r
1233 token = strtok(NULL, ",");
\r
1238 fprintf(stdout, "Info: JPWL capabilities enabled\n");
\r
1239 parameters->jpwl_epc_on = true;
\r
1243 #endif /* USE_JPWL */
\r
1245 /* ------------------------------------------------------ */
\r
1247 case 'J': /* jpip on */
\r
1249 parameters->jpip_on = OPJ_TRUE;
\r
1252 /* ------------------------------------------------------ */
\r
1255 fprintf(stderr, "ERROR -> Command line not valid\n");
\r
1260 /* check for possible errors */
\r
1261 if (parameters->cp_cinema){
\r
1262 if(parameters->tcp_numlayers > 1){
\r
1263 parameters->cp_rsiz = STD_RSIZ;
\r
1264 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 if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality)
\r
1269 && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ parameters->cp_fixed_quality))) {
\r
1270 fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");
\r
1272 } /* mod fixed_quality */
\r
1274 /* if no rate entered, lossless by default */
\r
1275 if (parameters->tcp_numlayers == 0) {
\r
1276 parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */
\r
1277 parameters->tcp_numlayers++;
\r
1278 parameters->cp_disto_alloc = 1;
\r
1281 if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) {
\r
1283 "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
\r
1284 parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0);
\r
1288 for (i = 0; i < parameters->numpocs; i++) {
\r
1289 if (parameters->POC[i].prg == -1) {
\r
1291 "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
\r
1300 /** 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
1301 @param buffer_size, increased by the length of the compressed index, in number of bytes
\r
1302 @return a pointer to a char[]
\r
1303 Syntax of the index:
\r
1304 one char for the version number (1): one byte because no problem with little endian, big endian etc.
\r
1305 one int for each of the following informations:
\r
1308 progression order
\r
1315 Nb of resolutions
\r
1317 for each resolution:
\r
1321 End main header position
\r
1326 tile start pos in codestream
\r
1327 tile header end position
\r
1328 tile end position in codestream
\r
1330 For each LRCP, RLCP etc.:
\r
1337 start position in the codestream
\r
1338 end position of this packet
\r
1340 char* create_index_into_byte_array(opj_codestream_info_t *cstr_info, int* buffer_size) {
\r
1341 int tileno, compno, layno, resno, precno, pack_nb, x, y;
\r
1342 char* buffer = NULL;
\r
1343 int buffer_pos = 0;
\r
1347 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1348 for (resno = 0; resno < cstr_info->numdecompos[0] + 1; resno++) {
\r
1349 prec_max = max(prec_max,cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]);
\r
1353 // Compute the size of the index buffer, in number of bytes*/
\r
1356 + (10 /* image_w until decomposition */
\r
1357 + (cstr_info->numdecompos[0]+1) * 2 /* pdx size for each tile */
\r
1358 + 2 /* main_head_end + codestream_size */
\r
1359 + cstr_info->tw * cstr_info->th * 4 /* tile info, without distorsion info */
\r
1360 + cstr_info->tw*cstr_info->th * cstr_info->numlayers * (cstr_info->numdecompos[0] + 1) * cstr_info->numcomps * prec_max *8
\r
1362 //printf("C: index buffer size = %d bytes\n", *buffer_size);
\r
1363 buffer = (char*) malloc(*buffer_size);
\r
1366 //opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to allocate index buffer for writing %d int\n", *buffer_size);
\r
1367 fprintf(stderr, "failed to allocate index buffer for writing %d int\n", *buffer_size);
\r
1371 buffer[0] = 1; // Version stored on a byte
\r
1373 // Remaining informations are stored on a int.
\r
1374 ((int*)buffer)[buffer_pos++] = cstr_info->image_w;
\r
1375 ((int*)buffer)[buffer_pos++] = cstr_info->image_h;
\r
1376 ((int*)buffer)[buffer_pos++] = cstr_info->prog;
\r
1377 ((int*)buffer)[buffer_pos++] = cstr_info->tile_x;
\r
1378 ((int*)buffer)[buffer_pos++] = cstr_info->tile_y;
\r
1379 ((int*)buffer)[buffer_pos++] = cstr_info->tw;
\r
1380 ((int*)buffer)[buffer_pos++] = cstr_info->th;
\r
1381 ((int*)buffer)[buffer_pos++] = cstr_info->numcomps;
\r
1382 ((int*)buffer)[buffer_pos++] = cstr_info->numlayers;
\r
1383 ((int*)buffer)[buffer_pos++] = cstr_info->numdecompos[0];
\r
1385 for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
\r
1386 /* based on tile 0 */
\r
1387 ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
\r
1388 ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
\r
1390 ((int*)buffer)[buffer_pos++] = cstr_info->main_head_end;
\r
1391 ((int*)buffer)[buffer_pos++] = cstr_info->codestream_size;
\r
1393 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1394 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].tileno;
\r
1395 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].start_pos;
\r
1396 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_header;
\r
1397 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_pos;
\r
1400 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1401 int start_pos, end_pos;
\r
1402 int max_numdecompos = 0;
\r
1405 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1406 if (max_numdecompos < cstr_info->numdecompos[compno])
\r
1407 max_numdecompos = cstr_info->numdecompos[compno];
\r
1410 if (cstr_info->prog == LRCP) { /* LRCP */
\r
1412 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1413 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1414 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1416 if (resno > cstr_info->numdecompos[compno])
\r
1418 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1419 for (precno = 0; precno < prec_max; precno++) {
\r
1420 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1421 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1422 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1423 ((int*)buffer)[buffer_pos++] = tileno;
\r
1424 ((int*)buffer)[buffer_pos++] = layno;
\r
1425 ((int*)buffer)[buffer_pos++] = resno;
\r
1426 ((int*)buffer)[buffer_pos++] = compno;
\r
1427 ((int*)buffer)[buffer_pos++] = precno;
\r
1428 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1429 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1436 else if (cstr_info->prog == RLCP) { /* RLCP */
\r
1438 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1439 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1440 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1442 if (resno > cstr_info->numdecompos[compno])
\r
1444 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1445 for (precno = 0; precno < prec_max; precno++) {
\r
1446 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1447 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1448 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1449 ((int*)buffer)[buffer_pos++] = tileno;
\r
1450 ((int*)buffer)[buffer_pos++] = resno;
\r
1451 ((int*)buffer)[buffer_pos++] = layno;
\r
1452 ((int*)buffer)[buffer_pos++] = compno;
\r
1453 ((int*)buffer)[buffer_pos++] = precno;
\r
1454 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1455 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1462 else if (cstr_info->prog == RPCL) { /* RPCL */
\r
1464 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1465 /* I suppose components have same XRsiz, YRsiz */
\r
1466 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1467 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1468 int x1 = x0 + cstr_info->tile_x;
\r
1469 int y1 = y0 + cstr_info->tile_y;
\r
1470 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1472 if (resno > cstr_info->numdecompos[compno])
\r
1474 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1475 for (precno = 0; precno < prec_max; precno++) {
\r
1476 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1477 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1478 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1479 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1480 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1481 for(y = y0; y < y1; y++) {
\r
1482 if (precno_y*pcy == y ) {
\r
1483 for (x = x0; x < x1; x++) {
\r
1484 if (precno_x*pcx == x ) {
\r
1485 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1486 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1487 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1488 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1489 ((int*)buffer)[buffer_pos++] = tileno;
\r
1490 ((int*)buffer)[buffer_pos++] = resno;
\r
1491 ((int*)buffer)[buffer_pos++] = precno;
\r
1492 ((int*)buffer)[buffer_pos++] = compno;
\r
1493 ((int*)buffer)[buffer_pos++] = layno;
\r
1494 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1495 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1501 } /* y = y0..y1 */
\r
1506 else if (cstr_info->prog == PCRL) { /* PCRL */
\r
1507 /* I suppose components have same XRsiz, YRsiz */
\r
1508 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1509 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1510 int x1 = x0 + cstr_info->tile_x;
\r
1511 int y1 = y0 + cstr_info->tile_y;
\r
1513 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1514 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1516 if (resno > cstr_info->numdecompos[compno])
\r
1518 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1519 for (precno = 0; precno < prec_max; precno++) {
\r
1520 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1521 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1522 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1523 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1524 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1525 for(y = y0; y < y1; y++) {
\r
1526 if (precno_y*pcy == y ) {
\r
1527 for (x = x0; x < x1; x++) {
\r
1528 if (precno_x*pcx == x ) {
\r
1529 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1530 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1531 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1532 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1533 ((int*)buffer)[buffer_pos++] = tileno;
\r
1534 ((int*)buffer)[buffer_pos++] = precno;
\r
1535 ((int*)buffer)[buffer_pos++] = compno;
\r
1536 ((int*)buffer)[buffer_pos++] = resno;
\r
1537 ((int*)buffer)[buffer_pos++] = layno;
\r
1538 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1539 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1545 } /* y = y0..y1 */
\r
1552 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1553 /* I suppose components have same XRsiz, YRsiz */
\r
1554 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1555 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1556 int x1 = x0 + cstr_info->tile_x;
\r
1557 int y1 = y0 + cstr_info->tile_y;
\r
1559 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1561 if (resno > cstr_info->numdecompos[compno])
\r
1563 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1564 for (precno = 0; precno < prec_max; precno++) {
\r
1565 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1566 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1567 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1568 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1569 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1570 for(y = y0; y < y1; y++) {
\r
1571 if (precno_y*pcy == y ) {
\r
1572 for (x = x0; x < x1; x++) {
\r
1573 if (precno_x*pcx == x ) {
\r
1574 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1575 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1576 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1577 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1578 ((int*)buffer)[buffer_pos++] = tileno;
\r
1579 ((int*)buffer)[buffer_pos++] = compno;
\r
1580 ((int*)buffer)[buffer_pos++] = precno;
\r
1581 ((int*)buffer)[buffer_pos++] = resno;
\r
1582 ((int*)buffer)[buffer_pos++] = layno;
\r
1583 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1584 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1590 } /* y = y0..y1 */
\r
1597 if (buffer_pos > *buffer_size) {
\r
1598 //opj_event_msg(j2k->cinfo, EVT_ERROR, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);
\r
1599 fprintf(stderr, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);
\r
1609 /* --------------------------------------------------------------------------
\r
1610 ------------ Get the image byte[] from the Java object -------------------*/
\r
1612 opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env, jobject obj, jclass cls) {
\r
1613 int i,max,shift,w,h,depth;
\r
1614 opj_image_t * img = NULL;
\r
1615 int compno, numcomps;
\r
1616 opj_image_t * image = NULL;
\r
1617 opj_image_comp_t *comp;
\r
1618 opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
\r
1619 OPJ_COLOR_SPACE color_space;
\r
1631 // Image width, height and depth
\r
1632 fid = (*env)->GetFieldID(env, cls,"width", "I");
\r
1633 ji = (*env)->GetIntField(env, obj, fid);
\r
1636 fid = (*env)->GetFieldID(env, cls,"height", "I");
\r
1637 ji = (*env)->GetIntField(env, obj, fid);
\r
1640 fid = (*env)->GetFieldID(env, cls,"depth", "I");
\r
1641 ji = (*env)->GetIntField(env, obj, fid);
\r
1647 color_space = CLRSPC_GRAY;
\r
1650 color_space = CLRSPC_SRGB;
\r
1652 memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
\r
1654 if (numcomps == 1) {
\r
1655 cmptparm[0].x0 = parameters->image_offset_x0;
\r
1656 cmptparm[0].y0 = parameters->image_offset_y0;
\r
1657 cmptparm[0].w = !cmptparm[0].x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm[0].x0 + (w - 1) * parameters->subsampling_dx + 1;
\r
1658 cmptparm[0].h = !cmptparm[0].y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm[0].y0 + (h - 1) * parameters->subsampling_dy + 1;
\r
1659 // Java types are always signed but we use them as unsigned types (shift of the negative part of
\r
1660 // the pixels of the images in Telemis before entering the encoder).
\r
1661 cmptparm[0].sgnd = 0;
\r
1663 cmptparm[0].prec=depth;
\r
1665 cmptparm[0].prec = 8;
\r
1666 cmptparm[0].bpp = cmptparm[0].prec;
\r
1667 cmptparm[0].dx = parameters->subsampling_dx;
\r
1668 cmptparm[0].dy = parameters->subsampling_dy;
\r
1669 /*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
1670 cmptparm[0].h, cmptparm[0].sgnd, cmptparm[0].bpp, cmptparm[0].dx, cmptparm[0].dy, color_space);*/
\r
1672 for(i = 0; i < numcomps; i++) {
\r
1673 cmptparm[i].prec = 8;
\r
1674 cmptparm[i].bpp = 8;
\r
1675 cmptparm[i].sgnd = 0;
\r
1676 cmptparm[i].dx = parameters->subsampling_dx;
\r
1677 cmptparm[i].dy = parameters->subsampling_dy;
\r
1678 cmptparm[i].w = w;
\r
1679 cmptparm[i].h = h;
\r
1683 /* create the image */
\r
1684 image = opj_image_create(numcomps, &cmptparm[0], color_space);
\r
1690 image->numcomps=1;
\r
1692 image->numcomps = 3;
\r
1695 /* set image offset and reference grid */
\r
1696 image->x0 = cmptparm[0].x0;
\r
1697 image->y0 = cmptparm[0].x0;
\r
1698 image->x1 = cmptparm[0].w;
\r
1699 image->y1 = cmptparm[0].h;
\r
1701 /* set image data */
\r
1702 for (compno=0; compno<numcomps; compno++) {
\r
1703 comp = &image->comps[compno];
\r
1706 fid = (*env)->GetFieldID(env, cls,"image8", "[B"); // byteArray []
\r
1707 jba = (*env)->GetObjectField(env, obj, fid);
\r
1708 len = (*env)->GetArrayLength(env, jba);
\r
1710 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, &isCopy);
\r
1711 //printf("C: before transfering 8 bpp image\n");
\r
1713 for(i=0; i< len;i++) {
\r
1714 comp->data[i] = (char) jbBody[i];
\r
1715 if (comp->data[i] > max) max = comp->data[i];
\r
1718 for(i=0; i< len;i++) {
\r
1719 comp->data[i] = (unsigned char) jbBody[i];
\r
1720 if (comp->data[i] > max) max = comp->data[i];
\r
1723 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1724 } else if(depth == 16) {
\r
1725 fid = (*env)->GetFieldID(env, cls,"image16", "[S"); // shortArray []
\r
1726 jsa = (*env)->GetObjectField(env, obj, fid);
\r
1727 len = (*env)->GetArrayLength(env, jsa);
\r
1729 jsBody = (*env)->GetPrimitiveArrayCritical(env, jsa, &isCopy);
\r
1730 //printf("C: before transfering 16 bpp image\n");
\r
1731 if (comp->sgnd) { // Special behaviour to deal with signed elements ??
\r
1732 comp->data[i] = (short) jsBody[i];
\r
1733 for(i=0; i< len;i++) {
\r
1734 if (comp->data[i] > max) max = comp->data[i];
\r
1737 for(i=0; i< len;i++) {
\r
1738 comp->data[i] = (unsigned short) jsBody[i];
\r
1739 if (comp->data[i] > max) max = comp->data[i];
\r
1742 (*env)->ReleasePrimitiveArrayCritical(env, jsa, jsBody, 0);
\r
1743 } else if (depth == 24) {
\r
1744 fid = (*env)->GetFieldID(env, cls,"image24", "[I"); // intArray []
\r
1745 jia = (*env)->GetObjectField(env, obj, fid);
\r
1746 len = (*env)->GetArrayLength(env, jia);
\r
1749 jiBody = (*env)->GetPrimitiveArrayCritical(env, jia, &isCopy);
\r
1750 //printf("C: before transfering 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);
\r
1751 if (comp->sgnd) { // Special behaviour to deal with signed elements ?? XXXXX
\r
1752 for(i=0; i< len;i++) {
\r
1753 comp->data[i] = ( ((int) jiBody[i]) & (0xFF << shift) ) >> shift;
\r
1754 if (comp->data[i] > max) max = comp->data[i];
\r
1757 for(i=0; i< len;i++) {
\r
1758 comp->data[i] = ( ((unsigned int) jiBody[i]) & (0xFF << shift) ) >> shift;
\r
1759 if (comp->data[i] > max) max = comp->data[i];
\r
1762 (*env)->ReleasePrimitiveArrayCritical(env, jia, jiBody, 0);
\r
1764 comp->bpp = int_floorlog2(max)+1;
\r
1765 comp->prec = comp->bpp;
\r
1766 //printf("C: component %d: max %d, real bpp = %d\n", compno, max, comp->bpp);
\r
1772 /* --------------------------------------------------------------------------
\r
1773 -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/
\r
1774 JNIEXPORT jlong JNICALL Java_org_openJpeg_OpenJPEGJavaEncoder_internalEncodeImageToJ2K(JNIEnv *env, jobject obj, jobjectArray javaParameters) {
\r
1775 int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */
\r
1776 char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */
\r
1778 opj_cparameters_t parameters; /* compression parameters */
\r
1779 img_fol_t img_fol;
\r
1780 opj_event_mgr_t event_mgr; /* event manager */
\r
1781 opj_image_t *image = NULL;
\r
1782 int i,j,num_images;
\r
1784 opj_codestream_info_t cstr_info; /* Codestream information structure */
\r
1785 char indexfilename[OPJ_PATH_LEN]; /* index file name */
\r
1787 int* compressed_index = NULL;
\r
1788 int compressed_index_size=-1;
\r
1789 // ==> Access variables to the Java member variables
\r
1797 callback_variables_t msgErrorCallback_vars;
\r
1798 // <== access variable to the Java member variables.
\r
1800 // For the encoding and storage into the file
\r
1801 opj_cinfo_t* cinfo;
\r
1802 int codestream_length;
\r
1803 opj_cio_t *cio = NULL;
\r
1806 // JNI reference to the calling class
\r
1807 cls = (*env)->GetObjectClass(env, obj);
\r
1809 // Pointers to be able to call a Java method for all the info and error messages
\r
1810 msgErrorCallback_vars.env = env;
\r
1811 msgErrorCallback_vars.jobj = &obj;
\r
1812 msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V");
\r
1813 msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V");
\r
1815 arraySize = (*env)->GetArrayLength(env, javaParameters);
\r
1816 argc = (int) arraySize +1;
\r
1817 argv = malloc(argc*sizeof(char*));
\r
1818 argv[0] = "ProgramName.exe"; // The program name: useless
\r
1820 for (i=1; i<argc; i++) {
\r
1821 object = (*env)->GetObjectArrayElement(env, javaParameters, i-1);
\r
1822 argv[i] = (*env)->GetStringUTFChars(env, object, &isCopy);
\r
1826 for (i=0; i<argc; i++) {
\r
1827 printf("[%s]",argv[i]);
\r
1832 configure the event callbacks
\r
1834 memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
\r
1835 event_mgr.error_handler = error_callback;
\r
1836 event_mgr.warning_handler = warning_callback;
\r
1837 event_mgr.info_handler = info_callback;
\r
1839 /* set encoding parameters to default values */
\r
1840 opj_set_default_encoder_parameters(¶meters);
\r
1841 parameters.cod_format = J2K_CFMT;
\r
1842 //parameters.index_on = 1;
\r
1844 /* Initialize indexfilename and img_fol */
\r
1845 *indexfilename = 0;
\r
1846 memset(&img_fol,0,sizeof(img_fol_t));
\r
1848 /* parse input and get user encoding parameters */
\r
1849 if (parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) {
\r
1850 // Release the Java arguments array
\r
1851 for (i=1; i<argc; i++)
\r
1852 (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
\r
1856 // Release the Java arguments array
\r
1857 for (i=1; i<argc; i++)
\r
1858 (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
\r
1860 if (parameters.cp_cinema){
\r
1861 cinema_parameters(¶meters);
\r
1865 /* Create comment for codestream */
\r
1866 if(parameters.cp_comment == NULL) {
\r
1867 const char comment[] = "Created by JavaOpenJPEG version ";
\r
1868 const size_t clen = strlen(comment);
\r
1869 const char *version = opj_version();
\r
1872 parameters.cp_comment = (char*)malloc(clen+strlen(version)+11);
\r
1873 sprintf(parameters.cp_comment,"%s%s with JPWL", comment, version);
\r
1875 parameters.cp_comment = (char*)malloc(clen+strlen(version)+1);
\r
1876 sprintf(parameters.cp_comment,"%s%s", comment, version);
\r
1882 /* Read directory if necessary */
\r
1885 /*Encoding image one by one*/
\r
1886 for(imageno=0;imageno<num_images;imageno++)
\r
1889 fprintf(stderr,"\n");
\r
1891 image = loadImage(¶meters, env, obj, cls);
\r
1892 //printf("C: after load image: image = %d\n", image);
\r
1894 fprintf(stderr, "Unable to load image\n");
\r
1898 /* Decide if MCT should be used */
\r
1899 parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
\r
1901 if(parameters.cp_cinema){
\r
1902 cinema_setup_encoder(¶meters,image,&img_fol);
\r
1905 /* encode the destination image */
\r
1906 /* ---------------------------- */
\r
1907 /* get a J2K compressor handle */
\r
1908 if (parameters.cod_format == J2K_CFMT) { /* J2K format output */
\r
1909 cinfo = opj_create_compress(CODEC_J2K);
\r
1910 } else { /* JP2 format output */
\r
1911 cinfo = opj_create_compress(CODEC_JP2);
\r
1913 /* catch events using our callbacks and give a local context */
\r
1914 opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, &msgErrorCallback_vars);
\r
1916 /* setup the encoder parameters using the current image and user parameters */
\r
1917 opj_setup_encoder(cinfo, ¶meters, image);
\r
1919 /* open a byte stream for writing */
\r
1920 /* allocate memory for all tiles */
\r
1921 cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
\r
1923 /* encode the image */
\r
1924 bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);
\r
1925 printf("C: after opj_encode_with_info\n");
\r
1927 opj_cio_close(cio);
\r
1928 fprintf(stderr, "failed to encode image\n");
\r
1931 codestream_length = cio_tell(cio);
\r
1933 /* write the index on disk, if needed (-x 'filename') */
\r
1934 if (*indexfilename) {
\r
1935 bSuccess = write_index_file(&cstr_info, indexfilename);
\r
1937 fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename);
\r
1941 compressed_index = create_index_into_byte_array(&cstr_info, &compressed_index_size);
\r
1942 /* Allocates the Java compressedIndex byte[] and sends this index into the Java object */
\r
1943 fid = (*env)->GetFieldID(env, cls,"compressedIndex", "[B");
\r
1944 jba = (*env)->NewByteArray(env, compressed_index_size+1);
\r
1945 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
\r
1946 memcpy(jbBody, compressed_index, compressed_index_size);
\r
1947 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1948 (*env)->SetObjectField(env, obj, fid, jba);
\r
1949 free(compressed_index);
\r
1951 /* write the generated codestream to disk ? */
\r
1952 if (parameters.outfile[0]!='\0') {
\r
1953 f = fopen(parameters.outfile, "wb");
\r
1955 fprintf(stderr, "failed to open [%s] for writing\n", parameters.outfile);
\r
1958 fwrite(cio->buffer, 1, codestream_length, f);
\r
1960 fprintf(stdout,"Generated outfile [%s]\n",parameters.outfile);
\r
1963 /* Write the generated codestream to the Java pre-allocated compressedStream byte[] */
\r
1964 fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");
\r
1965 jba = (*env)->GetObjectField(env, obj, fid);
\r
1966 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
\r
1967 memcpy(jbBody, cio->buffer, codestream_length);
\r
1968 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1970 /* close and free the byte stream */
\r
1971 opj_cio_close(cio);
\r
1973 /* free remaining compression structures */
\r
1974 opj_destroy_compress(cinfo);
\r
1975 opj_destroy_cstr_info(&cstr_info);
\r
1977 /* free image data */
\r
1978 opj_image_destroy(image);
\r
1981 /* free user parameters structure */
\r
1982 if(parameters.cp_comment) free(parameters.cp_comment);
\r
1983 if(parameters.cp_matrice) free(parameters.cp_matrice);
\r
1985 return codestream_length;
\r