--- /dev/null
+/*\r
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium\r
+ * Copyright (c) 2002-2007, Professor Benoit Macq\r
+ * Copyright (c) 2001-2003, David Janssens\r
+ * Copyright (c) 2002-2003, Yannick Verschueren\r
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe\r
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team \r
+ * Copyright (c) 2006-2007, Parvatha Elangovan\r
+ * Copyright (c) 2007, Patrick Piscaglia (Telemis)\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <jni.h>\r
+#include <math.h>\r
+\r
+#include "openjpeg.h"\r
+#include "compat/getopt.h"\r
+#include "convert.h"\r
+#include "index.h"\r
+#include "dirent.h"\r
+#include "org_openJpeg_OpenJPEGJavaEncoder.h"\r
+\r
+#ifndef WIN32\r
+#define stricmp strcasecmp\r
+#define strnicmp strncasecmp\r
+#endif\r
+\r
+/* ----------------------------------------------------------------------- */\r
+\r
+#define J2K_CFMT 0\r
+#define JP2_CFMT 1\r
+#define JPT_CFMT 2\r
+\r
+#define PXM_DFMT 10\r
+#define PGX_DFMT 11\r
+#define BMP_DFMT 12\r
+#define YUV_DFMT 13\r
+#define TIF_DFMT 14\r
+#define RAW_DFMT 15\r
+#define TGA_DFMT 16\r
+\r
+/* ----------------------------------------------------------------------- */\r
+#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/\r
+#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/\r
+#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/\r
+#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/\r
+\r
+extern int get_file_format(char *filename);\r
+extern void error_callback(const char *msg, void *client_data);\r
+extern warning_callback(const char *msg, void *client_data);\r
+extern void info_callback(const char *msg, void *client_data);\r
+\r
+typedef struct callback_variables {\r
+ JNIEnv *env;\r
+ /** 'jclass' object used to call a Java method from the C */\r
+ jobject *jobj;\r
+ /** 'jclass' object used to call a Java method from the C */\r
+ jmethodID message_mid;\r
+ jmethodID error_mid;\r
+} callback_variables_t;\r
+\r
+typedef struct dircnt{\r
+ /** Buffer for holding images read from Directory*/\r
+ char *filename_buf;\r
+ /** Pointer to the buffer*/\r
+ char **filename;\r
+}dircnt_t;\r
+\r
+typedef struct img_folder{\r
+ /** The directory path of the folder containing input images*/\r
+ char *imgdirpath;\r
+ /** Output format*/\r
+ char *out_format;\r
+ /** Enable option*/\r
+ char set_imgdir;\r
+ /** Enable Cod Format for output*/\r
+ char set_out_format;\r
+ /** User specified rate stored in case of cinema option*/\r
+ float *rates;\r
+}img_fol_t;\r
+\r
+void encode_help_display() {\r
+ fprintf(stdout,"HELP\n----\n\n");\r
+ fprintf(stdout,"- the -h option displays this help information on screen\n\n");\r
+\r
+/* UniPG>> */\r
+ fprintf(stdout,"List of parameters for the JPEG 2000 "\r
+#ifdef USE_JPWL\r
+ "+ JPWL "\r
+#endif /* USE_JPWL */\r
+ "encoder:\n");\r
+/* <<UniPG */\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"REMARKS:\n");\r
+ fprintf(stdout,"---------\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n");\r
+ fprintf(stdout,"COD and QCD never appear in the tile_header.\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"- This coder can encode a mega image, a test was made on a 24000x24000 pixels \n");\r
+ fprintf(stdout,"color image. You need enough disk space memory (twice the original) to encode \n");\r
+ fprintf(stdout,"the image,i.e. for a 1.5 GB image you need a minimum of 3GB of disk memory)\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"By default:\n");\r
+ fprintf(stdout,"------------\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," * Lossless\n");\r
+ fprintf(stdout," * 1 tile\n");\r
+ fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n");\r
+ fprintf(stdout," * Size of code-block : 64 x 64\n");\r
+ fprintf(stdout," * Number of resolutions: 6\n");\r
+ fprintf(stdout," * No SOP marker in the codestream\n");\r
+ fprintf(stdout," * No EPH marker in the codestream\n");\r
+ fprintf(stdout," * No sub-sampling in x or y direction\n");\r
+ fprintf(stdout," * No mode switch activated\n");\r
+ fprintf(stdout," * Progression order: LRCP\n");\r
+ fprintf(stdout," * No index file\n");\r
+ fprintf(stdout," * No ROI upshifted\n");\r
+ fprintf(stdout," * No offset of the origin of the image\n");\r
+ fprintf(stdout," * No offset of the origin of the tiles\n");\r
+ fprintf(stdout," * Reversible DWT 5-3\n");\r
+/* UniPG>> */\r
+#ifdef USE_JPWL\r
+ fprintf(stdout," * No JPWL protection\n");\r
+#endif /* USE_JPWL */\r
+/* <<UniPG */\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"Parameters:\n");\r
+ fprintf(stdout,"------------\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"Required Parameters (except with -h):\n");\r
+ fprintf(stdout,"One of the two options -ImgDir or -i must be used\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-ImgDir : Image file Directory path (example ../Images) \n");\r
+ fprintf(stdout," When using this option -OutFor must be used\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-OutFor \n");\r
+ fprintf(stdout," REQUIRED only if -ImgDir is used\n");\r
+ fprintf(stdout," Need to specify only format without filename <BMP> \n");\r
+ fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP, TIF, RAW and TGA formats\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-i : source file (-i source.pnm also *.pgm, *.ppm, *.bmp, *.tif, *.raw, *.tga) \n");\r
+ fprintf(stdout," When using this option -o must be used\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-o : destination file (-o dest.j2k or .jp2) \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"Optional Parameters:\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-h : display the help information \n ");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-cinema2K : Digital Cinema 2K profile compliant codestream for 2K resolution.(-cinema2k 24 or 48) \n");\r
+ fprintf(stdout," Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n"); \r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-cinema4K : Digital Cinema 4K profile compliant codestream for 4K resolution \n");\r
+ fprintf(stdout," Frames per second not required. Default value is 24fps\n"); \r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n ");\r
+ fprintf(stdout," - The rate specified for each quality level is the desired \n");\r
+ fprintf(stdout," compression factor.\n");\r
+ fprintf(stdout," Example: -r 20,10,1 means quality 1: compress 20x, \n");\r
+ fprintf(stdout," quality 2: compress 10x and quality 3: compress lossless\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," (options -r and -q cannot be used together)\n ");\r
+ fprintf(stdout,"\n");\r
+\r
+ fprintf(stdout,"-q : different psnr for successive layers (-q 30,40,50) \n ");\r
+\r
+ fprintf(stdout," (options -r and -q cannot be used together)\n ");\r
+\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-n : number of resolutions (-n 3) \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-b : size of code block (-b 32,32) \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-c : size of precinct (-c 128,128) \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-t : size of tile (-t 512,512) \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n");\r
+ fprintf(stdout," Remark: subsampling bigger than 2 can produce error\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-POC : Progression order change (-POC T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL) \n");\r
+ fprintf(stdout," Example: T1=0,0,1,5,3,CPRL \n");\r
+ fprintf(stdout," : Ttilenumber=Resolution num start,Component num start,Layer num end,Resolution num end,Component num end,Progression order\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-SOP : write SOP marker before each packet \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-EPH : write EPH marker after each header packet \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n");\r
+ fprintf(stdout," 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n");\r
+ fprintf(stdout," Indicate multiple modes by adding their values. \n");\r
+ fprintf(stdout," ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-x : create an index file *.Idx (-x index_name.Idx) \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-ROI : c=%%d,U=%%d : quantization indices upshifted \n");\r
+ fprintf(stdout," for component c=%%d [%%d = 0,1,2]\n");\r
+ fprintf(stdout," with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI c=0,U=25) \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-d : offset of the origin of the image (-d 150,300) \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-T : offset of the origin of the tiles (-T 100,75) \n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n");\r
+ fprintf(stdout,"\n");\r
+/* UniPG>> */\r
+#ifdef USE_JPWL\r
+ fprintf(stdout,"-W : adoption of JPWL (Part 11) capabilities (-W params)\n");\r
+ fprintf(stdout," The parameters can be written and repeated in any order:\n");\r
+ fprintf(stdout," [h<tilepart><=type>,s<tilepart><=method>,a=<addr>,...\n");\r
+ fprintf(stdout," ...,z=<size>,g=<range>,p<tilepart:pack><=type>]\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," h selects the header error protection (EPB): 'type' can be\n");\r
+ fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");\r
+ fprintf(stdout," if 'tilepart' is absent, it is for main and tile headers\n");\r
+ fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");\r
+ fprintf(stdout," onwards, up to the next h<> spec, or to the last tilepart\n");\r
+ fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," p selects the packet error protection (EEP/UEP with EPBs)\n");\r
+ fprintf(stdout," to be applied to raw data: 'type' can be\n");\r
+ fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n");\r
+ fprintf(stdout," if 'tilepart:pack' is absent, it is from tile 0, packet 0\n");\r
+ fprintf(stdout," if 'tilepart:pack' is present, it applies from that tile\n");\r
+ fprintf(stdout," and that packet onwards, up to the next packet spec\n");\r
+ fprintf(stdout," or to the last packet in the last tilepart in the stream\n");\r
+ fprintf(stdout," (max. %d specs)\n", JPWL_MAX_NO_PACKSPECS);\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," s enables sensitivity data insertion (ESD): 'method' can be\n");\r
+ fprintf(stdout," [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n");\r
+ fprintf(stdout," 4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n");\r
+ fprintf(stdout," if 'tilepart' is absent, it is for main header only\n");\r
+ fprintf(stdout," if 'tilepart' is present, it applies from that tile\n");\r
+ fprintf(stdout," onwards, up to the next s<> spec, or to the last tilepart\n");\r
+ fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS);\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," g determines the addressing mode: <range> can be\n");\r
+ fprintf(stdout," [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," a determines the size of data addressing: <addr> can be\n");\r
+ fprintf(stdout," 2/4 bytes (small/large codestreams). If not set, auto-mode\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," z determines the size of sensitivity values: <size> can be\n");\r
+ fprintf(stdout," 1/2 bytes, for the transformed pseudo-floating point value\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," ex.:\n");\r
+ 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
+ fprintf(stdout," s0=6,s3=-1,a=0,g=1,z=1\n");\r
+ fprintf(stdout," means\n");\r
+ fprintf(stdout," predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n");\r
+ fprintf(stdout," CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n");\r
+ fprintf(stdout," UEP rs(78,32) for packets 0 to 23 of tile 0,\n");\r
+ fprintf(stdout," UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n");\r
+ fprintf(stdout," UEP rs default for packets of tilepart 1,\n");\r
+ fprintf(stdout," no UEP for packets 0 to 19 of tilepart 3,\n");\r
+ fprintf(stdout," UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n");\r
+ fprintf(stdout," relative sensitivity ESD for MH,\n");\r
+ fprintf(stdout," TSE ESD from TPH 0 to TPH 2, byte range with automatic\n");\r
+ fprintf(stdout," size of addresses and 1 byte for each sensitivity value\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," ex.:\n");\r
+ fprintf(stdout," h,s,p\n");\r
+ fprintf(stdout," means\n");\r
+ fprintf(stdout," default protection to headers (MH and TPHs) as well as\n");\r
+ fprintf(stdout," data packets, one ESD in MH\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," N.B.: use the following recommendations when specifying\n");\r
+ fprintf(stdout," the JPWL parameters list\n");\r
+ fprintf(stdout," - when you use UEP, always pair the 'p' option with 'h'\n");\r
+ fprintf(stdout," \n");\r
+#endif /* USE_JPWL */\r
+/* <<UniPG */\r
+ fprintf(stdout,"IMPORTANT:\n");\r
+ fprintf(stdout,"-----------\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"The index file has the structure below:\n");\r
+ fprintf(stdout,"---------------------------------------\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"Image_height Image_width\n");\r
+ fprintf(stdout,"progression order\n");\r
+ fprintf(stdout,"Tiles_size_X Tiles_size_Y\n");\r
+ fprintf(stdout,"Tiles_nb_X Tiles_nb_Y\n");\r
+ fprintf(stdout,"Components_nb\n");\r
+ fprintf(stdout,"Layers_nb\n");\r
+ fprintf(stdout,"decomposition_levels\n");\r
+ fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n");\r
+ fprintf(stdout," [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n");\r
+ fprintf(stdout,"Main_header_start_position\n");\r
+ fprintf(stdout,"Main_header_end_position\n");\r
+ fprintf(stdout,"Codestream_size\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"INFO ON TILES\n");\r
+ fprintf(stdout,"tileno start_pos end_hd end_tile nbparts disto nbpix disto/nbpix\n");\r
+ fprintf(stdout,"Tile_0 start_pos end_Theader end_pos NumParts TotalDisto NumPix MaxMSE\n");\r
+ fprintf(stdout,"Tile_1 '' '' '' '' '' '' ''\n");\r
+ fprintf(stdout,"...\n");\r
+ fprintf(stdout,"Tile_Nt '' '' '' '' '' '' ''\n");\r
+ fprintf(stdout,"...\n");\r
+ fprintf(stdout,"TILE 0 DETAILS\n");\r
+ fprintf(stdout,"part_nb tileno num_packs start_pos end_tph_pos end_pos\n");\r
+ fprintf(stdout,"...\n");\r
+ fprintf(stdout,"Progression_string\n");\r
+ fprintf(stdout,"pack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos disto\n");\r
+ fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n");\r
+ fprintf(stdout,"...\n");\r
+ fprintf(stdout,"Tpacket_Np '' '' '' '' '' '' '' ''\n");\r
+\r
+ fprintf(stdout,"MaxDisto\n");\r
+\r
+ fprintf(stdout,"TotalDisto\n\n");\r
+}\r
+\r
+\r
+OPJ_PROG_ORDER give_progression(char progression[4]) {\r
+ if(strncmp(progression, "LRCP", 4) == 0) {\r
+ return LRCP;\r
+ }\r
+ if(strncmp(progression, "RLCP", 4) == 0) {\r
+ return RLCP;\r
+ }\r
+ if(strncmp(progression, "RPCL", 4) == 0) {\r
+ return RPCL;\r
+ }\r
+ if(strncmp(progression, "PCRL", 4) == 0) {\r
+ return PCRL;\r
+ }\r
+ if(strncmp(progression, "CPRL", 4) == 0) {\r
+ return CPRL;\r
+ }\r
+\r
+ return PROG_UNKNOWN;\r
+}\r
+\r
+\r
+/// <summary>\r
+/// Get logarithm of an integer and round downwards.\r
+/// </summary>\r
+int int_floorlog2(int a) {\r
+ int l;\r
+ for (l=0; a>1; l++) {\r
+ a>>=1;\r
+ }\r
+ return l;\r
+}\r
+\r
+static int initialise_4K_poc(opj_poc_t *POC, int numres){\r
+ POC[0].tile = 1; \r
+ POC[0].resno0 = 0; \r
+ POC[0].compno0 = 0;\r
+ POC[0].layno1 = 1;\r
+ POC[0].resno1 = numres-1;\r
+ POC[0].compno1 = 3;\r
+ POC[0].prg1 = CPRL;\r
+ POC[1].tile = 1;\r
+ POC[1].resno0 = numres-1; \r
+ POC[1].compno0 = 0;\r
+ POC[1].layno1 = 1;\r
+ POC[1].resno1 = numres;\r
+ POC[1].compno1 = 3;\r
+ POC[1].prg1 = CPRL;\r
+ return 2;\r
+}\r
+\r
+void cinema_parameters(opj_cparameters_t *parameters){\r
+ parameters->tile_size_on = false;\r
+ parameters->cp_tdx=1;\r
+ parameters->cp_tdy=1;\r
+ \r
+ /*Tile part*/\r
+ parameters->tp_flag = 'C';\r
+ parameters->tp_on = 1;\r
+\r
+ /*Tile and Image shall be at (0,0)*/\r
+ parameters->cp_tx0 = 0;\r
+ parameters->cp_ty0 = 0;\r
+ parameters->image_offset_x0 = 0;\r
+ parameters->image_offset_y0 = 0;\r
+\r
+ /*Codeblock size= 32*32*/\r
+ parameters->cblockw_init = 32; \r
+ parameters->cblockh_init = 32;\r
+ parameters->csty |= 0x01;\r
+\r
+ /*The progression order shall be CPRL*/\r
+ parameters->prog_order = CPRL;\r
+\r
+ /* No ROI */\r
+ parameters->roi_compno = -1;\r
+\r
+ parameters->subsampling_dx = 1; parameters->subsampling_dy = 1;\r
+\r
+ /* 9-7 transform */\r
+ parameters->irreversible = 1;\r
+\r
+}\r
+\r
+void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){\r
+ int i;\r
+ float temp_rate;\r
+ opj_poc_t *POC = NULL;\r
+\r
+ switch (parameters->cp_cinema){\r
+ case CINEMA2K_24:\r
+ case CINEMA2K_48:\r
+ if(parameters->numresolution > 6){\r
+ parameters->numresolution = 6;\r
+ }\r
+ if (!((image->comps[0].w == 2048) | (image->comps[0].h == 1080))){\r
+ fprintf(stdout,"Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3"\r
+ "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n",\r
+ image->comps[0].w,image->comps[0].h);\r
+ parameters->cp_rsiz = STD_RSIZ;\r
+ }\r
+ break;\r
+ \r
+ case CINEMA4K_24:\r
+ if(parameters->numresolution < 1){\r
+ parameters->numresolution = 1;\r
+ }else if(parameters->numresolution > 7){\r
+ parameters->numresolution = 7;\r
+ }\r
+ if (!((image->comps[0].w == 4096) | (image->comps[0].h == 2160))){\r
+ fprintf(stdout,"Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4" \r
+ "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n",\r
+ image->comps[0].w,image->comps[0].h);\r
+ parameters->cp_rsiz = STD_RSIZ;\r
+ }\r
+ parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution);\r
+ break;\r
+ }\r
+\r
+ switch (parameters->cp_cinema){\r
+ case CINEMA2K_24:\r
+ case CINEMA4K_24:\r
+ for(i=0 ; i<parameters->tcp_numlayers ; i++){\r
+ temp_rate = 0 ;\r
+ if (img_fol->rates[i]== 0){\r
+ parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
+ (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);\r
+ }else{\r
+ temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
+ (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);\r
+ if (temp_rate > CINEMA_24_CS ){\r
+ parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
+ (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy);\r
+ }else{\r
+ parameters->tcp_rates[i]= img_fol->rates[i];\r
+ }\r
+ }\r
+ }\r
+ parameters->max_comp_size = COMP_24_CS;\r
+ break;\r
+ \r
+ case CINEMA2K_48:\r
+ for(i=0 ; i<parameters->tcp_numlayers ; i++){\r
+ temp_rate = 0 ;\r
+ if (img_fol->rates[i]== 0){\r
+ parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
+ (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);\r
+ }else{\r
+ temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
+ (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy);\r
+ if (temp_rate > CINEMA_48_CS ){\r
+ parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ \r
+ (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy);\r
+ }else{\r
+ parameters->tcp_rates[i]= img_fol->rates[i];\r
+ }\r
+ }\r
+ }\r
+ parameters->max_comp_size = COMP_48_CS;\r
+ break;\r
+ }\r
+ parameters->cp_disto_alloc = 1;\r
+}\r
+\r
+\r
+/* ------------------------------------------------------------------------------------ */\r
+int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters,\r
+ img_fol_t *img_fol, char *indexfilename) {\r
+ int i, j,totlen;\r
+ option_t long_option[]={\r
+ {"cinema2K",REQ_ARG, NULL ,'w'},\r
+ {"cinema4K",NO_ARG, NULL ,'y'},\r
+ {"ImgDir",REQ_ARG, NULL ,'z'},\r
+ {"TP",REQ_ARG, NULL ,'v'},\r
+ {"SOP",NO_ARG, NULL ,'S'},\r
+ {"EPH",NO_ARG, NULL ,'E'},\r
+ {"OutFor",REQ_ARG, NULL ,'O'},\r
+ {"POC",REQ_ARG, NULL ,'P'},\r
+ {"ROI",REQ_ARG, NULL ,'R'},\r
+ };\r
+\r
+ /* parse the command line */\r
+/* UniPG>> */\r
+ const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:"\r
+#ifdef USE_JPWL\r
+ "W:"\r
+#endif /* USE_JPWL */\r
+ ;\r
+\r
+ /*printf("C: parse_cmdline_encoder:");\r
+ for (i=0; i<argc; i++) {\r
+ printf("[%s]",argv[i]);\r
+ }\r
+ printf("\n");*/\r
+\r
+ totlen=sizeof(long_option);\r
+ img_fol->set_out_format=0;\r
+ reset_options_reading();\r
+\r
+ while (1) {\r
+ int c = getopt_long(argc, argv, optlist,long_option,totlen);\r
+ if (c == -1)\r
+ break;\r
+ switch (c) {\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'o': /* output file */\r
+ {\r
+ char *outfile = optarg;\r
+ parameters->cod_format = get_file_format(outfile);\r
+ switch(parameters->cod_format) {\r
+ case J2K_CFMT:\r
+ case JP2_CFMT:\r
+ break;\r
+ default:\r
+ fprintf(stderr, "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile);\r
+ return 1;\r
+ }\r
+ strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+ case 'O': /* output format */\r
+ {\r
+ char outformat[50];\r
+ char *of = optarg;\r
+ sprintf(outformat,".%s",of);\r
+ img_fol->set_out_format = 1;\r
+ parameters->cod_format = get_file_format(outformat);\r
+ switch(parameters->cod_format) {\r
+ case J2K_CFMT:\r
+ case JP2_CFMT:\r
+ img_fol->out_format = optarg;\r
+ break;\r
+ default:\r
+ fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n");\r
+ return 1;\r
+ }\r
+ }\r
+ break;\r
+\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+\r
+ case 'r': /* rates rates/distorsion */\r
+ {\r
+ char *s = optarg;\r
+ while (sscanf(s, "%f", ¶meters->tcp_rates[parameters->tcp_numlayers]) == 1) {\r
+ parameters->tcp_numlayers++;\r
+ while (*s && *s != ',') {\r
+ s++;\r
+ }\r
+ if (!*s)\r
+ break;\r
+ s++;\r
+ }\r
+ parameters->cp_disto_alloc = 1;\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'q': /* add fixed_quality */\r
+ {\r
+ char *s = optarg;\r
+ while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers]) == 1) {\r
+ parameters->tcp_numlayers++;\r
+ while (*s && *s != ',') {\r
+ s++;\r
+ }\r
+ if (!*s)\r
+ break;\r
+ s++;\r
+ }\r
+ parameters->cp_fixed_quality = 1;\r
+ }\r
+ break;\r
+\r
+ /* dda */\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'f': /* mod fixed_quality (before : -q) */\r
+ {\r
+ int *row = NULL, *col = NULL;\r
+ int numlayers = 0, numresolution = 0, matrix_width = 0;\r
+\r
+ char *s = optarg;\r
+ sscanf(s, "%d", &numlayers);\r
+ s++;\r
+ if (numlayers > 9)\r
+ s++;\r
+\r
+ parameters->tcp_numlayers = numlayers;\r
+ numresolution = parameters->numresolution;\r
+ matrix_width = numresolution * 3;\r
+ parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int));\r
+ s = s + 2;\r
+\r
+ for (i = 0; i < numlayers; i++) {\r
+ row = ¶meters->cp_matrice[i * matrix_width];\r
+ col = row;\r
+ parameters->tcp_rates[i] = 1;\r
+ sscanf(s, "%d,", &col[0]);\r
+ s += 2;\r
+ if (col[0] > 9)\r
+ s++;\r
+ col[1] = 0;\r
+ col[2] = 0;\r
+ for (j = 1; j < numresolution; j++) {\r
+ col += 3;\r
+ sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]);\r
+ s += 6;\r
+ if (col[0] > 9)\r
+ s++;\r
+ if (col[1] > 9)\r
+ s++;\r
+ if (col[2] > 9)\r
+ s++;\r
+ }\r
+ if (i < numlayers - 1)\r
+ s++;\r
+ }\r
+ parameters->cp_fixed_alloc = 1;\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 't': /* tiles */\r
+ {\r
+ sscanf(optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy);\r
+ parameters->tile_size_on = true;\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'n': /* resolution */\r
+ {\r
+ sscanf(optarg, "%d", ¶meters->numresolution);\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+ case 'c': /* precinct dimension */\r
+ {\r
+ char sep;\r
+ int res_spec = 0;\r
+\r
+ char *s = optarg;\r
+ do {\r
+ sep = 0;\r
+ sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec],\r
+ ¶meters->prch_init[res_spec], &sep);\r
+ parameters->csty |= 0x01;\r
+ res_spec++;\r
+ s = strpbrk(s, "]") + 2;\r
+ }\r
+ while (sep == ',');\r
+ parameters->res_spec = res_spec;\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'b': /* code-block dimension */\r
+ {\r
+ int cblockw_init = 0, cblockh_init = 0;\r
+ sscanf(optarg, "%d,%d", &cblockw_init, &cblockh_init);\r
+ if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024\r
+ || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) {\r
+ fprintf(stderr,\r
+ "!! Size of code_block error (option -b) !!\n\nRestriction :\n"\r
+ " * width*height<=4096\n * 4<=width,height<= 1024\n\n");\r
+ return 1;\r
+ }\r
+ parameters->cblockw_init = cblockw_init;\r
+ parameters->cblockh_init = cblockh_init;\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'x': /* creation of index file */\r
+ {\r
+ char *index = optarg;\r
+ strncpy(indexfilename, index, OPJ_PATH_LEN);\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'p': /* progression order */\r
+ {\r
+ char progression[4];\r
+\r
+ strncpy(progression, optarg, 4);\r
+ parameters->prog_order = give_progression(progression);\r
+ if (parameters->prog_order == -1) {\r
+ fprintf(stderr, "Unrecognized progression order "\r
+ "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n");\r
+ return 1;\r
+ }\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 's': /* subsampling factor */\r
+ {\r
+ if (sscanf(optarg, "%d,%d", ¶meters->subsampling_dx,\r
+ ¶meters->subsampling_dy) != 2) {\r
+ fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n");\r
+ return 1;\r
+ }\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'd': /* coordonnate of the reference grid */\r
+ {\r
+ if (sscanf(optarg, "%d,%d", ¶meters->image_offset_x0,\r
+ ¶meters->image_offset_y0) != 2) {\r
+ fprintf(stderr, "-d 'coordonnate of the reference grid' argument "\r
+ "error !! [-d x0,y0]\n");\r
+ return 1;\r
+ }\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'h': /* display an help description */\r
+ encode_help_display();\r
+ return 1;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'P': /* POC */\r
+ {\r
+ int numpocs = 0; /* number of progression order change (POC) default 0 */\r
+ opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */\r
+\r
+ char *s = optarg;\r
+ POC = parameters->POC;\r
+\r
+ while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile,\r
+ &POC[numpocs].resno0, &POC[numpocs].compno0,\r
+ &POC[numpocs].layno1, &POC[numpocs].resno1,\r
+ &POC[numpocs].compno1, &POC[numpocs].progorder) == 7) {\r
+ POC[numpocs].prg1 = give_progression(POC[numpocs].progorder);\r
+ numpocs++;\r
+ while (*s && *s != '/') {\r
+ s++;\r
+ }\r
+ if (!*s) {\r
+ break;\r
+ }\r
+ s++;\r
+ }\r
+ parameters->numpocs = numpocs;\r
+ }\r
+ break;\r
+\r
+ /* ------------------------------------------------------ */\r
+\r
+ case 'S': /* SOP marker */\r
+ {\r
+ parameters->csty |= 0x02;\r
+ }\r
+ break;\r
+\r
+ /* ------------------------------------------------------ */\r
+\r
+ case 'E': /* EPH marker */\r
+ {\r
+ parameters->csty |= 0x04;\r
+ }\r
+ break;\r
+\r
+ /* ------------------------------------------------------ */\r
+\r
+ case 'M': /* Mode switch pas tous au point !! */\r
+ {\r
+ int value = 0;\r
+ if (sscanf(optarg, "%d", &value) == 1) {\r
+ for (i = 0; i <= 5; i++) {\r
+ int cache = value & (1 << i);\r
+ if (cache)\r
+ parameters->mode |= (1 << i);\r
+ }\r
+ }\r
+ }\r
+ break;\r
+\r
+ /* ------------------------------------------------------ */\r
+\r
+ case 'R': /* ROI */\r
+ {\r
+ if (sscanf(optarg, "c=%d,U=%d", ¶meters->roi_compno,\r
+ ¶meters->roi_shift) != 2) {\r
+ fprintf(stderr, "ROI error !! [-ROI c='compno',U='shift']\n");\r
+ return 1;\r
+ }\r
+ }\r
+ break;\r
+\r
+ /* ------------------------------------------------------ */\r
+\r
+ case 'T': /* Tile offset */\r
+ {\r
+ if (sscanf(optarg, "%d,%d", ¶meters->cp_tx0, ¶meters->cp_ty0) != 2) {\r
+ fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]");\r
+ return 1;\r
+ }\r
+ }\r
+ break;\r
+\r
+ /* ------------------------------------------------------ */\r
+\r
+ case 'C': /* add a comment */\r
+ {\r
+ parameters->cp_comment = (char*)malloc(strlen(optarg) + 1);\r
+ if(parameters->cp_comment) {\r
+ strcpy(parameters->cp_comment, optarg);\r
+ }\r
+ }\r
+ break;\r
+\r
+\r
+ /* ------------------------------------------------------ */\r
+\r
+ case 'I': /* reversible or not */\r
+ {\r
+ parameters->irreversible = 1;\r
+ }\r
+ break;\r
+\r
+ /* ------------------------------------------------------ */\r
+ \r
+ case 'v': /* Tile part generation*/\r
+ {\r
+ parameters->tp_flag = optarg[0];\r
+ parameters->tp_on = 1;\r
+ }\r
+ break; \r
+\r
+ /* ------------------------------------------------------ */\r
+ \r
+ case 'z': /* Image Directory path */\r
+ {\r
+ img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1);\r
+ strcpy(img_fol->imgdirpath,optarg);\r
+ img_fol->set_imgdir=1;\r
+ }\r
+ break;\r
+\r
+ /* ------------------------------------------------------ */\r
+ \r
+ case 'w': /* Digital Cinema 2K profile compliance*/\r
+ {\r
+ int fps=0;\r
+ sscanf(optarg,"%d",&fps);\r
+ if(fps == 24){\r
+ parameters->cp_cinema = CINEMA2K_24;\r
+ }else if(fps == 48 ){\r
+ parameters->cp_cinema = CINEMA2K_48;\r
+ }else {\r
+ fprintf(stderr,"Incorrect value!! must be 24 or 48\n");\r
+ return 1;\r
+ }\r
+ fprintf(stdout,"CINEMA 2K compliant codestream\n");\r
+ parameters->cp_rsiz = CINEMA2K;\r
+ \r
+ }\r
+ break;\r
+ \r
+ /* ------------------------------------------------------ */\r
+ \r
+ case 'y': /* Digital Cinema 4K profile compliance*/\r
+ {\r
+ parameters->cp_cinema = CINEMA4K_24;\r
+ fprintf(stdout,"CINEMA 4K compliant codestream\n");\r
+ parameters->cp_rsiz = CINEMA4K;\r
+ }\r
+ break;\r
+ \r
+ /* ------------------------------------------------------ */\r
+\r
+/* UniPG>> */\r
+#ifdef USE_JPWL\r
+ /* ------------------------------------------------------ */\r
+ \r
+ case 'W': /* JPWL capabilities switched on */\r
+ {\r
+ char *token = NULL;\r
+ int hprot, pprot, sens, addr, size, range;\r
+\r
+ /* we need to enable indexing */\r
+ if (!indexfilename) {\r
+ strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN);\r
+ }\r
+\r
+ /* search for different protection methods */\r
+\r
+ /* break the option in comma points and parse the result */\r
+ token = strtok(optarg, ",");\r
+ while(token != NULL) {\r
+\r
+ /* search header error protection method */\r
+ if (*token == 'h') {\r
+\r
+ static int tile = 0, tilespec = 0, lasttileno = 0;\r
+\r
+ hprot = 1; /* predefined method */\r
+\r
+ if(sscanf(token, "h=%d", &hprot) == 1) {\r
+ /* Main header, specified */\r
+ if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||\r
+ ((hprot >= 37) && (hprot <= 128)))) {\r
+ fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n", hprot);\r
+ return 1;\r
+ }\r
+ parameters->jpwl_hprot_MH = hprot;\r
+\r
+ } else if(sscanf(token, "h%d=%d", &tile, &hprot) == 2) {\r
+ /* Tile part header, specified */\r
+ if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) ||\r
+ ((hprot >= 37) && (hprot <= 128)))) {\r
+ fprintf(stderr, "ERROR -> invalid tile part header protection method h = %d\n", hprot);\r
+ return 1;\r
+ }\r
+ if (tile < 0) {\r
+ fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);\r
+ return 1;\r
+ }\r
+ if (tilespec < JPWL_MAX_NO_TILESPECS) {\r
+ parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;\r
+ parameters->jpwl_hprot_TPH[tilespec++] = hprot;\r
+ }\r
+\r
+ } else if(sscanf(token, "h%d", &tile) == 1) {\r
+ /* Tile part header, unspecified */\r
+ if (tile < 0) {\r
+ fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile);\r
+ return 1;\r
+ }\r
+ if (tilespec < JPWL_MAX_NO_TILESPECS) {\r
+ parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile;\r
+ parameters->jpwl_hprot_TPH[tilespec++] = hprot;\r
+ }\r
+\r
+\r
+ } else if (!strcmp(token, "h")) {\r
+ /* Main header, unspecified */\r
+ parameters->jpwl_hprot_MH = hprot;\r
+\r
+ } else {\r
+ fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);\r
+ return 1;\r
+ };\r
+\r
+ }\r
+\r
+ /* search packet error protection method */\r
+ if (*token == 'p') {\r
+\r
+ static int pack = 0, tile = 0, packspec = 0, lastpackno = 0;\r
+\r
+ pprot = 1; /* predefined method */\r
+\r
+ if (sscanf(token, "p=%d", &pprot) == 1) {\r
+ /* Method for all tiles and all packets */\r
+ if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||\r
+ ((pprot >= 37) && (pprot <= 128)))) {\r
+ fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n", pprot);\r
+ return 1;\r
+ }\r
+ parameters->jpwl_pprot_tileno[0] = 0;\r
+ parameters->jpwl_pprot_packno[0] = 0;\r
+ parameters->jpwl_pprot[0] = pprot;\r
+\r
+ } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) {\r
+ /* method specified from that tile on */\r
+ if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||\r
+ ((pprot >= 37) && (pprot <= 128)))) {\r
+ fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);\r
+ return 1;\r
+ }\r
+ if (tile < 0) {\r
+ fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);\r
+ return 1;\r
+ }\r
+ if (packspec < JPWL_MAX_NO_PACKSPECS) {\r
+ parameters->jpwl_pprot_tileno[packspec] = tile;\r
+ parameters->jpwl_pprot_packno[packspec] = 0;\r
+ parameters->jpwl_pprot[packspec++] = pprot;\r
+ }\r
+\r
+ } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) {\r
+ /* method fully specified from that tile and that packet on */\r
+ if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||\r
+ ((pprot >= 37) && (pprot <= 128)))) {\r
+ fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);\r
+ return 1;\r
+ }\r
+ if (tile < 0) {\r
+ fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);\r
+ return 1;\r
+ }\r
+ if (pack < 0) {\r
+ fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);\r
+ return 1;\r
+ }\r
+ if (packspec < JPWL_MAX_NO_PACKSPECS) {\r
+ parameters->jpwl_pprot_tileno[packspec] = tile;\r
+ parameters->jpwl_pprot_packno[packspec] = pack;\r
+ parameters->jpwl_pprot[packspec++] = pprot;\r
+ }\r
+\r
+ } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) {\r
+ /* default method from that tile and that packet on */\r
+ if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) ||\r
+ ((pprot >= 37) && (pprot <= 128)))) {\r
+ fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot);\r
+ return 1;\r
+ }\r
+ if (tile < 0) {\r
+ fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);\r
+ return 1;\r
+ }\r
+ if (pack < 0) {\r
+ fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack);\r
+ return 1;\r
+ }\r
+ if (packspec < JPWL_MAX_NO_PACKSPECS) {\r
+ parameters->jpwl_pprot_tileno[packspec] = tile;\r
+ parameters->jpwl_pprot_packno[packspec] = pack;\r
+ parameters->jpwl_pprot[packspec++] = pprot;\r
+ }\r
+\r
+ } else if (sscanf(token, "p%d", &tile) == 1) {\r
+ /* default from a tile on */\r
+ if (tile < 0) {\r
+ fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile);\r
+ return 1;\r
+ }\r
+ if (packspec < JPWL_MAX_NO_PACKSPECS) {\r
+ parameters->jpwl_pprot_tileno[packspec] = tile;\r
+ parameters->jpwl_pprot_packno[packspec] = 0;\r
+ parameters->jpwl_pprot[packspec++] = pprot;\r
+ }\r
+\r
+\r
+ } else if (!strcmp(token, "p")) {\r
+ /* all default */\r
+ parameters->jpwl_pprot_tileno[0] = 0;\r
+ parameters->jpwl_pprot_packno[0] = 0;\r
+ parameters->jpwl_pprot[0] = pprot;\r
+\r
+ } else {\r
+ fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token);\r
+ return 1;\r
+ };\r
+\r
+ }\r
+\r
+ /* search sensitivity method */\r
+ if (*token == 's') {\r
+\r
+ static int tile = 0, tilespec = 0, lasttileno = 0;\r
+\r
+ sens = 0; /* predefined: relative error */\r
+\r
+ if(sscanf(token, "s=%d", &sens) == 1) {\r
+ /* Main header, specified */\r
+ if ((sens < -1) || (sens > 7)) {\r
+ fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n", sens);\r
+ return 1;\r
+ }\r
+ parameters->jpwl_sens_MH = sens;\r
+\r
+ } else if(sscanf(token, "s%d=%d", &tile, &sens) == 2) {\r
+ /* Tile part header, specified */\r
+ if ((sens < -1) || (sens > 7)) {\r
+ fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n", sens);\r
+ return 1;\r
+ }\r
+ if (tile < 0) {\r
+ fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);\r
+ return 1;\r
+ }\r
+ if (tilespec < JPWL_MAX_NO_TILESPECS) {\r
+ parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;\r
+ parameters->jpwl_sens_TPH[tilespec++] = sens;\r
+ }\r
+\r
+ } else if(sscanf(token, "s%d", &tile) == 1) {\r
+ /* Tile part header, unspecified */\r
+ if (tile < 0) {\r
+ fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile);\r
+ return 1;\r
+ }\r
+ if (tilespec < JPWL_MAX_NO_TILESPECS) {\r
+ parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile;\r
+ parameters->jpwl_sens_TPH[tilespec++] = hprot;\r
+ }\r
+\r
+ } else if (!strcmp(token, "s")) {\r
+ /* Main header, unspecified */\r
+ parameters->jpwl_sens_MH = sens;\r
+\r
+ } else {\r
+ fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token);\r
+ return 1;\r
+ };\r
+ \r
+ parameters->jpwl_sens_size = 2; /* 2 bytes for default size */\r
+ }\r
+\r
+ /* search addressing size */\r
+ if (*token == 'a') {\r
+\r
+ static int tile = 0, tilespec = 0, lasttileno = 0;\r
+\r
+ addr = 0; /* predefined: auto */\r
+\r
+ if(sscanf(token, "a=%d", &addr) == 1) {\r
+ /* Specified */\r
+ if ((addr != 0) && (addr != 2) && (addr != 4)) {\r
+ fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr);\r
+ return 1;\r
+ }\r
+ parameters->jpwl_sens_addr = addr;\r
+\r
+ } else if (!strcmp(token, "a")) {\r
+ /* default */\r
+ parameters->jpwl_sens_addr = addr; /* auto for default size */\r
+\r
+ } else {\r
+ fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token);\r
+ return 1;\r
+ };\r
+ \r
+ }\r
+\r
+ /* search sensitivity size */\r
+ if (*token == 'z') {\r
+\r
+ static int tile = 0, tilespec = 0, lasttileno = 0;\r
+\r
+ size = 1; /* predefined: 1 byte */\r
+\r
+ if(sscanf(token, "z=%d", &size) == 1) {\r
+ /* Specified */\r
+ if ((size != 0) && (size != 1) && (size != 2)) {\r
+ fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size);\r
+ return 1;\r
+ }\r
+ parameters->jpwl_sens_size = size;\r
+\r
+ } else if (!strcmp(token, "a")) {\r
+ /* default */\r
+ parameters->jpwl_sens_size = size; /* 1 for default size */\r
+\r
+ } else {\r
+ fprintf(stderr, "ERROR -> invalid size selection = %s\n", token);\r
+ return 1;\r
+ };\r
+ \r
+ }\r
+\r
+ /* search range method */\r
+ if (*token == 'g') {\r
+\r
+ static int tile = 0, tilespec = 0, lasttileno = 0;\r
+\r
+ range = 0; /* predefined: 0 (packet) */\r
+\r
+ if(sscanf(token, "g=%d", &range) == 1) {\r
+ /* Specified */\r
+ if ((range < 0) || (range > 3)) {\r
+ fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range);\r
+ return 1;\r
+ }\r
+ parameters->jpwl_sens_range = range;\r
+\r
+ } else if (!strcmp(token, "g")) {\r
+ /* default */\r
+ parameters->jpwl_sens_range = range;\r
+\r
+ } else {\r
+ fprintf(stderr, "ERROR -> invalid range selection = %s\n", token);\r
+ return 1;\r
+ };\r
+ \r
+ }\r
+\r
+ /* next token or bust */\r
+ token = strtok(NULL, ",");\r
+ };\r
+\r
+\r
+ /* some info */\r
+ fprintf(stdout, "Info: JPWL capabilities enabled\n");\r
+ parameters->jpwl_epc_on = true;\r
+\r
+ }\r
+ break;\r
+#endif /* USE_JPWL */\r
+/* <<UniPG */\r
+\r
+ /* ------------------------------------------------------ */\r
+\r
+ default:\r
+ fprintf(stderr, "ERROR -> Command line not valid\n");\r
+ return 1;\r
+ }\r
+ }\r
+\r
+ /* check for possible errors */\r
+ if (parameters->cp_cinema){\r
+ if(parameters->tcp_numlayers > 1){\r
+ parameters->cp_rsiz = STD_RSIZ;\r
+ 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
+ }\r
+ }\r
+\r
+ if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality)\r
+ && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ parameters->cp_fixed_quality))) {\r
+ fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n");\r
+ return 1;\r
+ } /* mod fixed_quality */\r
+\r
+ /* if no rate entered, lossless by default */\r
+ if (parameters->tcp_numlayers == 0) {\r
+ parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */\r
+ parameters->tcp_numlayers++;\r
+ parameters->cp_disto_alloc = 1;\r
+ }\r
+\r
+ if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) {\r
+ fprintf(stderr,\r
+ "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n",\r
+ parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0);\r
+ return 1;\r
+ }\r
+\r
+ for (i = 0; i < parameters->numpocs; i++) {\r
+ if (parameters->POC[i].prg == -1) {\r
+ fprintf(stderr,\r
+ "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n",\r
+ i + 1);\r
+ }\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+/** 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
+ @param buffer_size, increased by the length of the compressed index, in number of bytes\r
+ @return a pointer to a char[]\r
+ Syntax of the index:\r
+ one char for the version number (1): one byte because no problem with little endian, big endian etc.\r
+ one int for each of the following informations:\r
+ Image Width \r
+ Image Height \r
+ progression order \r
+ Tile width \r
+ Tile height \r
+ Nb tiles in X \r
+ Nb tiles in Y \r
+ Nb of components \r
+ Nb of layers \r
+ Nb of resolutions \r
+\r
+ for each resolution: \r
+ Precinct width\r
+ Precinct height\r
+\r
+ End main header position \r
+ codestream size \r
+\r
+ For each tile: \r
+ tile number\r
+ tile start pos in codestream\r
+ tile header end position\r
+ tile end position in codestream\r
+\r
+ For each LRCP, RLCP etc.: \r
+ packet number\r
+ tile number\r
+ layer number\r
+ resolution number\r
+ component number\r
+ precinct number\r
+ start position in the codestream\r
+ end position of this packet\r
+ */\r
+char* create_index_into_byte_array(opj_codestream_info_t *cstr_info, int* buffer_size) {\r
+ int tileno, compno, layno, resno, precno, pack_nb, x, y;\r
+ char* buffer = NULL;\r
+ int buffer_pos = 0;\r
+ int prec_max = 0;\r
+ \r
+ prec_max = 0;\r
+ for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {\r
+ for (resno = 0; resno < cstr_info->numdecompos[0] + 1; resno++) {\r
+ prec_max = max(prec_max,cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno]);\r
+ }\r
+ }\r
+\r
+ // Compute the size of the index buffer, in number of bytes*/\r
+ *buffer_size = \r
+ 1 /* version */\r
+ + (10 /* image_w until decomposition */\r
+ + (cstr_info->numdecompos[0]+1) * 2 /* pdx size for each tile */\r
+ + 2 /* main_head_end + codestream_size */\r
+ + cstr_info->tw * cstr_info->th * 4 /* tile info, without distorsion info */\r
+ + cstr_info->tw*cstr_info->th * cstr_info->numlayers * (cstr_info->numdecompos[0] + 1) * cstr_info->numcomps * prec_max *8\r
+ ) * sizeof(int);\r
+ //printf("C: index buffer size = %d bytes\n", *buffer_size);\r
+ buffer = (char*) malloc(*buffer_size);\r
+\r
+ if (!buffer) {\r
+ //opj_event_msg(j2k->cinfo, EVT_ERROR, "failed to allocate index buffer for writing %d int\n", *buffer_size);\r
+ fprintf(stderr, "failed to allocate index buffer for writing %d int\n", *buffer_size);\r
+ return 0;\r
+ }\r
+ \r
+ buffer[0] = 1; // Version stored on a byte\r
+ buffer++;\r
+ // Remaining informations are stored on a int.\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->image_w;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->image_h;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->prog;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile_x;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile_y;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->tw;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->th;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->numcomps;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->numlayers;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->numdecompos[0];\r
+ \r
+ for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {\r
+ /* based on tile 0 */\r
+ ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);\r
+ ((int*)buffer)[buffer_pos++] = (1 << cstr_info->tile[0].pdx[resno]);\r
+ }\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->main_head_end;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->codestream_size;\r
+ \r
+ for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].tileno;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].start_pos;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_header;\r
+ ((int*)buffer)[buffer_pos++] = cstr_info->tile[tileno].end_pos;\r
+ }\r
+ \r
+ for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {\r
+ int start_pos, end_pos;\r
+ int max_numdecompos = 0;\r
+ pack_nb = 0;\r
+ \r
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
+ if (max_numdecompos < cstr_info->numdecompos[compno])\r
+ max_numdecompos = cstr_info->numdecompos[compno];\r
+ } \r
+\r
+ if (cstr_info->prog == LRCP) { /* LRCP */\r
+\r
+ for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
+ for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
+ int prec_max;\r
+ if (resno > cstr_info->numdecompos[compno])\r
+ break;\r
+ prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
+ for (precno = 0; precno < prec_max; precno++) {\r
+ start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
+ end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
+ ((int*)buffer)[buffer_pos++] = pack_nb;\r
+ ((int*)buffer)[buffer_pos++] = tileno;\r
+ ((int*)buffer)[buffer_pos++] = layno;\r
+ ((int*)buffer)[buffer_pos++] = resno;\r
+ ((int*)buffer)[buffer_pos++] = compno;\r
+ ((int*)buffer)[buffer_pos++] = precno;\r
+ ((int*)buffer)[buffer_pos++] = start_pos;\r
+ ((int*)buffer)[buffer_pos++] = end_pos;\r
+ pack_nb++;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } /* LRCP */\r
+ else if (cstr_info->prog == RLCP) { /* RLCP */\r
+\r
+ for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
+ for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
+ int prec_max; \r
+ if (resno > cstr_info->numdecompos[compno])\r
+ break;\r
+ prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
+ for (precno = 0; precno < prec_max; precno++) {\r
+ start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
+ end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
+ ((int*)buffer)[buffer_pos++] = pack_nb;\r
+ ((int*)buffer)[buffer_pos++] = tileno;\r
+ ((int*)buffer)[buffer_pos++] = resno;\r
+ ((int*)buffer)[buffer_pos++] = layno;\r
+ ((int*)buffer)[buffer_pos++] = compno;\r
+ ((int*)buffer)[buffer_pos++] = precno;\r
+ ((int*)buffer)[buffer_pos++] = start_pos;\r
+ ((int*)buffer)[buffer_pos++] = end_pos;\r
+ pack_nb++;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } /* RLCP */\r
+ else if (cstr_info->prog == RPCL) { /* RPCL */\r
+\r
+ for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
+ /* I suppose components have same XRsiz, YRsiz */\r
+ int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;\r
+ int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;\r
+ int x1 = x0 + cstr_info->tile_x;\r
+ int y1 = y0 + cstr_info->tile_y;\r
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
+ int prec_max; \r
+ if (resno > cstr_info->numdecompos[compno])\r
+ break;\r
+ prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
+ for (precno = 0; precno < prec_max; precno++) {\r
+ int pcnx = cstr_info->tile[tileno].pw[resno];\r
+ int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );\r
+ int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );\r
+ int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;\r
+ int precno_y = (int) floor( (float)precno/(float)pcnx );\r
+ for(y = y0; y < y1; y++) { \r
+ if (precno_y*pcy == y ) {\r
+ for (x = x0; x < x1; x++) { \r
+ if (precno_x*pcx == x ) {\r
+ for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
+ start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
+ end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
+ ((int*)buffer)[buffer_pos++] = pack_nb;\r
+ ((int*)buffer)[buffer_pos++] = tileno;\r
+ ((int*)buffer)[buffer_pos++] = resno;\r
+ ((int*)buffer)[buffer_pos++] = precno;\r
+ ((int*)buffer)[buffer_pos++] = compno;\r
+ ((int*)buffer)[buffer_pos++] = layno;\r
+ ((int*)buffer)[buffer_pos++] = start_pos;\r
+ ((int*)buffer)[buffer_pos++] = end_pos;\r
+ pack_nb++; \r
+ }\r
+ }\r
+ }/* x = x0..x1 */\r
+ } \r
+ } /* y = y0..y1 */\r
+ } /* precno */\r
+ } /* compno */\r
+ } /* resno */\r
+ } /* RPCL */\r
+ else if (cstr_info->prog == PCRL) { /* PCRL */\r
+ /* I suppose components have same XRsiz, YRsiz */\r
+ int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;\r
+ int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;\r
+ int x1 = x0 + cstr_info->tile_x;\r
+ int y1 = y0 + cstr_info->tile_y;\r
+\r
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
+ for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
+ int prec_max; \r
+ if (resno > cstr_info->numdecompos[compno])\r
+ break;\r
+ prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
+ for (precno = 0; precno < prec_max; precno++) {\r
+ int pcnx = cstr_info->tile[tileno].pw[resno];\r
+ int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );\r
+ int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );\r
+ int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;\r
+ int precno_y = (int) floor( (float)precno/(float)pcnx );\r
+ for(y = y0; y < y1; y++) { \r
+ if (precno_y*pcy == y ) {\r
+ for (x = x0; x < x1; x++) { \r
+ if (precno_x*pcx == x ) {\r
+ for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
+ start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
+ end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
+ ((int*)buffer)[buffer_pos++] = pack_nb;\r
+ ((int*)buffer)[buffer_pos++] = tileno;\r
+ ((int*)buffer)[buffer_pos++] = precno;\r
+ ((int*)buffer)[buffer_pos++] = compno;\r
+ ((int*)buffer)[buffer_pos++] = resno;\r
+ ((int*)buffer)[buffer_pos++] = layno;\r
+ ((int*)buffer)[buffer_pos++] = start_pos;\r
+ ((int*)buffer)[buffer_pos++] = end_pos;\r
+ pack_nb++; \r
+ }\r
+ }\r
+ }/* x = x0..x1 */\r
+ } \r
+ } /* y = y0..y1 */\r
+ } /* precno */\r
+ } /* resno */\r
+ } /* compno */\r
+ } /* PCRL */\r
+ else { /* CPRL */\r
+\r
+ for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
+ /* I suppose components have same XRsiz, YRsiz */\r
+ int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;\r
+ int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;\r
+ int x1 = x0 + cstr_info->tile_x;\r
+ int y1 = y0 + cstr_info->tile_y;\r
+ \r
+ for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
+ int prec_max; \r
+ if (resno > cstr_info->numdecompos[compno])\r
+ break;\r
+ prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
+ for (precno = 0; precno < prec_max; precno++) {\r
+ int pcnx = cstr_info->tile[tileno].pw[resno];\r
+ int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );\r
+ int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );\r
+ int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;\r
+ int precno_y = (int) floor( (float)precno/(float)pcnx );\r
+ for(y = y0; y < y1; y++) {\r
+ if (precno_y*pcy == y ) {\r
+ for (x = x0; x < x1; x++) {\r
+ if (precno_x*pcx == x ) {\r
+ for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
+ start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
+ end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
+ ((int*)buffer)[buffer_pos++] = pack_nb;\r
+ ((int*)buffer)[buffer_pos++] = tileno;\r
+ ((int*)buffer)[buffer_pos++] = compno;\r
+ ((int*)buffer)[buffer_pos++] = precno;\r
+ ((int*)buffer)[buffer_pos++] = resno;\r
+ ((int*)buffer)[buffer_pos++] = layno;\r
+ ((int*)buffer)[buffer_pos++] = start_pos;\r
+ ((int*)buffer)[buffer_pos++] = end_pos;\r
+ pack_nb++; \r
+ }\r
+ }\r
+ }/* x = x0..x1 */\r
+ }\r
+ } /* y = y0..y1 */\r
+ } /* precno */\r
+ } /* resno */\r
+ } /* compno */\r
+ } /* CPRL */ \r
+ } /* tileno */\r
+\r
+ if (buffer_pos > *buffer_size) {\r
+ //opj_event_msg(j2k->cinfo, EVT_ERROR, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);\r
+ fprintf(stderr, "index creation: buffer_pos (%d) > buffer_size (%d)!\n", buffer_pos, *buffer_size);\r
+ return 0;\r
+ }\r
+\r
+ return --buffer;\r
+}\r
+\r
+\r
+\r
+\r
+/* -------------------------------------------------------------------------- \r
+ ------------ Get the image byte[] from the Java object -------------------*/\r
+\r
+opj_image_t* loadImage(opj_cparameters_t *parameters, JNIEnv *env, jobject obj, jclass cls) {\r
+ int i,max,shift,w,h,depth;\r
+ opj_image_t * img = NULL;\r
+ int compno, numcomps;\r
+ opj_image_t * image = NULL;\r
+ opj_image_comp_t *comp;\r
+ opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */\r
+ OPJ_COLOR_SPACE color_space;\r
+ jfieldID fid;\r
+ jint ji;\r
+ jbyteArray jba;\r
+ jshortArray jsa;\r
+ jintArray jia;\r
+ int len;\r
+ jbyte *jbBody;\r
+ jshort *jsBody;\r
+ jint *jiBody;\r
+ boolean isCopy;\r
+\r
+ // Image width, height and depth\r
+ fid = (*env)->GetFieldID(env, cls,"width", "I");\r
+ ji = (*env)->GetIntField(env, obj, fid);\r
+ w = ji;\r
+\r
+ fid = (*env)->GetFieldID(env, cls,"height", "I");\r
+ ji = (*env)->GetIntField(env, obj, fid);\r
+ h = ji;\r
+ \r
+ fid = (*env)->GetFieldID(env, cls,"depth", "I");\r
+ ji = (*env)->GetIntField(env, obj, fid);\r
+ depth = ji;\r
+\r
+ // Read the image\r
+ if (depth <=16) {\r
+ numcomps = 1;\r
+ color_space = CLRSPC_GRAY;\r
+ } else {\r
+ numcomps = 3;\r
+ color_space = CLRSPC_SRGB;\r
+ }\r
+ memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t));\r
+\r
+ if (numcomps == 1) {\r
+ cmptparm[0].x0 = parameters->image_offset_x0;\r
+ cmptparm[0].y0 = parameters->image_offset_y0;\r
+ cmptparm[0].w = !cmptparm[0].x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm[0].x0 + (w - 1) * parameters->subsampling_dx + 1;\r
+ cmptparm[0].h = !cmptparm[0].y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm[0].y0 + (h - 1) * parameters->subsampling_dy + 1;\r
+ // Java types are always signed but we use them as unsigned types (shift of the negative part of \r
+ // the pixels of the images in Telemis before entering the encoder).\r
+ cmptparm[0].sgnd = 0;\r
+ if (depth<=16) \r
+ cmptparm[0].prec=depth;\r
+ else \r
+ cmptparm[0].prec = 8;\r
+ cmptparm[0].bpp = cmptparm[0].prec;\r
+ cmptparm[0].dx = parameters->subsampling_dx;\r
+ cmptparm[0].dy = parameters->subsampling_dy;\r
+ /*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
+ cmptparm[0].h, cmptparm[0].sgnd, cmptparm[0].bpp, cmptparm[0].dx, cmptparm[0].dy, color_space);*/\r
+ } else {\r
+ for(i = 0; i < numcomps; i++) {\r
+ cmptparm[i].prec = 8;\r
+ cmptparm[i].bpp = 8;\r
+ cmptparm[i].sgnd = 0;\r
+ cmptparm[i].dx = parameters->subsampling_dx;\r
+ cmptparm[i].dy = parameters->subsampling_dy;\r
+ cmptparm[i].w = w;\r
+ cmptparm[i].h = h;\r
+ }\r
+ }\r
+ \r
+ /* create the image */\r
+ image = opj_image_create(numcomps, &cmptparm[0], color_space);\r
+\r
+ if (!image)\r
+ return NULL;\r
+\r
+ if (depth <=16) {\r
+ image->numcomps=1;\r
+ } else {\r
+ image->numcomps = 3;\r
+ }\r
+\r
+ /* set image offset and reference grid */\r
+ image->x0 = cmptparm[0].x0;\r
+ image->y0 = cmptparm[0].x0;\r
+ image->x1 = cmptparm[0].w;\r
+ image->y1 = cmptparm[0].h;\r
+\r
+ /* set image data */\r
+ for (compno=0; compno<numcomps; compno++) {\r
+ comp = &image->comps[compno];\r
+ max = -100000;\r
+ if (depth == 8) {\r
+ fid = (*env)->GetFieldID(env, cls,"image8", "[B"); // byteArray []\r
+ jba = (*env)->GetObjectField(env, obj, fid);\r
+ len = (*env)->GetArrayLength(env, jba);\r
+ \r
+ jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, &isCopy);\r
+ //printf("C: before transfering 8 bpp image\n");\r
+ if (comp->sgnd) {\r
+ for(i=0; i< len;i++) {\r
+ comp->data[i] = (char) jbBody[i];\r
+ if (comp->data[i] > max) max = comp->data[i];\r
+ }\r
+ } else {\r
+ for(i=0; i< len;i++) {\r
+ comp->data[i] = (unsigned char) jbBody[i];\r
+ if (comp->data[i] > max) max = comp->data[i];\r
+ }\r
+ }\r
+ (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);\r
+ } else if(depth == 16) {\r
+ fid = (*env)->GetFieldID(env, cls,"image16", "[S"); // shortArray []\r
+ jsa = (*env)->GetObjectField(env, obj, fid);\r
+ len = (*env)->GetArrayLength(env, jsa);\r
+ \r
+ jsBody = (*env)->GetPrimitiveArrayCritical(env, jsa, &isCopy);\r
+ //printf("C: before transfering 16 bpp image\n");\r
+ if (comp->sgnd) { // Special behaviour to deal with signed elements ??\r
+ comp->data[i] = (short) jsBody[i];\r
+ for(i=0; i< len;i++) {\r
+ if (comp->data[i] > max) max = comp->data[i];\r
+ }\r
+ } else {\r
+ for(i=0; i< len;i++) {\r
+ comp->data[i] = (unsigned short) jsBody[i];\r
+ if (comp->data[i] > max) max = comp->data[i];\r
+ }\r
+ }\r
+ (*env)->ReleasePrimitiveArrayCritical(env, jsa, jsBody, 0);\r
+ } else if (depth == 24) {\r
+ fid = (*env)->GetFieldID(env, cls,"image24", "[I"); // intArray []\r
+ jia = (*env)->GetObjectField(env, obj, fid);\r
+ len = (*env)->GetArrayLength(env, jia);\r
+ shift = compno*8;\r
+\r
+ jiBody = (*env)->GetPrimitiveArrayCritical(env, jia, &isCopy);\r
+ //printf("C: before transfering 24 bpp image (component %d, signed = %d)\n", compno, comp->sgnd);\r
+ if (comp->sgnd) { // Special behaviour to deal with signed elements ?? XXXXX\r
+ for(i=0; i< len;i++) {\r
+ comp->data[i] = ( ((int) jiBody[i]) & (0xFF << shift) ) >> shift;\r
+ if (comp->data[i] > max) max = comp->data[i];\r
+ }\r
+ } else {\r
+ for(i=0; i< len;i++) {\r
+ comp->data[i] = ( ((unsigned int) jiBody[i]) & (0xFF << shift) ) >> shift;\r
+ if (comp->data[i] > max) max = comp->data[i];\r
+ }\r
+ }\r
+ (*env)->ReleasePrimitiveArrayCritical(env, jia, jiBody, 0);\r
+ }\r
+ comp->bpp = int_floorlog2(max)+1;\r
+ comp->prec = comp->bpp;\r
+ //printf("C: component %d: max %d, real bpp = %d\n", compno, max, comp->bpp);\r
+ }\r
+ return image;\r
+}\r
+\r
+\r
+/* --------------------------------------------------------------------------\r
+ -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/\r
+JNIEXPORT jlong JNICALL Java_org_openJpeg_OpenJPEGJavaEncoder_internalEncodeImageToJ2K(JNIEnv *env, jobject obj, jobjectArray javaParameters) {\r
+ int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */\r
+ char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */\r
+ bool bSuccess;\r
+ opj_cparameters_t parameters; /* compression parameters */\r
+ img_fol_t img_fol;\r
+ opj_event_mgr_t event_mgr; /* event manager */\r
+ opj_image_t *image = NULL;\r
+ int i,j,num_images;\r
+ int imageno;\r
+ opj_codestream_info_t cstr_info; /* Codestream information structure */\r
+ char indexfilename[OPJ_PATH_LEN]; /* index file name */\r
+\r
+ int* compressed_index = NULL;\r
+ int compressed_index_size=-1;\r
+ // ==> Access variables to the Java member variables\r
+ jsize arraySize;\r
+ jclass cls;\r
+ jobject object;\r
+ jboolean isCopy;\r
+ jfieldID fid;\r
+ jbyteArray jba;\r
+ jbyte *jbBody;\r
+ callback_variables_t msgErrorCallback_vars;\r
+ // <== access variable to the Java member variables.\r
+\r
+ // For the encoding and storage into the file\r
+ opj_cinfo_t* cinfo;\r
+ int codestream_length;\r
+ opj_cio_t *cio = NULL;\r
+ FILE *f = NULL;\r
+\r
+ // JNI reference to the calling class\r
+ cls = (*env)->GetObjectClass(env, obj);\r
+ \r
+ // Pointers to be able to call a Java method for all the info and error messages\r
+ msgErrorCallback_vars.env = env;\r
+ msgErrorCallback_vars.jobj = &obj;\r
+ msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V");\r
+ msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V");\r
+\r
+ arraySize = (*env)->GetArrayLength(env, javaParameters);\r
+ argc = (int) arraySize +1;\r
+ argv = malloc(argc*sizeof(char*));\r
+ argv[0] = "ProgramName.exe"; // The program name: useless\r
+ j=0;\r
+ for (i=1; i<argc; i++) {\r
+ object = (*env)->GetObjectArrayElement(env, javaParameters, i-1);\r
+ argv[i] = (*env)->GetStringUTFChars(env, object, &isCopy);\r
+ }\r
+\r
+ /*printf("C: ");\r
+ for (i=0; i<argc; i++) {\r
+ printf("[%s]",argv[i]);\r
+ }\r
+ printf("\n");*/\r
+\r
+ /*\r
+ configure the event callbacks\r
+ */\r
+ memset(&event_mgr, 0, sizeof(opj_event_mgr_t));\r
+ event_mgr.error_handler = error_callback;\r
+ event_mgr.warning_handler = warning_callback;\r
+ event_mgr.info_handler = info_callback;\r
+\r
+ /* set encoding parameters to default values */\r
+ opj_set_default_encoder_parameters(¶meters);\r
+ parameters.cod_format = J2K_CFMT;\r
+ //parameters.index_on = 1;\r
+\r
+ /* Initialize indexfilename and img_fol */\r
+ *indexfilename = 0;\r
+ memset(&img_fol,0,sizeof(img_fol_t));\r
+\r
+ /* parse input and get user encoding parameters */\r
+ if (parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) {\r
+ // Release the Java arguments array\r
+ for (i=1; i<argc; i++)\r
+ (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);\r
+ return -1;\r
+ }\r
+\r
+ // Release the Java arguments array\r
+ for (i=1; i<argc; i++)\r
+ (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);\r
+\r
+ if (parameters.cp_cinema){\r
+ cinema_parameters(¶meters);\r
+ }\r
+ \r
+\r
+ /* Create comment for codestream */\r
+ if(parameters.cp_comment == NULL) {\r
+ const char comment[] = "Created by JavaOpenJPEG version ";\r
+ const size_t clen = strlen(comment);\r
+ const char *version = opj_version();\r
+/* UniPG>> */\r
+#ifdef USE_JPWL\r
+ parameters.cp_comment = (char*)malloc(clen+strlen(version)+11);\r
+ sprintf(parameters.cp_comment,"%s%s with JPWL", comment, version);\r
+#else\r
+ parameters.cp_comment = (char*)malloc(clen+strlen(version)+1);\r
+ sprintf(parameters.cp_comment,"%s%s", comment, version);\r
+#endif\r
+/* <<UniPG */\r
+\r
+ }\r
+\r
+ /* Read directory if necessary */\r
+ num_images=1;\r
+\r
+ /*Encoding image one by one*/\r
+ for(imageno=0;imageno<num_images;imageno++)\r
+ {\r
+ image = NULL;\r
+ fprintf(stderr,"\n");\r
+\r
+ image = loadImage(¶meters, env, obj, cls);\r
+ //printf("C: after load image: image = %d\n", image);\r
+ if (!image) {\r
+ fprintf(stderr, "Unable to load image\n");\r
+ return -1; \r
+ }\r
+\r
+ /* Decide if MCT should be used */\r
+ parameters.tcp_mct = image->numcomps == 3 ? 1 : 0;\r
+\r
+ if(parameters.cp_cinema){\r
+ cinema_setup_encoder(¶meters,image,&img_fol);\r
+ }\r
+\r
+ /* encode the destination image */\r
+ /* ---------------------------- */\r
+ /* get a J2K compressor handle */\r
+ if (parameters.cod_format == J2K_CFMT) { /* J2K format output */\r
+ cinfo = opj_create_compress(CODEC_J2K);\r
+ } else { /* JP2 format output */\r
+ cinfo = opj_create_compress(CODEC_JP2);\r
+ }\r
+ /* catch events using our callbacks and give a local context */\r
+ opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, &msgErrorCallback_vars);\r
+\r
+ /* setup the encoder parameters using the current image and user parameters */\r
+ opj_setup_encoder(cinfo, ¶meters, image);\r
+\r
+ /* open a byte stream for writing */\r
+ /* allocate memory for all tiles */\r
+ cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);\r
+\r
+ /* encode the image */\r
+ bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info);\r
+ printf("C: after opj_encode_with_info\n");\r
+ if (!bSuccess) {\r
+ opj_cio_close(cio);\r
+ fprintf(stderr, "failed to encode image\n");\r
+ return -1;\r
+ }\r
+ codestream_length = cio_tell(cio);\r
+\r
+ /* write the index on disk, if needed (-x 'filename') */\r
+ if (*indexfilename) {\r
+ bSuccess = write_index_file(&cstr_info, indexfilename);\r
+ if (bSuccess) {\r
+ fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename);\r
+ }\r
+ }\r
+\r
+ compressed_index = create_index_into_byte_array(&cstr_info, &compressed_index_size);\r
+ /* Allocates the Java compressedIndex byte[] and sends this index into the Java object */\r
+ fid = (*env)->GetFieldID(env, cls,"compressedIndex", "[B");\r
+ jba = (*env)->NewByteArray(env, compressed_index_size+1);\r
+ jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);\r
+ memcpy(jbBody, compressed_index, compressed_index_size);\r
+ (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);\r
+ (*env)->SetObjectField(env, obj, fid, jba); \r
+ free(compressed_index);\r
+\r
+ /* write the generated codestream to disk ? */\r
+ if (parameters.outfile[0]!='\0') {\r
+ f = fopen(parameters.outfile, "wb");\r
+ if (!f) {\r
+ fprintf(stderr, "failed to open [%s] for writing\n", parameters.outfile);\r
+ return -1;\r
+ }\r
+ fwrite(cio->buffer, 1, codestream_length, f);\r
+ fclose(f);\r
+ fprintf(stdout,"Generated outfile [%s]\n",parameters.outfile);\r
+ }\r
+\r
+ /* Write the generated codestream to the Java pre-allocated compressedStream byte[] */\r
+ fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");\r
+ jba = (*env)->GetObjectField(env, obj, fid);\r
+ jbBody = (*env)->GetPrimitiveArrayCritical(env, jba, 0);\r
+ memcpy(jbBody, cio->buffer, codestream_length);\r
+ (*env)->ReleasePrimitiveArrayCritical(env, jba, jbBody, 0);\r
+\r
+ /* close and free the byte stream */\r
+ opj_cio_close(cio);\r
+\r
+ /* free remaining compression structures */\r
+ opj_destroy_compress(cinfo);\r
+ opj_destroy_cstr_info(&cstr_info);\r
+\r
+ /* free image data */\r
+ opj_image_destroy(image);\r
+ }\r
+\r
+ /* free user parameters structure */\r
+ if(parameters.cp_comment) free(parameters.cp_comment);\r
+ if(parameters.cp_matrice) free(parameters.cp_matrice);\r
+\r
+ return codestream_length;\r
+}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium\r
+ * Copyright (c) 2002-2007, Professor Benoit Macq\r
+ * Copyright (c) 2001-2003, David Janssens\r
+ * Copyright (c) 2002-2003, Yannick Verschueren\r
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe\r
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team\r
+ * Copyright (c) 2006-2007, Parvatha Elangovan\r
+ * Copyright (c) 2007, Patrick Piscaglia (Telemis)\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+ * POSSIBILITY OF SUCH DAMAGE.\r
+ */\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <jni.h>\r
+#include <math.h>\r
+\r
+#include "openjpeg.h"\r
+#include "compat/getopt.h"\r
+#include "convert.h"\r
+#include "dirent.h"\r
+#include "org_openJpeg_OpenJPEGJavaDecoder.h"\r
+\r
+#ifndef WIN32\r
+#define stricmp strcasecmp\r
+#define strnicmp strncasecmp\r
+#endif\r
+\r
+/* ----------------------------------------------------------------------- */\r
+\r
+#define J2K_CFMT 0\r
+#define JP2_CFMT 1\r
+#define JPT_CFMT 2\r
+\r
+#define PXM_DFMT 10\r
+#define PGX_DFMT 11\r
+#define BMP_DFMT 12\r
+#define YUV_DFMT 13\r
+#define TIF_DFMT 14\r
+#define RAW_DFMT 15\r
+#define TGA_DFMT 16\r
+\r
+/* ----------------------------------------------------------------------- */\r
+\r
+typedef struct callback_variables {\r
+ JNIEnv *env;\r
+ /** 'jclass' object used to call a Java method from the C */\r
+ jobject *jobj;\r
+ /** 'jclass' object used to call a Java method from the C */\r
+ jmethodID message_mid;\r
+ jmethodID error_mid;\r
+} callback_variables_t;\r
+\r
+typedef struct dircnt{\r
+ /** Buffer for holding images read from Directory*/\r
+ char *filename_buf;\r
+ /** Pointer to the buffer*/\r
+ char **filename;\r
+}dircnt_t;\r
+\r
+\r
+typedef struct img_folder{\r
+ /** The directory path of the folder containing input images*/\r
+ char *imgdirpath;\r
+ /** Output format*/\r
+ char *out_format;\r
+ /** Enable option*/\r
+ char set_imgdir;\r
+ /** Enable Cod Format for output*/\r
+ char set_out_format;\r
+\r
+}img_fol_t;\r
+\r
+\r
+void decode_help_display() {\r
+ fprintf(stdout,"HELP\n----\n\n");\r
+ fprintf(stdout,"- the -h option displays this help information on screen\n\n");\r
+\r
+/* UniPG>> */\r
+ fprintf(stdout,"List of parameters for the JPEG 2000 "\r
+#ifdef USE_JPWL\r
+ "+ JPWL "\r
+#endif /* USE_JPWL */\r
+ "decoder:\n");\r
+/* <<UniPG */\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout,"\n");\r
+ fprintf(stdout," -ImgDir \n");\r
+ fprintf(stdout," Image file Directory path \n");\r
+ fprintf(stdout," -OutFor \n");\r
+ fprintf(stdout," REQUIRED only if -ImgDir is used\n");\r
+ fprintf(stdout," Need to specify only format without filename <BMP> \n");\r
+ fprintf(stdout," Currently accepts PGM, PPM, PNM, PGX, BMP format\n");\r
+ fprintf(stdout," -i <compressed file>\n");\r
+ fprintf(stdout," REQUIRED only if an Input image directory not specified\n");\r
+ fprintf(stdout," Currently accepts J2K-files, JP2-files and JPT-files. The file type\n");\r
+ fprintf(stdout," is identified based on its suffix.\n");\r
+ fprintf(stdout," -o <decompressed file>\n");\r
+ fprintf(stdout," REQUIRED\n");\r
+ fprintf(stdout," Currently accepts PGM-files, PPM-files, PNM-files, PGX-files and\n");\r
+ fprintf(stdout," BMP-files. Binary data is written to the file (not ascii). If a PGX\n");\r
+ fprintf(stdout," filename is given, there will be as many output files as there are\n");\r
+ fprintf(stdout," components: an indice starting from 0 will then be appended to the\n");\r
+ fprintf(stdout," output filename, just before the \"pgx\" extension. If a PGM filename\n");\r
+ fprintf(stdout," is given and there are more than one component, only the first component\n");\r
+ fprintf(stdout," will be written to the file.\n");\r
+ fprintf(stdout," -r <reduce factor>\n");\r
+ fprintf(stdout," Set the number of highest resolution levels to be discarded. The\n");\r
+ fprintf(stdout," image resolution is effectively divided by 2 to the power of the\n");\r
+ fprintf(stdout," number of discarded levels. The reduce factor is limited by the\n");\r
+ fprintf(stdout," smallest total number of decomposition levels among tiles.\n");\r
+ fprintf(stdout," -l <number of quality layers to decode>\n");\r
+ fprintf(stdout," Set the maximum number of quality layers to decode. If there are\n");\r
+ fprintf(stdout," less quality layers than the specified number, all the quality layers\n");\r
+ fprintf(stdout," are decoded.\n");\r
+/* UniPG>> */\r
+#ifdef USE_JPWL\r
+ fprintf(stdout," -W <options>\n");\r
+ fprintf(stdout," Activates the JPWL correction capability, if the codestream complies.\n");\r
+ fprintf(stdout," Options can be a comma separated list of <param=val> tokens:\n");\r
+ fprintf(stdout," c, c=numcomps\n");\r
+ fprintf(stdout," numcomps is the number of expected components in the codestream\n");\r
+ fprintf(stdout," (search of first EPB rely upon this, default is %d)\n", JPWL_EXPECTED_COMPONENTS);\r
+#endif /* USE_JPWL */\r
+/* <<UniPG */\r
+ fprintf(stdout,"\n");\r
+}\r
+\r
+/* -------------------------------------------------------------------------- */\r
+\r
+int get_num_images(char *imgdirpath){\r
+ DIR *dir;\r
+ struct dirent* content; \r
+ int num_images = 0;\r
+\r
+ /*Reading the input images from given input directory*/\r
+\r
+ dir= opendir(imgdirpath);\r
+ if(!dir){\r
+ fprintf(stderr,"Could not open Folder %s\n",imgdirpath);\r
+ return 0;\r
+ }\r
+ \r
+ while((content=readdir(dir))!=NULL){\r
+ if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 )\r
+ continue;\r
+ num_images++;\r
+ }\r
+ return num_images;\r
+}\r
+\r
+int load_images(dircnt_t *dirptr, char *imgdirpath){\r
+ DIR *dir;\r
+ struct dirent* content; \r
+ int i = 0;\r
+\r
+ /*Reading the input images from given input directory*/\r
+\r
+ dir= opendir(imgdirpath);\r
+ if(!dir){\r
+ fprintf(stderr,"Could not open Folder %s\n",imgdirpath);\r
+ return 1;\r
+ }else {\r
+ fprintf(stderr,"Folder opened successfully\n");\r
+ }\r
+ \r
+ while((content=readdir(dir))!=NULL){\r
+ if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 )\r
+ continue;\r
+\r
+ strcpy(dirptr->filename[i],content->d_name);\r
+ i++;\r
+ }\r
+ return 0; \r
+}\r
+\r
+int get_file_format(char *filename) {\r
+ unsigned int i;\r
+ static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "tga", "j2k", "jp2", "jpt", "j2c" };\r
+ 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 };\r
+ char * ext = strrchr(filename, '.');\r
+ if (ext == NULL)\r
+ return -1;\r
+ ext++;\r
+ if(ext) {\r
+ for(i = 0; i < sizeof(format)/sizeof(*format); i++) {\r
+ if(strnicmp(ext, extension[i], 3) == 0) {\r
+ return format[i];\r
+ }\r
+ }\r
+ }\r
+\r
+ return -1;\r
+}\r
+\r
+\r
+/* -------------------------------------------------------------------------- */\r
+\r
+int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol) {\r
+ /* parse the command line */\r
+ int totlen;\r
+ option_t long_option[]={\r
+ {"ImgDir",REQ_ARG, NULL ,'y'},\r
+ {"OutFor",REQ_ARG, NULL ,'O'},\r
+ };\r
+\r
+/* UniPG>> */\r
+ const char optlist[] = "i:o:r:l:hx:"\r
+\r
+#ifdef USE_JPWL\r
+ "W:"\r
+#endif /* USE_JPWL */\r
+ ;\r
+ /*for (i=0; i<argc; i++) {\r
+ printf("[%s]",argv[i]);\r
+ }\r
+ printf("\n");*/\r
+\r
+/* <<UniPG */\r
+ totlen=sizeof(long_option);\r
+ img_fol->set_out_format = 0;\r
+ reset_options_reading();\r
+\r
+ while (1) {\r
+ int c = getopt_long(argc, argv,optlist,long_option,totlen);\r
+ if (c == -1)\r
+ break;\r
+ switch (c) {\r
+ case 'i': /* input file */\r
+ {\r
+ char *infile = optarg;\r
+ parameters->decod_format = get_file_format(infile);\r
+ switch(parameters->decod_format) {\r
+ case J2K_CFMT:\r
+ case JP2_CFMT:\r
+ case JPT_CFMT:\r
+ break;\r
+ default:\r
+ fprintf(stderr, \r
+ "!! Unrecognized format for infile : %s [accept only *.j2k, *.jp2, *.jpc or *.jpt] !!\n\n", \r
+ infile);\r
+ return 1;\r
+ }\r
+ strncpy(parameters->infile, infile, sizeof(parameters->infile)-1);\r
+ }\r
+ break;\r
+ \r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'o': /* output file */\r
+ {\r
+ char *outfile = optarg;\r
+ parameters->cod_format = get_file_format(outfile);\r
+ switch(parameters->cod_format) {\r
+ case PGX_DFMT:\r
+ case PXM_DFMT:\r
+ case BMP_DFMT:\r
+ case TIF_DFMT:\r
+ case RAW_DFMT:\r
+ case TGA_DFMT:\r
+ break;\r
+ default:\r
+ fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outfile);\r
+ return 1;\r
+ }\r
+ strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1);\r
+ }\r
+ break;\r
+ \r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'O': /* output format */\r
+ {\r
+ char outformat[50];\r
+ char *of = optarg;\r
+ sprintf(outformat,".%s",of);\r
+ img_fol->set_out_format = 1;\r
+ parameters->cod_format = get_file_format(outformat);\r
+ switch(parameters->cod_format) {\r
+ case PGX_DFMT:\r
+ img_fol->out_format = "pgx";\r
+ break;\r
+ case PXM_DFMT:\r
+ img_fol->out_format = "ppm";\r
+ break;\r
+ case BMP_DFMT:\r
+ img_fol->out_format = "bmp";\r
+ break;\r
+ case TIF_DFMT:\r
+ img_fol->out_format = "tif";\r
+ break;\r
+ case RAW_DFMT:\r
+ img_fol->out_format = "raw";\r
+ break;\r
+ case TGA_DFMT:\r
+ img_fol->out_format = "raw";\r
+ break;\r
+ default:\r
+ fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outformat);\r
+ return 1;\r
+ break;\r
+ }\r
+ }\r
+ break;\r
+\r
+ /* ----------------------------------------------------- */\r
+\r
+\r
+ case 'r': /* reduce option */\r
+ {\r
+ sscanf(optarg, "%d", ¶meters->cp_reduce);\r
+ }\r
+ break;\r
+ \r
+ /* ----------------------------------------------------- */\r
+ \r
+\r
+ case 'l': /* layering option */\r
+ {\r
+ sscanf(optarg, "%d", ¶meters->cp_layer);\r
+ }\r
+ break;\r
+ \r
+ /* ----------------------------------------------------- */\r
+\r
+ case 'h': /* display an help description */\r
+ decode_help_display();\r
+ return 1; \r
+\r
+ /* ------------------------------------------------------ */\r
+\r
+ case 'y': /* Image Directory path */\r
+ {\r
+ img_fol->imgdirpath = (char*)malloc(strlen(optarg) + 1);\r
+ strcpy(img_fol->imgdirpath,optarg);\r
+ img_fol->set_imgdir=1;\r
+ }\r
+ break;\r
+ /* ----------------------------------------------------- */\r
+/* UniPG>> */\r
+#ifdef USE_JPWL\r
+ \r
+ case 'W': /* activate JPWL correction */\r
+ {\r
+ char *token = NULL;\r
+\r
+ token = strtok(optarg, ",");\r
+ while(token != NULL) {\r
+\r
+ /* search expected number of components */\r
+ if (*token == 'c') {\r
+\r
+ static int compno;\r
+\r
+ compno = JPWL_EXPECTED_COMPONENTS; /* predefined no. of components */\r
+\r
+ if(sscanf(token, "c=%d", &compno) == 1) {\r
+ /* Specified */\r
+ if ((compno < 1) || (compno > 256)) {\r
+ fprintf(stderr, "ERROR -> invalid number of components c = %d\n", compno);\r
+ return 1;\r
+ }\r
+ parameters->jpwl_exp_comps = compno;\r
+\r
+ } else if (!strcmp(token, "c")) {\r
+ /* default */\r
+ parameters->jpwl_exp_comps = compno; /* auto for default size */\r
+\r
+ } else {\r
+ fprintf(stderr, "ERROR -> invalid components specified = %s\n", token);\r
+ return 1;\r
+ };\r
+ }\r
+\r
+ /* search maximum number of tiles */\r
+ if (*token == 't') {\r
+\r
+ static int tileno;\r
+\r
+ tileno = JPWL_MAXIMUM_TILES; /* maximum no. of tiles */\r
+\r
+ if(sscanf(token, "t=%d", &tileno) == 1) {\r
+ /* Specified */\r
+ if ((tileno < 1) || (tileno > JPWL_MAXIMUM_TILES)) {\r
+ fprintf(stderr, "ERROR -> invalid number of tiles t = %d\n", tileno);\r
+ return 1;\r
+ }\r
+ parameters->jpwl_max_tiles = tileno;\r
+\r
+ } else if (!strcmp(token, "t")) {\r
+ /* default */\r
+ parameters->jpwl_max_tiles = tileno; /* auto for default size */\r
+\r
+ } else {\r
+ fprintf(stderr, "ERROR -> invalid tiles specified = %s\n", token);\r
+ return 1;\r
+ };\r
+ }\r
+\r
+ /* next token or bust */\r
+ token = strtok(NULL, ",");\r
+ };\r
+ parameters->jpwl_correct = true;\r
+ fprintf(stdout, "JPWL correction capability activated\n");\r
+ fprintf(stdout, "- expecting %d components\n", parameters->jpwl_exp_comps);\r
+ }\r
+ break; \r
+#endif /* USE_JPWL */\r
+/* <<UniPG */ \r
+\r
+ /* ----------------------------------------------------- */\r
+ \r
+ default:\r
+ fprintf(stderr,"WARNING -> this option is not valid \"-%c %s\"\n",c, optarg);\r
+ break;\r
+ }\r
+ }\r
+\r
+ /* No check for possible errors before the -i and -o options are of course not mandatory*/\r
+\r
+ return 0;\r
+}\r
+\r
+/* -------------------------------------------------------------------------- */\r
+\r
+/**\r
+error callback returning the message to Java andexpecting a callback_variables_t client object\r
+*/\r
+void error_callback(const char *msg, void *client_data) {\r
+ callback_variables_t* vars = (callback_variables_t*) client_data;\r
+ JNIEnv *env = vars->env;\r
+ jstring jbuffer;\r
+\r
+ jbuffer = (*env)->NewStringUTF(env, msg);\r
+ (*env)->ExceptionClear(env);\r
+ (*env)->CallVoidMethod(env, *(vars->jobj), vars->error_mid, jbuffer);\r
+\r
+ if ((*env)->ExceptionOccurred(env)) {\r
+ fprintf(stderr,"C: Exception during call back method\n");\r
+ (*env)->ExceptionDescribe(env);\r
+ (*env)->ExceptionClear(env);\r
+ }\r
+ (*env)->DeleteLocalRef(env, jbuffer);\r
+}\r
+/**\r
+warning callback returning the message to Java andexpecting a callback_variables_t client object\r
+*/\r
+void warning_callback(const char *msg, void *client_data) {\r
+ callback_variables_t* vars = (callback_variables_t*) client_data;\r
+ JNIEnv *env = vars->env;\r
+ jstring jbuffer;\r
+\r
+ jbuffer = (*env)->NewStringUTF(env, msg);\r
+ (*env)->ExceptionClear(env);\r
+ (*env)->CallVoidMethod(env, *(vars->jobj), vars->message_mid, jbuffer);\r
+ \r
+ if ((*env)->ExceptionOccurred(env)) {\r
+ fprintf(stderr,"C: Exception during call back method\n");\r
+ (*env)->ExceptionDescribe(env);\r
+ (*env)->ExceptionClear(env);\r
+ }\r
+ (*env)->DeleteLocalRef(env, jbuffer);\r
+}\r
+/**\r
+information callback returning the message to Java andexpecting a callback_variables_t client object\r
+*/\r
+void info_callback(const char *msg, void *client_data) {\r
+ callback_variables_t* vars = (callback_variables_t*) client_data;\r
+ JNIEnv *env = vars->env;\r
+ jstring jbuffer;\r
+\r
+ jbuffer = (*env)->NewStringUTF(env, msg);\r
+ (*env)->ExceptionClear(env);\r
+ (*env)->CallVoidMethod(env, *(vars->jobj), vars->message_mid, jbuffer);\r
+\r
+ if ((*env)->ExceptionOccurred(env)) {\r
+ fprintf(stderr,"C: Exception during call back method\n");\r
+ (*env)->ExceptionDescribe(env);\r
+ (*env)->ExceptionClear(env);\r
+ }\r
+ (*env)->DeleteLocalRef(env, jbuffer);\r
+}\r
+\r
+\r
+/* --------------------------------------------------------------------------\r
+ -------------------- MAIN METHOD, CALLED BY JAVA -----------------------*/\r
+JNIEXPORT jint JNICALL Java_org_openJpeg_OpenJPEGJavaDecoder_internalDecodeJ2KtoImage(JNIEnv *env, jobject obj, jobjectArray javaParameters) {\r
+ int argc; /* To simulate the command line parameters (taken from the javaParameters variable) and be able to re-use the */\r
+ char **argv; /* 'parse_cmdline_decoder' method taken from the j2k_to_image project */\r
+ opj_dparameters_t parameters; /* decompression parameters */\r
+ img_fol_t img_fol;\r
+ opj_event_mgr_t event_mgr; /* event manager */\r
+ opj_image_t *image = NULL;\r
+ FILE *fsrc = NULL;\r
+ unsigned char *src = NULL;\r
+ int file_length;\r
+ int num_images;\r
+ int i,j,imageno;\r
+ opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */\r
+ opj_cio_t *cio = NULL;\r
+ int w,h;\r
+ long min_value, max_value;\r
+ short tempS; unsigned char tempUC, tempUC1, tempUC2;\r
+ // ==> Access variables to the Java member variables\r
+ jsize arraySize;\r
+ jclass cls;\r
+ jobject object;\r
+ jboolean isCopy;\r
+ jfieldID fid;\r
+ jbyteArray jba;\r
+ jshortArray jsa;\r
+ jintArray jia;\r
+ jbyte *jbBody, *ptrBBody;\r
+ jshort *jsBody, *ptrSBody;\r
+ jint *jiBody, *ptrIBody;\r
+ callback_variables_t msgErrorCallback_vars;\r
+ // <=== access variable to Java member variables */\r
+ int *ptr, *ptr1, *ptr2; // <== To transfer the decoded image to Java\r
+\r
+ /* configure the event callbacks */\r
+ memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); \r
+ event_mgr.error_handler = error_callback;\r
+ event_mgr.warning_handler = warning_callback;\r
+ event_mgr.info_handler = info_callback;\r
+\r
+ // JNI reference to the calling class\r
+ cls = (*env)->GetObjectClass(env, obj);\r
+\r
+ // Pointers to be able to call a Java method for all the info and error messages\r
+ msgErrorCallback_vars.env = env;\r
+ msgErrorCallback_vars.jobj = &obj;\r
+ msgErrorCallback_vars.message_mid = (*env)->GetMethodID(env, cls, "logMessage", "(Ljava/lang/String;)V");\r
+ msgErrorCallback_vars.error_mid = (*env)->GetMethodID(env, cls, "logError", "(Ljava/lang/String;)V");\r
+\r
+ // Get the String[] containing the parameters, and converts it into a char** to simulate command line arguments.\r
+ arraySize = (*env)->GetArrayLength(env, javaParameters);\r
+ argc = (int) arraySize +1;\r
+ argv = malloc(argc*sizeof(char*));\r
+ argv[0] = "ProgramName.exe"; // The program name: useless\r
+ j=0;\r
+ for (i=1; i<argc; i++) {\r
+ object = (*env)->GetObjectArrayElement(env, javaParameters, i-1);\r
+ argv[i] = (*env)->GetStringUTFChars(env, object, &isCopy);\r
+ }\r
+\r
+ /*printf("C: decoder params = ");\r
+ for (i=0; i<argc; i++) {\r
+ printf("[%s]",argv[i]);\r
+ }\r
+ printf("\n");*/\r
+\r
+ /* set decoding parameters to default values */\r
+ opj_set_default_decoder_parameters(¶meters);\r
+ parameters.decod_format = J2K_CFMT;\r
+\r
+ /* parse input and get user encoding parameters */\r
+ if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol) == 1) {\r
+ // Release the Java arguments array\r
+ for (i=1; i<argc; i++)\r
+ (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);\r
+ return -1;\r
+ }\r
+ // Release the Java arguments array\r
+ for (i=1; i<argc; i++)\r
+ (*env)->ReleaseStringUTFChars(env, (*env)->GetObjectArrayElement(env, javaParameters, i-1), argv[i]);\r
+\r
+ num_images=1;\r
+\r
+ // Get additional information from the Java object variables\r
+ fid = (*env)->GetFieldID(env, cls,"skippedResolutions", "I");\r
+ parameters.cp_reduce = (short) (*env)->GetIntField(env, obj, fid);\r
+\r
+ /*Decoding image one by one*/\r
+ for(imageno = 0; imageno < num_images ; imageno++)\r
+ {\r
+ image = NULL;\r
+ fprintf(stderr,"\n");\r
+\r
+ /* read the input file and put it in memory into the 'src' object, if the -i option is given in JavaParameters.\r
+ Implemented for debug purpose. */\r
+ /* -------------------------------------------------------------- */\r
+ if (parameters.infile && parameters.infile[0]!='\0') {\r
+ //printf("C: opening [%s]\n", parameters.infile);\r
+ fsrc = fopen(parameters.infile, "rb");\r
+ if (!fsrc) {\r
+ fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);\r
+ return 1;\r
+ }\r
+ fseek(fsrc, 0, SEEK_END);\r
+ file_length = ftell(fsrc);\r
+ fseek(fsrc, 0, SEEK_SET);\r
+ src = (unsigned char *) malloc(file_length);\r
+ fread(src, 1, file_length, fsrc);\r
+ fclose(fsrc);\r
+ //printf("C: %d bytes read from file\n",file_length);\r
+ } else {\r
+ // Preparing the transfer of the codestream from Java to C\r
+ //printf("C: before transfering codestream\n");\r
+ fid = (*env)->GetFieldID(env, cls,"compressedStream", "[B");\r
+ jba = (*env)->GetObjectField(env, obj, fid);\r
+ file_length = (*env)->GetArrayLength(env, jba);\r
+ jbBody = (*env)->GetByteArrayElements(env, jba, &isCopy);\r
+ src = (unsigned char*)jbBody;\r
+ }\r
+\r
+ /* decode the code-stream */\r
+ /* ---------------------- */\r
+\r
+ switch(parameters.decod_format) {\r
+ case J2K_CFMT:\r
+ {\r
+ /* JPEG-2000 codestream */\r
+\r
+ /* get a decoder handle */\r
+ dinfo = opj_create_decompress(CODEC_J2K);\r
+\r
+ /* catch events using our callbacks and give a local context */\r
+ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars);\r
+\r
+ /* setup the decoder decoding parameters using user parameters */\r
+ opj_setup_decoder(dinfo, ¶meters);\r
+\r
+ /* open a byte stream */\r
+ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);\r
+\r
+ /* decode the stream and fill the image structure */\r
+ image = opj_decode(dinfo, cio);\r
+ if(!image) {\r
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ return 1;\r
+ }\r
+\r
+ /* close the byte stream */\r
+ opj_cio_close(cio);\r
+ }\r
+ break;\r
+\r
+ case JP2_CFMT:\r
+ {\r
+ /* JPEG 2000 compressed image data */\r
+\r
+ /* get a decoder handle */\r
+ dinfo = opj_create_decompress(CODEC_JP2);\r
+\r
+ /* catch events using our callbacks and give a local context */\r
+ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars);\r
+\r
+ /* setup the decoder decoding parameters using the current image and user parameters */\r
+ opj_setup_decoder(dinfo, ¶meters);\r
+\r
+ /* open a byte stream */\r
+ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);\r
+\r
+ /* decode the stream and fill the image structure */\r
+ image = opj_decode(dinfo, cio);\r
+ if(!image) {\r
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ return 1;\r
+ }\r
+\r
+ /* close the byte stream */\r
+ opj_cio_close(cio);\r
+\r
+ }\r
+ break;\r
+\r
+ case JPT_CFMT:\r
+ {\r
+ /* JPEG 2000, JPIP */\r
+\r
+ /* get a decoder handle */\r
+ dinfo = opj_create_decompress(CODEC_JPT);\r
+\r
+ /* catch events using our callbacks and give a local context */\r
+ opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, &msgErrorCallback_vars);\r
+\r
+ /* setup the decoder decoding parameters using user parameters */\r
+ opj_setup_decoder(dinfo, ¶meters);\r
+\r
+ /* open a byte stream */\r
+ cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);\r
+\r
+ /* decode the stream and fill the image structure */\r
+ image = opj_decode(dinfo, cio);\r
+ if(!image) {\r
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");\r
+ opj_destroy_decompress(dinfo);\r
+ opj_cio_close(cio);\r
+ return 1;\r
+ }\r
+\r
+ /* close the byte stream */\r
+ opj_cio_close(cio);\r
+ }\r
+ break;\r
+\r
+ default:\r
+ fprintf(stderr, "skipping file..\n");\r
+ continue;\r
+ }\r
+\r
+ /* free the memory containing the code-stream */\r
+ if (parameters.infile && parameters.infile[0]!='\0') {\r
+ free(src);\r
+ } else {\r
+ (*env)->ReleaseByteArrayElements(env, jba, jbBody, 0);\r
+ }\r
+ src = NULL;\r
+\r
+ /* create output image.\r
+ If the -o parameter is given in the JavaParameters, write the decoded version into a file.\r
+ Implemented for debug purpose. */\r
+ /* ---------------------------------- */\r
+ switch (parameters.cod_format) {\r
+ case PXM_DFMT: /* PNM PGM PPM */\r
+ if (imagetopnm(image, parameters.outfile)) {\r
+ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);\r
+ }\r
+ else {\r
+ fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);\r
+ }\r
+ break;\r
+\r
+ case PGX_DFMT: /* PGX */\r
+ if(imagetopgx(image, parameters.outfile)){\r
+ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);\r
+ }\r
+ else {\r
+ fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);\r
+ }\r
+ break;\r
+\r
+ case BMP_DFMT: /* BMP */\r
+ if(imagetobmp(image, parameters.outfile)){\r
+ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile);\r
+ }\r
+ else {\r
+ fprintf(stdout,"Generated Outfile %s\n",parameters.outfile);\r
+ }\r
+ break;\r
+\r
+ }\r
+\r
+ // ========= Return the image to the Java structure ===============\r
+#ifdef CHECK_THRESHOLDS\r
+ printf("C: checking thresholds\n");\r
+#endif\r
+ // First compute the real with and height, in function of the resolutions decoded.\r
+ //wr = (image->comps[0].w + (1 << image->comps[0].factor) -1) >> image->comps[0].factor;\r
+ //hr = (image->comps[0].h + (1 << image->comps[0].factor) -1) >> image->comps[0].factor;\r
+ w = image->comps[0].w;\r
+ h = image->comps[0].h;\r
+\r
+ if (image->numcomps==3) { // 3 components color image\r
+ ptr = image->comps[0].data;\r
+ ptr1 = image->comps[1].data;\r
+ ptr2 = image->comps[2].data;\r
+#ifdef CHECK_THRESHOLDS \r
+ if (image->comps[0].sgnd) {\r
+ min_value = 0;\r
+ max_value = 255;\r
+ } else {\r
+ min_value = -128;\r
+ max_value = 127;\r
+ }\r
+#endif\r
+ // Get the pointer to the Java structure where the data must be copied\r
+ fid = (*env)->GetFieldID(env, cls,"image24", "[I");\r
+ jia = (*env)->GetObjectField(env, obj, fid);\r
+ jiBody = (*env)->GetIntArrayElements(env, jia, 0);\r
+ ptrIBody = jiBody;\r
+ printf("C: transfering image24: %d int to Java pointer=%d\n",image->numcomps*w*h, ptrIBody);\r
+\r
+ for (i=0; i<w*h; i++) {\r
+ tempUC = (unsigned char)(ptr[i]);\r
+ tempUC1 = (unsigned char)(ptr1[i]);\r
+ tempUC2 = (unsigned char)(ptr2[i]);\r
+#ifdef CHECK_THRESHOLDS\r
+ if (tempUC < min_value)\r
+ tempUC=min_value;\r
+ else if (tempUC > max_value)\r
+ tempUC=max_value;\r
+ if (tempUC1 < min_value)\r
+ tempUC1=min_value;\r
+ else if (tempUC1 > max_value)\r
+ tempUC1=max_value;\r
+ if (tempUC2 < min_value)\r
+ tempUC2=min_value;\r
+ else if (tempUC2 > max_value)\r
+ tempUC2=max_value;\r
+#endif\r
+ *(ptrIBody++) = (int) ( (tempUC2<<16) + (tempUC1<<8) + tempUC );\r
+ }\r
+ (*env)->ReleaseIntArrayElements(env, jia, jiBody, 0);\r
+\r
+ } else { // 1 component 8 or 16 bpp image\r
+ ptr = image->comps[0].data;\r
+ printf("C: before transfering a %d bpp image to java (length = %d)\n",image->comps[0].prec ,w*h);\r
+ if (image->comps[0].prec<=8) {\r
+ fid = (*env)->GetFieldID(env, cls,"image8", "[B");\r
+ jba = (*env)->GetObjectField(env, obj, fid);\r
+ jbBody = (*env)->GetByteArrayElements(env, jba, 0);\r
+ ptrBBody = jbBody;\r
+#ifdef CHECK_THRESHOLDS \r
+ if (image->comps[0].sgnd) {\r
+ min_value = 0;\r
+ max_value = 255;\r
+ } else {\r
+ min_value = -128;\r
+ max_value = 127;\r
+ }\r
+#endif \r
+ //printf("C: transfering %d shorts to Java image8 pointer = %d\n", wr*hr,ptrSBody);\r
+ for (i=0; i<w*h; i++) {\r
+ tempUC = (unsigned char) (ptr[i]);\r
+#ifdef CHECK_THRESHOLDS\r
+ if (tempUC<min_value)\r
+ tempUC = min_value;\r
+ else if (tempUC > max_value)\r
+ tempUC = max_value;\r
+#endif\r
+ *(ptrBBody++) = tempUC;\r
+ }\r
+ (*env)->ReleaseByteArrayElements(env, jba, jbBody, 0);\r
+ printf("C: image8 transfered to Java\n");\r
+ } else {\r
+ fid = (*env)->GetFieldID(env, cls,"image16", "[S");\r
+ jsa = (*env)->GetObjectField(env, obj, fid);\r
+ jsBody = (*env)->GetShortArrayElements(env, jsa, 0);\r
+ ptrSBody = jsBody;\r
+#ifdef CHECK_THRESHOLDS \r
+ if (image->comps[0].sgnd) {\r
+ min_value = 0;\r
+ max_value = 65535;\r
+ } else {\r
+ min_value = -32768;\r
+ max_value = 32767;\r
+ }\r
+ printf("C: minValue = %d, maxValue = %d\n", min_value, max_value);\r
+#endif \r
+ printf("C: transfering %d shorts to Java image16 pointer = %d\n", w*h,ptrSBody);\r
+ for (i=0; i<w*h; i++) {\r
+ tempS = (short) (ptr[i]);\r
+#ifdef CHECK_THRESHOLDS\r
+ if (tempS<min_value) {\r
+ printf("C: value %d truncated to %d\n", tempS, min_value);\r
+ tempS = min_value;\r
+ } else if (tempS > max_value) {\r
+ printf("C: value %d truncated to %d\n", tempS, max_value);\r
+ tempS = max_value;\r
+ }\r
+#endif\r
+ *(ptrSBody++) = tempS;\r
+ }\r
+ (*env)->ReleaseShortArrayElements(env, jsa, jsBody, 0);\r
+ printf("C: image16 completely filled\n");\r
+ }\r
+ } \r
+\r
+\r
+ /* free remaining structures */\r
+ if(dinfo) {\r
+ opj_destroy_decompress(dinfo);\r
+ }\r
+ /* free image data structure */\r
+ opj_image_destroy(image);\r
+\r
+ }\r
+ return 1; /* OK */\r
+}\r
+//end main\r
+\r