diff --git a/src/bin/common/opj_getopt.c b/src/bin/common/opj_getopt.c index 100cded7..484c839d 100644 --- a/src/bin/common/opj_getopt.c +++ b/src/bin/common/opj_getopt.c @@ -54,7 +54,7 @@ int opj_opterr = 1, /* if error message should be printed */ static char EMSG[]={""}; /* As this class remembers its values from one Java call to the other, reset the values before each use */ -void reset_options_reading(void) { +void opj_reset_options_reading(void) { opj_opterr = 1; opj_optind = 1; } diff --git a/src/bin/common/opj_getopt.h b/src/bin/common/opj_getopt.h index e1f41a56..f97e8b35 100644 --- a/src/bin/common/opj_getopt.h +++ b/src/bin/common/opj_getopt.h @@ -24,6 +24,6 @@ extern char *opj_optarg; extern int opj_getopt(int nargc, char *const *nargv, const char *ostr); extern int opj_getopt_long(int argc, char * const argv[], const char *optstring, const opj_option_t *longopts, int totlen); -extern void reset_options_reading(void); +extern void opj_reset_options_reading(void); #endif /* _GETOPT_H_ */ diff --git a/src/bin/jp2/opj_decompress.c b/src/bin/jp2/opj_decompress.c index d6a26010..bd76dcac 100644 --- a/src/bin/jp2/opj_decompress.c +++ b/src/bin/jp2/opj_decompress.c @@ -137,6 +137,9 @@ typedef struct opj_decompress_params opj_precision* precision; OPJ_UINT32 nb_precision; + + /* force output colorspace to RGB */ + OPJ_BOOL force_rgb; }opj_decompress_parameters; /* -------------------------------------------------------------------------- */ @@ -150,6 +153,8 @@ 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_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); + /* -------------------------------------------------------------------------- */ static void decode_help_display(void) { fprintf(stdout,"\nThis is the opj_decompress utility from the OpenJPEG project.\n" @@ -204,6 +209,8 @@ static void decode_help_display(void) { " 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" + " Force output image colorspace to RGB\n" "\n"); /* UniPG>> */ #ifdef USE_JPWL @@ -483,8 +490,9 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para /* parse the command line */ int totlen, c; opj_option_t long_option[]={ - {"ImgDir",REQ_ARG, NULL ,'y'}, - {"OutFor",REQ_ARG, NULL ,'O'} + {"ImgDir", REQ_ARG, NULL ,'y'}, + {"OutFor", REQ_ARG, NULL ,'O'}, + {"force-rgb", NO_ARG, NULL ,'FRGB'} }; const char optlist[] = "i:o:r:l:x:d:t:p:" @@ -496,6 +504,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para /* <set_out_format = 0; do { c = opj_getopt_long(argc, argv,optlist,long_option,totlen); @@ -680,6 +689,12 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para } break; /* ----------------------------------------------------- */ + case 'FRGB': /* Force RGB output */ + { + parameters->force_rgb = OPJ_TRUE; + } + break; + /* ----------------------------------------------------- */ /* UniPG>> */ #ifdef USE_JPWL @@ -866,6 +881,74 @@ static void destroy_parameters(opj_decompress_parameters* parameters) } } +/* -------------------------------------------------------------------------- */ + +static opj_image_t* convert_gray_to_rgb(opj_image_t* original) +{ + OPJ_UINT32 compno; + opj_image_t* l_new_image = NULL; + opj_image_cmptparm_t* l_new_components = NULL; + + l_new_components = (opj_image_cmptparm_t*)malloc((original->numcomps + 2U) * sizeof(opj_image_cmptparm_t)); + if (l_new_components == NULL) { + fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n"); + opj_image_destroy(original); + return NULL; + } + + l_new_components[0].bpp = l_new_components[1].bpp = l_new_components[2].bpp = original->comps[0].bpp; + l_new_components[0].dx = l_new_components[1].dx = l_new_components[2].dx = original->comps[0].dx; + l_new_components[0].dy = l_new_components[1].dy = l_new_components[2].dy = original->comps[0].dy; + l_new_components[0].h = l_new_components[1].h = l_new_components[2].h = original->comps[0].h; + l_new_components[0].w = l_new_components[1].w = l_new_components[2].w = original->comps[0].w; + l_new_components[0].prec = l_new_components[1].prec = l_new_components[2].prec = original->comps[0].prec; + l_new_components[0].sgnd = l_new_components[1].sgnd = l_new_components[2].sgnd = original->comps[0].sgnd; + l_new_components[0].x0 = l_new_components[1].x0 = l_new_components[2].x0 = original->comps[0].x0; + l_new_components[0].y0 = l_new_components[1].y0 = l_new_components[2].y0 = original->comps[0].y0; + + for(compno = 1U; compno < original->numcomps; ++compno) { + l_new_components[compno+2U].bpp = original->comps[compno].bpp; + l_new_components[compno+2U].dx = original->comps[compno].dx; + l_new_components[compno+2U].dy = original->comps[compno].dy; + l_new_components[compno+2U].h = original->comps[compno].h; + l_new_components[compno+2U].w = original->comps[compno].w; + l_new_components[compno+2U].prec = original->comps[compno].prec; + l_new_components[compno+2U].sgnd = original->comps[compno].sgnd; + l_new_components[compno+2U].x0 = original->comps[compno].x0; + l_new_components[compno+2U].y0 = original->comps[compno].y0; + } + + l_new_image = opj_image_create(original->numcomps + 2U, l_new_components, OPJ_CLRSPC_SRGB); + free(l_new_components); + if (l_new_image == NULL) { + fprintf(stderr, "ERROR -> opj_decompress: failed to allocate memory for RGB image!\n"); + opj_image_destroy(original); + return NULL; + } + + l_new_image->x0 = original->x0; + l_new_image->x1 = original->x1; + l_new_image->y0 = original->y0; + l_new_image->y1 = original->y1; + + l_new_image->comps[0].factor = l_new_image->comps[1].factor = l_new_image->comps[2].factor = original->comps[0].factor; + l_new_image->comps[0].alpha = l_new_image->comps[1].alpha = l_new_image->comps[2].alpha = original->comps[0].alpha; + l_new_image->comps[0].resno_decoded = l_new_image->comps[1].resno_decoded = l_new_image->comps[2].resno_decoded = original->comps[0].resno_decoded; + + memcpy(l_new_image->comps[0].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32)); + memcpy(l_new_image->comps[1].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32)); + memcpy(l_new_image->comps[2].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(OPJ_INT32)); + + for(compno = 1U; compno < original->numcomps; ++compno) { + l_new_image->comps[compno+2U].factor = original->comps[compno].factor; + l_new_image->comps[compno+2U].alpha = original->comps[compno].alpha; + l_new_image->comps[compno+2U].resno_decoded = original->comps[compno].resno_decoded; + memcpy(l_new_image->comps[compno+2U].data, original->comps[compno].data, original->comps[compno].w * original->comps[compno].h * sizeof(OPJ_INT32)); + } + opj_image_destroy(original); + return l_new_image; +} + /* -------------------------------------------------------------------------- */ /** * OPJ_DECOMPRESS MAIN @@ -1107,6 +1190,31 @@ int main(int argc, char **argv) } } + + /* Force RGB output */ + /* ---------------- */ + if (parameters.force_rgb) + { + switch (image->color_space) { + case OPJ_CLRSPC_SRGB: + break; + case OPJ_CLRSPC_GRAY: + image = convert_gray_to_rgb(image); + break; + default: + fprintf(stderr, "ERROR -> opj_decompress: don't know how to convert image to RGB colorspace!\n"); + opj_image_destroy(image); + image = NULL; + break; + } + if (image == NULL) { + fprintf(stderr, "ERROR -> opj_decompress: failed to convert to RGB image!\n"); + destroy_parameters(¶meters); + opj_destroy_codec(l_codec); + opj_stream_destroy(l_stream); + return EXIT_FAILURE; + } + } /* create output image */ /* ------------------- */ @@ -1217,7 +1325,3 @@ int main(int argc, char **argv) return failed ? EXIT_FAILURE : EXIT_SUCCESS; } /*end main*/ - - - - diff --git a/tests/conformance/CMakeLists.txt b/tests/conformance/CMakeLists.txt index 2b6b7732..157c46d1 100644 --- a/tests/conformance/CMakeLists.txt +++ b/tests/conformance/CMakeLists.txt @@ -440,6 +440,7 @@ foreach(numFileJP2 RANGE 1 9) -i ${INPUT_CONF}/${filenameInput} -o ${TEMP}/${filenameInput}.tif -p 8S + -force-rgb ) add_test(NAME ETS-JP2-${filenameInput}-compare2ref