1 /*
2 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3 * Copyright (c) 2002-2007, Professor Benoit Macq
4 * Copyright (c) 2001-2003, David Janssens
5 * Copyright (c) 2002-2003, Yannick Verschueren
6 * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
7 * Copyright (c) 2005, Herve Drolon, FreeImage Team
8 * Copyright (c) 2006-2007, Parvatha Elangovan
9 * Copyright (c) 2007, Patrick Piscaglia (Telemis)
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <jni.h>
37 #include <math.h>
38
39 #include "openjpeg.h"
40 #include "opj_getopt.h"
41 #include "convert.h"
42 #include "dirent.h"
43 #include "org_openJpeg_OpenJPEGJavaDecoder.h"
44
45 #ifndef _WIN32
46 #define stricmp strcasecmp
47 #define strnicmp strncasecmp
48 #endif
49
50 #include "format_defs.h"
51
52 typedef struct callback_variables {
53 JNIEnv *env;
54 /** 'jclass' object used to call a Java method from the C */
55 jobject *jobj;
56 /** 'jclass' object used to call a Java method from the C */
57 jmethodID message_mid;
58 jmethodID error_mid;
59 } callback_variables_t;
60
61 typedef struct dircnt{
62 /** Buffer for holding images read from Directory*/
63 char *filename_buf;
64 /** Pointer to the buffer*/
65 char **filename;
66 }dircnt_t;
67
68
69 typedef struct img_folder{
70 /** The directory path of the folder containing input images*/
71 char *imgdirpath;
72 /** Output format*/
73 char *out_format;
74 /** Enable option*/
75 char set_imgdir;
76 /** Enable Cod Format for output*/
77 char set_out_format;
78
79 }img_fol_t;
80
81
decode_help_display()82 void decode_help_display() {
83 fprintf(stdout,"HELP\n----\n\n");
84 fprintf(stdout,"- the -h option displays this help information on screen\n\n");
85
86 /* UniPG>> */
87 fprintf(stdout,"List of parameters for the JPEG 2000 "
88 #ifdef USE_JPWL
89 "+ JPWL "
90 #endif /* USE_JPWL */
91 "decoder:\n");
92 /* <<UniPG */
93 fprintf(stdout,"\n");
94 fprintf(stdout,"\n");
95 fprintf(stdout," -ImgDir \n");
96 fprintf(stdout," Image file Directory path \n");
97 fprintf(stdout," -OutFor \n");
98 fprintf(stdout," REQUIRED only if -ImgDir is used\n");
99 fprintf(stdout," Need to specify only format without filename <BMP> \n");
100 fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP format\n");
101 fprintf(stdout," -i <compressed file>\n");
102 fprintf(stdout," REQUIRED only if an Input image directory not specified\n");
103 fprintf(stdout," Currently accepts J2K-files, JP2-files and JPT-files. The file type\n");
104 fprintf(stdout," is identified based on its suffix.\n");
105 fprintf(stdout," -o <decompressed file>\n");
106 fprintf(stdout," REQUIRED\n");
107 fprintf(stdout," Currently accepts PGM-files, PPM-files, PNM-files, PGX-files and\n");
108 fprintf(stdout," BMP-files. Binary data is written to the file (not ascii). If a PGX\n");
109 fprintf(stdout," filename is given, there will be as many output files as there are\n");
110 fprintf(stdout," components: an indice starting from 0 will then be appended to the\n");
111 fprintf(stdout," output filename, just before the \"pgx\" extension. If a PGM filename\n");
112 fprintf(stdout," is given and there are more than one component, only the first component\n");
113 fprintf(stdout," will be written to the file.\n");
114 fprintf(stdout," -r <reduce factor>\n");
115 fprintf(stdout," Set the number of highest resolution levels to be discarded. The\n");
116 fprintf(stdout," image resolution is effectively divided by 2 to the power of the\n");
117 fprintf(stdout," number of discarded levels. The reduce factor is limited by the\n");
118 fprintf(stdout," smallest total number of decomposition levels among tiles.\n");
119 fprintf(stdout," -l <number of quality layers to decode>\n");
120 fprintf(stdout," Set the maximum number of quality layers to decode. If there are\n");
121 fprintf(stdout," less quality layers than the specified number, all the quality layers\n");
122 fprintf(stdout," are decoded.\n");
123 /* UniPG>> */
124 #ifdef USE_JPWL
125 fprintf(stdout," -W <options>\n");
126 fprintf(stdout," Activates the JPWL correction capability, if the codestream complies.\n");
127 fprintf(stdout," Options can be a comma separated list of <param=val> tokens:\n");
128 fprintf(stdout," c, c=numcomps\n");
129 fprintf(stdout," numcomps is the number of expected components in the codestream\n");
130 fprintf(stdout," (search of first EPB rely upon this, default is %d)\n", JPWL_EXPECTED_COMPONENTS);
131 #endif /* USE_JPWL */
132 /* <<UniPG */
133 fprintf(stdout,"\n");
134 }
135
136 /* -------------------------------------------------------------------------- */
137
get_num_images(char * imgdirpath)138 int get_num_images(char *imgdirpath){
139 DIR *dir;
140 struct dirent* content;
141 int num_images = 0;
142
143 /*Reading the input images from given input directory*/
144
145 dir= opendir(imgdirpath);
146 if(!dir){
147 fprintf(stderr,"Could not open Folder %s\n",imgdirpath);
148 return 0;
149 }
150
151 while((content=readdir(dir))!=NULL){
152 if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 )
153 continue;
154 num_images++;
155 }
156 return num_images;
157 }
158
load_images(dircnt_t * dirptr,char * imgdirpath)159 int load_images(dircnt_t *dirptr, char *imgdirpath){
160 DIR *dir;
161 struct dirent* content;
162 int i = 0;
163
164 /*Reading the input images from given input directory*/
165
166 dir= opendir(imgdirpath);
167 if(!dir){
168 fprintf(stderr,"Could not open Folder %s\n",imgdirpath);
169 return 1;
170 }else {
171 fprintf(stderr,"Folder opened successfully\n");
172 }
173
174 while((content=readdir(dir))!=NULL){
175 if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 )
176 continue;
177
178 strcpy(dirptr->filename[i],content->d_name);
179 i++;
180 }
181 return 0;
182 }
183
get_file_format(char * filename)184 int get_file_format(char *filename) {
185 unsigned int i;
186 static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "tga", "j2k", "jp2", "jpt", "j2c" };
187 static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, TGA_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT };
188 char * ext = strrchr(filename, '.');
189 if (ext == NULL)
190 return -1;
191 ext++;
192 if(ext) {
193 for(i = 0; i < sizeof(format)/sizeof(*format); i++) {
194 if(strnicmp(ext, extension[i], 3) == 0) {
195 return format[i];
196 }
197 }
198 }
199
200 return -1;
201 }
202
203
204 /* -------------------------------------------------------------------------- */
205
parse_cmdline_decoder(int argc,char * const argv[],opj_dparameters_t * parameters,img_fol_t * img_fol)206 int parse_cmdline_decoder(int argc, char * const argv[], opj_dparameters_t *parameters,img_fol_t *img_fol) {
207 /* parse the command line */
208 int totlen;
209 opj_option_t long_option[]={
210 {"ImgDir",REQ_ARG, NULL ,'y'},
211 {"OutFor",REQ_ARG, NULL ,'O'},
212 };
213
214 /* UniPG>> */
215 const char optlist[] = "i:o:r:l:hx:"
216
217 #ifdef USE_JPWL
218 "W:"
219 #endif /* USE_JPWL */
220 ;
221 /*for (i=0; i<argc; i++) {
222 printf("[%s]",argv[i]);
223 }
224 printf("\n");*/
225
226 /* <<UniPG */
227 totlen=sizeof(long_option);
228 img_fol->set_out_format = 0;
229 reset_options_reading();
230
231 while (1) {
232 int c = opj_getopt_long(argc, argv,optlist,long_option,totlen);
233 if (c == -1)
234 break;
235 switch (c) {
236 case 'i': /* input file */
237 {
238 char *infile = opj_optarg;
239 parameters->decod_format = get_file_format(infile);
240 switch(parameters->decod_format) {
241 case J2K_CFMT:
242 case JP2_CFMT:
243 case JPT_CFMT:
244 break;
245 default:
246 fprintf(stderr,
247 "!! Unrecognized format for infile : %s [accept only *.j2k, *.jp2, *.jpc or *.jpt] !!\n\n",
248 infile);
249 return 1;
250 }
251 strncpy(parameters->infile, infile, sizeof(parameters->infile)-1);
252 }
253 break;
254
255 /* ----------------------------------------------------- */
256
257 case 'o': /* output file */
258 {
259 char *outfile = opj_optarg;
260 parameters->cod_format = get_file_format(outfile);
261 switch(parameters->cod_format) {
262 case PGX_DFMT:
263 case PXM_DFMT:
264 case BMP_DFMT:
265 case TIF_DFMT:
266 case RAW_DFMT:
267 case TGA_DFMT:
268 break;
269 default:
270 fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outfile);
271 return 1;
272 }
273 strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);
274 }
275 break;
276
277 /* ----------------------------------------------------- */
278
279 case 'O': /* output format */
280 {
281 char outformat[50];
282 char *of = opj_optarg;
283 sprintf(outformat,".%s",of);
284 img_fol->set_out_format = 1;
285 parameters->cod_format = get_file_format(outformat);
286 switch(parameters->cod_format) {
287 case PGX_DFMT:
288 img_fol->out_format = "pgx";
289 break;
290 case PXM_DFMT:
291 img_fol->out_format = "ppm";
292 break;
293 case BMP_DFMT:
294 img_fol->out_format = "bmp";
295 break;
296 case TIF_DFMT:
297 img_fol->out_format = "tif";
298 break;
299 case RAW_DFMT:
300 img_fol->out_format = "raw";
301 break;
302 case TGA_DFMT:
303 img_fol->out_format = "raw";
304 break;
305 default:
306 fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outformat);
307 return 1;
308 break;
309 }
310 }
311 break;
312
313 /* ----------------------------------------------------- */
314
315
316 case 'r': /* reduce option */
317 {
318 sscanf(opj_optarg, "%d", ¶meters->cp_reduce);
319 }
320 break;
321
322 /* ----------------------------------------------------- */
323
324
325 case 'l': /* layering option */
326 {
327 sscanf(opj_optarg, "%d", ¶meters->cp_layer);
328 }
329 break;
330
331 /* ----------------------------------------------------- */
332
333 case 'h': /* display an help description */
334 decode_help_display();
335 return 1;
336
337 /* ------------------------------------------------------ */
338
339 case 'y': /* Image Directory path */
340 {
341 img_fol->imgdirpath = (char*)malloc(strlen(opj_optarg) + 1);
342
343 if(img_fol->imgdirpath == NULL) return 1;
344
345 strcpy(img_fol->imgdirpath,opj_optarg);
346 img_fol->set_imgdir=1;
347 }
348 break;
349 /* ----------------------------------------------------- */
350 /* UniPG>> */
351 #ifdef USE_JPWL
352
353 case 'W': /* activate JPWL correction */
354 {
355 char *token = NULL;
356
357 token = strtok(opj_optarg, ",");
358 while(token != NULL) {
359
360 /* search expected number of components */
361 if (*token == 'c') {
362
363 static int compno;
364
365 compno = JPWL_EXPECTED_COMPONENTS; /* predefined no. of components */
366
367 if(sscanf(token, "c=%d", &compno) == 1) {
368 /* Specified */
369 if ((compno < 1) || (compno > 256)) {
370 fprintf(stderr, "ERROR -> invalid number of components c = %d\n", compno);
371 return 1;
372 }
373 parameters->jpwl_exp_comps = compno;
374
375 } else if (!strcmp(token, "c")) {
376 /* default */
377 parameters->jpwl_exp_comps = compno; /* auto for default size */
378
379 } else {
380 fprintf(stderr, "ERROR -> invalid components specified = %s\n", token);
381 return 1;
382 };
383 }
384
385 /* search maximum number of tiles */
386 if (*token == 't') {
387
388 static int tileno;
389
390 tileno = JPWL_MAXIMUM_TILES; /* maximum no. of tiles */
391
392 if(sscanf(token, "t=%d", &tileno) == 1) {
393 /* Specified */
394 if ((tileno < 1) || (tileno > JPWL_MAXIMUM_TILES)) {
395 fprintf(stderr, "ERROR -> invalid number of tiles t = %d\n", tileno);
396 return 1;
397 }
398 parameters->jpwl_max_tiles = tileno;
399
400 } else if (!strcmp(token, "t")) {
401 /* default */
402 parameters->jpwl_max_tiles = tileno; /* auto for default size */
403
404 } else {
405 fprintf(stderr, "ERROR -> invalid tiles specified = %s\n", token);
406 return 1;
407 };
408 }
409
410 /* next token or bust */
411 token = strtok(NULL, ",");
412 };
413 parameters->jpwl_correct = true;
414 fprintf(stdout, "JPWL correction capability activated\n");
415 fprintf(stdout, "- expecting %d components\n", parameters->jpwl_exp_comps);
416 }
417 break;
418 #endif /* USE_JPWL */
419 /* <<UniPG */
420
421 /* ----------------------------------------------------- */
422
423 default:
424 fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, opj_optarg);
425 break;
426 }
427 }
428
429 /* No check for possible errors before the -i and -o options are of course not mandatory*/
430
431 return 0;
432 }/* parse_cmdline_decoder() */
433
434 /* -------------------------------------------------------------------------- */
435
436 /**
437 error callback returning the message to Java andexpecting a callback_variables_t client object
438 */
error_callback(const char * msg,void * client_data)439 void error_callback(const char *msg, void *client_data) {
440 callback_variables_t* vars = (callback_variables_t*) client_data;
441 JNIEnv *env = vars->env;
442 jstring jbuffer;
443
444 jbuffer = (*env)->NewStringUTF(env, msg);
445 (*env)->ExceptionClear(env);
446 (*env)->CallVoidMethod(env, *(vars->jobj), vars->error_mid, jbuffer);
447
448 if ((*env)->ExceptionOccurred(env)) {
449 fprintf(stderr,"C: Exception during call back method\n");
450 (*env)->ExceptionDescribe(env);
451 (*env)->ExceptionClear(env);
452 }
453 (*env)->DeleteLocalRef(env, jbuffer);
454 }
455 /**
456 warning callback returning the message to Java andexpecting a callback_variables_t client object
457 */
warning_callback(const char * msg,void * client_data)458 void warning_callback(const char *msg, void *client_data) {
459 callback_variables_t* vars = (callback_variables_t*) client_data;
460 JNIEnv *env = vars->env;
461 jstring jbuffer;
462
463 jbuffer = (*env)->NewStringUTF(env, msg);
464 (*env)->ExceptionClear(env);
465 (*env)->CallVoidMethod(env, *(vars->jobj), vars->message_mid, jbuffer);
466
467 if ((*env)->ExceptionOccurred(env)) {
468 fprintf(stderr,"C: Exception during call back method\n");
469 (*env)->ExceptionDescribe(env);
470 (*env)->ExceptionClear(env);
471 }
472 (*env)->DeleteLocalRef(env, jbuffer);
473 }
474 /**
475 information callback returning the message to Java andexpecting a callback_variables_t client object
476 */
info_callback(const char * msg,void * client_data)477 void info_callback(const char *msg, void *client_data) {
478 callback_variables_t* vars = (callback_variables_t*) client_data;
479 JNIEnv *env = vars->env;
480 jstring jbuffer;
481
482 jbuffer = (*env)->NewStringUTF(env, msg);
483 (*env)->ExceptionClear(env);
484 (*env)->CallVoidMethod(env, *(vars->jobj), vars->message_mid, jbuffer);
485
486 if ((*env)->ExceptionOccurred(env)) {
487 fprintf(stderr,"C: Exception during call back method\n");
488 (*env)->ExceptionDescribe(env);
489 (*env)->ExceptionClear(env);
490 }
491 (*env)->DeleteLocalRef(env, jbuffer);
492 }
493
494 #define FAILS -1
495 #define OK 0
496 /* --------------------------------------------------------------------------
497 -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/
Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2KtoImage(JNIEnv * env,jobject obj,jobjectArray javaParameters)498 JNIEXPORT jint JNICALL Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2KtoImage(JNIEnv *env, jobject obj, jobjectArray javaParameters) {
499 int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */
500 const char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */
501 opj_dparameters_t parameters; /* decompression parameters */
502 img_fol_t img_fol;
503 opj_event_mgr_t event_mgr; /* event manager */
504 opj_image_t *image = NULL;
505 FILE *fsrc = NULL;
506 unsigned char *src = NULL;
507 int file_length;
508 int num_images;
509 int i,j,imageno;
510 opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
511 opj_cio_t *cio = NULL;
512 int w,h;
513 long min_value, max_value;
514 short tempS; unsigned char tempUC, tempUC1, tempUC2;
515 /* ==> Access variables to the Java member variables */
516 jsize arraySize;
517 jclass cls;
518 jobject object;
519 jboolean isCopy;
520 jfieldID fid;
521 jbyteArray jba;
522 jshortArray jsa;
523 jintArray jia;
524 jbyte *jbBody, *ptrBBody;
525 jshort *jsBody, *ptrSBody;
526 jint *jiBody, *ptrIBody;
527 callback_variables_t msgErrorCallback_vars;
528 /* <=== access variable to Java member variables */
529 int *ptr, *ptr1, *ptr2;/* <== To transfer the decoded image to Java */
530 jint retval = FAILS;
531
532 /* configure the event callbacks */
533 memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
534 event_mgr.error_handler = error_callback;
535 event_mgr.warning_handler = warning_callback;
536 event_mgr.info_handler = info_callback;
537
538 /* JNI reference to the calling class */
539 cls = (*env)->GetObjectClass(env, obj);
540
541 /* Pointers to be able to call a Java method
542 * for all the info and error messages
543 */
544 msgErrorCallback_vars.env = env;
545 msgErrorCallback_vars.jobj = &obj;
546 msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V");
547 msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V");
548
549 /* Get the String[] containing the parameters */
550
551 arraySize = (*env)->GetArrayLength(env, javaParameters);
552 argc = (int) arraySize +1;
553 argv = (const char **)malloc(argc*sizeof(char*));
554
555 if(argv == NULL) return FAILS;
556
557 argv[0] = "ProgramName.exe";/* The program name: useless */
558 j=0;
559 for (i=1; i<argc; i++) {
560 object = (*env)->GetObjectArrayElement(env, javaParameters, i-1);
561 argv[i] = (*env)->GetStringUTFChars(env, object, &isCopy);
562 }
563
564 /*printf("C: decoder params = ");
565 for (i=0; i<argc; i++) {
566 printf("[%s]",argv[i]);
567 }
568 printf("\n");*/
569
570 /* set decoding parameters to default values */
571 opj_set_default_decoder_parameters(¶meters);
572 parameters.decod_format = J2K_CFMT;
573
574 /* parse input and get user encoding parameters */
575 j = parse_cmdline_decoder(argc, (char * const*)argv, ¶meters,&img_fol);
576
577 /* Release the Java arguments array */
578 for (i=1; i<argc; i++)
579 (*env)->ReleaseStringUTFChars(env,
580 (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);
581
582 if(j == 1) goto fin; /* failure */
583
584 num_images=1;
585
586 /* Get additional information from the Java object variables */
587 fid = (*env)->GetFieldID(env, cls,"skippedResolutions", "I");
588 parameters.cp_reduce = (short) (*env)->GetIntField(env, obj, fid);
589
590 /*Decoding image one by one*/
591 for(imageno = 0; imageno < num_images ; imageno++)
592 {
593 image = NULL;
594 fprintf(stderr,"\n");
595
596 /* read the input file and put it in memory into the 'src' object, if the -i option is given in JavaParameters.
597 Implemented for debug purpose. */
598 /* -------------------------------------------------------------- */
599 if (parameters.infile && parameters.infile[0]!='\0') {
600 /* printf("C: opening [%s]\n", parameters.infile); */
601 fsrc = fopen(parameters.infile, "rb");
602 if (!fsrc) {
603 fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
604 goto fin;
605 }
606 fseek(fsrc, 0, SEEK_END);
607 file_length = ftell(fsrc);
608 fseek(fsrc, 0, SEEK_SET);
609 src = (unsigned char *) malloc(file_length);
610
611 if(src == NULL) goto fin;
612
613 fread(src, 1, file_length, fsrc);
614 fclose(fsrc);
615 /* printf("C: %d bytes read from file\n",file_length); */
616 } else {
617 /* Preparing the transfer of the codestream from Java to C */
618 /* printf("C: before transfering codestream\n"); */
619 fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");
620 jba = (*env)->GetObjectField(env, obj, fid);
621 file_length = (*env)->GetArrayLength(env, jba);
622 jbBody = (*env)->GetByteArrayElements(env, jba, &isCopy);
623 src = (unsigned char*)jbBody;
624 }
625
626 /* decode the code-stream */
627 /* ---------------------- */
628
629 switch(parameters.decod_format) {
630 case J2K_CFMT:
631 {
632 /* JPEG-2000 codestream */
633
634 /* get a decoder handle */
635 dinfo = opj_create_decompress(CODEC_J2K);
636
637 /* catch events using our callbacks and give a local context */
638 opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars);
639
640 /* setup the decoder decoding parameters using user parameters */
641 opj_setup_decoder(dinfo, ¶meters);
642
643 /* open a byte stream */
644 cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
645
646 /* decode the stream and fill the image structure */
647 image = opj_decode(dinfo, cio);
648 if(!image) {
649 fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
650 opj_destroy_decompress(dinfo);
651 opj_cio_close(cio);
652 goto fin;
653 }
654
655 /* close the byte stream */
656 opj_cio_close(cio);
657 }
658 break;
659
660 case JP2_CFMT:
661 {
662 /* JPEG 2000 compressed image data */
663
664 /* get a decoder handle */
665 dinfo = opj_create_decompress(CODEC_JP2);
666
667 /* catch events using our callbacks and give a local context */
668 opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars);
669
670 /* setup the decoder decoding parameters using the current image and user parameters */
671 opj_setup_decoder(dinfo, ¶meters);
672
673 /* open a byte stream */
674 cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
675
676 /* decode the stream and fill the image structure */
677 image = opj_decode(dinfo, cio);
678 if(!image) {
679 fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
680 opj_destroy_decompress(dinfo);
681 opj_cio_close(cio);
682 goto fin;
683 }
684
685 /* close the byte stream */
686 opj_cio_close(cio);
687
688 }
689 break;
690
691 case JPT_CFMT:
692 {
693 /* JPEG 2000, JPIP */
694
695 /* get a decoder handle */
696 dinfo = opj_create_decompress(CODEC_JPT);
697
698 /* catch events using our callbacks and give a local context */
699 opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars);
700
701 /* setup the decoder decoding parameters using user parameters */
702 opj_setup_decoder(dinfo, ¶meters);
703
704 /* open a byte stream */
705 cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
706
707 /* decode the stream and fill the image structure */
708 image = opj_decode(dinfo, cio);
709 if(!image) {
710 fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
711 opj_destroy_decompress(dinfo);
712 opj_cio_close(cio);
713 goto fin;
714 }
715
716 /* close the byte stream */
717 opj_cio_close(cio);
718 }
719 break;
720
721 default:
722 fprintf(stderr, "skipping file..\n");
723 continue;
724 }
725
726 /* free the memory containing the code-stream */
727 if (parameters.infile && parameters.infile[0]!='\0') {
728 free(src);
729 } else {
730 (*env)->ReleaseByteArrayElements(env, jba, jbBody, 0);
731 }
732 src = NULL;
733
734 /* create output image.
735 If the -o parameter is given in the JavaParameters, write the decoded version into a file.
736 Implemented for debug purpose. */
737 /* ---------------------------------- */
738 switch (parameters.cod_format) {
739 case PXM_DFMT: /* PNM PGM PPM */
740 if (imagetopnm(image, parameters.outfile)) {
741 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
742 }
743 else {
744 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
745 }
746 break;
747
748 case PGX_DFMT: /* PGX */
749 if(imagetopgx(image, parameters.outfile)){
750 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
751 }
752 else {
753 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
754 }
755 break;
756
757 case BMP_DFMT: /* BMP */
758 if(imagetobmp(image, parameters.outfile)){
759 fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);
760 }
761 else {
762 fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);
763 }
764 break;
765
766 }
767
768 /* ========= Return the image to the Java structure =============== */
769 #ifdef CHECK_THRESHOLDS
770 printf("C: checking thresholds\n");
771 #endif
772 /* First compute the real with and height,
773 * in function of the resolutions decoded.
774 */
775 /*---
776 wr = (image->comps[0].w + (1 << image->comps[0].factor) -1) >> image->comps[0].factor;
777 hr = (image->comps[0].h + (1 << image->comps[0].factor) -1) >> image->comps[0].factor;
778 ---*/
779 w = image->comps[0].w;
780 h = image->comps[0].h;
781
782 if (image->numcomps==3) { /* 3 components color image */
783 ptr = image->comps[0].data;
784 ptr1 = image->comps[1].data;
785 ptr2 = image->comps[2].data;
786 #ifdef CHECK_THRESHOLDS
787 if (image->comps[0].sgnd) {
788 min_value = -128;
789 max_value = 127;
790 } else {
791 min_value = 0;
792 max_value = 255;
793 }
794 #endif
795 /* Get the pointer to the Java structure where the data must be copied */
796 fid = (*env)->GetFieldID(env, cls,"image24", "[I");
797 jia = (*env)->GetObjectField(env, obj, fid);
798 jiBody = (*env)->GetIntArrayElements(env, jia, 0);
799 ptrIBody = jiBody;
800 printf("C: transfering image24: %d int to Java pointer=%d\n",image->numcomps*w*h, ptrIBody);
801
802 for (i=0; i<w*h; i++) {
803 tempUC = (unsigned char)(ptr[i]);
804 tempUC1 = (unsigned char)(ptr1[i]);
805 tempUC2 = (unsigned char)(ptr2[i]);
806 #ifdef CHECK_THRESHOLDS
807 if (tempUC < min_value)
808 tempUC=min_value;
809 else if (tempUC > max_value)
810 tempUC=max_value;
811 if (tempUC1 < min_value)
812 tempUC1=min_value;
813 else if (tempUC1 > max_value)
814 tempUC1=max_value;
815 if (tempUC2 < min_value)
816 tempUC2=min_value;
817 else if (tempUC2 > max_value)
818 tempUC2=max_value;
819 #endif
820 *(ptrIBody++) = (int) ( (tempUC2<<16) + (tempUC1<<8) + tempUC );
821 }
822 (*env)->ReleaseIntArrayElements(env, jia, jiBody, 0);
823
824 } else { /* 1 component 8 or 16 bpp image */
825 ptr = image->comps[0].data;
826 printf("C: before transfering a %d bpp image to java (length = %d)\n",image->comps[0].prec ,w*h);
827 if (image->comps[0].prec<=8) {
828 fid = (*env)->GetFieldID(env, cls,"image8", "[B");
829 jba = (*env)->GetObjectField(env, obj, fid);
830 jbBody = (*env)->GetByteArrayElements(env, jba, 0);
831 ptrBBody = jbBody;
832 #ifdef CHECK_THRESHOLDS
833 if (image->comps[0].sgnd) {
834 min_value = -128;
835 max_value = 127;
836 } else {
837 min_value = 0;
838 max_value = 255;
839 }
840 #endif
841 /* printf("C: transfering %d shorts to Java image8 pointer = %d\n", wr*hr,ptrSBody); */
842 for (i=0; i<w*h; i++) {
843 tempUC = (unsigned char) (ptr[i]);
844 #ifdef CHECK_THRESHOLDS
845 if (tempUC<min_value)
846 tempUC = min_value;
847 else if (tempUC > max_value)
848 tempUC = max_value;
849 #endif
850 *(ptrBBody++) = tempUC;
851 }
852 (*env)->ReleaseByteArrayElements(env, jba, jbBody, 0);
853 printf("C: image8 transfered to Java\n");
854 } else {
855 fid = (*env)->GetFieldID(env, cls,"image16", "[S");
856 jsa = (*env)->GetObjectField(env, obj, fid);
857 jsBody = (*env)->GetShortArrayElements(env, jsa, 0);
858 ptrSBody = jsBody;
859 #ifdef CHECK_THRESHOLDS
860 if (image->comps[0].sgnd) {
861 min_value = -32768;
862 max_value = 32767;
863 } else {
864 min_value = 0;
865 max_value = 65535;
866 }
867 printf("C: minValue = %d, maxValue = %d\n", min_value, max_value);
868 #endif
869 printf("C: transfering %d shorts to Java image16 pointer = %d\n", w*h,ptrSBody);
870 for (i=0; i<w*h; i++) {
871 tempS = (short) (ptr[i]);
872 #ifdef CHECK_THRESHOLDS
873 if (tempS<min_value) {
874 printf("C: value %d truncated to %d\n", tempS, min_value);
875 tempS = min_value;
876 } else if (tempS > max_value) {
877 printf("C: value %d truncated to %d\n", tempS, max_value);
878 tempS = max_value;
879 }
880 #endif
881 *(ptrSBody++) = tempS;
882 }
883 (*env)->ReleaseShortArrayElements(env, jsa, jsBody, 0);
884 printf("C: image16 completely filled\n");
885 }
886 }
887
888
889 /* free remaining structures */
890 if(dinfo) {
891 opj_destroy_decompress(dinfo);
892 }
893 /* free image data structure */
894 opj_image_destroy(image);
895
896 }
897 retval = OK;
898
899 fin:
900 free(argv);
901
902 return retval;
903 }
904 /* end main MAIN */
905
906