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 "compat/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 /* ----------------------------------------------------------------------- */
\r
65 /* ----------------------------------------------------------------------- */
\r
66 #define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/
\r
67 #define CINEMA_48_CS 651041 /*Codestream length for 48fps*/
\r
68 #define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/
\r
69 #define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/
\r
71 extern int get_file_format(char *filename);
\r
72 extern void error_callback(const char *msg, void *client_data);
\r
73 extern warning_callback(const char *msg, void *client_data);
\r
74 extern void info_callback(const char *msg, void *client_data);
\r
76 typedef struct callback_variables {
\r
78 /** 'jclass' object used to call a Java method from the C */
\r
80 /** 'jclass' object used to call a Java method from the C */
\r
81 jmethodID message_mid;
\r
82 jmethodID error_mid;
\r
83 } callback_variables_t;
\r
85 typedef struct dircnt{
\r
86 /** Buffer for holding images read from Directory*/
\r
88 /** Pointer to the buffer*/
\r
92 typedef struct img_folder{
\r
93 /** The directory path of the folder containing input images*/
\r
99 /** Enable Cod Format for output*/
\r
100 char set_out_format;
\r
101 /** User specified rate stored in case of cinema option*/
\r
105 void encode_help_display() {
\r
106 fprintf(stdout,"HELP\n----\n\n");
\r
107 fprintf(stdout,"- the -h option displays this help information on screen\n\n");
\r
110 fprintf(stdout,"List of parameters for the JPEG 2000 "
\r
113 #endif /* USE_JPWL */
\r
116 fprintf(stdout,"\n");
\r
117 fprintf(stdout,"REMARKS:\n");
\r
118 fprintf(stdout,"---------\n");
\r
119 fprintf(stdout,"\n");
\r
120 fprintf(stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n");
\r
121 fprintf(stdout,"COD and QCD never appear in the tile_header.\n");
\r
122 fprintf(stdout,"\n");
\r
123 fprintf(stdout,"- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n");
\r
124 fprintf(stdout,"color image. You need enough disk space memory (twice the original) to encode \n");
\r
125 fprintf(stdout,"the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n");
\r
126 fprintf(stdout,"\n");
\r
127 fprintf(stdout,"By default:\n");
\r
128 fprintf(stdout,"------------\n");
\r
129 fprintf(stdout,"\n");
\r
130 fprintf(stdout," * Lossless\n");
\r
131 fprintf(stdout," * 1 tile\n");
\r
132 fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");
\r
133 fprintf(stdout," * Size of code-block : 64 x 64\n");
\r
134 fprintf(stdout," * Number of resolutions: 6\n");
\r
135 fprintf(stdout," * No SOP marker in the codestream\n");
\r
136 fprintf(stdout," * No EPH marker in the codestream\n");
\r
137 fprintf(stdout," * No sub-sampling in x or y direction\n");
\r
138 fprintf(stdout," * No mode switch activated\n");
\r
139 fprintf(stdout," * Progression order: LRCP\n");
\r
140 fprintf(stdout," * No index file\n");
\r
141 fprintf(stdout," * No ROI upshifted\n");
\r
142 fprintf(stdout," * No offset of the origin of the image\n");
\r
143 fprintf(stdout," * No offset of the origin of the tiles\n");
\r
144 fprintf(stdout," * Reversible DWT 5-3\n");
\r
147 fprintf(stdout," * No JPWL protection\n");
\r
148 #endif /* USE_JPWL */
\r
150 fprintf(stdout,"\n");
\r
151 fprintf(stdout,"Parameters:\n");
\r
152 fprintf(stdout,"------------\n");
\r
153 fprintf(stdout,"\n");
\r
154 fprintf(stdout,"Required Parameters (except with -h):\n");
\r
155 fprintf(stdout,"One of the two options -ImgDir or -i must be used\n");
\r
156 fprintf(stdout,"\n");
\r
157 fprintf(stdout,"-ImgDir : Image file Directory path (example ../Images) \n");
\r
158 fprintf(stdout," When using this option -OutFor must be used\n");
\r
159 fprintf(stdout,"\n");
\r
160 fprintf(stdout,"-OutFor \n");
\r
161 fprintf(stdout," REQUIRED only if -ImgDir is used\n");
\r
162 fprintf(stdout," Need to specify only format without filename <BMP> \n");
\r
163 fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA formats\n");
\r
164 fprintf(stdout,"\n");
\r
165 fprintf(stdout,"-i : source file (-i source.pnm also *.pgm, *.ppm, *.bmp, *.tif, *.raw, *.tga) \n");
\r
166 fprintf(stdout," When using this option -o must be used\n");
\r
167 fprintf(stdout,"\n");
\r
168 fprintf(stdout,"-o : destination file (-o dest.j2k or .jp2) \n");
\r
169 fprintf(stdout,"\n");
\r
170 fprintf(stdout,"Optional Parameters:\n");
\r
171 fprintf(stdout,"\n");
\r
172 fprintf(stdout,"-h : display the help information \n ");
\r
173 fprintf(stdout,"\n");
\r
174 fprintf(stdout,"-cinema2K : Digital Cinema 2K profile compliant codestream for 2K resolution.(-cinema2k 24 or 48) \n");
\r
175 fprintf(stdout," Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n");
\r
176 fprintf(stdout,"\n");
\r
177 fprintf(stdout,"-cinema4K : Digital Cinema 4K profile compliant codestream for 4K resolution \n");
\r
178 fprintf(stdout," Frames per second not required. Default value is 24fps\n");
\r
179 fprintf(stdout,"\n");
\r
180 fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n ");
\r
181 fprintf(stdout," - The rate specified for each quality level is the desired \n");
\r
182 fprintf(stdout," compression factor.\n");
\r
183 fprintf(stdout," Example: -r 20,10,1 means quality 1: compress 20x, \n");
\r
184 fprintf(stdout," quality 2: compress 10x and quality 3: compress lossless\n");
\r
185 fprintf(stdout,"\n");
\r
186 fprintf(stdout," (options -r and -q cannot be used together)\n ");
\r
187 fprintf(stdout,"\n");
\r
189 fprintf(stdout,"-q : different psnr for successive layers (-q 30,40,50) \n ");
\r
191 fprintf(stdout," (options -r and -q cannot be used together)\n ");
\r
193 fprintf(stdout,"\n");
\r
194 fprintf(stdout,"-n : number of resolutions (-n 3) \n");
\r
195 fprintf(stdout,"\n");
\r
196 fprintf(stdout,"-b : size of code block (-b 32,32) \n");
\r
197 fprintf(stdout,"\n");
\r
198 fprintf(stdout,"-c : size of precinct (-c 128,128) \n");
\r
199 fprintf(stdout,"\n");
\r
200 fprintf(stdout,"-t : size of tile (-t 512,512) \n");
\r
201 fprintf(stdout,"\n");
\r
202 fprintf(stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
\r
203 fprintf(stdout,"\n");
\r
204 fprintf(stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n");
\r
205 fprintf(stdout," Remark: subsampling bigger than 2 can produce error\n");
\r
206 fprintf(stdout,"\n");
\r
207 fprintf(stdout,"-POC : Progression order change (-POC T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL) \n");
\r
208 fprintf(stdout," Example: T1=0,0,1,5,3,CPRL \n");
\r
209 fprintf(stdout," : Ttilenumber=Resolution num start,Component num start,Layer num end,Resolution num end,Component num end,Progression order\n");
\r
210 fprintf(stdout,"\n");
\r
211 fprintf(stdout,"-SOP : write SOP marker before each packet \n");
\r
212 fprintf(stdout,"\n");
\r
213 fprintf(stdout,"-EPH : write EPH marker after each header packet \n");
\r
214 fprintf(stdout,"\n");
\r
215 fprintf(stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
\r
216 fprintf(stdout," 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");
\r
217 fprintf(stdout," Indicate multiple modes by adding their values. \n");
\r
218 fprintf(stdout," ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
\r
219 fprintf(stdout,"\n");
\r
220 fprintf(stdout,"-x : create an index file *.Idx (-x index_name.Idx) \n");
\r
221 fprintf(stdout,"\n");
\r
222 fprintf(stdout,"-ROI : c=%%d,U=%%d : quantization indices upshifted \n");
\r
223 fprintf(stdout," for component c=%%d [%%d = 0,1,2]\n");
\r
224 fprintf(stdout," with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI c=0,U=25) \n");
\r
225 fprintf(stdout,"\n");
\r
226 fprintf(stdout,"-d : offset of the origin of the image (-d 150,300) \n");
\r
227 fprintf(stdout,"\n");
\r
228 fprintf(stdout,"-T : offset of the origin of the tiles (-T 100,75) \n");
\r
229 fprintf(stdout,"\n");
\r
230 fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n");
\r
231 fprintf(stdout,"\n");
\r
234 fprintf(stdout,"-W : adoption of JPWL (Part 11) capabilities (-W params)\n");
\r
235 fprintf(stdout," The parameters can be written and repeated in any order:\n");
\r
236 fprintf(stdout," [h<tilepart><=type>,s<tilepart><=method>,a=<addr>,...\n");
\r
237 fprintf(stdout," ...,z=<size>,g=<range>,p<tilepart:pack><=type>]\n");
\r
238 fprintf(stdout,"\n");
\r
239 fprintf(stdout," h selects the header error protection (EPB): 'type' can be\n");
\r
240 fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
\r
241 fprintf(stdout," if 'tilepart' is absent, it is for main and tile headers\n");
\r
242 fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");
\r
243 fprintf(stdout," onwards, up to the next h<> spec, or to the last tilepart\n");
\r
244 fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);
\r
245 fprintf(stdout,"\n");
\r
246 fprintf(stdout," p selects the packet error protection (EEP/UEP with EPBs)\n");
\r
247 fprintf(stdout," to be applied to raw data: 'type' can be\n");
\r
248 fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
\r
249 fprintf(stdout," if 'tilepart:pack' is absent, it is from tile 0, packet 0\n");
\r
250 fprintf(stdout," if 'tilepart:pack' is present, it applies from that tile\n");
\r
251 fprintf(stdout," and that packet onwards, up to the next packet spec\n");
\r
252 fprintf(stdout," or to the last packet in the last tilepart in the stream\n");
\r
253 fprintf(stdout," (max. %d specs)\n", JPWL_MAX_NO_PACKSPECS);
\r
254 fprintf(stdout,"\n");
\r
255 fprintf(stdout," s enables sensitivity data insertion (ESD): 'method' can be\n");
\r
256 fprintf(stdout," [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n");
\r
257 fprintf(stdout," 4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n");
\r
258 fprintf(stdout," if 'tilepart' is absent, it is for main header only\n");
\r
259 fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");
\r
260 fprintf(stdout," onwards, up to the next s<> spec, or to the last tilepart\n");
\r
261 fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);
\r
262 fprintf(stdout,"\n");
\r
263 fprintf(stdout," g determines the addressing mode: <range> can be\n");
\r
264 fprintf(stdout," [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n");
\r
265 fprintf(stdout,"\n");
\r
266 fprintf(stdout," a determines the size of data addressing: <addr> can be\n");
\r
267 fprintf(stdout," 2/4 bytes (small/large codestreams). If not set, auto-mode\n");
\r
268 fprintf(stdout,"\n");
\r
269 fprintf(stdout," z determines the size of sensitivity values: <size> can be\n");
\r
270 fprintf(stdout," 1/2 bytes, for the transformed pseudo-floating point value\n");
\r
271 fprintf(stdout,"\n");
\r
272 fprintf(stdout," ex.:\n");
\r
273 fprintf(stdout," h,h0=64,h3=16,h5=32,p0=78,p0:24=56,p1,p3:0=0,p3:20=32,s=0,\n");
\r
274 fprintf(stdout," s0=6,s3=-1,a=0,g=1,z=1\n");
\r
275 fprintf(stdout," means\n");
\r
276 fprintf(stdout," predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n");
\r
277 fprintf(stdout," CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n");
\r
278 fprintf(stdout," UEP rs(78,32) for packets 0 to 23 of tile 0,\n");
\r
279 fprintf(stdout," UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n");
\r
280 fprintf(stdout," UEP rs default for packets of tilepart 1,\n");
\r
281 fprintf(stdout," no UEP for packets 0 to 19 of tilepart 3,\n");
\r
282 fprintf(stdout," UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n");
\r
283 fprintf(stdout," relative sensitivity ESD for MH,\n");
\r
284 fprintf(stdout," TSE ESD from TPH 0 to TPH 2, byte range with automatic\n");
\r
285 fprintf(stdout," size of addresses and 1 byte for each sensitivity value\n");
\r
286 fprintf(stdout,"\n");
\r
287 fprintf(stdout," ex.:\n");
\r
288 fprintf(stdout," h,s,p\n");
\r
289 fprintf(stdout," means\n");
\r
290 fprintf(stdout," default protection to headers (MH and TPHs) as well as\n");
\r
291 fprintf(stdout," data packets, one ESD in MH\n");
\r
292 fprintf(stdout,"\n");
\r
293 fprintf(stdout," N.B.: use the following recommendations when specifying\n");
\r
294 fprintf(stdout," the JPWL parameters list\n");
\r
295 fprintf(stdout," - when you use UEP, always pair the 'p' option with 'h'\n");
\r
296 fprintf(stdout," \n");
\r
297 #endif /* USE_JPWL */
\r
299 fprintf(stdout,"IMPORTANT:\n");
\r
300 fprintf(stdout,"-----------\n");
\r
301 fprintf(stdout,"\n");
\r
302 fprintf(stdout,"The index file has the structure below:\n");
\r
303 fprintf(stdout,"---------------------------------------\n");
\r
304 fprintf(stdout,"\n");
\r
305 fprintf(stdout,"Image_height Image_width\n");
\r
306 fprintf(stdout,"progression order\n");
\r
307 fprintf(stdout,"Tiles_size_X Tiles_size_Y\n");
\r
308 fprintf(stdout,"Tiles_nb_X Tiles_nb_Y\n");
\r
309 fprintf(stdout,"Components_nb\n");
\r
310 fprintf(stdout,"Layers_nb\n");
\r
311 fprintf(stdout,"decomposition_levels\n");
\r
312 fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");
\r
313 fprintf(stdout," [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");
\r
314 fprintf(stdout,"Main_header_start_position\n");
\r
315 fprintf(stdout,"Main_header_end_position\n");
\r
316 fprintf(stdout,"Codestream_size\n");
\r
317 fprintf(stdout,"\n");
\r
318 fprintf(stdout,"INFO ON TILES\n");
\r
319 fprintf(stdout,"tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n");
\r
320 fprintf(stdout,"Tile_0 start_pos end_Theader end_pos NumParts TotalDisto NumPix MaxMSE\n");
\r
321 fprintf(stdout,"Tile_1 '' '' '' '' '' '' ''\n");
\r
322 fprintf(stdout,"...\n");
\r
323 fprintf(stdout,"Tile_Nt '' '' '' '' '' '' ''\n");
\r
324 fprintf(stdout,"...\n");
\r
325 fprintf(stdout,"TILE 0 DETAILS\n");
\r
326 fprintf(stdout,"part_nb tileno num_packs start_pos end_tph_pos end_pos\n");
\r
327 fprintf(stdout,"...\n");
\r
328 fprintf(stdout,"Progression_string\n");
\r
329 fprintf(stdout,"pack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n");
\r
330 fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");
\r
331 fprintf(stdout,"...\n");
\r
332 fprintf(stdout,"Tpacket_Np '' '' '' '' '' '' '' ''\n");
\r
334 fprintf(stdout,"MaxDisto\n");
\r
336 fprintf(stdout,"TotalDisto\n\n");
\r
340 OPJ_PROG_ORDER give_progression(char progression[4]) {
\r
341 if(strncmp(progression, "LRCP", 4) == 0) {
\r
344 if(strncmp(progression, "RLCP", 4) == 0) {
\r
347 if(strncmp(progression, "RPCL", 4) == 0) {
\r
350 if(strncmp(progression, "PCRL", 4) == 0) {
\r
353 if(strncmp(progression, "CPRL", 4) == 0) {
\r
357 return PROG_UNKNOWN;
\r
362 /// Get logarithm of an integer and round downwards.
\r
364 int int_floorlog2(int a) {
\r
366 for (l=0; a>1; l++) {
\r
372 static int initialise_4K_poc(opj_poc_t *POC, int numres){
\r
374 POC[0].resno0 = 0;
\r
375 POC[0].compno0 = 0;
\r
377 POC[0].resno1 = numres-1;
\r
378 POC[0].compno1 = 3;
\r
379 POC[0].prg1 = CPRL;
\r
381 POC[1].resno0 = numres-1;
\r
382 POC[1].compno0 = 0;
\r
384 POC[1].resno1 = numres;
\r
385 POC[1].compno1 = 3;
\r
386 POC[1].prg1 = CPRL;
\r
390 void cinema_parameters(opj_cparameters_t *parameters){
\r
391 parameters->tile_size_on = false;
\r
392 parameters->cp_tdx=1;
\r
393 parameters->cp_tdy=1;
\r
396 parameters->tp_flag = 'C';
\r
397 parameters->tp_on = 1;
\r
399 /*Tile and Image shall be at (0,0)*/
\r
400 parameters->cp_tx0 = 0;
\r
401 parameters->cp_ty0 = 0;
\r
402 parameters->image_offset_x0 = 0;
\r
403 parameters->image_offset_y0 = 0;
\r
405 /*Codeblock size= 32*32*/
\r
406 parameters->cblockw_init = 32;
\r
407 parameters->cblockh_init = 32;
\r
408 parameters->csty |= 0x01;
\r
410 /*The progression order shall be CPRL*/
\r
411 parameters->prog_order = CPRL;
\r
414 parameters->roi_compno = -1;
\r
416 parameters->subsampling_dx = 1; parameters->subsampling_dy = 1;
\r
418 /* 9-7 transform */
\r
419 parameters->irreversible = 1;
\r
423 void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){
\r
426 opj_poc_t *POC = NULL;
\r
428 switch (parameters->cp_cinema){
\r
431 if(parameters->numresolution > 6){
\r
432 parameters->numresolution = 6;
\r
434 if (!((image->comps[0].w == 2048) | (image->comps[0].h == 1080))){
\r
435 fprintf(stdout,"Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3"
\r
436 "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
\r
437 image->comps[0].w,image->comps[0].h);
\r
438 parameters->cp_rsiz = STD_RSIZ;
\r
443 if(parameters->numresolution < 1){
\r
444 parameters->numresolution = 1;
\r
445 }else if(parameters->numresolution > 7){
\r
446 parameters->numresolution = 7;
\r
448 if (!((image->comps[0].w == 4096) | (image->comps[0].h == 2160))){
\r
449 fprintf(stdout,"Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4"
\r
450 "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
\r
451 image->comps[0].w,image->comps[0].h);
\r
452 parameters->cp_rsiz = STD_RSIZ;
\r
454 parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution);
\r
458 switch (parameters->cp_cinema){
\r
461 for(i=0 ; i<parameters->tcp_numlayers ; i++){
\r
463 if (img_fol->rates[i]== 0){
\r
464 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
465 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
467 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
468 (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
\r
469 if (temp_rate > CINEMA_24_CS ){
\r
470 parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
471 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
473 parameters->tcp_rates[i]= img_fol->rates[i];
\r
477 parameters->max_comp_size = COMP_24_CS;
\r
481 for(i=0 ; i<parameters->tcp_numlayers ; i++){
\r
483 if (img_fol->rates[i]== 0){
\r
484 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
485 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
487 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
488 (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
\r
489 if (temp_rate > CINEMA_48_CS ){
\r
490 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
491 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
493 parameters->tcp_rates[i]= img_fol->rates[i];
\r
497 parameters->max_comp_size = COMP_48_CS;
\r
500 parameters->cp_disto_alloc = 1;
\r
504 /* ------------------------------------------------------------------------------------ */
\r
505 int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
\r
506 img_fol_t *img_fol, char *indexfilename) {
\r
508 option_t long_option[]={
\r
509 {"cinema2K",REQ_ARG, NULL ,'w'},
\r
510 {"cinema4K",NO_ARG, NULL ,'y'},
\r
511 {"ImgDir",REQ_ARG, NULL ,'z'},
\r
512 {"TP",REQ_ARG, NULL ,'v'},
\r
513 {"SOP",NO_ARG, NULL ,'S'},
\r
514 {"EPH",NO_ARG, NULL ,'E'},
\r
515 {"OutFor",REQ_ARG, NULL ,'O'},
\r
516 {"POC",REQ_ARG, NULL ,'P'},
\r
517 {"ROI",REQ_ARG, NULL ,'R'},
\r
520 /* parse the command line */
\r
522 const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:"
\r
525 #endif /* USE_JPWL */
\r
528 /*printf("C: parse_cmdline_encoder:");
\r
529 for (i=0; i<argc; i++) {
\r
530 printf("[%s]",argv[i]);
\r
534 totlen=sizeof(long_option);
\r
535 img_fol->set_out_format=0;
\r
536 reset_options_reading();
\r
539 int c = getopt_long(argc, argv, optlist,long_option,totlen);
\r
544 /* ----------------------------------------------------- */
\r
546 case 'o': /* output file */
\r
548 char *outfile = optarg;
\r
549 parameters->cod_format = get_file_format(outfile);
\r
550 switch(parameters->cod_format) {
\r
555 fprintf(stderr, "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile);
\r
558 strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);
\r
562 /* ----------------------------------------------------- */
\r
563 case 'O': /* output format */
\r
565 char outformat[50];
\r
567 sprintf(outformat,".%s",of);
\r
568 img_fol->set_out_format = 1;
\r
569 parameters->cod_format = get_file_format(outformat);
\r
570 switch(parameters->cod_format) {
\r
573 img_fol->out_format = optarg;
\r
576 fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n");
\r
583 /* ----------------------------------------------------- */
\r
586 case 'r': /* rates rates/distorsion */
\r
589 while (sscanf(s, "%f", ¶meters->tcp_rates[parameters->tcp_numlayers]) == 1) {
\r
590 parameters->tcp_numlayers++;
\r
591 while (*s && *s != ',') {
\r
598 parameters->cp_disto_alloc = 1;
\r
602 /* ----------------------------------------------------- */
\r
604 case 'q': /* add fixed_quality */
\r
607 while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers]) == 1) {
\r
608 parameters->tcp_numlayers++;
\r
609 while (*s && *s != ',') {
\r
616 parameters->cp_fixed_quality = 1;
\r
621 /* ----------------------------------------------------- */
\r
623 case 'f': /* mod fixed_quality (before : -q) */
\r
625 int *row = NULL, *col = NULL;
\r
626 int numlayers = 0, numresolution = 0, matrix_width = 0;
\r
629 sscanf(s, "%d", &numlayers);
\r
634 parameters->tcp_numlayers = numlayers;
\r
635 numresolution = parameters->numresolution;
\r
636 matrix_width = numresolution * 3;
\r
637 parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int));
\r
640 for (i = 0; i < numlayers; i++) {
\r
641 row = ¶meters->cp_matrice[i * matrix_width];
\r
643 parameters->tcp_rates[i] = 1;
\r
644 sscanf(s, "%d,", &col[0]);
\r
650 for (j = 1; j < numresolution; j++) {
\r
652 sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);
\r
661 if (i < numlayers - 1)
\r
664 parameters->cp_fixed_alloc = 1;
\r
668 /* ----------------------------------------------------- */
\r
670 case 't': /* tiles */
\r
672 sscanf(optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy);
\r
673 parameters->tile_size_on = true;
\r
677 /* ----------------------------------------------------- */
\r
679 case 'n': /* resolution */
\r
681 sscanf(optarg, "%d", ¶meters->numresolution);
\r
685 /* ----------------------------------------------------- */
\r
686 case 'c': /* precinct dimension */
\r
694 sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec],
\r
695 ¶meters->prch_init[res_spec], &sep);
\r
696 parameters->csty |= 0x01;
\r
698 s = strpbrk(s, "]") + 2;
\r
700 while (sep == ',');
\r
701 parameters->res_spec = res_spec;
\r
705 /* ----------------------------------------------------- */
\r
707 case 'b': /* code-block dimension */
\r
709 int cblockw_init = 0, cblockh_init = 0;
\r
710 sscanf(optarg, "%d,%d", &cblockw_init, &cblockh_init);
\r
711 if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
\r
712 || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
\r
714 "!! Size of code_block error (option -b) !!\n\nRestriction :\n"
\r
715 " * width*height<=4096\n * 4<=width,height<= 1024\n\n");
\r
718 parameters->cblockw_init = cblockw_init;
\r
719 parameters->cblockh_init = cblockh_init;
\r
723 /* ----------------------------------------------------- */
\r
725 case 'x': /* creation of index file */
\r
727 char *index = optarg;
\r
728 strncpy(indexfilename, index, OPJ_PATH_LEN);
\r
732 /* ----------------------------------------------------- */
\r
734 case 'p': /* progression order */
\r
736 char progression[4];
\r
738 strncpy(progression, optarg, 4);
\r
739 parameters->prog_order = give_progression(progression);
\r
740 if (parameters->prog_order == -1) {
\r
741 fprintf(stderr, "Unrecognized progression order "
\r
742 "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
\r
748 /* ----------------------------------------------------- */
\r
750 case 's': /* subsampling factor */
\r
752 if (sscanf(optarg, "%d,%d", ¶meters->subsampling_dx,
\r
753 ¶meters->subsampling_dy) != 2) {
\r
754 fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n");
\r
760 /* ----------------------------------------------------- */
\r
762 case 'd': /* coordonnate of the reference grid */
\r
764 if (sscanf(optarg, "%d,%d", ¶meters->image_offset_x0,
\r
765 ¶meters->image_offset_y0) != 2) {
\r
766 fprintf(stderr, "-d 'coordonnate of the reference grid' argument "
\r
767 "error !! [-d x0,y0]\n");
\r
773 /* ----------------------------------------------------- */
\r
775 case 'h': /* display an help description */
\r
776 encode_help_display();
\r
779 /* ----------------------------------------------------- */
\r
781 case 'P': /* POC */
\r
783 int numpocs = 0; /* number of progression order change (POC) default 0 */
\r
784 opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */
\r
787 POC = parameters->POC;
\r
789 while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,
\r
790 &POC[numpocs].resno0, &POC[numpocs].compno0,
\r
791 &POC[numpocs].layno1, &POC[numpocs].resno1,
\r
792 &POC[numpocs].compno1, &POC[numpocs].progorder) == 7) {
\r
793 POC[numpocs].prg1 = give_progression(POC[numpocs].progorder);
\r
795 while (*s && *s != '/') {
\r
803 parameters->numpocs = numpocs;
\r
807 /* ------------------------------------------------------ */
\r
809 case 'S': /* SOP marker */
\r
811 parameters->csty |= 0x02;
\r
815 /* ------------------------------------------------------ */
\r
817 case 'E': /* EPH marker */
\r
819 parameters->csty |= 0x04;
\r
823 /* ------------------------------------------------------ */
\r
825 case 'M': /* Mode switch pas tous au point !! */
\r
828 if (sscanf(optarg, "%d", &value) == 1) {
\r
829 for (i = 0; i <= 5; i++) {
\r
830 int cache = value & (1 << i);
\r
832 parameters->mode |= (1 << i);
\r
838 /* ------------------------------------------------------ */
\r
840 case 'R': /* ROI */
\r
842 if (sscanf(optarg, "c=%d,U=%d", ¶meters->roi_compno,
\r
843 ¶meters->roi_shift) != 2) {
\r
844 fprintf(stderr, "ROI error !! [-ROI c='compno',U='shift']\n");
\r
850 /* ------------------------------------------------------ */
\r
852 case 'T': /* Tile offset */
\r
854 if (sscanf(optarg, "%d,%d", ¶meters->cp_tx0, ¶meters->cp_ty0) != 2) {
\r
855 fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");
\r
861 /* ------------------------------------------------------ */
\r
863 case 'C': /* add a comment */
\r
865 parameters->cp_comment = (char*)malloc(strlen(optarg) + 1);
\r
866 if(parameters->cp_comment) {
\r
867 strcpy(parameters->cp_comment, optarg);
\r
873 /* ------------------------------------------------------ */
\r
875 case 'I': /* reversible or not */
\r
877 parameters->irreversible = 1;
\r
881 /* ------------------------------------------------------ */
\r
883 case 'v': /* Tile part generation*/
\r
885 parameters->tp_flag = optarg[0];
\r
886 parameters->tp_on = 1;
\r
890 /* ------------------------------------------------------ */
\r
892 case 'z': /* Image Directory path */
\r
894 img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1);
\r
895 strcpy(img_fol->imgdirpath,optarg);
\r
896 img_fol->set_imgdir=1;
\r
900 /* ------------------------------------------------------ */
\r
902 case 'w': /* Digital Cinema 2K profile compliance*/
\r
905 sscanf(optarg,"%d",&fps);
\r
907 parameters->cp_cinema = CINEMA2K_24;
\r
908 }else if(fps == 48 ){
\r
909 parameters->cp_cinema = CINEMA2K_48;
\r
911 fprintf(stderr,"Incorrect value!! must be 24 or 48\n");
\r
914 fprintf(stdout,"CINEMA 2K compliant codestream\n");
\r
915 parameters->cp_rsiz = CINEMA2K;
\r
920 /* ------------------------------------------------------ */
\r
922 case 'y': /* Digital Cinema 4K profile compliance*/
\r
924 parameters->cp_cinema = CINEMA4K_24;
\r
925 fprintf(stdout,"CINEMA 4K compliant codestream\n");
\r
926 parameters->cp_rsiz = CINEMA4K;
\r
930 /* ------------------------------------------------------ */
\r
934 /* ------------------------------------------------------ */
\r
936 case 'W': /* JPWL capabilities switched on */
\r
938 char *token = NULL;
\r
939 int hprot, pprot, sens, addr, size, range;
\r
941 /* we need to enable indexing */
\r
942 if (!indexfilename) {
\r
943 strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN);
\r
946 /* search for different protection methods */
\r
948 /* break the option in comma points and parse the result */
\r
949 token = strtok(optarg, ",");
\r
950 while(token != NULL) {
\r
952 /* search header error protection method */
\r
953 if (*token == 'h') {
\r
955 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
957 hprot = 1; /* predefined method */
\r
959 if(sscanf(token, "h=%d", &hprot) == 1) {
\r
960 /* Main header, specified */
\r
961 if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
\r
962 ((hprot >= 37) && (hprot <= 128)))) {
\r
963 fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n", hprot);
\r
966 parameters->jpwl_hprot_MH = hprot;
\r
968 } else if(sscanf(token, "h%d=%d", &tile, &hprot) == 2) {
\r
969 /* Tile part header, specified */
\r
970 if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
\r
971 ((hprot >= 37) && (hprot <= 128)))) {
\r
972 fprintf(stderr, "ERROR -> invalid tile part header protection method h = %d\n", hprot);
\r
976 fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);
\r
979 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
980 parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
\r
981 parameters->jpwl_hprot_TPH[tilespec++] = hprot;
\r
984 } else if(sscanf(token, "h%d", &tile) == 1) {
\r
985 /* Tile part header, unspecified */
\r
987 fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);
\r
990 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
991 parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
\r
992 parameters->jpwl_hprot_TPH[tilespec++] = hprot;
\r
996 } else if (!strcmp(token, "h")) {
\r
997 /* Main header, unspecified */
\r
998 parameters->jpwl_hprot_MH = hprot;
\r
1001 fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
\r
1007 /* search packet error protection method */
\r
1008 if (*token == 'p') {
\r
1010 static int pack = 0, tile = 0, packspec = 0, lastpackno = 0;
\r
1012 pprot = 1; /* predefined method */
\r
1014 if (sscanf(token, "p=%d", &pprot) == 1) {
\r
1015 /* Method for all tiles and all packets */
\r
1016 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1017 ((pprot >= 37) && (pprot <= 128)))) {
\r
1018 fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n", pprot);
\r
1021 parameters->jpwl_pprot_tileno[0] = 0;
\r
1022 parameters->jpwl_pprot_packno[0] = 0;
\r
1023 parameters->jpwl_pprot[0] = pprot;
\r
1025 } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) {
\r
1026 /* method specified from that tile on */
\r
1027 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1028 ((pprot >= 37) && (pprot <= 128)))) {
\r
1029 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1033 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1036 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1037 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1038 parameters->jpwl_pprot_packno[packspec] = 0;
\r
1039 parameters->jpwl_pprot[packspec++] = pprot;
\r
1042 } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) {
\r
1043 /* method fully specified from that tile and that packet on */
\r
1044 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1045 ((pprot >= 37) && (pprot <= 128)))) {
\r
1046 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1050 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1054 fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);
\r
1057 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1058 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1059 parameters->jpwl_pprot_packno[packspec] = pack;
\r
1060 parameters->jpwl_pprot[packspec++] = pprot;
\r
1063 } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) {
\r
1064 /* default method from that tile and that packet on */
\r
1065 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1066 ((pprot >= 37) && (pprot <= 128)))) {
\r
1067 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1071 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1075 fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);
\r
1078 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1079 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1080 parameters->jpwl_pprot_packno[packspec] = pack;
\r
1081 parameters->jpwl_pprot[packspec++] = pprot;
\r
1084 } else if (sscanf(token, "p%d", &tile) == 1) {
\r
1085 /* default from a tile on */
\r
1087 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1090 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1091 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1092 parameters->jpwl_pprot_packno[packspec] = 0;
\r
1093 parameters->jpwl_pprot[packspec++] = pprot;
\r
1097 } else if (!strcmp(token, "p")) {
\r
1099 parameters->jpwl_pprot_tileno[0] = 0;
\r
1100 parameters->jpwl_pprot_packno[0] = 0;
\r
1101 parameters->jpwl_pprot[0] = pprot;
\r
1104 fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
\r
1110 /* search sensitivity method */
\r
1111 if (*token == 's') {
\r
1113 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1115 sens = 0; /* predefined: relative error */
\r
1117 if(sscanf(token, "s=%d", &sens) == 1) {
\r
1118 /* Main header, specified */
\r
1119 if ((sens < -1) || (sens > 7)) {
\r
1120 fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n", sens);
\r
1123 parameters->jpwl_sens_MH = sens;
\r
1125 } else if(sscanf(token, "s%d=%d", &tile, &sens) == 2) {
\r
1126 /* Tile part header, specified */
\r
1127 if ((sens < -1) || (sens > 7)) {
\r
1128 fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n", sens);
\r
1132 fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
\r
1135 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
1136 parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
\r
1137 parameters->jpwl_sens_TPH[tilespec++] = sens;
\r
1140 } else if(sscanf(token, "s%d", &tile) == 1) {
\r
1141 /* Tile part header, unspecified */
\r
1143 fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
\r
1146 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
1147 parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
\r
1148 parameters->jpwl_sens_TPH[tilespec++] = hprot;
\r
1151 } else if (!strcmp(token, "s")) {
\r
1152 /* Main header, unspecified */
\r
1153 parameters->jpwl_sens_MH = sens;
\r
1156 fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token);
\r
1160 parameters->jpwl_sens_size = 2; /* 2 bytes for default size */
\r
1163 /* search addressing size */
\r
1164 if (*token == 'a') {
\r
1166 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1168 addr = 0; /* predefined: auto */
\r
1170 if(sscanf(token, "a=%d", &addr) == 1) {
\r
1172 if ((addr != 0) && (addr != 2) && (addr != 4)) {
\r
1173 fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr);
\r
1176 parameters->jpwl_sens_addr = addr;
\r
1178 } else if (!strcmp(token, "a")) {
\r
1180 parameters->jpwl_sens_addr = addr; /* auto for default size */
\r
1183 fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token);
\r
1189 /* search sensitivity size */
\r
1190 if (*token == 'z') {
\r
1192 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1194 size = 1; /* predefined: 1 byte */
\r
1196 if(sscanf(token, "z=%d", &size) == 1) {
\r
1198 if ((size != 0) && (size != 1) && (size != 2)) {
\r
1199 fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size);
\r
1202 parameters->jpwl_sens_size = size;
\r
1204 } else if (!strcmp(token, "a")) {
\r
1206 parameters->jpwl_sens_size = size; /* 1 for default size */
\r
1209 fprintf(stderr, "ERROR -> invalid size selection = %s\n", token);
\r
1215 /* search range method */
\r
1216 if (*token == 'g') {
\r
1218 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1220 range = 0; /* predefined: 0 (packet) */
\r
1222 if(sscanf(token, "g=%d", &range) == 1) {
\r
1224 if ((range < 0) || (range > 3)) {
\r
1225 fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range);
\r
1228 parameters->jpwl_sens_range = range;
\r
1230 } else if (!strcmp(token, "g")) {
\r
1232 parameters->jpwl_sens_range = range;
\r
1235 fprintf(stderr, "ERROR -> invalid range selection = %s\n", token);
\r
1241 /* next token or bust */
\r
1242 token = strtok(NULL, ",");
\r
1247 fprintf(stdout, "Info: JPWL capabilities enabled\n");
\r
1248 parameters->jpwl_epc_on = true;
\r
1252 #endif /* USE_JPWL */
\r
1255 /* ------------------------------------------------------ */
\r
1258 fprintf(stderr, "ERROR -> Command line not valid\n");
\r
1263 /* check for possible errors */
\r
1264 if (parameters->cp_cinema){
\r
1265 if(parameters->tcp_numlayers > 1){
\r
1266 parameters->cp_rsiz = STD_RSIZ;
\r
1267 fprintf(stdout,"Warning: DC profiles do not allow more than one quality layer. The codestream created will not be compliant with the DC profile\n");
\r
1271 if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality)
\r
1272 && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ parameters->cp_fixed_quality))) {
\r
1273 fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");
\r
1275 } /* mod fixed_quality */
\r
1277 /* if no rate entered, lossless by default */
\r
1278 if (parameters->tcp_numlayers == 0) {
\r
1279 parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */
\r
1280 parameters->tcp_numlayers++;
\r
1281 parameters->cp_disto_alloc = 1;
\r
1284 if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) {
\r
1286 "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
\r
1287 parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0);
\r
1291 for (i = 0; i < parameters->numpocs; i++) {
\r
1292 if (parameters->POC[i].prg == -1) {
\r
1294 "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
\r
1303 /** Create the same index as j2k_create_index does, but in an int[] instead of in a file ==> easy to pass it back to Java, to transfer it etc.
\r
1304 @param buffer_size, increased by the length of the compressed index, in number of bytes
\r
1305 @return a pointer to a char[]
\r
1306 Syntax of the index:
\r
1307 one char for the version number (1): one byte because no problem with little endian, big endian etc.
\r
1308 one int for each of the following informations:
\r
1311 progression order
\r
1318 Nb of resolutions
\r
1320 for each resolution:
\r
1324 End main header position
\r
1329 tile start pos in codestream
\r
1330 tile header end position
\r
1331 tile end position in codestream
\r
1333 For each LRCP, RLCP etc.:
\r
1340 start position in the codestream
\r
1341 end position of this packet
\r
1343 char* create_index_into_byte_array(opj_codestream_info_t *cstr_info, int* buffer_size) {
\r
1344 int tileno, compno, layno, resno, precno, pack_nb, x, y;
\r
1345 char* buffer = NULL;
\r
1346 int buffer_pos = 0;
\r
1350 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1351 for (resno = 0; resno < cstr_info->numdecompos[0] + 1; resno++) {
\r
1352 prec_max = max(prec_max,cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]);
\r
1356 // Compute the size of the index buffer, in number of bytes*/
\r
1359 + (10 /* image_w until decomposition */
\r
1360 + (cstr_info->numdecompos[0]+1) * 2 /* pdx size for each tile */
\r
1361 + 2 /* main_head_end + codestream_size */
\r
1362 + cstr_info->tw * cstr_info->th * 4 /* tile info, without distorsion info */
\r
1363 + cstr_info->tw*cstr_info->th * cstr_info->numlayers * (cstr_info->numdecompos[0] + 1) * cstr_info->numcomps * prec_max *8
\r
1365 //printf("C: index buffer size = %d bytes\n", *buffer_size);
\r
1366 buffer = (char*) malloc(*buffer_size);
\r
1369 //opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to allocate index buffer for writing %d int\n", *buffer_size);
\r
1370 fprintf(stderr, "failed to allocate index buffer for writing %d int\n", *buffer_size);
\r
1374 buffer[0] = 1; // Version stored on a byte
\r
1376 // Remaining informations are stored on a int.
\r
1377 ((int*)buffer)[buffer_pos++] = cstr_info->image_w;
\r
1378 ((int*)buffer)[buffer_pos++] = cstr_info->image_h;
\r
1379 ((int*)buffer)[buffer_pos++] = cstr_info->prog;
\r
1380 ((int*)buffer)[buffer_pos++] = cstr_info->tile_x;
\r
1381 ((int*)buffer)[buffer_pos++] = cstr_info->tile_y;
\r
1382 ((int*)buffer)[buffer_pos++] = cstr_info->tw;
\r
1383 ((int*)buffer)[buffer_pos++] = cstr_info->th;
\r
1384 ((int*)buffer)[buffer_pos++] = cstr_info->numcomps;
\r
1385 ((int*)buffer)[buffer_pos++] = cstr_info->numlayers;
\r
1386 ((int*)buffer)[buffer_pos++] = cstr_info->numdecompos[0];
\r
1388 for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
\r
1389 /* based on tile 0 */
\r
1390 ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
\r
1391 ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
\r
1393 ((int*)buffer)[buffer_pos++] = cstr_info->main_head_end;
\r
1394 ((int*)buffer)[buffer_pos++] = cstr_info->codestream_size;
\r
1396 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1397 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].tileno;
\r
1398 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].start_pos;
\r
1399 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_header;
\r
1400 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_pos;
\r
1403 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1404 int start_pos, end_pos;
\r
1405 int max_numdecompos = 0;
\r
1408 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1409 if (max_numdecompos < cstr_info->numdecompos[compno])
\r
1410 max_numdecompos = cstr_info->numdecompos[compno];
\r
1413 if (cstr_info->prog == LRCP) { /* LRCP */
\r
1415 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1416 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1417 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1419 if (resno > cstr_info->numdecompos[compno])
\r
1421 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1422 for (precno = 0; precno < prec_max; precno++) {
\r
1423 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1424 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1425 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1426 ((int*)buffer)[buffer_pos++] = tileno;
\r
1427 ((int*)buffer)[buffer_pos++] = layno;
\r
1428 ((int*)buffer)[buffer_pos++] = resno;
\r
1429 ((int*)buffer)[buffer_pos++] = compno;
\r
1430 ((int*)buffer)[buffer_pos++] = precno;
\r
1431 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1432 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1439 else if (cstr_info->prog == RLCP) { /* RLCP */
\r
1441 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1442 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1443 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1445 if (resno > cstr_info->numdecompos[compno])
\r
1447 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1448 for (precno = 0; precno < prec_max; precno++) {
\r
1449 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1450 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1451 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1452 ((int*)buffer)[buffer_pos++] = tileno;
\r
1453 ((int*)buffer)[buffer_pos++] = resno;
\r
1454 ((int*)buffer)[buffer_pos++] = layno;
\r
1455 ((int*)buffer)[buffer_pos++] = compno;
\r
1456 ((int*)buffer)[buffer_pos++] = precno;
\r
1457 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1458 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1465 else if (cstr_info->prog == RPCL) { /* RPCL */
\r
1467 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1468 /* I suppose components have same XRsiz, YRsiz */
\r
1469 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1470 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1471 int x1 = x0 + cstr_info->tile_x;
\r
1472 int y1 = y0 + cstr_info->tile_y;
\r
1473 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1475 if (resno > cstr_info->numdecompos[compno])
\r
1477 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1478 for (precno = 0; precno < prec_max; precno++) {
\r
1479 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1480 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1481 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1482 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1483 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1484 for(y = y0; y < y1; y++) {
\r
1485 if (precno_y*pcy == y ) {
\r
1486 for (x = x0; x < x1; x++) {
\r
1487 if (precno_x*pcx == x ) {
\r
1488 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1489 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1490 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1491 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1492 ((int*)buffer)[buffer_pos++] = tileno;
\r
1493 ((int*)buffer)[buffer_pos++] = resno;
\r
1494 ((int*)buffer)[buffer_pos++] = precno;
\r
1495 ((int*)buffer)[buffer_pos++] = compno;
\r
1496 ((int*)buffer)[buffer_pos++] = layno;
\r
1497 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1498 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1504 } /* y = y0..y1 */
\r
1509 else if (cstr_info->prog == PCRL) { /* PCRL */
\r
1510 /* I suppose components have same XRsiz, YRsiz */
\r
1511 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1512 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1513 int x1 = x0 + cstr_info->tile_x;
\r
1514 int y1 = y0 + cstr_info->tile_y;
\r
1516 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1517 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1519 if (resno > cstr_info->numdecompos[compno])
\r
1521 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1522 for (precno = 0; precno < prec_max; precno++) {
\r
1523 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1524 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1525 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1526 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1527 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1528 for(y = y0; y < y1; y++) {
\r
1529 if (precno_y*pcy == y ) {
\r
1530 for (x = x0; x < x1; x++) {
\r
1531 if (precno_x*pcx == x ) {
\r
1532 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1533 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1534 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1535 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1536 ((int*)buffer)[buffer_pos++] = tileno;
\r
1537 ((int*)buffer)[buffer_pos++] = precno;
\r
1538 ((int*)buffer)[buffer_pos++] = compno;
\r
1539 ((int*)buffer)[buffer_pos++] = resno;
\r
1540 ((int*)buffer)[buffer_pos++] = layno;
\r
1541 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1542 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1548 } /* y = y0..y1 */
\r
1555 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1556 /* I suppose components have same XRsiz, YRsiz */
\r
1557 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1558 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1559 int x1 = x0 + cstr_info->tile_x;
\r
1560 int y1 = y0 + cstr_info->tile_y;
\r
1562 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1564 if (resno > cstr_info->numdecompos[compno])
\r
1566 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1567 for (precno = 0; precno < prec_max; precno++) {
\r
1568 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1569 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1570 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1571 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1572 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1573 for(y = y0; y < y1; y++) {
\r
1574 if (precno_y*pcy == y ) {
\r
1575 for (x = x0; x < x1; x++) {
\r
1576 if (precno_x*pcx == x ) {
\r
1577 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1578 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1579 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1580 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1581 ((int*)buffer)[buffer_pos++] = tileno;
\r
1582 ((int*)buffer)[buffer_pos++] = compno;
\r
1583 ((int*)buffer)[buffer_pos++] = precno;
\r
1584 ((int*)buffer)[buffer_pos++] = resno;
\r
1585 ((int*)buffer)[buffer_pos++] = layno;
\r
1586 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1587 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1593 } /* y = y0..y1 */
\r
1600 if (buffer_pos > *buffer_size) {
\r
1601 //opj_event_msg(j2k->cinfo, EVT_ERROR, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);
\r
1602 fprintf(stderr, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);
\r
1612 /* --------------------------------------------------------------------------
\r
1613 ------------ Get the image byte[] from the Java object -------------------*/
\r
1615 opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env, jobject obj, jclass cls) {
\r
1616 int i,max,shift,w,h,depth;
\r
1617 opj_image_t * img = NULL;
\r
1618 int compno, numcomps;
\r
1619 opj_image_t * image = NULL;
\r
1620 opj_image_comp_t *comp;
\r
1621 opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
\r
1622 OPJ_COLOR_SPACE color_space;
\r
1634 // Image width, height and depth
\r
1635 fid = (*env)->GetFieldID(env, cls,"width", "I");
\r
1636 ji = (*env)->GetIntField(env, obj, fid);
\r
1639 fid = (*env)->GetFieldID(env, cls,"height", "I");
\r
1640 ji = (*env)->GetIntField(env, obj, fid);
\r
1643 fid = (*env)->GetFieldID(env, cls,"depth", "I");
\r
1644 ji = (*env)->GetIntField(env, obj, fid);
\r
1650 color_space = CLRSPC_GRAY;
\r
1653 color_space = CLRSPC_SRGB;
\r
1655 memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
\r
1657 if (numcomps == 1) {
\r
1658 cmptparm[0].x0 = parameters->image_offset_x0;
\r
1659 cmptparm[0].y0 = parameters->image_offset_y0;
\r
1660 cmptparm[0].w = !cmptparm[0].x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm[0].x0 + (w - 1) * parameters->subsampling_dx + 1;
\r
1661 cmptparm[0].h = !cmptparm[0].y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm[0].y0 + (h - 1) * parameters->subsampling_dy + 1;
\r
1662 // Java types are always signed but we use them as unsigned types (shift of the negative part of
\r
1663 // the pixels of the images in Telemis before entering the encoder).
\r
1664 cmptparm[0].sgnd = 0;
\r
1666 cmptparm[0].prec=depth;
\r
1668 cmptparm[0].prec = 8;
\r
1669 cmptparm[0].bpp = cmptparm[0].prec;
\r
1670 cmptparm[0].dx = parameters->subsampling_dx;
\r
1671 cmptparm[0].dy = parameters->subsampling_dy;
\r
1672 /*printf("C: component 0 initialised: x0=%d, y0=%d, w=%d, h=%d, sgnd=%d, bpp=%d, dx=%d, dy=%d, color_space=%d\n", cmptparm[0].x0, cmptparm[0].y0, cmptparm[0].w,
\r
1673 cmptparm[0].h, cmptparm[0].sgnd, cmptparm[0].bpp, cmptparm[0].dx, cmptparm[0].dy, color_space);*/
\r
1675 for(i = 0; i < numcomps; i++) {
\r
1676 cmptparm[i].prec = 8;
\r
1677 cmptparm[i].bpp = 8;
\r
1678 cmptparm[i].sgnd = 0;
\r
1679 cmptparm[i].dx = parameters->subsampling_dx;
\r
1680 cmptparm[i].dy = parameters->subsampling_dy;
\r
1681 cmptparm[i].w = w;
\r
1682 cmptparm[i].h = h;
\r
1686 /* create the image */
\r
1687 image = opj_image_create(numcomps, &cmptparm[0], color_space);
\r
1693 image->numcomps=1;
\r
1695 image->numcomps = 3;
\r
1698 /* set image offset and reference grid */
\r
1699 image->x0 = cmptparm[0].x0;
\r
1700 image->y0 = cmptparm[0].x0;
\r
1701 image->x1 = cmptparm[0].w;
\r
1702 image->y1 = cmptparm[0].h;
\r
1704 /* set image data */
\r
1705 for (compno=0; compno<numcomps; compno++) {
\r
1706 comp = &image->comps[compno];
\r
1709 fid = (*env)->GetFieldID(env, cls,"image8", "[B"); // byteArray []
\r
1710 jba = (*env)->GetObjectField(env, obj, fid);
\r
1711 len = (*env)->GetArrayLength(env, jba);
\r
1713 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, &isCopy);
\r
1714 //printf("C: before transfering 8 bpp image\n");
\r
1716 for(i=0; i< len;i++) {
\r
1717 comp->data[i] = (char) jbBody[i];
\r
1718 if (comp->data[i] > max) max = comp->data[i];
\r
1721 for(i=0; i< len;i++) {
\r
1722 comp->data[i] = (unsigned char) jbBody[i];
\r
1723 if (comp->data[i] > max) max = comp->data[i];
\r
1726 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1727 } else if(depth == 16) {
\r
1728 fid = (*env)->GetFieldID(env, cls,"image16", "[S"); // shortArray []
\r
1729 jsa = (*env)->GetObjectField(env, obj, fid);
\r
1730 len = (*env)->GetArrayLength(env, jsa);
\r
1732 jsBody = (*env)->GetPrimitiveArrayCritical(env, jsa, &isCopy);
\r
1733 //printf("C: before transfering 16 bpp image\n");
\r
1734 if (comp->sgnd) { // Special behaviour to deal with signed elements ??
\r
1735 comp->data[i] = (short) jsBody[i];
\r
1736 for(i=0; i< len;i++) {
\r
1737 if (comp->data[i] > max) max = comp->data[i];
\r
1740 for(i=0; i< len;i++) {
\r
1741 comp->data[i] = (unsigned short) jsBody[i];
\r
1742 if (comp->data[i] > max) max = comp->data[i];
\r
1745 (*env)->ReleasePrimitiveArrayCritical(env, jsa, jsBody, 0);
\r
1746 } else if (depth == 24) {
\r
1747 fid = (*env)->GetFieldID(env, cls,"image24", "[I"); // intArray []
\r
1748 jia = (*env)->GetObjectField(env, obj, fid);
\r
1749 len = (*env)->GetArrayLength(env, jia);
\r
1752 jiBody = (*env)->GetPrimitiveArrayCritical(env, jia, &isCopy);
\r
1753 //printf("C: before transfering 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);
\r
1754 if (comp->sgnd) { // Special behaviour to deal with signed elements ?? XXXXX
\r
1755 for(i=0; i< len;i++) {
\r
1756 comp->data[i] = ( ((int) jiBody[i]) & (0xFF << shift) ) >> shift;
\r
1757 if (comp->data[i] > max) max = comp->data[i];
\r
1760 for(i=0; i< len;i++) {
\r
1761 comp->data[i] = ( ((unsigned int) jiBody[i]) & (0xFF << shift) ) >> shift;
\r
1762 if (comp->data[i] > max) max = comp->data[i];
\r
1765 (*env)->ReleasePrimitiveArrayCritical(env, jia, jiBody, 0);
\r
1767 comp->bpp = int_floorlog2(max)+1;
\r
1768 comp->prec = comp->bpp;
\r
1769 //printf("C: component %d: max %d, real bpp = %d\n", compno, max, comp->bpp);
\r
1775 /* --------------------------------------------------------------------------
\r
1776 -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/
\r
1777 JNIEXPORT jlong JNICALL Java_org_openJpeg_OpenJPEGJavaEncoder_internalEncodeImageToJ2K(JNIEnv *env, jobject obj, jobjectArray javaParameters) {
\r
1778 int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */
\r
1779 char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */
\r
1781 opj_cparameters_t parameters; /* compression parameters */
\r
1782 img_fol_t img_fol;
\r
1783 opj_event_mgr_t event_mgr; /* event manager */
\r
1784 opj_image_t *image = NULL;
\r
1785 int i,j,num_images;
\r
1787 opj_codestream_info_t cstr_info; /* Codestream information structure */
\r
1788 char indexfilename[OPJ_PATH_LEN]; /* index file name */
\r
1790 int* compressed_index = NULL;
\r
1791 int compressed_index_size=-1;
\r
1792 // ==> Access variables to the Java member variables
\r
1800 callback_variables_t msgErrorCallback_vars;
\r
1801 // <== access variable to the Java member variables.
\r
1803 // For the encoding and storage into the file
\r
1804 opj_cinfo_t* cinfo;
\r
1805 int codestream_length;
\r
1806 opj_cio_t *cio = NULL;
\r
1809 // JNI reference to the calling class
\r
1810 cls = (*env)->GetObjectClass(env, obj);
\r
1812 // Pointers to be able to call a Java method for all the info and error messages
\r
1813 msgErrorCallback_vars.env = env;
\r
1814 msgErrorCallback_vars.jobj = &obj;
\r
1815 msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V");
\r
1816 msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V");
\r
1818 arraySize = (*env)->GetArrayLength(env, javaParameters);
\r
1819 argc = (int) arraySize +1;
\r
1820 argv = malloc(argc*sizeof(char*));
\r
1821 argv[0] = "ProgramName.exe"; // The program name: useless
\r
1823 for (i=1; i<argc; i++) {
\r
1824 object = (*env)->GetObjectArrayElement(env, javaParameters, i-1);
\r
1825 argv[i] = (*env)->GetStringUTFChars(env, object, &isCopy);
\r
1829 for (i=0; i<argc; i++) {
\r
1830 printf("[%s]",argv[i]);
\r
1835 configure the event callbacks
\r
1837 memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
\r
1838 event_mgr.error_handler = error_callback;
\r
1839 event_mgr.warning_handler = warning_callback;
\r
1840 event_mgr.info_handler = info_callback;
\r
1842 /* set encoding parameters to default values */
\r
1843 opj_set_default_encoder_parameters(¶meters);
\r
1844 parameters.cod_format = J2K_CFMT;
\r
1845 //parameters.index_on = 1;
\r
1847 /* Initialize indexfilename and img_fol */
\r
1848 *indexfilename = 0;
\r
1849 memset(&img_fol,0,sizeof(img_fol_t));
\r
1851 /* parse input and get user encoding parameters */
\r
1852 if (parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) {
\r
1853 // Release the Java arguments array
\r
1854 for (i=1; i<argc; i++)
\r
1855 (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
\r
1859 // Release the Java arguments array
\r
1860 for (i=1; i<argc; i++)
\r
1861 (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
\r
1863 if (parameters.cp_cinema){
\r
1864 cinema_parameters(¶meters);
\r
1868 /* Create comment for codestream */
\r
1869 if(parameters.cp_comment == NULL) {
\r
1870 const char comment[] = "Created by JavaOpenJPEG version ";
\r
1871 const size_t clen = strlen(comment);
\r
1872 const char *version = opj_version();
\r
1875 parameters.cp_comment = (char*)malloc(clen+strlen(version)+11);
\r
1876 sprintf(parameters.cp_comment,"%s%s with JPWL", comment, version);
\r
1878 parameters.cp_comment = (char*)malloc(clen+strlen(version)+1);
\r
1879 sprintf(parameters.cp_comment,"%s%s", comment, version);
\r
1885 /* Read directory if necessary */
\r
1888 /*Encoding image one by one*/
\r
1889 for(imageno=0;imageno<num_images;imageno++)
\r
1892 fprintf(stderr,"\n");
\r
1894 image = loadImage(¶meters, env, obj, cls);
\r
1895 //printf("C: after load image: image = %d\n", image);
\r
1897 fprintf(stderr, "Unable to load image\n");
\r
1901 /* Decide if MCT should be used */
\r
1902 parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
\r
1904 if(parameters.cp_cinema){
\r
1905 cinema_setup_encoder(¶meters,image,&img_fol);
\r
1908 /* encode the destination image */
\r
1909 /* ---------------------------- */
\r
1910 /* get a J2K compressor handle */
\r
1911 if (parameters.cod_format == J2K_CFMT) { /* J2K format output */
\r
1912 cinfo = opj_create_compress(CODEC_J2K);
\r
1913 } else { /* JP2 format output */
\r
1914 cinfo = opj_create_compress(CODEC_JP2);
\r
1916 /* catch events using our callbacks and give a local context */
\r
1917 opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, &msgErrorCallback_vars);
\r
1919 /* setup the encoder parameters using the current image and user parameters */
\r
1920 opj_setup_encoder(cinfo, ¶meters, image);
\r
1922 /* open a byte stream for writing */
\r
1923 /* allocate memory for all tiles */
\r
1924 cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
\r
1926 /* encode the image */
\r
1927 bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);
\r
1928 printf("C: after opj_encode_with_info\n");
\r
1930 opj_cio_close(cio);
\r
1931 fprintf(stderr, "failed to encode image\n");
\r
1934 codestream_length = cio_tell(cio);
\r
1936 /* write the index on disk, if needed (-x 'filename') */
\r
1937 if (*indexfilename) {
\r
1938 bSuccess = write_index_file(&cstr_info, indexfilename);
\r
1940 fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename);
\r
1944 compressed_index = create_index_into_byte_array(&cstr_info, &compressed_index_size);
\r
1945 /* Allocates the Java compressedIndex byte[] and sends this index into the Java object */
\r
1946 fid = (*env)->GetFieldID(env, cls,"compressedIndex", "[B");
\r
1947 jba = (*env)->NewByteArray(env, compressed_index_size+1);
\r
1948 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
\r
1949 memcpy(jbBody, compressed_index, compressed_index_size);
\r
1950 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1951 (*env)->SetObjectField(env, obj, fid, jba);
\r
1952 free(compressed_index);
\r
1954 /* write the generated codestream to disk ? */
\r
1955 if (parameters.outfile[0]!='\0') {
\r
1956 f = fopen(parameters.outfile, "wb");
\r
1958 fprintf(stderr, "failed to open [%s] for writing\n", parameters.outfile);
\r
1961 fwrite(cio->buffer, 1, codestream_length, f);
\r
1963 fprintf(stdout,"Generated outfile [%s]\n",parameters.outfile);
\r
1966 /* Write the generated codestream to the Java pre-allocated compressedStream byte[] */
\r
1967 fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");
\r
1968 jba = (*env)->GetObjectField(env, obj, fid);
\r
1969 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
\r
1970 memcpy(jbBody, cio->buffer, codestream_length);
\r
1971 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1973 /* close and free the byte stream */
\r
1974 opj_cio_close(cio);
\r
1976 /* free remaining compression structures */
\r
1977 opj_destroy_compress(cinfo);
\r
1978 opj_destroy_cstr_info(&cstr_info);
\r
1980 /* free image data */
\r
1981 opj_image_destroy(image);
\r
1984 /* free user parameters structure */
\r
1985 if(parameters.cp_comment) free(parameters.cp_comment);
\r
1986 if(parameters.cp_matrice) free(parameters.cp_matrice);
\r
1988 return codestream_length;
\r