2 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
\r
3 * Copyright (c) 2002-2007, Professor Benoit Macq
\r
4 * Copyright (c) 2001-2003, David Janssens
\r
5 * Copyright (c) 2002-2003, Yannick Verschueren
\r
6 * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
\r
7 * Copyright (c) 2005, Herve Drolon, FreeImage Team
\r
8 * Copyright (c) 2006-2007, Parvatha Elangovan
\r
9 * Copyright (c) 2007, Patrick Piscaglia (Telemis)
\r
10 * All rights reserved.
\r
12 * Redistribution and use in source and binary forms, with or without
\r
13 * modification, are permitted provided that the following conditions
\r
15 * 1. Redistributions of source code must retain the above copyright
\r
16 * notice, this list of conditions and the following disclaimer.
\r
17 * 2. Redistributions in binary form must reproduce the above copyright
\r
18 * notice, this list of conditions and the following disclaimer in the
\r
19 * documentation and/or other materials provided with the distribution.
\r
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
\r
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\r
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
\r
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
\r
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
\r
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
\r
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
\r
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
\r
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
\r
31 * POSSIBILITY OF SUCH DAMAGE.
\r
39 #include "openjpeg.h"
\r
40 #include "opj_getopt.h"
\r
41 #include "convert.h"
\r
44 #include "org_openJpeg_OpenJPEGJavaEncoder.h"
\r
47 #define stricmp strcasecmp
\r
48 #define strnicmp strncasecmp
\r
51 #include "format_defs.h"
\r
53 #define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/
\r
54 #define CINEMA_48_CS 651041 /*Codestream length for 48fps*/
\r
55 #define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/
\r
56 #define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/
\r
58 extern int get_file_format(char *filename);
\r
59 extern void error_callback(const char *msg, void *client_data);
\r
60 extern warning_callback(const char *msg, void *client_data);
\r
61 extern void info_callback(const char *msg, void *client_data);
\r
63 typedef struct callback_variables {
\r
65 /** 'jclass' object used to call a Java method from the C */
\r
67 /** 'jclass' object used to call a Java method from the C */
\r
68 jmethodID message_mid;
\r
69 jmethodID error_mid;
\r
70 } callback_variables_t;
\r
72 typedef struct dircnt{
\r
73 /** Buffer for holding images read from Directory*/
\r
75 /** Pointer to the buffer*/
\r
79 typedef struct img_folder{
\r
80 /** The directory path of the folder containing input images*/
\r
86 /** Enable Cod Format for output*/
\r
87 char set_out_format;
\r
88 /** User specified rate stored in case of cinema option*/
\r
92 void encode_help_display() {
\r
93 fprintf(stdout,"HELP\n----\n\n");
\r
94 fprintf(stdout,"- the -h option displays this help information on screen\n\n");
\r
97 fprintf(stdout,"List of parameters for the JPEG 2000 "
\r
100 #endif /* USE_JPWL */
\r
103 fprintf(stdout,"\n");
\r
104 fprintf(stdout,"REMARKS:\n");
\r
105 fprintf(stdout,"---------\n");
\r
106 fprintf(stdout,"\n");
\r
107 fprintf(stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n");
\r
108 fprintf(stdout,"COD and QCD never appear in the tile_header.\n");
\r
109 fprintf(stdout,"\n");
\r
110 fprintf(stdout,"- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n");
\r
111 fprintf(stdout,"color image. You need enough disk space memory (twice the original) to encode \n");
\r
112 fprintf(stdout,"the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n");
\r
113 fprintf(stdout,"\n");
\r
114 fprintf(stdout,"By default:\n");
\r
115 fprintf(stdout,"------------\n");
\r
116 fprintf(stdout,"\n");
\r
117 fprintf(stdout," * Lossless\n");
\r
118 fprintf(stdout," * 1 tile\n");
\r
119 fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");
\r
120 fprintf(stdout," * Size of code-block : 64 x 64\n");
\r
121 fprintf(stdout," * Number of resolutions: 6\n");
\r
122 fprintf(stdout," * No SOP marker in the codestream\n");
\r
123 fprintf(stdout," * No EPH marker in the codestream\n");
\r
124 fprintf(stdout," * No sub-sampling in x or y direction\n");
\r
125 fprintf(stdout," * No mode switch activated\n");
\r
126 fprintf(stdout," * Progression order: LRCP\n");
\r
127 fprintf(stdout," * No index file\n");
\r
128 fprintf(stdout," * No ROI upshifted\n");
\r
129 fprintf(stdout," * No offset of the origin of the image\n");
\r
130 fprintf(stdout," * No offset of the origin of the tiles\n");
\r
131 fprintf(stdout," * Reversible DWT 5-3\n");
\r
134 fprintf(stdout," * No JPWL protection\n");
\r
135 #endif /* USE_JPWL */
\r
137 fprintf(stdout,"\n");
\r
138 fprintf(stdout,"Parameters:\n");
\r
139 fprintf(stdout,"------------\n");
\r
140 fprintf(stdout,"\n");
\r
141 fprintf(stdout,"Required Parameters (except with -h):\n");
\r
142 fprintf(stdout,"One of the two options -ImgDir or -i must be used\n");
\r
143 fprintf(stdout,"\n");
\r
144 fprintf(stdout,"-ImgDir : Image file Directory path (example ../Images) \n");
\r
145 fprintf(stdout," When using this option -OutFor must be used\n");
\r
146 fprintf(stdout,"\n");
\r
147 fprintf(stdout,"-OutFor \n");
\r
148 fprintf(stdout," REQUIRED only if -ImgDir is used\n");
\r
149 fprintf(stdout," Need to specify only format without filename <BMP> \n");
\r
150 fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA formats\n");
\r
151 fprintf(stdout,"\n");
\r
152 fprintf(stdout,"-i : source file (-i source.pnm also *.pgm, *.ppm, *.bmp, *.tif, *.raw, *.tga) \n");
\r
153 fprintf(stdout," When using this option -o must be used\n");
\r
154 fprintf(stdout,"\n");
\r
155 fprintf(stdout,"-o : destination file (-o dest.j2k or .jp2) \n");
\r
156 fprintf(stdout,"\n");
\r
157 fprintf(stdout,"Optional Parameters:\n");
\r
158 fprintf(stdout,"\n");
\r
159 fprintf(stdout,"-h : display the help information \n ");
\r
160 fprintf(stdout,"\n");
\r
161 fprintf(stdout,"-cinema2K : Digital Cinema 2K profile compliant codestream for 2K resolution.(-cinema2k 24 or 48) \n");
\r
162 fprintf(stdout," Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n");
\r
163 fprintf(stdout,"\n");
\r
164 fprintf(stdout,"-cinema4K : Digital Cinema 4K profile compliant codestream for 4K resolution \n");
\r
165 fprintf(stdout," Frames per second not required. Default value is 24fps\n");
\r
166 fprintf(stdout,"\n");
\r
167 fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n ");
\r
168 fprintf(stdout," - The rate specified for each quality level is the desired \n");
\r
169 fprintf(stdout," compression factor.\n");
\r
170 fprintf(stdout," Example: -r 20,10,1 means quality 1: compress 20x, \n");
\r
171 fprintf(stdout," quality 2: compress 10x and quality 3: compress lossless\n");
\r
172 fprintf(stdout,"\n");
\r
173 fprintf(stdout," (options -r and -q cannot be used together)\n ");
\r
174 fprintf(stdout,"\n");
\r
176 fprintf(stdout,"-q : different psnr for successive layers (-q 30,40,50) \n ");
\r
178 fprintf(stdout," (options -r and -q cannot be used together)\n ");
\r
180 fprintf(stdout,"\n");
\r
181 fprintf(stdout,"-n : number of resolutions (-n 3) \n");
\r
182 fprintf(stdout,"\n");
\r
183 fprintf(stdout,"-b : size of code block (-b 32,32) \n");
\r
184 fprintf(stdout,"\n");
\r
185 fprintf(stdout,"-c : size of precinct (-c 128,128) \n");
\r
186 fprintf(stdout,"\n");
\r
187 fprintf(stdout,"-t : size of tile (-t 512,512) \n");
\r
188 fprintf(stdout,"\n");
\r
189 fprintf(stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");
\r
190 fprintf(stdout,"\n");
\r
191 fprintf(stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n");
\r
192 fprintf(stdout," Remark: subsampling bigger than 2 can produce error\n");
\r
193 fprintf(stdout,"\n");
\r
194 fprintf(stdout,"-POC : Progression order change (-POC T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL) \n");
\r
195 fprintf(stdout," Example: T1=0,0,1,5,3,CPRL \n");
\r
196 fprintf(stdout," : Ttilenumber=Resolution num start,Component num start,Layer num end,Resolution num end,Component num end,Progression order\n");
\r
197 fprintf(stdout,"\n");
\r
198 fprintf(stdout,"-SOP : write SOP marker before each packet \n");
\r
199 fprintf(stdout,"\n");
\r
200 fprintf(stdout,"-EPH : write EPH marker after each header packet \n");
\r
201 fprintf(stdout,"\n");
\r
202 fprintf(stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");
\r
203 fprintf(stdout," 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");
\r
204 fprintf(stdout," Indicate multiple modes by adding their values. \n");
\r
205 fprintf(stdout," ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");
\r
206 fprintf(stdout,"\n");
\r
207 fprintf(stdout,"-TP : devide packets of every tile into tile-parts (-TP R) [R, L, C]\n");
\r
208 fprintf(stdout,"\n");
\r
209 fprintf(stdout,"-x : create an index file *.Idx (-x index_name.Idx) \n");
\r
210 fprintf(stdout,"\n");
\r
211 fprintf(stdout,"-ROI : c=%%d,U=%%d : quantization indices upshifted \n");
\r
212 fprintf(stdout," for component c=%%d [%%d = 0,1,2]\n");
\r
213 fprintf(stdout," with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI c=0,U=25) \n");
\r
214 fprintf(stdout,"\n");
\r
215 fprintf(stdout,"-d : offset of the origin of the image (-d 150,300) \n");
\r
216 fprintf(stdout,"\n");
\r
217 fprintf(stdout,"-T : offset of the origin of the tiles (-T 100,75) \n");
\r
218 fprintf(stdout,"\n");
\r
219 fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n");
\r
220 fprintf(stdout,"\n");
\r
221 fprintf(stdout,"-jpip : write jpip codestream index box in JP2 output file\n");
\r
222 fprintf(stdout," NOTICE: currently supports only RPCL order\n");
\r
223 fprintf(stdout,"\n");
\r
226 fprintf(stdout,"-W : adoption of JPWL (Part 11) capabilities (-W params)\n");
\r
227 fprintf(stdout," The parameters can be written and repeated in any order:\n");
\r
228 fprintf(stdout," [h<tilepart><=type>,s<tilepart><=method>,a=<addr>,...\n");
\r
229 fprintf(stdout," ...,z=<size>,g=<range>,p<tilepart:pack><=type>]\n");
\r
230 fprintf(stdout,"\n");
\r
231 fprintf(stdout," h selects the header error protection (EPB): 'type' can be\n");
\r
232 fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");
\r
233 fprintf(stdout," if 'tilepart' is absent, it is for main and tile headers\n");
\r
234 fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");
\r
235 fprintf(stdout," onwards, up to the next h<> spec, or to the last tilepart\n");
\r
236 fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);
\r
237 fprintf(stdout,"\n");
\r
238 fprintf(stdout," p selects the packet error protection (EEP/UEP with EPBs)\n");
\r
239 fprintf(stdout," to be applied to raw data: '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:pack' is absent, it is from tile 0, packet 0\n");
\r
242 fprintf(stdout," if 'tilepart:pack' is present, it applies from that tile\n");
\r
243 fprintf(stdout," and that packet onwards, up to the next packet spec\n");
\r
244 fprintf(stdout," or to the last packet in the last tilepart in the stream\n");
\r
245 fprintf(stdout," (max. %d specs)\n", JPWL_MAX_NO_PACKSPECS);
\r
246 fprintf(stdout,"\n");
\r
247 fprintf(stdout," s enables sensitivity data insertion (ESD): 'method' can be\n");
\r
248 fprintf(stdout," [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n");
\r
249 fprintf(stdout," 4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n");
\r
250 fprintf(stdout," if 'tilepart' is absent, it is for main header only\n");
\r
251 fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");
\r
252 fprintf(stdout," onwards, up to the next s<> spec, or to the last tilepart\n");
\r
253 fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);
\r
254 fprintf(stdout,"\n");
\r
255 fprintf(stdout," g determines the addressing mode: <range> can be\n");
\r
256 fprintf(stdout," [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n");
\r
257 fprintf(stdout,"\n");
\r
258 fprintf(stdout," a determines the size of data addressing: <addr> can be\n");
\r
259 fprintf(stdout," 2/4 bytes (small/large codestreams). If not set, auto-mode\n");
\r
260 fprintf(stdout,"\n");
\r
261 fprintf(stdout," z determines the size of sensitivity values: <size> can be\n");
\r
262 fprintf(stdout," 1/2 bytes, for the transformed pseudo-floating point value\n");
\r
263 fprintf(stdout,"\n");
\r
264 fprintf(stdout," ex.:\n");
\r
265 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
266 fprintf(stdout," s0=6,s3=-1,a=0,g=1,z=1\n");
\r
267 fprintf(stdout," means\n");
\r
268 fprintf(stdout," predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n");
\r
269 fprintf(stdout," CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n");
\r
270 fprintf(stdout," UEP rs(78,32) for packets 0 to 23 of tile 0,\n");
\r
271 fprintf(stdout," UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n");
\r
272 fprintf(stdout," UEP rs default for packets of tilepart 1,\n");
\r
273 fprintf(stdout," no UEP for packets 0 to 19 of tilepart 3,\n");
\r
274 fprintf(stdout," UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n");
\r
275 fprintf(stdout," relative sensitivity ESD for MH,\n");
\r
276 fprintf(stdout," TSE ESD from TPH 0 to TPH 2, byte range with automatic\n");
\r
277 fprintf(stdout," size of addresses and 1 byte for each sensitivity value\n");
\r
278 fprintf(stdout,"\n");
\r
279 fprintf(stdout," ex.:\n");
\r
280 fprintf(stdout," h,s,p\n");
\r
281 fprintf(stdout," means\n");
\r
282 fprintf(stdout," default protection to headers (MH and TPHs) as well as\n");
\r
283 fprintf(stdout," data packets, one ESD in MH\n");
\r
284 fprintf(stdout,"\n");
\r
285 fprintf(stdout," N.B.: use the following recommendations when specifying\n");
\r
286 fprintf(stdout," the JPWL parameters list\n");
\r
287 fprintf(stdout," - when you use UEP, always pair the 'p' option with 'h'\n");
\r
288 fprintf(stdout," \n");
\r
289 #endif /* USE_JPWL */
\r
291 fprintf(stdout,"IMPORTANT:\n");
\r
292 fprintf(stdout,"-----------\n");
\r
293 fprintf(stdout,"\n");
\r
294 fprintf(stdout,"The index file has the structure below:\n");
\r
295 fprintf(stdout,"---------------------------------------\n");
\r
296 fprintf(stdout,"\n");
\r
297 fprintf(stdout,"Image_height Image_width\n");
\r
298 fprintf(stdout,"progression order\n");
\r
299 fprintf(stdout,"Tiles_size_X Tiles_size_Y\n");
\r
300 fprintf(stdout,"Tiles_nb_X Tiles_nb_Y\n");
\r
301 fprintf(stdout,"Components_nb\n");
\r
302 fprintf(stdout,"Layers_nb\n");
\r
303 fprintf(stdout,"decomposition_levels\n");
\r
304 fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");
\r
305 fprintf(stdout," [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");
\r
306 fprintf(stdout,"Main_header_start_position\n");
\r
307 fprintf(stdout,"Main_header_end_position\n");
\r
308 fprintf(stdout,"Codestream_size\n");
\r
309 fprintf(stdout,"\n");
\r
310 fprintf(stdout,"INFO ON TILES\n");
\r
311 fprintf(stdout,"tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n");
\r
312 fprintf(stdout,"Tile_0 start_pos end_Theader end_pos NumParts TotalDisto NumPix MaxMSE\n");
\r
313 fprintf(stdout,"Tile_1 '' '' '' '' '' '' ''\n");
\r
314 fprintf(stdout,"...\n");
\r
315 fprintf(stdout,"Tile_Nt '' '' '' '' '' '' ''\n");
\r
316 fprintf(stdout,"...\n");
\r
317 fprintf(stdout,"TILE 0 DETAILS\n");
\r
318 fprintf(stdout,"part_nb tileno num_packs start_pos end_tph_pos end_pos\n");
\r
319 fprintf(stdout,"...\n");
\r
320 fprintf(stdout,"Progression_string\n");
\r
321 fprintf(stdout,"pack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n");
\r
322 fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");
\r
323 fprintf(stdout,"...\n");
\r
324 fprintf(stdout,"Tpacket_Np '' '' '' '' '' '' '' ''\n");
\r
326 fprintf(stdout,"MaxDisto\n");
\r
328 fprintf(stdout,"TotalDisto\n\n");
\r
332 OPJ_PROG_ORDER give_progression(char progression[4]) {
\r
333 if(strncmp(progression, "LRCP", 4) == 0) {
\r
336 if(strncmp(progression, "RLCP", 4) == 0) {
\r
339 if(strncmp(progression, "RPCL", 4) == 0) {
\r
342 if(strncmp(progression, "PCRL", 4) == 0) {
\r
345 if(strncmp(progression, "CPRL", 4) == 0) {
\r
349 return PROG_UNKNOWN;
\r
354 /// Get logarithm of an integer and round downwards.
\r
356 int int_floorlog2(int a) {
\r
358 for (l=0; a>1; l++) {
\r
364 static int initialise_4K_poc(opj_poc_t *POC, int numres){
\r
366 POC[0].resno0 = 0;
\r
367 POC[0].compno0 = 0;
\r
369 POC[0].resno1 = numres-1;
\r
370 POC[0].compno1 = 3;
\r
371 POC[0].prg1 = CPRL;
\r
373 POC[1].resno0 = numres-1;
\r
374 POC[1].compno0 = 0;
\r
376 POC[1].resno1 = numres;
\r
377 POC[1].compno1 = 3;
\r
378 POC[1].prg1 = CPRL;
\r
382 void cinema_parameters(opj_cparameters_t *parameters){
\r
383 parameters->tile_size_on = false;
\r
384 parameters->cp_tdx=1;
\r
385 parameters->cp_tdy=1;
\r
388 parameters->tp_flag = 'C';
\r
389 parameters->tp_on = 1;
\r
391 /*Tile and Image shall be at (0,0)*/
\r
392 parameters->cp_tx0 = 0;
\r
393 parameters->cp_ty0 = 0;
\r
394 parameters->image_offset_x0 = 0;
\r
395 parameters->image_offset_y0 = 0;
\r
397 /*Codeblock size= 32*32*/
\r
398 parameters->cblockw_init = 32;
\r
399 parameters->cblockh_init = 32;
\r
400 parameters->csty |= 0x01;
\r
402 /*The progression order shall be CPRL*/
\r
403 parameters->prog_order = CPRL;
\r
406 parameters->roi_compno = -1;
\r
408 parameters->subsampling_dx = 1; parameters->subsampling_dy = 1;
\r
410 /* 9-7 transform */
\r
411 parameters->irreversible = 1;
\r
415 void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){
\r
418 opj_poc_t *POC = NULL;
\r
420 switch (parameters->cp_cinema){
\r
423 if(parameters->numresolution > 6){
\r
424 parameters->numresolution = 6;
\r
426 if (!((image->comps[0].w == 2048) | (image->comps[0].h == 1080))){
\r
427 fprintf(stdout,"Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3"
\r
428 "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",
\r
429 image->comps[0].w,image->comps[0].h);
\r
430 parameters->cp_rsiz = STD_RSIZ;
\r
435 if(parameters->numresolution < 1){
\r
436 parameters->numresolution = 1;
\r
437 }else if(parameters->numresolution > 7){
\r
438 parameters->numresolution = 7;
\r
440 if (!((image->comps[0].w == 4096) | (image->comps[0].h == 2160))){
\r
441 fprintf(stdout,"Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4"
\r
442 "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",
\r
443 image->comps[0].w,image->comps[0].h);
\r
444 parameters->cp_rsiz = STD_RSIZ;
\r
446 parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution);
\r
450 switch (parameters->cp_cinema){
\r
453 for(i=0 ; i<parameters->tcp_numlayers ; i++){
\r
455 if (img_fol->rates[i]== 0){
\r
456 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
457 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
459 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
460 (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
\r
461 if (temp_rate > CINEMA_24_CS ){
\r
462 parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
463 (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
465 parameters->tcp_rates[i]= img_fol->rates[i];
\r
469 parameters->max_comp_size = COMP_24_CS;
\r
473 for(i=0 ; i<parameters->tcp_numlayers ; i++){
\r
475 if (img_fol->rates[i]== 0){
\r
476 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
477 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
479 temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
480 (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);
\r
481 if (temp_rate > CINEMA_48_CS ){
\r
482 parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/
\r
483 (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);
\r
485 parameters->tcp_rates[i]= img_fol->rates[i];
\r
489 parameters->max_comp_size = COMP_48_CS;
\r
492 parameters->cp_disto_alloc = 1;
\r
496 /* ------------------------------------------------------------------------------------ */
\r
497 int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,
\r
498 img_fol_t *img_fol, char *indexfilename) {
\r
500 opj_option_t long_option[]={
\r
501 {"cinema2K",REQ_ARG, NULL ,'w'},
\r
502 {"cinema4K",NO_ARG, NULL ,'y'},
\r
503 {"ImgDir",REQ_ARG, NULL ,'z'},
\r
504 {"TP",REQ_ARG, NULL ,'u'},
\r
505 {"SOP",NO_ARG, NULL ,'S'},
\r
506 {"EPH",NO_ARG, NULL ,'E'},
\r
507 {"OutFor",REQ_ARG, NULL ,'O'},
\r
508 {"POC",REQ_ARG, NULL ,'P'},
\r
509 {"ROI",REQ_ARG, NULL ,'R'},
\r
510 {"jpip",NO_ARG, NULL, 'J'}
\r
513 /* parse the command line */
\r
515 const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:J"
\r
518 #endif /* USE_JPWL */
\r
521 /*printf("C: parse_cmdline_encoder:");
\r
522 for (i=0; i<argc; i++) {
\r
523 printf("[%s]",argv[i]);
\r
527 totlen=sizeof(long_option);
\r
528 img_fol->set_out_format=0;
\r
529 reset_options_reading();
\r
532 int c = opj_getopt_long(argc, argv, optlist,long_option,totlen);
\r
537 /* ----------------------------------------------------- */
\r
539 case 'o': /* output file */
\r
541 char *outfile = opj_optarg;
\r
542 parameters->cod_format = get_file_format(outfile);
\r
543 switch(parameters->cod_format) {
\r
548 fprintf(stderr, "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile);
\r
551 strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);
\r
555 /* ----------------------------------------------------- */
\r
556 case 'O': /* output format */
\r
558 char outformat[50];
\r
559 char *of = opj_optarg;
\r
560 sprintf(outformat,".%s",of);
\r
561 img_fol->set_out_format = 1;
\r
562 parameters->cod_format = get_file_format(outformat);
\r
563 switch(parameters->cod_format) {
\r
566 img_fol->out_format = opj_optarg;
\r
569 fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n");
\r
576 /* ----------------------------------------------------- */
\r
579 case 'r': /* rates rates/distorsion */
\r
581 char *s = opj_optarg;
\r
582 while (sscanf(s, "%f", ¶meters->tcp_rates[parameters->tcp_numlayers]) == 1) {
\r
583 parameters->tcp_numlayers++;
\r
584 while (*s && *s != ',') {
\r
591 parameters->cp_disto_alloc = 1;
\r
595 /* ----------------------------------------------------- */
\r
597 case 'q': /* add fixed_quality */
\r
599 char *s = opj_optarg;
\r
600 while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers]) == 1) {
\r
601 parameters->tcp_numlayers++;
\r
602 while (*s && *s != ',') {
\r
609 parameters->cp_fixed_quality = 1;
\r
614 /* ----------------------------------------------------- */
\r
616 case 'f': /* mod fixed_quality (before : -q) */
\r
618 int *row = NULL, *col = NULL;
\r
619 int numlayers = 0, numresolution = 0, matrix_width = 0;
\r
621 char *s = opj_optarg;
\r
622 sscanf(s, "%d", &numlayers);
\r
627 parameters->tcp_numlayers = numlayers;
\r
628 numresolution = parameters->numresolution;
\r
629 matrix_width = numresolution * 3;
\r
630 parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int));
\r
633 for (i = 0; i < numlayers; i++) {
\r
634 row = ¶meters->cp_matrice[i * matrix_width];
\r
636 parameters->tcp_rates[i] = 1;
\r
637 sscanf(s, "%d,", &col[0]);
\r
643 for (j = 1; j < numresolution; j++) {
\r
645 sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);
\r
654 if (i < numlayers - 1)
\r
657 parameters->cp_fixed_alloc = 1;
\r
661 /* ----------------------------------------------------- */
\r
663 case 't': /* tiles */
\r
665 sscanf(opj_optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy);
\r
666 parameters->tile_size_on = true;
\r
670 /* ----------------------------------------------------- */
\r
672 case 'n': /* resolution */
\r
674 sscanf(opj_optarg, "%d", ¶meters->numresolution);
\r
678 /* ----------------------------------------------------- */
\r
679 case 'c': /* precinct dimension */
\r
684 char *s = opj_optarg;
\r
687 sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec],
\r
688 ¶meters->prch_init[res_spec], &sep);
\r
689 parameters->csty |= 0x01;
\r
691 s = strpbrk(s, "]") + 2;
\r
693 while (sep == ',');
\r
694 parameters->res_spec = res_spec;
\r
698 /* ----------------------------------------------------- */
\r
700 case 'b': /* code-block dimension */
\r
702 int cblockw_init = 0, cblockh_init = 0;
\r
703 sscanf(opj_optarg, "%d,%d", &cblockw_init, &cblockh_init);
\r
704 if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024
\r
705 || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {
\r
707 "!! Size of code_block error (option -b) !!\n\nRestriction :\n"
\r
708 " * width*height<=4096\n * 4<=width,height<= 1024\n\n");
\r
711 parameters->cblockw_init = cblockw_init;
\r
712 parameters->cblockh_init = cblockh_init;
\r
716 /* ----------------------------------------------------- */
\r
718 case 'x': /* creation of index file */
\r
720 char *index = opj_optarg;
\r
721 strncpy(indexfilename, index, OPJ_PATH_LEN);
\r
725 /* ----------------------------------------------------- */
\r
727 case 'p': /* progression order */
\r
729 char progression[4];
\r
731 strncpy(progression, opj_optarg, 4);
\r
732 parameters->prog_order = give_progression(progression);
\r
733 if (parameters->prog_order == -1) {
\r
734 fprintf(stderr, "Unrecognized progression order "
\r
735 "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");
\r
741 /* ----------------------------------------------------- */
\r
743 case 's': /* subsampling factor */
\r
745 if (sscanf(opj_optarg, "%d,%d", ¶meters->subsampling_dx,
\r
746 ¶meters->subsampling_dy) != 2) {
\r
747 fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n");
\r
753 /* ----------------------------------------------------- */
\r
755 case 'd': /* coordonnate of the reference grid */
\r
757 if (sscanf(opj_optarg, "%d,%d", ¶meters->image_offset_x0,
\r
758 ¶meters->image_offset_y0) != 2) {
\r
759 fprintf(stderr, "-d 'coordonnate of the reference grid' argument "
\r
760 "error !! [-d x0,y0]\n");
\r
766 /* ----------------------------------------------------- */
\r
768 case 'h': /* display an help description */
\r
769 encode_help_display();
\r
772 /* ----------------------------------------------------- */
\r
774 case 'P': /* POC */
\r
776 int numpocs = 0; /* number of progression order change (POC) default 0 */
\r
777 opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */
\r
779 char *s = opj_optarg;
\r
780 POC = parameters->POC;
\r
782 while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,
\r
783 &POC[numpocs].resno0, &POC[numpocs].compno0,
\r
784 &POC[numpocs].layno1, &POC[numpocs].resno1,
\r
785 &POC[numpocs].compno1, &POC[numpocs].progorder) == 7) {
\r
786 POC[numpocs].prg1 = give_progression(POC[numpocs].progorder);
\r
788 while (*s && *s != '/') {
\r
796 parameters->numpocs = numpocs;
\r
800 /* ------------------------------------------------------ */
\r
802 case 'S': /* SOP marker */
\r
804 parameters->csty |= 0x02;
\r
808 /* ------------------------------------------------------ */
\r
810 case 'E': /* EPH marker */
\r
812 parameters->csty |= 0x04;
\r
816 /* ------------------------------------------------------ */
\r
818 case 'M': /* Mode switch pas tous au point !! */
\r
821 if (sscanf(opj_optarg, "%d", &value) == 1) {
\r
822 for (i = 0; i <= 5; i++) {
\r
823 int cache = value & (1 << i);
\r
825 parameters->mode |= (1 << i);
\r
831 /* ------------------------------------------------------ */
\r
833 case 'R': /* ROI */
\r
835 if (sscanf(opj_optarg, "c=%d,U=%d", ¶meters->roi_compno,
\r
836 ¶meters->roi_shift) != 2) {
\r
837 fprintf(stderr, "ROI error !! [-ROI c='compno',U='shift']\n");
\r
843 /* ------------------------------------------------------ */
\r
845 case 'T': /* Tile offset */
\r
847 if (sscanf(opj_optarg, "%d,%d", ¶meters->cp_tx0, ¶meters->cp_ty0) != 2) {
\r
848 fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");
\r
854 /* ------------------------------------------------------ */
\r
856 case 'C': /* add a comment */
\r
858 parameters->cp_comment = (char*)malloc(strlen(opj_optarg) + 1);
\r
859 if(parameters->cp_comment) {
\r
860 strcpy(parameters->cp_comment, opj_optarg);
\r
866 /* ------------------------------------------------------ */
\r
868 case 'I': /* reversible or not */
\r
870 parameters->irreversible = 1;
\r
874 /* ------------------------------------------------------ */
\r
876 case 'u': /* Tile part generation*/
\r
878 parameters->tp_flag = opj_optarg[0];
\r
879 parameters->tp_on = 1;
\r
883 /* ------------------------------------------------------ */
\r
885 case 'z': /* Image Directory path */
\r
887 img_fol->imgdirpath = (char*)malloc(strlen(opj_optarg) + 1);
\r
888 strcpy(img_fol->imgdirpath,opj_optarg);
\r
889 img_fol->set_imgdir=1;
\r
893 /* ------------------------------------------------------ */
\r
895 case 'w': /* Digital Cinema 2K profile compliance*/
\r
898 sscanf(opj_optarg,"%d",&fps);
\r
900 parameters->cp_cinema = CINEMA2K_24;
\r
901 }else if(fps == 48 ){
\r
902 parameters->cp_cinema = CINEMA2K_48;
\r
904 fprintf(stderr,"Incorrect value!! must be 24 or 48\n");
\r
907 fprintf(stdout,"CINEMA 2K compliant codestream\n");
\r
908 parameters->cp_rsiz = CINEMA2K;
\r
913 /* ------------------------------------------------------ */
\r
915 case 'y': /* Digital Cinema 4K profile compliance*/
\r
917 parameters->cp_cinema = CINEMA4K_24;
\r
918 fprintf(stdout,"CINEMA 4K compliant codestream\n");
\r
919 parameters->cp_rsiz = CINEMA4K;
\r
923 /* ------------------------------------------------------ */
\r
927 /* ------------------------------------------------------ */
\r
929 case 'W': /* JPWL capabilities switched on */
\r
931 char *token = NULL;
\r
932 int hprot, pprot, sens, addr, size, range;
\r
934 /* we need to enable indexing */
\r
935 if (!indexfilename) {
\r
936 strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN);
\r
939 /* search for different protection methods */
\r
941 /* break the option in comma points and parse the result */
\r
942 token = strtok(opj_optarg, ",");
\r
943 while(token != NULL) {
\r
945 /* search header error protection method */
\r
946 if (*token == 'h') {
\r
948 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
950 hprot = 1; /* predefined method */
\r
952 if(sscanf(token, "h=%d", &hprot) == 1) {
\r
953 /* Main header, specified */
\r
954 if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
\r
955 ((hprot >= 37) && (hprot <= 128)))) {
\r
956 fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n", hprot);
\r
959 parameters->jpwl_hprot_MH = hprot;
\r
961 } else if(sscanf(token, "h%d=%d", &tile, &hprot) == 2) {
\r
962 /* Tile part header, specified */
\r
963 if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||
\r
964 ((hprot >= 37) && (hprot <= 128)))) {
\r
965 fprintf(stderr, "ERROR -> invalid tile part header protection method h = %d\n", hprot);
\r
969 fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);
\r
972 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
973 parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
\r
974 parameters->jpwl_hprot_TPH[tilespec++] = hprot;
\r
977 } else if(sscanf(token, "h%d", &tile) == 1) {
\r
978 /* Tile part header, unspecified */
\r
980 fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);
\r
983 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
984 parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;
\r
985 parameters->jpwl_hprot_TPH[tilespec++] = hprot;
\r
989 } else if (!strcmp(token, "h")) {
\r
990 /* Main header, unspecified */
\r
991 parameters->jpwl_hprot_MH = hprot;
\r
994 fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
\r
1000 /* search packet error protection method */
\r
1001 if (*token == 'p') {
\r
1003 static int pack = 0, tile = 0, packspec = 0, lastpackno = 0;
\r
1005 pprot = 1; /* predefined method */
\r
1007 if (sscanf(token, "p=%d", &pprot) == 1) {
\r
1008 /* Method for all tiles and all packets */
\r
1009 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1010 ((pprot >= 37) && (pprot <= 128)))) {
\r
1011 fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n", pprot);
\r
1014 parameters->jpwl_pprot_tileno[0] = 0;
\r
1015 parameters->jpwl_pprot_packno[0] = 0;
\r
1016 parameters->jpwl_pprot[0] = pprot;
\r
1018 } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) {
\r
1019 /* method specified from that tile on */
\r
1020 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1021 ((pprot >= 37) && (pprot <= 128)))) {
\r
1022 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1026 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1029 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1030 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1031 parameters->jpwl_pprot_packno[packspec] = 0;
\r
1032 parameters->jpwl_pprot[packspec++] = pprot;
\r
1035 } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) {
\r
1036 /* method fully specified from that tile and that packet on */
\r
1037 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1038 ((pprot >= 37) && (pprot <= 128)))) {
\r
1039 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1043 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1047 fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);
\r
1050 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1051 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1052 parameters->jpwl_pprot_packno[packspec] = pack;
\r
1053 parameters->jpwl_pprot[packspec++] = pprot;
\r
1056 } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) {
\r
1057 /* default method from that tile and that packet on */
\r
1058 if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||
\r
1059 ((pprot >= 37) && (pprot <= 128)))) {
\r
1060 fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);
\r
1064 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1068 fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);
\r
1071 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1072 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1073 parameters->jpwl_pprot_packno[packspec] = pack;
\r
1074 parameters->jpwl_pprot[packspec++] = pprot;
\r
1077 } else if (sscanf(token, "p%d", &tile) == 1) {
\r
1078 /* default from a tile on */
\r
1080 fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);
\r
1083 if (packspec < JPWL_MAX_NO_PACKSPECS) {
\r
1084 parameters->jpwl_pprot_tileno[packspec] = tile;
\r
1085 parameters->jpwl_pprot_packno[packspec] = 0;
\r
1086 parameters->jpwl_pprot[packspec++] = pprot;
\r
1090 } else if (!strcmp(token, "p")) {
\r
1092 parameters->jpwl_pprot_tileno[0] = 0;
\r
1093 parameters->jpwl_pprot_packno[0] = 0;
\r
1094 parameters->jpwl_pprot[0] = pprot;
\r
1097 fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);
\r
1103 /* search sensitivity method */
\r
1104 if (*token == 's') {
\r
1106 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1108 sens = 0; /* predefined: relative error */
\r
1110 if(sscanf(token, "s=%d", &sens) == 1) {
\r
1111 /* Main header, specified */
\r
1112 if ((sens < -1) || (sens > 7)) {
\r
1113 fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n", sens);
\r
1116 parameters->jpwl_sens_MH = sens;
\r
1118 } else if(sscanf(token, "s%d=%d", &tile, &sens) == 2) {
\r
1119 /* Tile part header, specified */
\r
1120 if ((sens < -1) || (sens > 7)) {
\r
1121 fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n", sens);
\r
1125 fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
\r
1128 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
1129 parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
\r
1130 parameters->jpwl_sens_TPH[tilespec++] = sens;
\r
1133 } else if(sscanf(token, "s%d", &tile) == 1) {
\r
1134 /* Tile part header, unspecified */
\r
1136 fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);
\r
1139 if (tilespec < JPWL_MAX_NO_TILESPECS) {
\r
1140 parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;
\r
1141 parameters->jpwl_sens_TPH[tilespec++] = hprot;
\r
1144 } else if (!strcmp(token, "s")) {
\r
1145 /* Main header, unspecified */
\r
1146 parameters->jpwl_sens_MH = sens;
\r
1149 fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token);
\r
1153 parameters->jpwl_sens_size = 2; /* 2 bytes for default size */
\r
1156 /* search addressing size */
\r
1157 if (*token == 'a') {
\r
1159 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1161 addr = 0; /* predefined: auto */
\r
1163 if(sscanf(token, "a=%d", &addr) == 1) {
\r
1165 if ((addr != 0) && (addr != 2) && (addr != 4)) {
\r
1166 fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr);
\r
1169 parameters->jpwl_sens_addr = addr;
\r
1171 } else if (!strcmp(token, "a")) {
\r
1173 parameters->jpwl_sens_addr = addr; /* auto for default size */
\r
1176 fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token);
\r
1182 /* search sensitivity size */
\r
1183 if (*token == 'z') {
\r
1185 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1187 size = 1; /* predefined: 1 byte */
\r
1189 if(sscanf(token, "z=%d", &size) == 1) {
\r
1191 if ((size != 0) && (size != 1) && (size != 2)) {
\r
1192 fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size);
\r
1195 parameters->jpwl_sens_size = size;
\r
1197 } else if (!strcmp(token, "a")) {
\r
1199 parameters->jpwl_sens_size = size; /* 1 for default size */
\r
1202 fprintf(stderr, "ERROR -> invalid size selection = %s\n", token);
\r
1208 /* search range method */
\r
1209 if (*token == 'g') {
\r
1211 static int tile = 0, tilespec = 0, lasttileno = 0;
\r
1213 range = 0; /* predefined: 0 (packet) */
\r
1215 if(sscanf(token, "g=%d", &range) == 1) {
\r
1217 if ((range < 0) || (range > 3)) {
\r
1218 fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range);
\r
1221 parameters->jpwl_sens_range = range;
\r
1223 } else if (!strcmp(token, "g")) {
\r
1225 parameters->jpwl_sens_range = range;
\r
1228 fprintf(stderr, "ERROR -> invalid range selection = %s\n", token);
\r
1234 /* next token or bust */
\r
1235 token = strtok(NULL, ",");
\r
1240 fprintf(stdout, "Info: JPWL capabilities enabled\n");
\r
1241 parameters->jpwl_epc_on = true;
\r
1245 #endif /* USE_JPWL */
\r
1247 /* ------------------------------------------------------ */
\r
1249 case 'J': /* jpip on */
\r
1251 parameters->jpip_on = OPJ_TRUE;
\r
1254 /* ------------------------------------------------------ */
\r
1257 fprintf(stderr, "ERROR -> Command line not valid\n");
\r
1262 /* check for possible errors */
\r
1263 if (parameters->cp_cinema){
\r
1264 if(parameters->tcp_numlayers > 1){
\r
1265 parameters->cp_rsiz = STD_RSIZ;
\r
1266 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
1270 if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality)
\r
1271 && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ parameters->cp_fixed_quality))) {
\r
1272 fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");
\r
1274 } /* mod fixed_quality */
\r
1276 /* if no rate entered, lossless by default */
\r
1277 if (parameters->tcp_numlayers == 0) {
\r
1278 parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */
\r
1279 parameters->tcp_numlayers++;
\r
1280 parameters->cp_disto_alloc = 1;
\r
1283 if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) {
\r
1285 "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",
\r
1286 parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0);
\r
1290 for (i = 0; i < parameters->numpocs; i++) {
\r
1291 if (parameters->POC[i].prg == -1) {
\r
1293 "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",
\r
1302 /** 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
1303 @param buffer_size, increased by the length of the compressed index, in number of bytes
\r
1304 @return a pointer to a char[]
\r
1305 Syntax of the index:
\r
1306 one char for the version number (1): one byte because no problem with little endian, big endian etc.
\r
1307 one int for each of the following informations:
\r
1310 progression order
\r
1317 Nb of resolutions
\r
1319 for each resolution:
\r
1323 End main header position
\r
1328 tile start pos in codestream
\r
1329 tile header end position
\r
1330 tile end position in codestream
\r
1332 For each LRCP, RLCP etc.:
\r
1339 start position in the codestream
\r
1340 end position of this packet
\r
1342 char* create_index_into_byte_array(opj_codestream_info_t *cstr_info, int* buffer_size) {
\r
1343 int tileno, compno, layno, resno, precno, pack_nb, x, y;
\r
1344 char* buffer = NULL;
\r
1345 int buffer_pos = 0;
\r
1349 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1350 for (resno = 0; resno < cstr_info->numdecompos[0] + 1; resno++) {
\r
1351 prec_max = max(prec_max,cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]);
\r
1355 // Compute the size of the index buffer, in number of bytes*/
\r
1358 + (10 /* image_w until decomposition */
\r
1359 + (cstr_info->numdecompos[0]+1) * 2 /* pdx size for each tile */
\r
1360 + 2 /* main_head_end + codestream_size */
\r
1361 + cstr_info->tw * cstr_info->th * 4 /* tile info, without distorsion info */
\r
1362 + cstr_info->tw*cstr_info->th * cstr_info->numlayers * (cstr_info->numdecompos[0] + 1) * cstr_info->numcomps * prec_max *8
\r
1364 //printf("C: index buffer size = %d bytes\n", *buffer_size);
\r
1365 buffer = (char*) malloc(*buffer_size);
\r
1368 //opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to allocate index buffer for writing %d int\n", *buffer_size);
\r
1369 fprintf(stderr, "failed to allocate index buffer for writing %d int\n", *buffer_size);
\r
1373 buffer[0] = 1; // Version stored on a byte
\r
1375 // Remaining informations are stored on a int.
\r
1376 ((int*)buffer)[buffer_pos++] = cstr_info->image_w;
\r
1377 ((int*)buffer)[buffer_pos++] = cstr_info->image_h;
\r
1378 ((int*)buffer)[buffer_pos++] = cstr_info->prog;
\r
1379 ((int*)buffer)[buffer_pos++] = cstr_info->tile_x;
\r
1380 ((int*)buffer)[buffer_pos++] = cstr_info->tile_y;
\r
1381 ((int*)buffer)[buffer_pos++] = cstr_info->tw;
\r
1382 ((int*)buffer)[buffer_pos++] = cstr_info->th;
\r
1383 ((int*)buffer)[buffer_pos++] = cstr_info->numcomps;
\r
1384 ((int*)buffer)[buffer_pos++] = cstr_info->numlayers;
\r
1385 ((int*)buffer)[buffer_pos++] = cstr_info->numdecompos[0];
\r
1387 for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
\r
1388 /* based on tile 0 */
\r
1389 ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
\r
1390 ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);
\r
1392 ((int*)buffer)[buffer_pos++] = cstr_info->main_head_end;
\r
1393 ((int*)buffer)[buffer_pos++] = cstr_info->codestream_size;
\r
1395 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1396 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].tileno;
\r
1397 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].start_pos;
\r
1398 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_header;
\r
1399 ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_pos;
\r
1402 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
\r
1403 int start_pos, end_pos;
\r
1404 int max_numdecompos = 0;
\r
1407 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1408 if (max_numdecompos < cstr_info->numdecompos[compno])
\r
1409 max_numdecompos = cstr_info->numdecompos[compno];
\r
1412 if (cstr_info->prog == LRCP) { /* LRCP */
\r
1414 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1415 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1416 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1418 if (resno > cstr_info->numdecompos[compno])
\r
1420 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1421 for (precno = 0; precno < prec_max; precno++) {
\r
1422 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1423 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1424 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1425 ((int*)buffer)[buffer_pos++] = tileno;
\r
1426 ((int*)buffer)[buffer_pos++] = layno;
\r
1427 ((int*)buffer)[buffer_pos++] = resno;
\r
1428 ((int*)buffer)[buffer_pos++] = compno;
\r
1429 ((int*)buffer)[buffer_pos++] = precno;
\r
1430 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1431 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1438 else if (cstr_info->prog == RLCP) { /* RLCP */
\r
1440 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1441 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1442 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1444 if (resno > cstr_info->numdecompos[compno])
\r
1446 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1447 for (precno = 0; precno < prec_max; precno++) {
\r
1448 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1449 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1450 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1451 ((int*)buffer)[buffer_pos++] = tileno;
\r
1452 ((int*)buffer)[buffer_pos++] = resno;
\r
1453 ((int*)buffer)[buffer_pos++] = layno;
\r
1454 ((int*)buffer)[buffer_pos++] = compno;
\r
1455 ((int*)buffer)[buffer_pos++] = precno;
\r
1456 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1457 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1464 else if (cstr_info->prog == RPCL) { /* RPCL */
\r
1466 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1467 /* I suppose components have same XRsiz, YRsiz */
\r
1468 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1469 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1470 int x1 = x0 + cstr_info->tile_x;
\r
1471 int y1 = y0 + cstr_info->tile_y;
\r
1472 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1474 if (resno > cstr_info->numdecompos[compno])
\r
1476 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1477 for (precno = 0; precno < prec_max; precno++) {
\r
1478 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1479 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1480 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1481 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1482 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1483 for(y = y0; y < y1; y++) {
\r
1484 if (precno_y*pcy == y ) {
\r
1485 for (x = x0; x < x1; x++) {
\r
1486 if (precno_x*pcx == x ) {
\r
1487 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1488 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1489 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1490 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1491 ((int*)buffer)[buffer_pos++] = tileno;
\r
1492 ((int*)buffer)[buffer_pos++] = resno;
\r
1493 ((int*)buffer)[buffer_pos++] = precno;
\r
1494 ((int*)buffer)[buffer_pos++] = compno;
\r
1495 ((int*)buffer)[buffer_pos++] = layno;
\r
1496 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1497 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1503 } /* y = y0..y1 */
\r
1508 else if (cstr_info->prog == PCRL) { /* PCRL */
\r
1509 /* I suppose components have same XRsiz, YRsiz */
\r
1510 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1511 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1512 int x1 = x0 + cstr_info->tile_x;
\r
1513 int y1 = y0 + cstr_info->tile_y;
\r
1515 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1516 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1518 if (resno > cstr_info->numdecompos[compno])
\r
1520 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1521 for (precno = 0; precno < prec_max; precno++) {
\r
1522 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1523 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1524 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1525 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1526 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1527 for(y = y0; y < y1; y++) {
\r
1528 if (precno_y*pcy == y ) {
\r
1529 for (x = x0; x < x1; x++) {
\r
1530 if (precno_x*pcx == x ) {
\r
1531 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1532 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1533 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1534 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1535 ((int*)buffer)[buffer_pos++] = tileno;
\r
1536 ((int*)buffer)[buffer_pos++] = precno;
\r
1537 ((int*)buffer)[buffer_pos++] = compno;
\r
1538 ((int*)buffer)[buffer_pos++] = resno;
\r
1539 ((int*)buffer)[buffer_pos++] = layno;
\r
1540 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1541 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1547 } /* y = y0..y1 */
\r
1554 for (compno = 0; compno < cstr_info->numcomps; compno++) {
\r
1555 /* I suppose components have same XRsiz, YRsiz */
\r
1556 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
\r
1557 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
\r
1558 int x1 = x0 + cstr_info->tile_x;
\r
1559 int y1 = y0 + cstr_info->tile_y;
\r
1561 for (resno = 0; resno < max_numdecompos + 1; resno++) {
\r
1563 if (resno > cstr_info->numdecompos[compno])
\r
1565 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
\r
1566 for (precno = 0; precno < prec_max; precno++) {
\r
1567 int pcnx = cstr_info->tile[tileno].pw[resno];
\r
1568 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
\r
1569 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
\r
1570 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
\r
1571 int precno_y = (int) floor( (float)precno/(float)pcnx );
\r
1572 for(y = y0; y < y1; y++) {
\r
1573 if (precno_y*pcy == y ) {
\r
1574 for (x = x0; x < x1; x++) {
\r
1575 if (precno_x*pcx == x ) {
\r
1576 for (layno = 0; layno < cstr_info->numlayers; layno++) {
\r
1577 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
\r
1578 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
\r
1579 ((int*)buffer)[buffer_pos++] = pack_nb;
\r
1580 ((int*)buffer)[buffer_pos++] = tileno;
\r
1581 ((int*)buffer)[buffer_pos++] = compno;
\r
1582 ((int*)buffer)[buffer_pos++] = precno;
\r
1583 ((int*)buffer)[buffer_pos++] = resno;
\r
1584 ((int*)buffer)[buffer_pos++] = layno;
\r
1585 ((int*)buffer)[buffer_pos++] = start_pos;
\r
1586 ((int*)buffer)[buffer_pos++] = end_pos;
\r
1592 } /* y = y0..y1 */
\r
1599 if (buffer_pos > *buffer_size) {
\r
1600 //opj_event_msg(j2k->cinfo, EVT_ERROR, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);
\r
1601 fprintf(stderr, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);
\r
1611 /* --------------------------------------------------------------------------
\r
1612 ------------ Get the image byte[] from the Java object -------------------*/
\r
1614 opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env, jobject obj, jclass cls) {
\r
1615 int i,max,shift,w,h,depth;
\r
1616 opj_image_t * img = NULL;
\r
1617 int compno, numcomps;
\r
1618 opj_image_t * image = NULL;
\r
1619 opj_image_comp_t *comp;
\r
1620 opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */
\r
1621 OPJ_COLOR_SPACE color_space;
\r
1633 // Image width, height and depth
\r
1634 fid = (*env)->GetFieldID(env, cls,"width", "I");
\r
1635 ji = (*env)->GetIntField(env, obj, fid);
\r
1638 fid = (*env)->GetFieldID(env, cls,"height", "I");
\r
1639 ji = (*env)->GetIntField(env, obj, fid);
\r
1642 fid = (*env)->GetFieldID(env, cls,"depth", "I");
\r
1643 ji = (*env)->GetIntField(env, obj, fid);
\r
1649 color_space = CLRSPC_GRAY;
\r
1652 color_space = CLRSPC_SRGB;
\r
1654 memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));
\r
1656 if (numcomps == 1) {
\r
1657 cmptparm[0].x0 = parameters->image_offset_x0;
\r
1658 cmptparm[0].y0 = parameters->image_offset_y0;
\r
1659 cmptparm[0].w = !cmptparm[0].x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm[0].x0 + (w - 1) * parameters->subsampling_dx + 1;
\r
1660 cmptparm[0].h = !cmptparm[0].y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm[0].y0 + (h - 1) * parameters->subsampling_dy + 1;
\r
1661 // Java types are always signed but we use them as unsigned types (shift of the negative part of
\r
1662 // the pixels of the images in Telemis before entering the encoder).
\r
1663 cmptparm[0].sgnd = 0;
\r
1665 cmptparm[0].prec=depth;
\r
1667 cmptparm[0].prec = 8;
\r
1668 cmptparm[0].bpp = cmptparm[0].prec;
\r
1669 cmptparm[0].dx = parameters->subsampling_dx;
\r
1670 cmptparm[0].dy = parameters->subsampling_dy;
\r
1671 /*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
1672 cmptparm[0].h, cmptparm[0].sgnd, cmptparm[0].bpp, cmptparm[0].dx, cmptparm[0].dy, color_space);*/
\r
1674 for(i = 0; i < numcomps; i++) {
\r
1675 cmptparm[i].prec = 8;
\r
1676 cmptparm[i].bpp = 8;
\r
1677 cmptparm[i].sgnd = 0;
\r
1678 cmptparm[i].dx = parameters->subsampling_dx;
\r
1679 cmptparm[i].dy = parameters->subsampling_dy;
\r
1680 cmptparm[i].w = w;
\r
1681 cmptparm[i].h = h;
\r
1685 /* create the image */
\r
1686 image = opj_image_create(numcomps, &cmptparm[0], color_space);
\r
1692 image->numcomps=1;
\r
1694 image->numcomps = 3;
\r
1697 /* set image offset and reference grid */
\r
1698 image->x0 = cmptparm[0].x0;
\r
1699 image->y0 = cmptparm[0].x0;
\r
1700 image->x1 = cmptparm[0].w;
\r
1701 image->y1 = cmptparm[0].h;
\r
1703 /* set image data */
\r
1704 for (compno=0; compno<numcomps; compno++) {
\r
1705 comp = &image->comps[compno];
\r
1708 fid = (*env)->GetFieldID(env, cls,"image8", "[B"); // byteArray []
\r
1709 jba = (*env)->GetObjectField(env, obj, fid);
\r
1710 len = (*env)->GetArrayLength(env, jba);
\r
1712 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, &isCopy);
\r
1713 //printf("C: before transfering 8 bpp image\n");
\r
1715 for(i=0; i< len;i++) {
\r
1716 comp->data[i] = (char) jbBody[i];
\r
1717 if (comp->data[i] > max) max = comp->data[i];
\r
1720 for(i=0; i< len;i++) {
\r
1721 comp->data[i] = (unsigned char) jbBody[i];
\r
1722 if (comp->data[i] > max) max = comp->data[i];
\r
1725 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1726 } else if(depth == 16) {
\r
1727 fid = (*env)->GetFieldID(env, cls,"image16", "[S"); // shortArray []
\r
1728 jsa = (*env)->GetObjectField(env, obj, fid);
\r
1729 len = (*env)->GetArrayLength(env, jsa);
\r
1731 jsBody = (*env)->GetPrimitiveArrayCritical(env, jsa, &isCopy);
\r
1732 //printf("C: before transfering 16 bpp image\n");
\r
1733 if (comp->sgnd) { // Special behaviour to deal with signed elements ??
\r
1734 comp->data[i] = (short) jsBody[i];
\r
1735 for(i=0; i< len;i++) {
\r
1736 if (comp->data[i] > max) max = comp->data[i];
\r
1739 for(i=0; i< len;i++) {
\r
1740 comp->data[i] = (unsigned short) jsBody[i];
\r
1741 if (comp->data[i] > max) max = comp->data[i];
\r
1744 (*env)->ReleasePrimitiveArrayCritical(env, jsa, jsBody, 0);
\r
1745 } else if (depth == 24) {
\r
1746 fid = (*env)->GetFieldID(env, cls,"image24", "[I"); // intArray []
\r
1747 jia = (*env)->GetObjectField(env, obj, fid);
\r
1748 len = (*env)->GetArrayLength(env, jia);
\r
1751 jiBody = (*env)->GetPrimitiveArrayCritical(env, jia, &isCopy);
\r
1752 //printf("C: before transfering 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);
\r
1753 if (comp->sgnd) { // Special behaviour to deal with signed elements ?? XXXXX
\r
1754 for(i=0; i< len;i++) {
\r
1755 comp->data[i] = ( ((int) jiBody[i]) & (0xFF << shift) ) >> shift;
\r
1756 if (comp->data[i] > max) max = comp->data[i];
\r
1759 for(i=0; i< len;i++) {
\r
1760 comp->data[i] = ( ((unsigned int) jiBody[i]) & (0xFF << shift) ) >> shift;
\r
1761 if (comp->data[i] > max) max = comp->data[i];
\r
1764 (*env)->ReleasePrimitiveArrayCritical(env, jia, jiBody, 0);
\r
1766 comp->bpp = int_floorlog2(max)+1;
\r
1767 comp->prec = comp->bpp;
\r
1768 //printf("C: component %d: max %d, real bpp = %d\n", compno, max, comp->bpp);
\r
1774 /* --------------------------------------------------------------------------
\r
1775 -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/
\r
1776 JNIEXPORT jlong JNICALL Java_org_openJpeg_OpenJPEGJavaEncoder_internalEncodeImageToJ2K(JNIEnv *env, jobject obj, jobjectArray javaParameters) {
\r
1777 int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */
\r
1778 char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */
\r
1780 opj_cparameters_t parameters; /* compression parameters */
\r
1781 img_fol_t img_fol;
\r
1782 opj_event_mgr_t event_mgr; /* event manager */
\r
1783 opj_image_t *image = NULL;
\r
1784 int i,j,num_images;
\r
1786 opj_codestream_info_t cstr_info; /* Codestream information structure */
\r
1787 char indexfilename[OPJ_PATH_LEN]; /* index file name */
\r
1789 int* compressed_index = NULL;
\r
1790 int compressed_index_size=-1;
\r
1791 // ==> Access variables to the Java member variables
\r
1799 callback_variables_t msgErrorCallback_vars;
\r
1800 // <== access variable to the Java member variables.
\r
1802 // For the encoding and storage into the file
\r
1803 opj_cinfo_t* cinfo;
\r
1804 int codestream_length;
\r
1805 opj_cio_t *cio = NULL;
\r
1808 // JNI reference to the calling class
\r
1809 cls = (*env)->GetObjectClass(env, obj);
\r
1811 // Pointers to be able to call a Java method for all the info and error messages
\r
1812 msgErrorCallback_vars.env = env;
\r
1813 msgErrorCallback_vars.jobj = &obj;
\r
1814 msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V");
\r
1815 msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V");
\r
1817 arraySize = (*env)->GetArrayLength(env, javaParameters);
\r
1818 argc = (int) arraySize +1;
\r
1819 argv = malloc(argc*sizeof(char*));
\r
1820 argv[0] = "ProgramName.exe"; // The program name: useless
\r
1822 for (i=1; i<argc; i++) {
\r
1823 object = (*env)->GetObjectArrayElement(env, javaParameters, i-1);
\r
1824 argv[i] = (*env)->GetStringUTFChars(env, object, &isCopy);
\r
1828 for (i=0; i<argc; i++) {
\r
1829 printf("[%s]",argv[i]);
\r
1834 configure the event callbacks
\r
1836 memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
\r
1837 event_mgr.error_handler = error_callback;
\r
1838 event_mgr.warning_handler = warning_callback;
\r
1839 event_mgr.info_handler = info_callback;
\r
1841 /* set encoding parameters to default values */
\r
1842 opj_set_default_encoder_parameters(¶meters);
\r
1843 parameters.cod_format = J2K_CFMT;
\r
1844 //parameters.index_on = 1;
\r
1846 /* Initialize indexfilename and img_fol */
\r
1847 *indexfilename = 0;
\r
1848 memset(&img_fol,0,sizeof(img_fol_t));
\r
1850 /* parse input and get user encoding parameters */
\r
1851 if (parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) {
\r
1852 // Release the Java arguments array
\r
1853 for (i=1; i<argc; i++)
\r
1854 (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
\r
1858 // Release the Java arguments array
\r
1859 for (i=1; i<argc; i++)
\r
1860 (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
\r
1862 if (parameters.cp_cinema){
\r
1863 cinema_parameters(¶meters);
\r
1867 /* Create comment for codestream */
\r
1868 if(parameters.cp_comment == NULL) {
\r
1869 const char comment[] = "Created by JavaOpenJPEG version ";
\r
1870 const size_t clen = strlen(comment);
\r
1871 const char *version = opj_version();
\r
1874 parameters.cp_comment = (char*)malloc(clen+strlen(version)+11);
\r
1875 sprintf(parameters.cp_comment,"%s%s with JPWL", comment, version);
\r
1877 parameters.cp_comment = (char*)malloc(clen+strlen(version)+1);
\r
1878 sprintf(parameters.cp_comment,"%s%s", comment, version);
\r
1884 /* Read directory if necessary */
\r
1887 /*Encoding image one by one*/
\r
1888 for(imageno=0;imageno<num_images;imageno++)
\r
1891 fprintf(stderr,"\n");
\r
1893 image = loadImage(¶meters, env, obj, cls);
\r
1894 //printf("C: after load image: image = %d\n", image);
\r
1896 fprintf(stderr, "Unable to load image\n");
\r
1900 /* Decide if MCT should be used */
\r
1901 parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;
\r
1903 if(parameters.cp_cinema){
\r
1904 cinema_setup_encoder(¶meters,image,&img_fol);
\r
1907 /* encode the destination image */
\r
1908 /* ---------------------------- */
\r
1909 /* get a J2K compressor handle */
\r
1910 if (parameters.cod_format == J2K_CFMT) { /* J2K format output */
\r
1911 cinfo = opj_create_compress(CODEC_J2K);
\r
1912 } else { /* JP2 format output */
\r
1913 cinfo = opj_create_compress(CODEC_JP2);
\r
1915 /* catch events using our callbacks and give a local context */
\r
1916 opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, &msgErrorCallback_vars);
\r
1918 /* setup the encoder parameters using the current image and user parameters */
\r
1919 opj_setup_encoder(cinfo, ¶meters, image);
\r
1921 /* open a byte stream for writing */
\r
1922 /* allocate memory for all tiles */
\r
1923 cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
\r
1925 /* encode the image */
\r
1926 bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);
\r
1927 printf("C: after opj_encode_with_info\n");
\r
1929 opj_cio_close(cio);
\r
1930 fprintf(stderr, "failed to encode image\n");
\r
1933 codestream_length = cio_tell(cio);
\r
1935 /* write the index on disk, if needed (-x 'filename') */
\r
1936 if (*indexfilename) {
\r
1937 bSuccess = write_index_file(&cstr_info, indexfilename);
\r
1939 fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename);
\r
1943 compressed_index = create_index_into_byte_array(&cstr_info, &compressed_index_size);
\r
1944 /* Allocates the Java compressedIndex byte[] and sends this index into the Java object */
\r
1945 fid = (*env)->GetFieldID(env, cls,"compressedIndex", "[B");
\r
1946 jba = (*env)->NewByteArray(env, compressed_index_size+1);
\r
1947 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
\r
1948 memcpy(jbBody, compressed_index, compressed_index_size);
\r
1949 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1950 (*env)->SetObjectField(env, obj, fid, jba);
\r
1951 free(compressed_index);
\r
1953 /* write the generated codestream to disk ? */
\r
1954 if (parameters.outfile[0]!='\0') {
\r
1955 f = fopen(parameters.outfile, "wb");
\r
1957 fprintf(stderr, "failed to open [%s] for writing\n", parameters.outfile);
\r
1960 fwrite(cio->buffer, 1, codestream_length, f);
\r
1962 fprintf(stdout,"Generated outfile [%s]\n",parameters.outfile);
\r
1965 /* Write the generated codestream to the Java pre-allocated compressedStream byte[] */
\r
1966 fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");
\r
1967 jba = (*env)->GetObjectField(env, obj, fid);
\r
1968 jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);
\r
1969 memcpy(jbBody, cio->buffer, codestream_length);
\r
1970 (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);
\r
1972 /* close and free the byte stream */
\r
1973 opj_cio_close(cio);
\r
1975 /* free remaining compression structures */
\r
1976 opj_destroy_compress(cinfo);
\r
1977 opj_destroy_cstr_info(&cstr_info);
\r
1979 /* free image data */
\r
1980 opj_image_destroy(image);
\r
1983 /* free user parameters structure */
\r
1984 if(parameters.cp_comment) free(parameters.cp_comment);
\r
1985 if(parameters.cp_matrice) free(parameters.cp_matrice);
\r
1987 return codestream_length;
\r