2 * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
\r
3 * Copyright (c) 2002-2014, 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
7 * Copyright (c) 2003-2014, Antonin Descampe
\r
8 * Copyright (c) 2005, Herve Drolon, FreeImage Team
\r
9 * Copyright (c) 2006-2007, Parvatha Elangovan
\r
10 * Copyright (c) 2007, Patrick Piscaglia (Telemis)
\r
11 * All rights reserved.
\r
13 * Redistribution and use in source and binary forms, with or without
\r
14 * modification, are permitted provided that the following conditions
\r
16 * 1. Redistributions of source code must retain the above copyright
\r
17 * notice, this list of conditions and the following disclaimer.
\r
18 * 2. Redistributions in binary form must reproduce the above copyright
\r
19 * notice, this list of conditions and the following disclaimer in the
\r
20 * documentation and/or other materials provided with the distribution.
\r
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
\r
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\r
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
\r
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
\r
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
\r
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
\r
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
\r
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
\r
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
\r
32 * POSSIBILITY OF SUCH DAMAGE.
\r
40 #include "openjpeg.h"
\r
41 #include "opj_includes.h"
\r
42 #include "opj_getopt.h"
\r
43 #include "convert.h"
\r
46 #include "org_openJpeg_OpenJPEGJavaEncoder.h"
\r
49 #define stricmp strcasecmp
\r
50 #define strnicmp strncasecmp
\r
53 #include "format_defs.h"
\r
55 #define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/
\r
56 #define CINEMA_48_CS 651041 /*Codestream length for 48fps*/
\r
57 #define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/
\r
58 #define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/
\r
60 extern int get_file_format(char *filename);
\r
61 extern void error_callback(const char *msg, void *client_data);
\r
62 extern void warning_callback(const char *msg, void *client_data);
\r
63 extern void info_callback(const char *msg, void *client_data);
\r
65 typedef struct callback_variables {
\r
67 /** 'jclass' object used to call a Java method from the C */
\r
69 /** 'jclass' object used to call a Java method from the C */
\r
70 jmethodID message_mid;
\r
71 jmethodID error_mid;
\r
72 } callback_variables_t;
\r
74 typedef struct dircnt{
\r
75 /** Buffer for holding images read from Directory*/
\r
77 /** Pointer to the buffer*/
\r
81 typedef struct img_folder{
\r
82 /** The directory path of the folder containing input images*/
\r
88 /** Enable Cod Format for output*/
\r
89 char set_out_format;
\r
90 /** User specified rate stored in case of cinema option*/
\r
94 static void encode_help_display() {
\r
95 fprintf(stdout,"HELP\n----\n\n");
\r
96 fprintf(stdout,"- the -h option displays this help information on screen\n\n");
\r
99 fprintf(stdout,"List of parameters for the JPEG 2000 "
\r
102 #endif /* USE_JPWL */
\r
105 fprintf(stdout,"\n");
\r
106 fprintf(stdout,"REMARKS:\n");
\r
107 fprintf(stdout,"---------\n");
\r
108 fprintf(stdout,"\n");
\r
109 fprintf(stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n");
\r
110 fprintf(stdout,"COD and QCD never appear in the tile_header.\n");
\r
111 fprintf(stdout,"\n");
\r
112 fprintf(stdout,"- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n");
\r
113 fprintf(stdout,"color image. You need enough disk space memory (twice the original) to encode \n");
\r
114 fprintf(stdout,"the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n");
\r
115 fprintf(stdout,"\n");
\r
116 fprintf(stdout,"By default:\n");
\r
117 fprintf(stdout,"------------\n");
\r
118 fprintf(stdout,"\n");
\r
119 fprintf(stdout," * Lossless\n");
\r
120 fprintf(stdout," * 1 tile\n");
\r
121 fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");
\r
122 fprintf(stdout," * Size of code-block : 64 x 64\n");
\r
123 fprintf(stdout," * Number of resolutions: 6\n");
\r
124 fprintf(stdout," * No SOP marker in the codestream\n");
\r
125 fprintf(stdout," * No EPH marker in the codestream\n");
\r
126 fprintf(stdout," * No sub-sampling in x or y direction\n");
\r
127 fprintf(stdout," * No mode switch activated\n");
\r
128 fprintf(stdout," * Progression order: LRCP\n");
\r
129 fprintf(stdout," * No index file\n");
\r
130 fprintf(stdout," * No ROI upshifted\n");
\r
131 fprintf(stdout," * No offset of the origin of the image\n");
\r
132 fprintf(stdout," * No offset of the origin of the tiles\n");
\r
133 fprintf(stdout," * Reversible DWT 5-3\n");
\r
136 fprintf(stdout," * No JPWL protection\n");
\r
137 #endif /* USE_JPWL */
\r
139 fprintf(stdout,"\n");
\r
140 fprintf(stdout,"Parameters:\n");
\r
141 fprintf(stdout,"------------\n");
\r
142 fprintf(stdout,"\n");
\r
143 fprintf(stdout,"Required Parameters (except with -h):\n");
\r
144 fprintf(stdout,"One of the two options -ImgDir or -i must be used\n");
\r
145 fprintf(stdout,"\n");
\r
146 fprintf(stdout,"-ImgDir : Image file Directory path (example ../Images) \n");
\r
147 fprintf(stdout," When using this option -OutFor must be used\n");
\r
148 fprintf(stdout,"\n");
\r
149 fprintf(stdout,"-OutFor \n");
\r
150 fprintf(stdout," REQUIRED only if -ImgDir is used\n");
\r
151 fprintf(stdout," Need to specify only format without filename <BMP> \n");
\r
152 fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA formats\n");
\r
153 fprintf(stdout,"\n");
\r
154 fprintf(stdout,"-i : source file (-i source.pnm also *.pgm, *.ppm, *.bmp, *.tif, *.raw, *.tga) \n");
\r
155 fprintf(stdout," When using this option -o must be used\n");
\r
156 fprintf(stdout,"\n");
\r
157 fprintf(stdout,"-o : destination file (-o dest.j2k or .jp2) \n");
\r
158 fprintf(stdout,"\n");
\r
159 fprintf(stdout,"Optional Parameters:\n");
\r
160 fprintf(stdout,"\n");
\r
161 fprintf(stdout,"-h : display the help information \n ");
\r
162 fprintf(stdout,"\n");
\r
163 fprintf(stdout,"-cinema2K : Digital Cinema 2K profile compliant codestream for 2K resolution.(-cinema2k 24 or 48) \n");
\r
164 fprintf(stdout," Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n");
\r
165 fprintf(stdout,"\n");
\r
166 fprintf(stdout,"-cinema4K : Digital Cinema 4K profile compliant codestream for 4K resolution \n");
\r
167 fprintf(stdout," Frames per second not required. Default value is 24fps\n");
\r
168 fprintf(stdout,"\n");
\r
169 fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n ");
\r
170 fprintf(stdout," - The rate specified for each quality level is the desired \n");
\r
171 fprintf(stdout," compression factor.\n");
\r
172 fprintf(stdout," Example: -r 20,10,1 means quality 1: compress 20x, \n");
\r
173 fprintf(stdout," quality 2: compress 10x and quality 3: compress lossless\n");
\r
174 fprintf(stdout,"\n");
\r
175 fprintf(stdout," (options -r and -q cannot be used together)\n ");
\r
176 fprintf(stdout,"\n");
\r
178 fprintf(stdout,"-q : different psnr for successive layers (-q 30,40,50) \n ");
\r
180 fprintf(stdout," (options -r and -q cannot be used together)\n ");
\r
182 fprintf(stdout,"\n");
\r
183 fprintf(stdout,"-n : number of resolutions (-n 3) \n");
\r
184 fprintf(stdout,"\n");
\r
185 fprintf(stdout,"-b : size of code block (-b 32,32) \n");
\r
186 fprintf(stdout,"\n");
\r
187 fprintf(stdout,"-c : size of precinct (-c 128,128) \n");
\r
188 fprintf(stdout,"\n");
\r
189 fprintf(stdout,"-t : size of tile (-t 512,512) \n");
\r
190 fprintf(stdout,"\n");
\r
191 fprintf(stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
\r
192 fprintf(stdout,"\n");
\r
193 fprintf(stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n");
\r
194 fprintf(stdout," Remark: subsampling bigger than 2 can produce error\n");
\r
195 fprintf(stdout,"\n");
\r
196 fprintf(stdout,"-POC : Progression order change (-POC T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL) \n");
\r
197 fprintf(stdout," Example: T1=0,0,1,5,3,CPRL \n");
\r
198 fprintf(stdout," : Ttilenumber=Resolution num start,Component num start,Layer num end,Resolution num end,Component num end,Progression order\n");
\r
199 fprintf(stdout,"\n");
\r
200 fprintf(stdout,"-SOP : write SOP marker before each packet \n");
\r
201 fprintf(stdout,"\n");
\r
202 fprintf(stdout,"-EPH : write EPH marker after each header packet \n");
\r
203 fprintf(stdout,"\n");
\r
204 fprintf(stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
\r
205 fprintf(stdout," 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");
\r
206 fprintf(stdout," Indicate multiple modes by adding their values. \n");
\r
207 fprintf(stdout," ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
\r
208 fprintf(stdout,"\n");
\r
209 fprintf(stdout,"-TP : devide packets of every tile into tile-parts (-TP R) [R, L, C]\n");
\r
210 fprintf(stdout,"\n");
\r
211 fprintf(stdout,"-x : create an index file *.Idx (-x index_name.Idx) \n");
\r
212 fprintf(stdout,"\n");
\r
213 fprintf(stdout,"-ROI : c=%%d,U=%%d : quantization indices upshifted \n");
\r
214 fprintf(stdout," for component c=%%d [%%d = 0,1,2]\n");
\r
215 fprintf(stdout," with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI c=0,U=25) \n");
\r
216 fprintf(stdout,"\n");
\r
217 fprintf(stdout,"-d : offset of the origin of the image (-d 150,300) \n");
\r
218 fprintf(stdout,"\n");
\r
219 fprintf(stdout,"-T : offset of the origin of the tiles (-T 100,75) \n");
\r
220 fprintf(stdout,"\n");
\r
221 fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n");
\r
222 fprintf(stdout,"\n");
\r
223 fprintf(stdout,"-jpip : write jpip codestream index box in JP2 output file\n");
\r
224 fprintf(stdout," NOTICE: currently supports only RPCL order\n");
\r
225 fprintf(stdout,"\n");
\r
228 fprintf(stdout,"-W : adoption of JPWL (Part 11) capabilities (-W params)\n");
\r
229 fprintf(stdout," The parameters can be written and repeated in any order:\n");
\r
230 fprintf(stdout," [h<tilepart><=type>,s<tilepart><=method>,a=<addr>,...\n");
\r
231 fprintf(stdout," ...,z=<size>,g=<range>,p<tilepart:pack><=type>]\n");
\r
232 fprintf(stdout,"\n");
\r
233 fprintf(stdout," h selects the header error protection (EPB): 'type' can be\n");
\r
234 fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
\r
235 fprintf(stdout," if 'tilepart' is absent, it is for main and tile headers\n");
\r
236 fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");
\r
237 fprintf(stdout," onwards, up to the next h<> spec, or to the last tilepart\n");
\r
238 fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);
\r
239 fprintf(stdout,"\n");
\r
240 fprintf(stdout," p selects the packet error protection (EEP/UEP with EPBs)\n");
\r
241 fprintf(stdout," to be applied to raw data: 'type' can be\n");
\r
242 fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
\r
243 fprintf(stdout," if 'tilepart:pack' is absent, it is from tile 0, packet 0\n");
\r
244 fprintf(stdout," if 'tilepart:pack' is present, it applies from that tile\n");
\r
245 fprintf(stdout," and that packet onwards, up to the next packet spec\n");
\r
246 fprintf(stdout," or to the last packet in the last tilepart in the stream\n");
\r
247 fprintf(stdout," (max. %d specs)\n", JPWL_MAX_NO_PACKSPECS);
\r
248 fprintf(stdout,"\n");
\r
249 fprintf(stdout," s enables sensitivity data insertion (ESD): 'method' can be\n");
\r
250 fprintf(stdout," [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n");
\r
251 fprintf(stdout," 4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n");
\r
252 fprintf(stdout," if 'tilepart' is absent, it is for main header only\n");
\r
253 fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");
\r
254 fprintf(stdout," onwards, up to the next s<> spec, or to the last tilepart\n");
\r
255 fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);
\r
256 fprintf(stdout,"\n");
\r
257 fprintf(stdout," g determines the addressing mode: <range> can be\n");
\r
258 fprintf(stdout," [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n");
\r
259 fprintf(stdout,"\n");
\r
260 fprintf(stdout," a determines the size of data addressing: <addr> can be\n");
\r
261 fprintf(stdout," 2/4 bytes (small/large codestreams). If not set, auto-mode\n");
\r
262 fprintf(stdout,"\n");
\r
263 fprintf(stdout," z determines the size of sensitivity values: <size> can be\n");
\r
264 fprintf(stdout," 1/2 bytes, for the transformed pseudo-floating point value\n");
\r
265 fprintf(stdout,"\n");
\r
266 fprintf(stdout," ex.:\n");
\r
267 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
268 fprintf(stdout," s0=6,s3=-1,a=0,g=1,z=1\n");
\r
269 fprintf(stdout," means\n");
\r
270 fprintf(stdout," predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n");
\r
271 fprintf(stdout," CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n");
\r
272 fprintf(stdout," UEP rs(78,32) for packets 0 to 23 of tile 0,\n");
\r
273 fprintf(stdout," UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n");
\r
274 fprintf(stdout," UEP rs default for packets of tilepart 1,\n");
\r
275 fprintf(stdout," no UEP for packets 0 to 19 of tilepart 3,\n");
\r
276 fprintf(stdout," UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n");
\r
277 fprintf(stdout," relative sensitivity ESD for MH,\n");
\r
278 fprintf(stdout," TSE ESD from TPH 0 to TPH 2, byte range with automatic\n");
\r
279 fprintf(stdout," size of addresses and 1 byte for each sensitivity value\n");
\r
280 fprintf(stdout,"\n");
\r
281 fprintf(stdout," ex.:\n");
\r
282 fprintf(stdout," h,s,p\n");
\r
283 fprintf(stdout," means\n");
\r
284 fprintf(stdout," default protection to headers (MH and TPHs) as well as\n");
\r
285 fprintf(stdout," data packets, one ESD in MH\n");
\r
286 fprintf(stdout,"\n");
\r
287 fprintf(stdout," N.B.: use the following recommendations when specifying\n");
\r
288 fprintf(stdout," the JPWL parameters list\n");
\r
289 fprintf(stdout," - when you use UEP, always pair the 'p' option with 'h'\n");
\r
290 fprintf(stdout," \n");
\r
291 #endif /* USE_JPWL */
\r
293 fprintf(stdout,"IMPORTANT:\n");
\r
294 fprintf(stdout,"-----------\n");
\r
295 fprintf(stdout,"\n");
\r
296 fprintf(stdout,"The index file has the structure below:\n");
\r
297 fprintf(stdout,"---------------------------------------\n");
\r
298 fprintf(stdout,"\n");
\r
299 fprintf(stdout,"Image_height Image_width\n");
\r
300 fprintf(stdout,"progression order\n");
\r
301 fprintf(stdout,"Tiles_size_X Tiles_size_Y\n");
\r
302 fprintf(stdout,"Tiles_nb_X Tiles_nb_Y\n");
\r
303 fprintf(stdout,"Components_nb\n");
\r
304 fprintf(stdout,"Layers_nb\n");
\r
305 fprintf(stdout,"decomposition_levels\n");
\r
306 fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");
\r
307 fprintf(stdout," [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");
\r
308 fprintf(stdout,"Main_header_start_position\n");
\r
309 fprintf(stdout,"Main_header_end_position\n");
\r
310 fprintf(stdout,"Codestream_size\n");
\r
311 fprintf(stdout,"\n");
\r
312 fprintf(stdout,"INFO ON TILES\n");
\r
313 fprintf(stdout,"tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n");
\r
314 fprintf(stdout,"Tile_0 start_pos end_Theader end_pos NumParts TotalDisto NumPix MaxMSE\n");
\r
315 fprintf(stdout,"Tile_1 '' '' '' '' '' '' ''\n");
\r
316 fprintf(stdout,"...\n");
\r
317 fprintf(stdout,"Tile_Nt '' '' '' '' '' '' ''\n");
\r
318 fprintf(stdout,"...\n");
\r
319 fprintf(stdout,"TILE 0 DETAILS\n");
\r
320 fprintf(stdout,"part_nb tileno num_packs start_pos end_tph_pos end_pos\n");
\r
321 fprintf(stdout,"...\n");
\r
322 fprintf(stdout,"Progression_string\n");
\r
323 fprintf(stdout,"pack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n");
\r
324 fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");
\r
325 fprintf(stdout,"...\n");
\r
326 fprintf(stdout,"Tpacket_Np '' '' '' '' '' '' '' ''\n");
\r
328 fprintf(stdout,"MaxDisto\n");
\r
330 fprintf(stdout,"TotalDisto\n\n");
\r
334 static OPJ_PROG_ORDER give_progression(const char progression[4]) {
\r
335 if(strncmp(progression, "LRCP", 4) == 0) {
\r
338 if(strncmp(progression, "RLCP", 4) == 0) {
\r
341 if(strncmp(progression, "RPCL", 4) == 0) {
\r
344 if(strncmp(progression, "PCRL", 4) == 0) {
\r
347 if(strncmp(progression, "CPRL", 4) == 0) {
\r
351 return PROG_UNKNOWN;
\r
354 static int initialise_4K_poc(opj_poc_t *POC, int numres){
\r
356 POC[0].resno0 = 0;
\r
357 POC[0].compno0 = 0;
\r
359 POC[0].resno1 = numres-1;
\r
360 POC[0].compno1 = 3;
\r
361 POC[0].prg1 = CPRL;
\r
363 POC[1].resno0 = numres-1;
\r
364 POC[1].compno0 = 0;
\r
366 POC[1].resno1 = numres;
\r
367 POC[1].compno1 = 3;
\r
368 POC[1].prg1 = CPRL;
\r
372 static void cinema_parameters(opj_cparameters_t *parameters){
\r
373 parameters->tile_size_on = OPJ_FALSE;
\r
374 parameters->cp_tdx=1;
\r
375 parameters->cp_tdy=1;
\r
378 parameters->tp_flag = 'C';
\r
379 parameters->tp_on = 1;
\r
381 /*Tile and Image shall be at (0,0)*/
\r
382 parameters->cp_tx0 = 0;
\r
383 parameters->cp_ty0 = 0;
\r
384 parameters->image_offset_x0 = 0;
\r
385 parameters->image_offset_y0 = 0;
\r
387 /*Codeblock size= 32*32*/
\r
388 parameters->cblockw_init = 32;
\r
389 parameters->cblockh_init = 32;
\r
390 parameters->csty |= 0x01;
\r
392 /*The progression order shall be CPRL*/
\r
393 parameters->prog_order = CPRL;
\r
396 parameters->roi_compno = -1;
\r
398 parameters->subsampling_dx = 1; parameters->subsampling_dy = 1;
\r
400 /* 9-7 transform */
\r
401 parameters->irreversible = 1;
\r
405 static void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){
\r
408 opj_poc_t *POC = NULL;
\r
410 switch (parameters->cp_cinema){
\r
413 if(parameters->numresolution > 6){
\r
414 parameters->numresolution = 6;
\r
416 if (!((image->comps[0].w == 2048) | (image->comps[0].h == 1080))){
\r
417 fprintf(stdout,"Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3"
\r
418 "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
\r
419 image->comps[0].w,image->comps[0].h);
\r
420 parameters->cp_rsiz = STD_RSIZ;
\r
425 if(parameters->numresolution < 1){
\r
426 parameters->numresolution = 1;
\r
427 }else if(parameters->numresolution > 7){
\r
428 parameters->numresolution = 7;
\r
430 if (!((image->comps[0].w == 4096) | (image->comps[0].h == 2160))){
\r
431 fprintf(stdout,"Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4"
\r
432 "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
\r
433 image->comps[0].w,image->comps[0].h);
\r
434 parameters->cp_rsiz = STD_RSIZ;
\r
436 parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution);
\r
440 switch (parameters->cp_cinema){
\r
443 for(i=0 ; i<parameters->tcp_numlayers ; i++){
\r
445 if (img_fol->rates[i]== 0){
\r
446 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
447 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
449 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
450 (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
\r
451 if (temp_rate > CINEMA_24_CS ){
\r
452 parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
453 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
455 parameters->tcp_rates[i]= img_fol->rates[i];
\r
459 parameters->max_comp_size = COMP_24_CS;
\r
463 for(i=0 ; i<parameters->tcp_numlayers ; i++){
\r
465 if (img_fol->rates[i]== 0){
\r
466 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
467 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
469 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
470 (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
\r
471 if (temp_rate > CINEMA_48_CS ){
\r
472 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
473 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
475 parameters->tcp_rates[i]= img_fol->rates[i];
\r
479 parameters->max_comp_size = COMP_48_CS;
\r
482 parameters->cp_disto_alloc = 1;
\r
486 /* ------------------------------------------------------------------------------------ */
\r
487 static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
\r
488 img_fol_t *img_fol, char *indexfilename) {
\r
490 opj_option_t long_option[]={
\r
491 {"cinema2K",REQ_ARG, NULL ,'w'},
\r
492 {"cinema4K",NO_ARG, NULL ,'y'},
\r
493 {"ImgDir",REQ_ARG, NULL ,'z'},
\r
494 {"TP",REQ_ARG, NULL ,'u'},
\r
495 {"SOP",NO_ARG, NULL ,'S'},
\r
496 {"EPH",NO_ARG, NULL ,'E'},
\r
497 {"OutFor",REQ_ARG, NULL ,'O'},
\r
498 {"POC",REQ_ARG, NULL ,'P'},
\r
499 {"ROI",REQ_ARG, NULL ,'R'},
\r
500 {"jpip",NO_ARG, NULL, 'J'}
\r
503 /* parse the command line */
\r
505 const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:"
\r
508 #endif /* USE_JPWL */
\r
511 /*printf("C: parse_cmdline_encoder:");
\r
512 for (i=0; i<argc; i++) {
\r
513 printf("[%s]",argv[i]);
\r
517 totlen=sizeof(long_option);
\r
518 img_fol->set_out_format=0;
\r
519 reset_options_reading();
\r
522 int c = opj_getopt_long(argc, argv, optlist,long_option,totlen);
\r
527 /* ----------------------------------------------------- */
\r
529 case 'o': /* output file */
\r
531 char *outfile = opj_optarg;
\r
532 parameters->cod_format = get_file_format(outfile);
\r
533 switch(parameters->cod_format) {
\r
538 fprintf(stderr, "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile);
\r
541 strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);
\r
545 /* ----------------------------------------------------- */
\r
546 case 'O': /* output format */
\r
548 char outformat[50];
\r
549 char *of = opj_optarg;
\r
550 sprintf(outformat,".%s",of);
\r
551 img_fol->set_out_format = 1;
\r
552 parameters->cod_format = get_file_format(outformat);
\r
553 switch(parameters->cod_format) {
\r
556 img_fol->out_format = opj_optarg;
\r
559 fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n");
\r
566 /* ----------------------------------------------------- */
\r
569 case 'r': /* rates rates/distorsion */
\r
571 char *s = opj_optarg;
\r
572 while (sscanf(s, "%f", ¶meters->tcp_rates[parameters->tcp_numlayers]) == 1) {
\r
573 parameters->tcp_numlayers++;
\r
574 while (*s && *s != ',') {
\r
581 parameters->cp_disto_alloc = 1;
\r
585 /* ----------------------------------------------------- */
\r
587 case 'q': /* add fixed_quality */
\r
589 char *s = opj_optarg;
\r
590 while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers]) == 1) {
\r
591 parameters->tcp_numlayers++;
\r
592 while (*s && *s != ',') {
\r
599 parameters->cp_fixed_quality = 1;
\r
604 /* ----------------------------------------------------- */
\r
606 case 'f': /* mod fixed_quality (before : -q) */
\r
608 int *row = NULL, *col = NULL;
\r
609 int numlayers = 0, numresolution = 0, matrix_width = 0;
\r
611 char *s = opj_optarg;
\r
612 sscanf(s, "%d", &numlayers);
\r
617 parameters->tcp_numlayers = numlayers;
\r
618 numresolution = parameters->numresolution;
\r
619 matrix_width = numresolution * 3;
\r
620 parameters->cp_matrice = (int *) opj_malloc(numlayers * matrix_width * sizeof(int));
\r
623 for (i = 0; i < numlayers; i++) {
\r
624 row = ¶meters->cp_matrice[i * matrix_width];
\r
626 parameters->tcp_rates[i] = 1;
\r
627 sscanf(s, "%d,", &col[0]);
\r
633 for (j = 1; j < numresolution; j++) {
\r
635 sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);
\r
644 if (i < numlayers - 1)
\r
647 parameters->cp_fixed_alloc = 1;
\r
651 /* ----------------------------------------------------- */
\r
653 case 't': /* tiles */
\r
655 sscanf(opj_optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy);
\r
656 parameters->tile_size_on = OPJ_TRUE;
\r
660 /* ----------------------------------------------------- */
\r
662 case 'n': /* resolution */
\r
664 sscanf(opj_optarg, "%d", ¶meters->numresolution);
\r
668 /* ----------------------------------------------------- */
\r
669 case 'c': /* precinct dimension */
\r
674 char *s = opj_optarg;
\r
677 sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec],
\r
678 ¶meters->prch_init[res_spec], &sep);
\r
679 parameters->csty |= 0x01;
\r
681 s = strpbrk(s, "]") + 2;
\r
683 while (sep == ',');
\r
684 parameters->res_spec = res_spec;
\r
688 /* ----------------------------------------------------- */
\r
690 case 'b': /* code-block dimension */
\r
692 int cblockw_init = 0, cblockh_init = 0;
\r
693 sscanf(opj_optarg, "%d,%d", &cblockw_init, &cblockh_init);
\r
694 if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
\r
695 || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
\r
697 "!! Size of code_block error (option -b) !!\n\nRestriction :\n"
\r
698 " * width*height<=4096\n * 4<=width,height<= 1024\n\n");
\r
701 parameters->cblockw_init = cblockw_init;
\r
702 parameters->cblockh_init = cblockh_init;
\r
706 /* ----------------------------------------------------- */
\r
708 case 'x': /* creation of index file */
\r
710 char *index = opj_optarg;
\r
711 strncpy(indexfilename, index, OPJ_PATH_LEN);
\r
715 /* ----------------------------------------------------- */
\r
717 case 'p': /* progression order */
\r
719 char progression[4];
\r
721 strncpy(progression, opj_optarg, 4);
\r
722 parameters->prog_order = give_progression(progression);
\r
723 if (parameters->prog_order == -1) {
\r
724 fprintf(stderr, "Unrecognized progression order "
\r
725 "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
\r
731 /* ----------------------------------------------------- */
\r
733 case 's': /* subsampling factor */
\r
735 if (sscanf(opj_optarg, "%d,%d", ¶meters->subsampling_dx,
\r
736 ¶meters->subsampling_dy) != 2) {
\r
737 fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n");
\r
743 /* ----------------------------------------------------- */
\r
745 case 'd': /* coordonnate of the reference grid */
\r
747 if (sscanf(opj_optarg, "%d,%d", ¶meters->image_offset_x0,
\r
748 ¶meters->image_offset_y0) != 2) {
\r
749 fprintf(stderr, "-d 'coordonnate of the reference grid' argument "
\r
750 "error !! [-d x0,y0]\n");
\r
756 /* ----------------------------------------------------- */
\r
758 case 'h': /* display an help description */
\r
759 encode_help_display();
\r
762 /* ----------------------------------------------------- */
\r
764 case 'P': /* POC */
\r
766 int numpocs = 0; /* number of progression order change (POC) default 0 */
\r
767 opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */
\r
769 char *s = opj_optarg;
\r
770 POC = parameters->POC;
\r
772 while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,
\r
773 &POC[numpocs].resno0, &POC[numpocs].compno0,
\r
774 &POC[numpocs].layno1, &POC[numpocs].resno1,
\r
775 &POC[numpocs].compno1, &POC[numpocs].progorder) == 7) {
\r
776 POC[numpocs].prg1 = give_progression(POC[numpocs].progorder);
\r
778 while (*s && *s != '/') {
\r
786 parameters->numpocs = numpocs;
\r
790 /* ------------------------------------------------------ */
\r
792 case 'S': /* SOP marker */
\r
794 parameters->csty |= 0x02;
\r
798 /* ------------------------------------------------------ */
\r
800 case 'E': /* EPH marker */
\r
802 parameters->csty |= 0x04;
\r
806 /* ------------------------------------------------------ */
\r
808 case 'M': /* Mode switch pas tous au point !! */
\r
811 if (sscanf(opj_optarg, "%d", &value) == 1) {
\r
812 for (i = 0; i <= 5; i++) {
\r
813 int cache = value & (1 << i);
\r
815 parameters->mode |= (1 << i);
\r
821 /* ------------------------------------------------------ */
\r
823 case 'R': /* ROI */
\r
825 if (sscanf(opj_optarg, "c=%d,U=%d", ¶meters->roi_compno,
\r
826 ¶meters->roi_shift) != 2) {
\r
827 fprintf(stderr, "ROI error !! [-ROI c='compno',U='shift']\n");
\r
833 /* ------------------------------------------------------ */
\r
835 case 'T': /* Tile offset */
\r
837 if (sscanf(opj_optarg, "%d,%d", ¶meters->cp_tx0, ¶meters->cp_ty0) != 2) {
\r
838 fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");
\r
844 /* ------------------------------------------------------ */
\r
846 case 'C': /* add a comment */
\r
848 parameters->cp_comment = (char*)opj_malloc(strlen(opj_optarg) + 1);
\r
849 if(parameters->cp_comment) {
\r
850 strcpy(parameters->cp_comment, opj_optarg);
\r
856 /* ------------------------------------------------------ */
\r
858 case 'I': /* reversible or not */
\r
860 parameters->irreversible = 1;
\r
864 /* ------------------------------------------------------ */
\r
866 case 'u': /* Tile part generation*/
\r
868 parameters->tp_flag = opj_optarg[0];
\r
869 parameters->tp_on = 1;
\r
873 /* ------------------------------------------------------ */
\r
875 case 'z': /* Image Directory path */
\r
877 img_fol->imgdirpath = (char*)opj_malloc(strlen(opj_optarg) + 1);
\r
878 strcpy(img_fol->imgdirpath,opj_optarg);
\r
879 img_fol->set_imgdir=1;
\r
883 /* ------------------------------------------------------ */
\r
885 case 'w': /* Digital Cinema 2K profile compliance*/
\r
888 sscanf(opj_optarg,"%d",&fps);
\r
890 parameters->cp_cinema = CINEMA2K_24;
\r
891 }else if(fps == 48 ){
\r
892 parameters->cp_cinema = CINEMA2K_48;
\r
894 fprintf(stderr,"Incorrect value!! must be 24 or 48\n");
\r
897 fprintf(stdout,"CINEMA 2K compliant codestream\n");
\r
898 parameters->cp_rsiz = CINEMA2K;
\r
903 /* ------------------------------------------------------ */
\r
905 case 'y': /* Digital Cinema 4K profile compliance*/
\r
907 parameters->cp_cinema = CINEMA4K_24;
\r
908 fprintf(stdout,"CINEMA 4K compliant codestream\n");
\r
909 parameters->cp_rsiz = CINEMA4K;
\r
913 /* ------------------------------------------------------ */
\r
917 /* ------------------------------------------------------ */
\r
919 case 'W': /* JPWL capabilities switched on */
\r
921 char *token = NULL;
\r
922 int hprot, pprot, sens, addr, size, range;
\r
924 /* we need to enable indexing */
\r
925 if (!indexfilename) {
\r
926 strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN);
\r
929 /* search for different protection methods */
\r
931 /* break the option in comma points and parse the result */
\r
932 token = strtok(opj_optarg, ",");
\r
933 while(token != NULL) {
\r
935 /* search header error protection method */
\r
936 if (*token == 'h') {
\r
938 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
940 hprot = 1; /* predefined method */
\r
942 if(sscanf(token, "h=%d", &hprot) == 1) {
\r
943 /* Main header, specified */
\r
944 if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
\r
945 ((hprot >= 37) && (hprot <= 128)))) {
\r
946 fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n", hprot);
\r
949 parameters->jpwl_hprot_MH = hprot;
\r
951 } else if(sscanf(token, "h%d=%d", &tile, &hprot) == 2) {
\r
952 /* Tile part header, specified */
\r
953 if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
\r
954 ((hprot >= 37) && (hprot <= 128)))) {
\r
955 fprintf(stderr, "ERROR -> invalid tile part header protection method h = %d\n", hprot);
\r
959 fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);
\r
962 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
963 parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
\r
964 parameters->jpwl_hprot_TPH[tilespec++] = hprot;
\r
967 } else if(sscanf(token, "h%d", &tile) == 1) {
\r
968 /* Tile part header, unspecified */
\r
970 fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);
\r
973 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
974 parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
\r
975 parameters->jpwl_hprot_TPH[tilespec++] = hprot;
\r
979 } else if (!strcmp(token, "h")) {
\r
980 /* Main header, unspecified */
\r
981 parameters->jpwl_hprot_MH = hprot;
\r
984 fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
\r
990 /* search packet error protection method */
\r
991 if (*token == 'p') {
\r
993 static int pack = 0, tile = 0, packspec = 0, lastpackno = 0;
\r
995 pprot = 1; /* predefined method */
\r
997 if (sscanf(token, "p=%d", &pprot) == 1) {
\r
998 /* Method for all tiles and all packets */
\r
999 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1000 ((pprot >= 37) && (pprot <= 128)))) {
\r
1001 fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n", pprot);
\r
1004 parameters->jpwl_pprot_tileno[0] = 0;
\r
1005 parameters->jpwl_pprot_packno[0] = 0;
\r
1006 parameters->jpwl_pprot[0] = pprot;
\r
1008 } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) {
\r
1009 /* method specified from that tile on */
\r
1010 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1011 ((pprot >= 37) && (pprot <= 128)))) {
\r
1012 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1016 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1019 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1020 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1021 parameters->jpwl_pprot_packno[packspec] = 0;
\r
1022 parameters->jpwl_pprot[packspec++] = pprot;
\r
1025 } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) {
\r
1026 /* method fully specified from that tile and that packet 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
1037 fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);
\r
1040 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1041 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1042 parameters->jpwl_pprot_packno[packspec] = pack;
\r
1043 parameters->jpwl_pprot[packspec++] = pprot;
\r
1046 } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) {
\r
1047 /* default method from that tile and that packet on */
\r
1048 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1049 ((pprot >= 37) && (pprot <= 128)))) {
\r
1050 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1054 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1058 fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);
\r
1061 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1062 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1063 parameters->jpwl_pprot_packno[packspec] = pack;
\r
1064 parameters->jpwl_pprot[packspec++] = pprot;
\r
1067 } else if (sscanf(token, "p%d", &tile) == 1) {
\r
1068 /* default from a tile on */
\r
1070 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1073 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1074 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1075 parameters->jpwl_pprot_packno[packspec] = 0;
\r
1076 parameters->jpwl_pprot[packspec++] = pprot;
\r
1080 } else if (!strcmp(token, "p")) {
\r
1082 parameters->jpwl_pprot_tileno[0] = 0;
\r
1083 parameters->jpwl_pprot_packno[0] = 0;
\r
1084 parameters->jpwl_pprot[0] = pprot;
\r
1087 fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
\r
1093 /* search sensitivity method */
\r
1094 if (*token == 's') {
\r
1096 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1098 sens = 0; /* predefined: relative error */
\r
1100 if(sscanf(token, "s=%d", &sens) == 1) {
\r
1101 /* Main header, specified */
\r
1102 if ((sens < -1) || (sens > 7)) {
\r
1103 fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n", sens);
\r
1106 parameters->jpwl_sens_MH = sens;
\r
1108 } else if(sscanf(token, "s%d=%d", &tile, &sens) == 2) {
\r
1109 /* Tile part header, specified */
\r
1110 if ((sens < -1) || (sens > 7)) {
\r
1111 fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n", sens);
\r
1115 fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
\r
1118 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
1119 parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
\r
1120 parameters->jpwl_sens_TPH[tilespec++] = sens;
\r
1123 } else if(sscanf(token, "s%d", &tile) == 1) {
\r
1124 /* Tile part header, unspecified */
\r
1126 fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
\r
1129 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
1130 parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
\r
1131 parameters->jpwl_sens_TPH[tilespec++] = hprot;
\r
1134 } else if (!strcmp(token, "s")) {
\r
1135 /* Main header, unspecified */
\r
1136 parameters->jpwl_sens_MH = sens;
\r
1139 fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token);
\r
1143 parameters->jpwl_sens_size = 2; /* 2 bytes for default size */
\r
1146 /* search addressing size */
\r
1147 if (*token == 'a') {
\r
1149 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1151 addr = 0; /* predefined: auto */
\r
1153 if(sscanf(token, "a=%d", &addr) == 1) {
\r
1155 if ((addr != 0) && (addr != 2) && (addr != 4)) {
\r
1156 fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr);
\r
1159 parameters->jpwl_sens_addr = addr;
\r
1161 } else if (!strcmp(token, "a")) {
\r
1163 parameters->jpwl_sens_addr = addr; /* auto for default size */
\r
1166 fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token);
\r
1172 /* search sensitivity size */
\r
1173 if (*token == 'z') {
\r
1175 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1177 size = 1; /* predefined: 1 byte */
\r
1179 if(sscanf(token, "z=%d", &size) == 1) {
\r
1181 if ((size != 0) && (size != 1) && (size != 2)) {
\r
1182 fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size);
\r
1185 parameters->jpwl_sens_size = size;
\r
1187 } else if (!strcmp(token, "a")) {
\r
1189 parameters->jpwl_sens_size = size; /* 1 for default size */
\r
1192 fprintf(stderr, "ERROR -> invalid size selection = %s\n", token);
\r
1198 /* search range method */
\r
1199 if (*token == 'g') {
\r
1201 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1203 range = 0; /* predefined: 0 (packet) */
\r
1205 if(sscanf(token, "g=%d", &range) == 1) {
\r
1207 if ((range < 0) || (range > 3)) {
\r
1208 fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range);
\r
1211 parameters->jpwl_sens_range = range;
\r
1213 } else if (!strcmp(token, "g")) {
\r
1215 parameters->jpwl_sens_range = range;
\r
1218 fprintf(stderr, "ERROR -> invalid range selection = %s\n", token);
\r
1224 /* next token or bust */
\r
1225 token = strtok(NULL, ",");
\r
1230 fprintf(stdout, "Info: JPWL capabilities enabled\n");
\r
1231 parameters->jpwl_epc_on = true;
\r
1235 #endif /* USE_JPWL */
\r
1237 /* ------------------------------------------------------ */
\r
1240 /* ------------------------------------------------------ */
\r
1243 fprintf(stderr, "ERROR -> Command line not valid\n");
\r
1248 /* check for possible errors */
\r
1249 if (parameters->cp_cinema){
\r
1250 if(parameters->tcp_numlayers > 1){
\r
1251 parameters->cp_rsiz = STD_RSIZ;
\r
1252 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
1256 if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality)
\r
1257 && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ parameters->cp_fixed_quality))) {
\r
1258 fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");
\r
1260 } /* mod fixed_quality */
\r
1262 /* if no rate entered, lossless by default */
\r
1263 if (parameters->tcp_numlayers == 0) {
\r
1264 parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */
\r
1265 parameters->tcp_numlayers++;
\r
1266 parameters->cp_disto_alloc = 1;
\r
1269 if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) {
\r
1271 "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
\r
1272 parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0);
\r
1276 for (i = 0; i < parameters->numpocs; i++) {
\r
1277 if (parameters->POC[i].prg == -1) {
\r
1279 "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
\r
1288 /** 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
1289 @param buffer_size, increased by the length of the compressed index, in number of bytes
\r
1290 @return a pointer to a char[]
\r
1291 Syntax of the index:
\r
1292 one char for the version number (1): one byte because no problem with little endian, big endian etc.
\r
1293 one int for each of the following informations:
\r
1296 progression order
\r
1303 Nb of resolutions
\r
1305 for each resolution:
\r
1309 End main header position
\r
1314 tile start pos in codestream
\r
1315 tile header end position
\r
1316 tile end position in codestream
\r
1318 For each LRCP, RLCP etc.:
\r
1325 start position in the codestream
\r
1326 end position of this packet
\r
1328 static char* create_index_into_byte_array(opj_codestream_info_t *cstr_info, int* buffer_size) {
\r
1329 int tileno, compno, layno, resno, precno, pack_nb, x, y;
\r
1330 char* buffer = NULL;
\r
1331 int buffer_pos = 0;
\r
1335 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1336 for (resno = 0; resno < cstr_info->numdecompos[0] + 1; resno++) {
\r
1337 prec_max = int_max(prec_max,cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]);
\r
1341 /* Compute the size of the index buffer, in number of bytes*/
\r
1344 + (10 /* image_w until decomposition */
\r
1345 + (cstr_info->numdecompos[0]+1) * 2 /* pdx size for each tile */
\r
1346 + 2 /* main_head_end + codestream_size */
\r
1347 + cstr_info->tw * cstr_info->th * 4 /* tile info, without distorsion info */
\r
1348 + cstr_info->tw*cstr_info->th * cstr_info->numlayers * (cstr_info->numdecompos[0] + 1) * cstr_info->numcomps * prec_max *8
\r
1350 /*printf("C: index buffer size = %d bytes\n", *buffer_size);*/
\r
1351 buffer = (char*) opj_malloc(*buffer_size);
\r
1354 /*opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to allocate index buffer for writing %d int\n", *buffer_size);*/
\r
1355 fprintf(stderr, "failed to allocate index buffer for writing %d int\n", *buffer_size);
\r
1359 buffer[0] = 1; /* Version stored on a byte*/
\r
1361 /* Remaining informations are stored on a int.*/
\r
1362 ((int*)buffer)[buffer_pos++] = cstr_info->image_w;
\r
1363 ((int*)buffer)[buffer_pos++] = cstr_info->image_h;
\r
1364 ((int*)buffer)[buffer_pos++] = cstr_info->prog;
\r
1365 ((int*)buffer)[buffer_pos++] = cstr_info->tile_x;
\r
1366 ((int*)buffer)[buffer_pos++] = cstr_info->tile_y;
\r
1367 ((int*)buffer)[buffer_pos++] = cstr_info->tw;
\r
1368 ((int*)buffer)[buffer_pos++] = cstr_info->th;
\r
1369 ((int*)buffer)[buffer_pos++] = cstr_info->numcomps;
\r
1370 ((int*)buffer)[buffer_pos++] = cstr_info->numlayers;
\r
1371 ((int*)buffer)[buffer_pos++] = cstr_info->numdecompos[0];
\r
1373 for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
\r
1374 /* based on tile 0 */
\r
1375 ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
\r
1376 ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
\r
1378 ((int*)buffer)[buffer_pos++] = cstr_info->main_head_end;
\r
1379 ((int*)buffer)[buffer_pos++] = cstr_info->codestream_size;
\r
1381 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1382 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].tileno;
\r
1383 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].start_pos;
\r
1384 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_header;
\r
1385 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_pos;
\r
1388 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1389 int start_pos, end_pos;
\r
1390 int max_numdecompos = 0;
\r
1393 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1394 if (max_numdecompos < cstr_info->numdecompos[compno])
\r
1395 max_numdecompos = cstr_info->numdecompos[compno];
\r
1398 if (cstr_info->prog == LRCP) { /* LRCP */
\r
1400 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1401 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1402 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1404 if (resno > cstr_info->numdecompos[compno])
\r
1406 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1407 for (precno = 0; precno < prec_max; precno++) {
\r
1408 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1409 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1410 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1411 ((int*)buffer)[buffer_pos++] = tileno;
\r
1412 ((int*)buffer)[buffer_pos++] = layno;
\r
1413 ((int*)buffer)[buffer_pos++] = resno;
\r
1414 ((int*)buffer)[buffer_pos++] = compno;
\r
1415 ((int*)buffer)[buffer_pos++] = precno;
\r
1416 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1417 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1424 else if (cstr_info->prog == RLCP) { /* RLCP */
\r
1426 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1427 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1428 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1430 if (resno > cstr_info->numdecompos[compno])
\r
1432 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1433 for (precno = 0; precno < prec_max; precno++) {
\r
1434 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1435 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1436 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1437 ((int*)buffer)[buffer_pos++] = tileno;
\r
1438 ((int*)buffer)[buffer_pos++] = resno;
\r
1439 ((int*)buffer)[buffer_pos++] = layno;
\r
1440 ((int*)buffer)[buffer_pos++] = compno;
\r
1441 ((int*)buffer)[buffer_pos++] = precno;
\r
1442 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1443 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1450 else if (cstr_info->prog == RPCL) { /* RPCL */
\r
1452 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1453 /* I suppose components have same XRsiz, YRsiz */
\r
1454 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1455 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1456 int x1 = x0 + cstr_info->tile_x;
\r
1457 int y1 = y0 + cstr_info->tile_y;
\r
1458 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1460 if (resno > cstr_info->numdecompos[compno])
\r
1462 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1463 for (precno = 0; precno < prec_max; precno++) {
\r
1464 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1465 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1466 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1467 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1468 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1469 for(y = y0; y < y1; y++) {
\r
1470 if (precno_y*pcy == y ) {
\r
1471 for (x = x0; x < x1; x++) {
\r
1472 if (precno_x*pcx == x ) {
\r
1473 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1474 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1475 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1476 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1477 ((int*)buffer)[buffer_pos++] = tileno;
\r
1478 ((int*)buffer)[buffer_pos++] = resno;
\r
1479 ((int*)buffer)[buffer_pos++] = precno;
\r
1480 ((int*)buffer)[buffer_pos++] = compno;
\r
1481 ((int*)buffer)[buffer_pos++] = layno;
\r
1482 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1483 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1489 } /* y = y0..y1 */
\r
1494 else if (cstr_info->prog == PCRL) { /* PCRL */
\r
1495 /* I suppose components have same XRsiz, YRsiz */
\r
1496 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1497 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1498 int x1 = x0 + cstr_info->tile_x;
\r
1499 int y1 = y0 + cstr_info->tile_y;
\r
1501 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1502 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1504 if (resno > cstr_info->numdecompos[compno])
\r
1506 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1507 for (precno = 0; precno < prec_max; precno++) {
\r
1508 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1509 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1510 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1511 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1512 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1513 for(y = y0; y < y1; y++) {
\r
1514 if (precno_y*pcy == y ) {
\r
1515 for (x = x0; x < x1; x++) {
\r
1516 if (precno_x*pcx == x ) {
\r
1517 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1518 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1519 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1520 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1521 ((int*)buffer)[buffer_pos++] = tileno;
\r
1522 ((int*)buffer)[buffer_pos++] = precno;
\r
1523 ((int*)buffer)[buffer_pos++] = compno;
\r
1524 ((int*)buffer)[buffer_pos++] = resno;
\r
1525 ((int*)buffer)[buffer_pos++] = layno;
\r
1526 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1527 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1533 } /* y = y0..y1 */
\r
1540 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1541 /* I suppose components have same XRsiz, YRsiz */
\r
1542 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1543 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1544 int x1 = x0 + cstr_info->tile_x;
\r
1545 int y1 = y0 + cstr_info->tile_y;
\r
1547 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1549 if (resno > cstr_info->numdecompos[compno])
\r
1551 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1552 for (precno = 0; precno < prec_max; precno++) {
\r
1553 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1554 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1555 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1556 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1557 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1558 for(y = y0; y < y1; y++) {
\r
1559 if (precno_y*pcy == y ) {
\r
1560 for (x = x0; x < x1; x++) {
\r
1561 if (precno_x*pcx == x ) {
\r
1562 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1563 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1564 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1565 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1566 ((int*)buffer)[buffer_pos++] = tileno;
\r
1567 ((int*)buffer)[buffer_pos++] = compno;
\r
1568 ((int*)buffer)[buffer_pos++] = precno;
\r
1569 ((int*)buffer)[buffer_pos++] = resno;
\r
1570 ((int*)buffer)[buffer_pos++] = layno;
\r
1571 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1572 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1578 } /* y = y0..y1 */
\r
1585 if (buffer_pos > *buffer_size) {
\r
1586 /*opj_event_msg(j2k->cinfo, EVT_ERROR, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);*/
\r
1587 fprintf(stderr, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);
\r
1597 /* --------------------------------------------------------------------------
\r
1598 ------------ Get the image byte[] from the Java object -------------------*/
\r
1600 static opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env, jobject obj, jclass cls) {
\r
1601 int i,max,shift,w,h,depth;
\r
1602 opj_image_t * img = NULL;
\r
1603 int compno, numcomps;
\r
1604 opj_image_t * image = NULL;
\r
1605 opj_image_comp_t *comp;
\r
1606 opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
\r
1607 OPJ_COLOR_SPACE color_space;
\r
1619 /* Image width, height and depth*/
\r
1620 fid = (*env)->GetFieldID(env, cls,"width", "I");
\r
1621 ji = (*env)->GetIntField(env, obj, fid);
\r
1624 fid = (*env)->GetFieldID(env, cls,"height", "I");
\r
1625 ji = (*env)->GetIntField(env, obj, fid);
\r
1628 fid = (*env)->GetFieldID(env, cls,"depth", "I");
\r
1629 ji = (*env)->GetIntField(env, obj, fid);
\r
1632 /* Read the image*/
\r
1635 color_space = CLRSPC_GRAY;
\r
1638 color_space = CLRSPC_SRGB;
\r
1640 memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
\r
1642 if (numcomps == 1) {
\r
1643 cmptparm[0].x0 = parameters->image_offset_x0;
\r
1644 cmptparm[0].y0 = parameters->image_offset_y0;
\r
1645 cmptparm[0].w = !cmptparm[0].x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm[0].x0 + (w - 1) * parameters->subsampling_dx + 1;
\r
1646 cmptparm[0].h = !cmptparm[0].y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm[0].y0 + (h - 1) * parameters->subsampling_dy + 1;
\r
1647 /* Java types are always signed but we use them as unsigned types (shift of the negative part of
\r
1648 the pixels of the images in Telemis before entering the encoder).*/
\r
1649 cmptparm[0].sgnd = 0;
\r
1651 cmptparm[0].prec=depth;
\r
1653 cmptparm[0].prec = 8;
\r
1654 cmptparm[0].bpp = cmptparm[0].prec;
\r
1655 cmptparm[0].dx = parameters->subsampling_dx;
\r
1656 cmptparm[0].dy = parameters->subsampling_dy;
\r
1657 /*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
1658 cmptparm[0].h, cmptparm[0].sgnd, cmptparm[0].bpp, cmptparm[0].dx, cmptparm[0].dy, color_space);*/
\r
1660 for(i = 0; i < numcomps; i++) {
\r
1661 cmptparm[i].prec = 8;
\r
1662 cmptparm[i].bpp = 8;
\r
1663 cmptparm[i].sgnd = 0;
\r
1664 cmptparm[i].dx = parameters->subsampling_dx;
\r
1665 cmptparm[i].dy = parameters->subsampling_dy;
\r
1666 cmptparm[i].w = w;
\r
1667 cmptparm[i].h = h;
\r
1671 /* create the image */
\r
1672 image = opj_image_create(numcomps, &cmptparm[0], color_space);
\r
1678 image->numcomps=1;
\r
1680 image->numcomps = 3;
\r
1683 /* set image offset and reference grid */
\r
1684 image->x0 = cmptparm[0].x0;
\r
1685 image->y0 = cmptparm[0].x0;
\r
1686 image->x1 = cmptparm[0].w;
\r
1687 image->y1 = cmptparm[0].h;
\r
1689 /* set image data */
\r
1690 for (compno=0; compno<numcomps; compno++) {
\r
1691 comp = &image->comps[compno];
\r
1694 fid = (*env)->GetFieldID(env, cls,"image8", "[B"); /* byteArray []*/
\r
1695 jba = (*env)->GetObjectField(env, obj, fid);
\r
1696 len = (*env)->GetArrayLength(env, jba);
\r
1698 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, &isCopy);
\r
1699 /*printf("C: before transfering 8 bpp image\n");*/
\r
1701 for(i=0; i< len;i++) {
\r
1702 comp->data[i] = (char) jbBody[i];
\r
1703 if (comp->data[i] > max) max = comp->data[i];
\r
1706 for(i=0; i< len;i++) {
\r
1707 comp->data[i] = (unsigned char) jbBody[i];
\r
1708 if (comp->data[i] > max) max = comp->data[i];
\r
1711 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1712 } else if(depth == 16) {
\r
1713 fid = (*env)->GetFieldID(env, cls,"image16", "[S"); /* shortArray []*/
\r
1714 jsa = (*env)->GetObjectField(env, obj, fid);
\r
1715 len = (*env)->GetArrayLength(env, jsa);
\r
1717 jsBody = (*env)->GetPrimitiveArrayCritical(env, jsa, &isCopy);
\r
1718 /*printf("C: before transfering 16 bpp image\n");*/
\r
1719 if (comp->sgnd) { /* Special behaviour to deal with signed elements ??*/
\r
1720 comp->data[i] = (short) jsBody[i];
\r
1721 for(i=0; i< len;i++) {
\r
1722 if (comp->data[i] > max) max = comp->data[i];
\r
1725 for(i=0; i< len;i++) {
\r
1726 comp->data[i] = (unsigned short) jsBody[i];
\r
1727 if (comp->data[i] > max) max = comp->data[i];
\r
1730 (*env)->ReleasePrimitiveArrayCritical(env, jsa, jsBody, 0);
\r
1731 } else if (depth == 24) {
\r
1732 fid = (*env)->GetFieldID(env, cls,"image24", "[I"); /* intArray []*/
\r
1733 jia = (*env)->GetObjectField(env, obj, fid);
\r
1734 len = (*env)->GetArrayLength(env, jia);
\r
1737 jiBody = (*env)->GetPrimitiveArrayCritical(env, jia, &isCopy);
\r
1738 /*printf("C: before transfering 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);*/
\r
1739 if (comp->sgnd) { /* Special behaviour to deal with signed elements ?? XXXXX*/
\r
1740 for(i=0; i< len;i++) {
\r
1741 comp->data[i] = ( ((int) jiBody[i]) & (0xFF << shift) ) >> shift;
\r
1742 if (comp->data[i] > max) max = comp->data[i];
\r
1745 for(i=0; i< len;i++) {
\r
1746 comp->data[i] = ( ((unsigned int) jiBody[i]) & (0xFF << shift) ) >> shift;
\r
1747 if (comp->data[i] > max) max = comp->data[i];
\r
1750 (*env)->ReleasePrimitiveArrayCritical(env, jia, jiBody, 0);
\r
1752 comp->bpp = int_floorlog2(max)+1;
\r
1753 comp->prec = comp->bpp;
\r
1754 /*printf("C: component %d: max %d, real bpp = %d\n", compno, max, comp->bpp);*/
\r
1760 /* --------------------------------------------------------------------------
\r
1761 -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/
\r
1762 JNIEXPORT jlong JNICALL Java_org_openJpeg_OpenJPEGJavaEncoder_internalEncodeImageToJ2K(JNIEnv *env, jobject obj, jobjectArray javaParameters) {
\r
1763 int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */
\r
1764 char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */
\r
1765 opj_bool bSuccess;
\r
1766 opj_cparameters_t parameters; /* compression parameters */
\r
1767 img_fol_t img_fol;
\r
1768 opj_event_mgr_t event_mgr; /* event manager */
\r
1769 opj_image_t *image = NULL;
\r
1770 int i,j,num_images;
\r
1772 opj_codestream_info_t cstr_info; /* Codestream information structure */
\r
1773 char indexfilename[OPJ_PATH_LEN]; /* index file name */
\r
1775 char* compressed_index = NULL;
\r
1776 int compressed_index_size=-1;
\r
1777 /* ==> Access variables to the Java member variables*/
\r
1785 callback_variables_t msgErrorCallback_vars;
\r
1786 /* <== access variable to the Java member variables.*/
\r
1788 /* For the encoding and storage into the file*/
\r
1789 opj_cinfo_t* cinfo;
\r
1790 int codestream_length;
\r
1791 opj_cio_t *cio = NULL;
\r
1794 /* JNI reference to the calling class*/
\r
1795 cls = (*env)->GetObjectClass(env, obj);
\r
1797 /* Pointers to be able to call a Java method for all the info and error messages*/
\r
1798 msgErrorCallback_vars.env = env;
\r
1799 msgErrorCallback_vars.jobj = &obj;
\r
1800 msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V");
\r
1801 msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V");
\r
1803 arraySize = (*env)->GetArrayLength(env, javaParameters);
\r
1804 argc = (int) arraySize +1;
\r
1805 argv = opj_malloc(argc*sizeof(char*));
\r
1806 argv[0] = "ProgramName.exe"; /* The program name: useless*/
\r
1808 for (i=1; i<argc; i++) {
\r
1809 object = (*env)->GetObjectArrayElement(env, javaParameters, i-1);
\r
1810 argv[i] = (char*)(*env)->GetStringUTFChars(env, object, &isCopy);
\r
1814 for (i=0; i<argc; i++) {
\r
1815 printf("[%s]",argv[i]);
\r
1820 configure the event callbacks
\r
1822 memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
\r
1823 event_mgr.error_handler = error_callback;
\r
1824 event_mgr.warning_handler = warning_callback;
\r
1825 event_mgr.info_handler = info_callback;
\r
1827 /* set encoding parameters to default values */
\r
1828 opj_set_default_encoder_parameters(¶meters);
\r
1829 parameters.cod_format = J2K_CFMT;
\r
1830 /*parameters.index_on = 1;*/
\r
1832 /* Initialize indexfilename and img_fol */
\r
1833 *indexfilename = 0;
\r
1834 memset(&img_fol,0,sizeof(img_fol_t));
\r
1836 /* parse input and get user encoding parameters */
\r
1837 if (parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) {
\r
1838 /* Release the Java arguments array*/
\r
1839 for (i=1; i<argc; i++)
\r
1840 (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
\r
1844 /* Release the Java arguments array*/
\r
1845 for (i=1; i<argc; i++)
\r
1846 (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
\r
1848 if (parameters.cp_cinema){
\r
1849 cinema_parameters(¶meters);
\r
1853 /* Create comment for codestream */
\r
1854 if(parameters.cp_comment == NULL) {
\r
1855 const char comment[] = "Created by JavaOpenJPEG version ";
\r
1856 const size_t clen = strlen(comment);
\r
1857 const char *version = opj_version();
\r
1860 parameters.cp_comment = (char*)opj_malloc(clen+strlen(version)+11);
\r
1861 sprintf(parameters.cp_comment,"%s%s with JPWL", comment, version);
\r
1863 parameters.cp_comment = (char*)opj_malloc(clen+strlen(version)+1);
\r
1864 sprintf(parameters.cp_comment,"%s%s", comment, version);
\r
1870 /* Read directory if necessary */
\r
1873 /*Encoding image one by one*/
\r
1874 for(imageno=0;imageno<num_images;imageno++)
\r
1877 fprintf(stderr,"\n");
\r
1879 image = loadImage(¶meters, env, obj, cls);
\r
1880 /*printf("C: after load image: image = %d\n", image);*/
\r
1882 fprintf(stderr, "Unable to load image\n");
\r
1886 /* Decide if MCT should be used */
\r
1887 parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
\r
1889 if(parameters.cp_cinema){
\r
1890 cinema_setup_encoder(¶meters,image,&img_fol);
\r
1893 /* encode the destination image */
\r
1894 /* ---------------------------- */
\r
1895 /* get a J2K compressor handle */
\r
1896 if (parameters.cod_format == J2K_CFMT) { /* J2K format output */
\r
1897 cinfo = opj_create_compress(CODEC_J2K);
\r
1898 } else { /* JP2 format output */
\r
1899 cinfo = opj_create_compress(CODEC_JP2);
\r
1901 /* catch events using our callbacks and give a local context */
\r
1902 opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, &msgErrorCallback_vars);
\r
1904 /* setup the encoder parameters using the current image and user parameters */
\r
1905 opj_setup_encoder(cinfo, ¶meters, image);
\r
1907 /* open a byte stream for writing */
\r
1908 /* allocate memory for all tiles */
\r
1909 cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
\r
1911 /* encode the image */
\r
1912 bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);
\r
1913 printf("C: after opj_encode_with_info\n");
\r
1915 opj_cio_close(cio);
\r
1916 fprintf(stderr, "failed to encode image\n");
\r
1919 codestream_length = cio_tell(cio);
\r
1921 /* write the index on disk, if needed (-x 'filename') */
\r
1922 if (*indexfilename) {
\r
1923 bSuccess = write_index_file(&cstr_info, indexfilename);
\r
1925 fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename);
\r
1929 compressed_index = create_index_into_byte_array(&cstr_info, &compressed_index_size);
\r
1930 /* Allocates the Java compressedIndex byte[] and sends this index into the Java object */
\r
1931 fid = (*env)->GetFieldID(env, cls,"compressedIndex", "[B");
\r
1932 jba = (*env)->NewByteArray(env, compressed_index_size+1);
\r
1933 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
\r
1934 memcpy(jbBody, compressed_index, compressed_index_size);
\r
1935 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1936 (*env)->SetObjectField(env, obj, fid, jba);
\r
1937 opj_free(compressed_index);
\r
1939 /* write the generated codestream to disk ? */
\r
1940 if (parameters.outfile[0]!='\0') {
\r
1941 f = fopen(parameters.outfile, "wb");
\r
1943 fprintf(stderr, "failed to open [%s] for writing\n", parameters.outfile);
\r
1946 fwrite(cio->buffer, 1, codestream_length, f);
\r
1948 fprintf(stdout,"Generated outfile [%s]\n",parameters.outfile);
\r
1951 /* Write the generated codestream to the Java pre-allocated compressedStream byte[] */
\r
1952 fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");
\r
1953 jba = (*env)->GetObjectField(env, obj, fid);
\r
1954 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
\r
1955 memcpy(jbBody, cio->buffer, codestream_length);
\r
1956 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1958 /* close and free the byte stream */
\r
1959 opj_cio_close(cio);
\r
1961 /* free remaining compression structures */
\r
1962 opj_destroy_compress(cinfo);
\r
1963 opj_destroy_cstr_info(&cstr_info);
\r
1965 /* free image data */
\r
1966 opj_image_destroy(image);
\r
1969 /* free user parameters structure */
\r
1970 if(parameters.cp_comment) opj_free(parameters.cp_comment);
\r
1971 if(parameters.cp_matrice) opj_free(parameters.cp_matrice);
\r
1973 return codestream_length;
\r