X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fbin%2Fjp2%2Fopj_decompress.c;h=83160c3d18e19d0383cc32c22236491e0c635777;hb=4d5c5e7c4891491d61c7deaf77d9238b3621c32a;hp=e1ce8a1accb83cfa31b13e08bcc7bccaf63a3632;hpb=131cc98491eff5136dac4415928174387ef3e613;p=openjpeg.git diff --git a/src/bin/jp2/opj_decompress.c b/src/bin/jp2/opj_decompress.c index e1ce8a1a..83160c3d 100644 --- a/src/bin/jp2/opj_decompress.c +++ b/src/bin/jp2/opj_decompress.c @@ -43,6 +43,7 @@ #include #include #include +#include #ifdef _WIN32 #include "windirent.h" @@ -56,6 +57,9 @@ #define strncasecmp _strnicmp #else #include +#include +#include +#include #endif /* _WIN32 */ #include "openjpeg.h" @@ -72,6 +76,7 @@ #include "color.h" #include "format_defs.h" +#include "opj_string.h" typedef struct dircnt{ /** Buffer for holding images read from Directory*/ @@ -118,6 +123,8 @@ typedef struct opj_decompress_params int decod_format; /** output file format 0: PGX, 1: PxM, 2: BMP */ int cod_format; + /** index file name */ + char indexfilename[OPJ_PATH_LEN]; /** Decoding area left boundary */ OPJ_UINT32 DA_x0; @@ -142,6 +149,10 @@ typedef struct opj_decompress_params int force_rgb; /* upsample components according to their dx/dy values */ int upsample; + /* split output components to different files */ + int split_pnm; + /** number of threads */ + int num_threads; }opj_decompress_parameters; /* -------------------------------------------------------------------------- */ @@ -152,7 +163,7 @@ int get_file_format(const char *filename); char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_decompress_parameters *parameters); static int infile_format(const char *fname); -int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol, char *indexfilename); +int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol); int parse_DA_values( char* inArg, unsigned int *DA_x0, unsigned int *DA_y0, unsigned int *DA_x1, unsigned int *DA_y1); static opj_image_t* convert_gray_to_rgb(opj_image_t* original); @@ -170,12 +181,12 @@ static void decode_help_display(void) { " Image file Directory path \n" " -OutFor \n" " REQUIRED only if -ImgDir is used\n" - " Output format for decompressed images.\n" - " -i \n" + " Output format for decompressed images.\n"); + fprintf(stdout," -i \n" " REQUIRED only if an Input image directory is not specified\n" " Currently accepts J2K-files, JP2-files and JPT-files. The file type\n" - " is identified based on its suffix.\n" - " -o \n" + " is identified based on its suffix.\n"); + fprintf(stdout," -o \n" " REQUIRED\n" " Currently accepts formats specified above (see OutFor option)\n" " Binary data is written to the file (not ascii). If a PGX\n" @@ -183,8 +194,8 @@ static void decode_help_display(void) { " components: an indice starting from 0 will then be appended to the\n" " output filename, just before the \"pgx\" extension. If a PGM filename\n" " is given and there are more than one component, only the first component\n" - " will be written to the file.\n" - " -r \n" + " will be written to the file.\n"); + fprintf(stdout," -r \n" " Set the number of highest resolution levels to be discarded. The\n" " image resolution is effectively divided by 2 to the power of the\n" " number of discarded levels. The reduce factor is limited by the\n" @@ -192,8 +203,8 @@ static void decode_help_display(void) { " -l \n" " Set the maximum number of quality layers to decode. If there are\n" " less quality layers than the specified number, all the quality layers\n" - " are decoded.\n" - " -x \n" + " are decoded.\n"); + fprintf(stdout," -x \n" " Create an index file *.Idx (-x index_name.Idx) \n" " -d \n" " OPTIONAL\n" @@ -202,20 +213,25 @@ static void decode_help_display(void) { " -t \n" " OPTIONAL\n" " Set the tile number of the decoded tile. Follow the JPEG2000 convention from left-up to bottom-up\n" - " By default all tiles are decoded.\n" - " -p [C|S][,[C|S][,...]]\n" + " By default all tiles are decoded.\n"); + fprintf(stdout," -p [C|S][,[C|S][,...]]\n" " OPTIONAL\n" - " Force the precision (bit depth) of components.\n" - " There shall be at least 1 value. Theres no limit on the number of values (comma separated, last values ignored if too much values).\n" + " Force the precision (bit depth) of components.\n"); + fprintf(stdout," There shall be at least 1 value. Theres no limit on the number of values (comma separated, last values ignored if too much values).\n" " If there are less values than components, the last value is used for remaining components.\n" " If 'C' is specified (default), values are clipped.\n" " If 'S' is specified, values are scaled.\n" - " A 0 value can be specified (meaning original bit depth).\n" - " -force-rgb\n" + " A 0 value can be specified (meaning original bit depth).\n"); + fprintf(stdout," -force-rgb\n" " Force output image colorspace to RGB\n" " -upsample\n" " Downsampled components will be upsampled to image size\n" - "\n"); + " -split-pnm\n" + " Split output components to different files when writing to PNM\n"); + if( opj_has_thread_support() ) { + fprintf(stdout," -threads \n" + " Number of threads to use for decoding.\n"); + } /* UniPG>> */ #ifdef USE_JPWL fprintf(stdout," -W \n" @@ -245,7 +261,7 @@ static OPJ_BOOL parse_precision(const char* option, opj_decompress_parameters* p for(;;) { - OPJ_UINT32 prec; + int prec; char mode; char comma; int count; @@ -263,7 +279,7 @@ static OPJ_BOOL parse_precision(const char* option, opj_decompress_parameters* p count = 3; } if (count == 3) { - if (prec > 32U) { + if ((prec < 1) || (prec > 32)) { fprintf(stderr,"Invalid precision %d in precision option %s\n", prec, option); l_result = OPJ_FALSE; break; @@ -281,7 +297,7 @@ static OPJ_BOOL parse_precision(const char* option, opj_decompress_parameters* p if (parameters->precision == NULL) { /* first one */ - parameters->precision = malloc(sizeof(opj_precision)); + parameters->precision = (opj_precision *)malloc(sizeof(opj_precision)); if (parameters->precision == NULL) { fprintf(stderr,"Could not allocate memory for precision option\n"); l_result = OPJ_FALSE; @@ -297,7 +313,7 @@ static OPJ_BOOL parse_precision(const char* option, opj_decompress_parameters* p break; } - l_new = realloc(parameters->precision, l_new_size * sizeof(opj_precision)); + l_new = (opj_precision *)realloc(parameters->precision, l_new_size * sizeof(opj_precision)); if (l_new == NULL) { fprintf(stderr,"Could not allocate memory for precision option\n"); l_result = OPJ_FALSE; @@ -306,7 +322,7 @@ static OPJ_BOOL parse_precision(const char* option, opj_decompress_parameters* p parameters->precision = l_new; } - parameters->precision[parameters->nb_precision].prec = prec; + parameters->precision[parameters->nb_precision].prec = (OPJ_UINT32)prec; switch (mode) { case 'C': parameters->precision[parameters->nb_precision].mode = OPJ_PREC_MODE_CLIP; @@ -354,6 +370,7 @@ int get_num_images(char *imgdirpath){ continue; num_images++; } + closedir(dir); return num_images; } @@ -380,6 +397,7 @@ int load_images(dircnt_t *dirptr, char *imgdirpath){ strcpy(dirptr->filename[i],content->d_name); i++; } + closedir(dir); return 0; } @@ -388,7 +406,7 @@ int get_file_format(const char *filename) { unsigned int i; static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" }; static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT }; - char * ext = strrchr(filename, '.'); + const char * ext = strrchr(filename, '.'); if (ext == NULL) return -1; ext++; @@ -403,6 +421,12 @@ int get_file_format(const char *filename) { return -1; } +#ifdef _WIN32 +const char* path_separator = "\\"; +#else +const char* path_separator = "/"; +#endif + /* -------------------------------------------------------------------------- */ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_decompress_parameters *parameters){ char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],outfilename[OPJ_PATH_LEN],temp_ofname[OPJ_PATH_LEN]; @@ -410,11 +434,13 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_decompre strcpy(image_filename,dirptr->filename[imageno]); fprintf(stderr,"File Number %d \"%s\"\n",imageno,image_filename); - parameters->decod_format = infile_format(image_filename); + sprintf(infilename, "%s%s%s", img_fol->imgdirpath, path_separator, image_filename); + parameters->decod_format = infile_format(infilename); if (parameters->decod_format == -1) return 1; - sprintf(infilename,"%s/%s",img_fol->imgdirpath,image_filename); - strncpy(parameters->infile, infilename, sizeof(infilename)); + if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infilename) != 0) { + return 1; + } /*Set output file*/ strcpy(temp_ofname,strtok(image_filename,".")); @@ -424,7 +450,9 @@ char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_decompre } if(img_fol->set_out_format==1){ sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format); - strncpy(parameters->outfile, outfilename, sizeof(outfilename)); + if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), outfilename) != 0) { + return 1; + } } return 0; } @@ -490,14 +518,16 @@ static int infile_format(const char *fname) * Parse the command line */ /* -------------------------------------------------------------------------- */ -int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol, char *indexfilename) { +int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol) { /* parse the command line */ int totlen, c; opj_option_t long_option[]={ - {"ImgDir", REQ_ARG, NULL ,'y'}, - {"OutFor", REQ_ARG, NULL ,'O'}, - {"force-rgb", NO_ARG, &(parameters->force_rgb), 1}, - {"upsample", NO_ARG, &(parameters->upsample), 1} + {"ImgDir", REQ_ARG, NULL,'y'}, + {"OutFor", REQ_ARG, NULL,'O'}, + {"force-rgb", NO_ARG, NULL, 1}, + {"upsample", NO_ARG, NULL, 1}, + {"split-pnm", NO_ARG, NULL, 1}, + {"threads", REQ_ARG, NULL, 'T'} }; const char optlist[] = "i:o:r:l:x:d:t:p:" @@ -508,6 +538,10 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para #endif /* USE_JPWL */ /* <force_rgb); + long_option[3].flag = &(parameters->upsample); + long_option[4].flag = &(parameters->split_pnm); totlen=sizeof(long_option); opj_reset_options_reading(); img_fol->set_out_format = 0; @@ -541,7 +575,10 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para infile); return 1; } - strncpy(parameters->infile, infile, sizeof(parameters->infile)-1); + if (opj_strcpy_s(parameters->infile, sizeof(parameters->infile), infile) != 0) { + fprintf(stderr, "[ERROR] Path is too long\n"); + return 1; + } } break; @@ -569,10 +606,13 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para case PNG_DFMT: break; default: - fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outfile); + fprintf(stderr, "Unknown output format image %s [only *.png, *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!!\n", outfile); return 1; } - strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1); + if (opj_strcpy_s(parameters->outfile, sizeof(parameters->outfile), outfile) != 0) { + fprintf(stderr, "[ERROR] Path is too long\n"); + return 1; + } } break; @@ -611,7 +651,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para img_fol->out_format = "png"; break; default: - fprintf(stderr, "Unknown output format image %s [only *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!! \n", outformat); + fprintf(stderr, "Unknown output format image %s [only *.png, *.pnm, *.pgm, *.ppm, *.pgx, *.bmp, *.tif, *.raw or *.tga]!!\n", outformat); return 1; break; } @@ -623,7 +663,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para case 'r': /* reduce option */ { - sscanf(opj_optarg, "%ud", &(parameters->core.cp_reduce)); + sscanf(opj_optarg, "%u", &(parameters->core.cp_reduce)); } break; @@ -632,7 +672,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para case 'l': /* layering option */ { - sscanf(opj_optarg, "%ud", &(parameters->core.cp_layer)); + sscanf(opj_optarg, "%u", &(parameters->core.cp_layer)); } break; @@ -647,6 +687,9 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para case 'y': /* Image Directory path */ { img_fol->imgdirpath = (char*)malloc(strlen(opj_optarg) + 1); + if(img_fol->imgdirpath == NULL){ + return 1; + } strcpy(img_fol->imgdirpath,opj_optarg); img_fol->set_imgdir=1; } @@ -656,11 +699,14 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para case 'd': /* Input decode ROI */ { - int size_optarg = (int)strlen(opj_optarg) + 1; - char *ROI_values = (char*) malloc((size_t)size_optarg); + size_t size_optarg = (size_t)strlen(opj_optarg) + 1U; + char *ROI_values = (char*) malloc(size_optarg); + if (ROI_values == NULL) { + fprintf(stderr, "[ERROR] Couldn't allocate memory\n"); + return 1; + } ROI_values[0] = '\0'; - strncpy(ROI_values, opj_optarg, strlen(opj_optarg)); - ROI_values[strlen(opj_optarg)] = '\0'; + memcpy(ROI_values, opj_optarg, size_optarg); /*printf("ROI_values = %s [%d / %d]\n", ROI_values, strlen(ROI_values), size_optarg ); */ parse_DA_values( ROI_values, ¶meters->DA_x0, ¶meters->DA_y0, ¶meters->DA_x1, ¶meters->DA_y1); @@ -672,7 +718,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para case 't': /* Input tile index */ { - sscanf(opj_optarg, "%ud", ¶meters->tile_index); + sscanf(opj_optarg, "%u", ¶meters->tile_index); parameters->nb_tile_to_decode = 1; } break; @@ -681,8 +727,10 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para case 'x': /* Creation of index file */ { - char *index = opj_optarg; - strncpy(indexfilename, index, OPJ_PATH_LEN); + if (opj_strcpy_s(parameters->indexfilename, sizeof(parameters->indexfilename), opj_optarg) != 0) { + fprintf(stderr, "[ERROR] Path is too long\n"); + return 1; + } } break; @@ -767,6 +815,22 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para break; #endif /* USE_JPWL */ /* <num_threads = opj_get_num_cpus(); + if( parameters->num_threads == 1 ) + parameters->num_threads = 0; + } + else + { + sscanf(opj_optarg, "%d", ¶meters->num_threads); + } + } + break; /* ----------------------------------------------------- */ @@ -834,6 +898,35 @@ int parse_DA_values( char* inArg, unsigned int *DA_x0, unsigned int *DA_y0, unsi } } +OPJ_FLOAT64 opj_clock(void) { +#ifdef _WIN32 + /* _WIN32: use QueryPerformance (very accurate) */ + LARGE_INTEGER freq , t ; + /* freq is the clock speed of the CPU */ + QueryPerformanceFrequency(&freq) ; + /* cout << "freq = " << ((double) freq.QuadPart) << endl; */ + /* t is the high resolution performance counter (see MSDN) */ + QueryPerformanceCounter ( & t ) ; + return freq.QuadPart ? (t.QuadPart / (OPJ_FLOAT64)freq.QuadPart) : 0; +#elif defined(__linux) + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return( (OPJ_FLOAT64)ts.tv_sec + (OPJ_FLOAT64)ts.tv_nsec * 1e-9 ); +#else + /* Unix : use resource usage */ + /* FIXME: this counts the total CPU time, instead of the user perceived time */ + struct rusage t; + OPJ_FLOAT64 procTime; + /* (1) Get the rusage data structure at this moment (man getrusage) */ + getrusage(0,&t); + /* (2) What is the elapsed time ? - CPU time = User time + System time */ + /* (2a) Get the seconds */ + procTime = (OPJ_FLOAT64)(t.ru_utime.tv_sec + t.ru_stime.tv_sec); + /* (2b) More precisely! Get the microseconds part ! */ + return ( procTime + (OPJ_FLOAT64)(t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ; +#endif +} + /* -------------------------------------------------------------------------- */ /** @@ -1046,7 +1139,7 @@ static opj_image_t* upsample_image_components(opj_image_t* original) l_dst += l_new_cmp->w; } - if(l_new_cmp->h > (l_org_cmp->dy - 1U)) { /* check substraction overflow for really small images */ + if(l_new_cmp->h > (l_org_cmp->dy - 1U)) { /* check subtraction overflow for really small images */ for (; y < l_new_cmp->h - (l_org_cmp->dy - 1U); y += l_org_cmp->dy) { OPJ_UINT32 x, dy; OPJ_UINT32 xorg; @@ -1055,7 +1148,7 @@ static opj_image_t* upsample_image_components(opj_image_t* original) for (x = 0U; x < xoff; ++x) { l_dst[x] = 0; } - if (l_new_cmp->w > (l_org_cmp->dx - 1U)) { /* check substraction overflow for really small images */ + if (l_new_cmp->w > (l_org_cmp->dx - 1U)) { /* check subtraction overflow for really small images */ for (; x < l_new_cmp->w - (l_org_cmp->dx - 1U); x += l_org_cmp->dx, ++xorg) { OPJ_UINT32 dx; for (dx = 0U; dx < l_org_cmp->dx; ++dx) { @@ -1083,7 +1176,7 @@ static opj_image_t* upsample_image_components(opj_image_t* original) for (x = 0U; x < xoff; ++x) { l_dst[x] = 0; } - if (l_new_cmp->w > (l_org_cmp->dx - 1U)) { /* check substraction overflow for really small images */ + if (l_new_cmp->w > (l_org_cmp->dx - 1U)) { /* check subtraction overflow for really small images */ for (; x < l_new_cmp->w - (l_org_cmp->dx - 1U); x += l_org_cmp->dx, ++xorg) { OPJ_UINT32 dx; for (dx = 0U; dx < l_org_cmp->dx; ++dx) { @@ -1123,26 +1216,22 @@ int main(int argc, char **argv) opj_codec_t* l_codec = NULL; /* Handle to a decompressor */ opj_codestream_index_t* cstr_index = NULL; - char indexfilename[OPJ_PATH_LEN]; /* index file name */ - OPJ_INT32 num_images, imageno; img_fol_t img_fol; dircnt_t *dirptr = NULL; int failed = 0; + OPJ_FLOAT64 t, tCumulative = 0; + OPJ_UINT32 numDecompressedImages = 0; /* set decoding parameters to default values */ set_default_parameters(¶meters); - /* FIXME Initialize indexfilename and img_fol */ - *indexfilename = 0; - /* Initialize img_fol */ memset(&img_fol,0,sizeof(img_fol_t)); /* parse input and get user encoding parameters */ - if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol, indexfilename) == 1) { - destroy_parameters(¶meters); - return EXIT_FAILURE; + if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol) == 1) { + failed = 1; goto fin; } /* Initialize reading of directory */ @@ -1151,26 +1240,30 @@ int main(int argc, char **argv) num_images=get_num_images(img_fol.imgdirpath); dirptr=(dircnt_t*)malloc(sizeof(dircnt_t)); - if(dirptr){ - dirptr->filename_buf = (char*)malloc((size_t)num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ - dirptr->filename = (char**) malloc((size_t)num_images*sizeof(char*)); + if(!dirptr){ + destroy_parameters(¶meters); + return EXIT_FAILURE; + } + dirptr->filename_buf = (char*)malloc((size_t)num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ + if(!dirptr->filename_buf){ + failed = 1; goto fin; + } + + dirptr->filename = (char**) malloc((size_t)num_images*sizeof(char*)); - if(!dirptr->filename_buf){ - destroy_parameters(¶meters); - return EXIT_FAILURE; - } - for(it_image=0;it_imagefilename[it_image] = dirptr->filename_buf + it_image*OPJ_PATH_LEN; - } + if(!dirptr->filename){ + failed = 1; goto fin; + } + for(it_image=0;it_imagefilename[it_image] = dirptr->filename_buf + it_image*OPJ_PATH_LEN; } + if(load_images(dirptr,img_fol.imgdirpath)==1){ - destroy_parameters(¶meters); - return EXIT_FAILURE; + failed = 1; goto fin; } if (num_images==0){ fprintf(stdout,"Folder is empty\n"); - destroy_parameters(¶meters); - return EXIT_FAILURE; + failed = 1; goto fin; } }else{ num_images=1; @@ -1195,8 +1288,7 @@ int main(int argc, char **argv) l_stream = opj_stream_create_default_file_stream(parameters.infile,1); if (!l_stream){ fprintf(stderr, "ERROR -> failed to create the stream from the file %s\n", parameters.infile); - destroy_parameters(¶meters); - return EXIT_FAILURE; + failed = 1; goto fin; } /* decode the JPEG2000 stream */ @@ -1233,24 +1325,30 @@ int main(int argc, char **argv) opj_set_warning_handler(l_codec, warning_callback,00); opj_set_error_handler(l_codec, error_callback,00); + t = opj_clock(); + /* Setup the decoder decoding parameters using user parameters */ if ( !opj_setup_decoder(l_codec, &(parameters.core)) ){ - fprintf(stderr, "ERROR -> opj_compress: failed to setup the decoder\n"); - destroy_parameters(¶meters); + fprintf(stderr, "ERROR -> opj_decompress: failed to setup the decoder\n"); opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); - return EXIT_FAILURE; + failed = 1; goto fin; + } + + if( parameters.num_threads >= 1 && !opj_codec_set_threads(l_codec, parameters.num_threads) ) { + fprintf(stderr, "ERROR -> opj_decompress: failed to set number of threads\n"); + opj_stream_destroy(l_stream); + opj_destroy_codec(l_codec); + failed = 1; goto fin; } - /* Read the main header of the codestream and if necessary the JP2 boxes*/ if(! opj_read_header(l_stream, l_codec, &image)){ fprintf(stderr, "ERROR -> opj_decompress: failed to read the header\n"); - destroy_parameters(¶meters); opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); - return EXIT_FAILURE; + failed = 1; goto fin; } if (!parameters.nb_tile_to_decode) { @@ -1258,21 +1356,19 @@ int main(int argc, char **argv) if (!opj_set_decode_area(l_codec, image, (OPJ_INT32)parameters.DA_x0, (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, (OPJ_INT32)parameters.DA_y1)){ fprintf(stderr, "ERROR -> opj_decompress: failed to set the decoded area\n"); - destroy_parameters(¶meters); opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); opj_image_destroy(image); - return EXIT_FAILURE; + failed = 1; goto fin; } /* Get the decoded image */ if (!(opj_decode(l_codec, l_stream, image) && opj_end_decompress(l_codec, l_stream))) { fprintf(stderr,"ERROR -> opj_decompress: failed to decode image!\n"); - destroy_parameters(¶meters); opj_destroy_codec(l_codec); opj_stream_destroy(l_stream); opj_image_destroy(image); - return EXIT_FAILURE; + failed = 1; goto fin; } } else { @@ -1283,27 +1379,25 @@ int main(int argc, char **argv) opj_destroy_codec(l_codec); opj_stream_destroy(l_stream); opj_image_destroy(image); - return EXIT_FAILURE; + failed = 1; goto fin; }*/ if (!opj_get_decoded_tile(l_codec, l_stream, image, parameters.tile_index)) { fprintf(stderr, "ERROR -> opj_decompress: failed to decode tile!\n"); - destroy_parameters(¶meters); opj_destroy_codec(l_codec); opj_stream_destroy(l_stream); opj_image_destroy(image); - return EXIT_FAILURE; + failed = 1; goto fin; } fprintf(stdout, "tile %d is decoded!\n\n", parameters.tile_index); } + tCumulative += opj_clock() - t; + numDecompressedImages++; + /* Close the byte stream */ opj_stream_destroy(l_stream); - if(image->color_space == OPJ_CLRSPC_SYCC){ - color_sycc_to_rgb(image); /* FIXME */ - } - if( image->color_space != OPJ_CLRSPC_SYCC && image->numcomps == 3 && image->comps[0].dx == image->comps[0].dy && image->comps[1].dx != 1 ) @@ -1311,9 +1405,22 @@ int main(int argc, char **argv) else if (image->numcomps <= 2) image->color_space = OPJ_CLRSPC_GRAY; + if(image->color_space == OPJ_CLRSPC_SYCC){ + color_sycc_to_rgb(image); + } + else if((image->color_space == OPJ_CLRSPC_CMYK) && (parameters.cod_format != TIF_DFMT)){ + color_cmyk_to_rgb(image); + } + else if(image->color_space == OPJ_CLRSPC_EYCC){ + color_esycc_to_rgb(image); + } + if(image->icc_profile_buf) { #if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2) - color_apply_icc_profile(image); /* FIXME */ + if(image->icc_profile_len) + color_apply_icc_profile(image); + else + color_cielab_to_rgb(image); #endif free(image->icc_profile_buf); image->icc_profile_buf = NULL; image->icc_profile_len = 0; @@ -1359,9 +1466,8 @@ int main(int argc, char **argv) image = upsample_image_components(image); if (image == NULL) { fprintf(stderr, "ERROR -> opj_decompress: failed to upsample image components!\n"); - destroy_parameters(¶meters); opj_destroy_codec(l_codec); - return EXIT_FAILURE; + failed = 1; goto fin; } } @@ -1383,9 +1489,8 @@ int main(int argc, char **argv) } if (image == NULL) { fprintf(stderr, "ERROR -> opj_decompress: failed to convert to RGB image!\n"); - destroy_parameters(¶meters); opj_destroy_codec(l_codec); - return EXIT_FAILURE; + failed = 1; goto fin; } } @@ -1393,7 +1498,7 @@ int main(int argc, char **argv) /* ------------------- */ switch (parameters.cod_format) { case PXM_DFMT: /* PNM PGM PPM */ - if (imagetopnm(image, parameters.outfile)) { + if (imagetopnm(image, parameters.outfile, parameters.split_pnm)) { fprintf(stderr,"[ERROR] Outfile %s not generated\n",parameters.outfile); failed = 1; } @@ -1492,9 +1597,19 @@ int main(int argc, char **argv) /* destroy the codestream index */ opj_destroy_cstr_index(&cstr_index); - if(failed) remove(parameters.outfile); + if(failed) (void)remove(parameters.outfile); /* ignore return value */ } +fin: destroy_parameters(¶meters); + if(failed && img_fol.imgdirpath) free(img_fol.imgdirpath); + if(dirptr){ + if(dirptr->filename) free(dirptr->filename); + if(dirptr->filename_buf) free(dirptr->filename_buf); + free(dirptr); + } + if (numDecompressedImages) { + fprintf(stdout, "decode time: %d ms\n", (int)( (tCumulative * 1000.0) / (OPJ_FLOAT64)numDecompressedImages)); + } return failed ? EXIT_FAILURE : EXIT_SUCCESS; } -/*end main*/ +/*end main()*/