summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormayeut <mayeut@users.noreply.github.com>2015-10-18 16:07:40 +0200
committermayeut <mayeut@users.noreply.github.com>2015-10-18 16:07:40 +0200
commit7ad3e2a870a02a6d5effce55d8d90705ac27e3ff (patch)
treef652e26936b5b8fee641b95cf481b35d5a476bfb
parent9542c08d62297509a5097a3800478013c2534379 (diff)
Add "-p", "-force-rgb" and "-upsample" options to j2k_to_image
Fix #606
-rw-r--r--applications/codec/convert.c103
-rw-r--r--applications/codec/convert.h4
-rw-r--r--applications/codec/j2k_to_image.c545
3 files changed, 628 insertions, 24 deletions
diff --git a/applications/codec/convert.c b/applications/codec/convert.c
index f1ac4791..bb5c52bf 100644
--- a/applications/codec/convert.c
+++ b/applications/codec/convert.c
@@ -48,6 +48,23 @@
#include "openjpeg.h"
#include "convert.h"
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#if defined(_WIN32)
+typedef signed __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef signed __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef signed __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+#error unsupported platform
+#endif
+#endif
+
/*
* Get logarithm of an integer and round downwards.
*
@@ -61,6 +78,92 @@ static int int_floorlog2(int a) {
return l;
}
+/* Component precision scaling */
+void clip_component(opj_image_comp_t* component, int precision)
+{
+ size_t i, len;
+ unsigned int umax = (unsigned int)((int)-1);
+
+ len = (size_t)component->w * (size_t)component->h;
+ if (precision < 32) {
+ umax = (1U << precision) - 1U;
+ }
+
+ if (component->sgnd) {
+ int* l_data = component->data;
+ int max = (int)(umax / 2U);
+ int min = -max - 1;
+ for (i = 0U; i < len; ++i) {
+ if (l_data[i] > max) {
+ l_data[i] = max;
+ } else if (l_data[i] < min) {
+ l_data[i] = min;
+ }
+ }
+ } else {
+ unsigned int* l_data = (unsigned int*)component->data;
+ for (i = 0U; i < len; ++i) {
+ if (l_data[i] > umax) {
+ l_data[i] = umax;
+ }
+ }
+ }
+ component->prec = precision;
+}
+
+/* Component precision scaling */
+static void scale_component_up(opj_image_comp_t* component, int precision)
+{
+ size_t i, len;
+
+ len = (size_t)component->w * (size_t)component->h;
+ if (component->sgnd) {
+ int64_t newMax = (int64_t)(1U << (precision - 1));
+ int64_t oldMax = (int64_t)(1U << (component->prec - 1));
+ int* l_data = component->data;
+ for (i = 0; i < len; ++i) {
+ l_data[i] = (int)(((int64_t)l_data[i] * newMax) / oldMax);
+ }
+ } else {
+ uint64_t newMax = (uint64_t)((1U << precision) - 1U);
+ uint64_t oldMax = (uint64_t)((1U << component->prec) - 1U);
+ unsigned int* l_data = (unsigned int*)component->data;
+ for (i = 0; i < len; ++i) {
+ l_data[i] = (unsigned int)(((uint64_t)l_data[i] * newMax) / oldMax);
+ }
+ }
+ component->prec = precision;
+ component->bpp = precision;
+}
+void scale_component(opj_image_comp_t* component, int precision)
+{
+ int shift;
+ size_t i, len;
+
+ if (component->prec == precision) {
+ return;
+ }
+ if (component->prec < precision) {
+ scale_component_up(component, precision);
+ return;
+ }
+ shift = (int)(component->prec - precision);
+ len = (size_t)component->w * (size_t)component->h;
+ if (component->sgnd) {
+ int* l_data = component->data;
+ for (i = 0U; i < len; ++i) {
+ l_data[i] >>= shift;
+ }
+ } else {
+ unsigned int* l_data = (unsigned int*)component->data;
+ for (i = 0U; i < len; ++i) {
+ l_data[i] >>= shift;
+ }
+ }
+ component->bpp = precision;
+ component->prec = precision;
+}
+
/* -->> -->> -->> -->>
TGA IMAGE FORMAT
diff --git a/applications/codec/convert.h b/applications/codec/convert.h
index d2f82fcf..0fb2ee6f 100644
--- a/applications/codec/convert.h
+++ b/applications/codec/convert.h
@@ -47,6 +47,10 @@ typedef struct raw_cparameters {
/*@}*/
} raw_cparameters_t;
+/* Component precision scaling */
+void clip_component(opj_image_comp_t* component, int precision);
+void scale_component(opj_image_comp_t* component, int precision);
+
/* TGA conversion */
opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters);
int imagetotga(opj_image_t * image, const char *outfile);
diff --git a/applications/codec/j2k_to_image.c b/applications/codec/j2k_to_image.c
index 43dc7c35..4fba5007 100644
--- a/applications/codec/j2k_to_image.c
+++ b/applications/codec/j2k_to_image.c
@@ -85,6 +85,40 @@ typedef struct img_folder{
}img_fol_t;
+typedef enum opj_prec_mode
+{
+ OPJ_PREC_MODE_CLIP,
+ OPJ_PREC_MODE_SCALE
+} opj_precision_mode;
+
+typedef struct opj_prec
+{
+ int prec;
+ opj_precision_mode mode;
+}opj_precision;
+
+typedef struct opj_decompress_params
+{
+ /** core library parameters */
+ opj_dparameters_t core;
+
+ /** input file name */
+ char infile[OPJ_PATH_LEN];
+ /** output file name */
+ char outfile[OPJ_PATH_LEN];
+ /** input file format 0: J2K, 1: JP2, 2: JPT */
+ int decod_format;
+ /** output file format 0: PGX, 1: PxM, 2: BMP */
+ int cod_format;
+
+ opj_precision* precision;
+ int nb_precision;
+ /* force output colorspace to RGB */
+ int force_rgb;
+ /* upsample components according to their dx/dy values */
+ int upsample;
+}opj_decompress_parameters;
+
static void decode_help_display(void) {
fprintf(stdout,"HELP for j2k_to_image\n----\n\n");
fprintf(stdout,"- the -h option displays this help information on screen\n\n");
@@ -128,6 +162,18 @@ static void decode_help_display(void) {
fprintf(stdout," are decoded.\n");
fprintf(stdout," -x \n");
fprintf(stdout," Create an index file *.Idx (-x index_name.Idx) \n");
+ fprintf(stdout," -p <comp 0 precision>[C|S][,<comp 1 precision>[C|S][,...]]\n");
+ fprintf(stdout," OPTIONAL\n");
+ fprintf(stdout," 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");
+ fprintf(stdout," If there are less values than components, the last value is used for remaining components.\n");
+ fprintf(stdout," If 'C' is specified (default), values are clipped.\n");
+ fprintf(stdout," If 'S' is specified, values are scaled.\n");
+ fprintf(stdout," A 0 value can be specified (meaning original bit depth).\n");
+ fprintf(stdout," -force-rgb\n");
+ fprintf(stdout," Force output image colorspace to RGB\n");
+ fprintf(stdout," -upsample\n");
+ fprintf(stdout," Downsampled components will be upsampled to image size\n");
fprintf(stdout,"\n");
/* UniPG>> */
#ifdef USE_JPWL
@@ -144,6 +190,111 @@ static void decode_help_display(void) {
/* -------------------------------------------------------------------------- */
+static opj_bool parse_precision(const char* option, opj_decompress_parameters* parameters)
+{
+ const char* l_remaining = option;
+ opj_bool l_result = OPJ_TRUE;
+
+ /* reset */
+ if (parameters->precision) {
+ free(parameters->precision);
+ parameters->precision = NULL;
+ }
+ parameters->nb_precision = 0U;
+
+ for(;;)
+ {
+ int prec;
+ char mode;
+ char comma;
+ int count;
+
+ count = sscanf(l_remaining, "%d%c%c", &prec, &mode, &comma);
+ if (count == 1) {
+ mode = 'C';
+ count++;
+ }
+ if ((count == 2) || (mode==',')) {
+ if (mode==',') {
+ mode = 'C';
+ }
+ comma=',';
+ count = 3;
+ }
+ if (count == 3) {
+ if ((prec < 1) || (prec > 32)) {
+ fprintf(stderr,"Invalid precision %d in precision option %s\n", prec, option);
+ l_result = OPJ_FALSE;
+ break;
+ }
+ if ((mode != 'C') && (mode != 'S')) {
+ fprintf(stderr,"Invalid precision mode %c in precision option %s\n", mode, option);
+ l_result = OPJ_FALSE;
+ break;
+ }
+ if (comma != ',') {
+ fprintf(stderr,"Invalid character %c in precision option %s\n", comma, option);
+ l_result = OPJ_FALSE;
+ break;
+ }
+
+ if (parameters->precision == NULL) {
+ /* first one */
+ 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;
+ break;
+ }
+ } else {
+ int l_new_size = parameters->nb_precision + 1U;
+ opj_precision* l_new;
+
+ if (l_new_size == 0U) {
+ fprintf(stderr,"Could not allocate memory for precision option\n");
+ l_result = OPJ_FALSE;
+ break;
+ }
+
+ 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;
+ break;
+ }
+ parameters->precision = l_new;
+ }
+
+ parameters->precision[parameters->nb_precision].prec = prec;
+ switch (mode) {
+ case 'C':
+ parameters->precision[parameters->nb_precision].mode = OPJ_PREC_MODE_CLIP;
+ break;
+ case 'S':
+ parameters->precision[parameters->nb_precision].mode = OPJ_PREC_MODE_SCALE;
+ break;
+ default:
+ break;
+ }
+ parameters->nb_precision++;
+
+ l_remaining = strchr(l_remaining, ',');
+ if (l_remaining == NULL) {
+ break;
+ }
+ l_remaining += 1;
+ } else {
+ fprintf(stderr,"Could not parse precision option %s\n", option);
+ l_result = OPJ_FALSE;
+ break;
+ }
+ }
+
+ return l_result;
+}
+
+/* -------------------------------------------------------------------------- */
+
static int get_num_images(char *imgdirpath){
DIR *dir;
struct dirent* content;
@@ -211,7 +362,7 @@ static int get_file_format(char *filename) {
return -1;
}
-static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters){
+static 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];
char *temp_p, temp1[OPJ_PATH_LEN]="";
@@ -237,18 +388,20 @@ static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_d
}
/* -------------------------------------------------------------------------- */
-static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol, char *indexfilename) {
+static int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *parameters,img_fol_t *img_fol, char *indexfilename) {
/* parse the command line */
int totlen, c;
opj_option_t long_option[]={
{"ImgDir",REQ_ARG, NULL ,'y'},
- {"OutFor",REQ_ARG, NULL ,'O'},
+ {"OutFor",REQ_ARG, NULL ,'O'},
+ {"force-rgb", NO_ARG, NULL, 1},
+ {"upsample", NO_ARG, NULL, 1},
#ifdef USE_SYSTEM_GETOPT
- {0,0,0,0} /* GNU getopt_long requirement */
+ {0,0,0,0} /* GNU getopt_long requirement */
#endif
};
- const char optlist[] = "i:o:r:l:x:"
+ const char optlist[] = "i:o:r:l:x:p:"
/* UniPG>> */
#ifdef USE_JPWL
@@ -256,7 +409,10 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
#endif /* USE_JPWL */
/* <<UniPG */
"h" ;
- totlen=sizeof(long_option);
+
+ long_option[2].flag = &(parameters->force_rgb);
+ long_option[3].flag = &(parameters->upsample);
+ totlen=sizeof(long_option);
img_fol->set_out_format = 0;
do {
#ifdef USE_SYSTEM_GETOPT
@@ -267,6 +423,8 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
if (c == -1)
break;
switch (c) {
+ case 0: /* long opt with flag */
+ break;
case 'i': /* input file */
{
char *infile = opj_optarg;
@@ -353,7 +511,7 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
case 'r': /* reduce option */
{
- sscanf(opj_optarg, "%d", &parameters->cp_reduce);
+ sscanf(opj_optarg, "%d", &parameters->core.cp_reduce);
}
break;
@@ -362,7 +520,7 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
case 'l': /* layering option */
{
- sscanf(opj_optarg, "%d", &parameters->cp_layer);
+ sscanf(opj_optarg, "%d", &parameters->core.cp_layer);
}
break;
@@ -389,6 +547,15 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
}
break;
/* ----------------------------------------------------- */
+ case 'p': /* Force precision */
+ {
+ if (!parse_precision(opj_optarg, parameters))
+ {
+ return 1;
+ }
+ }
+ break;
+ /* ----------------------------------------------------- */
/* UniPG>> */
#ifdef USE_JPWL
@@ -496,6 +663,32 @@ static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *param
/* -------------------------------------------------------------------------- */
+static void set_default_parameters(opj_decompress_parameters* parameters)
+{
+ if (parameters) {
+ memset(parameters, 0, sizeof(opj_decompress_parameters));
+
+ /* default decoding parameters (command line specific) */
+ parameters->decod_format = -1;
+ parameters->cod_format = -1;
+
+ /* default decoding parameters (core) */
+ opj_set_default_decoder_parameters(&(parameters->core));
+ }
+}
+
+static void destroy_parameters(opj_decompress_parameters* parameters)
+{
+ if (parameters) {
+ if (parameters->precision) {
+ free(parameters->precision);
+ parameters->precision = NULL;
+ }
+ }
+}
+
+/* -------------------------------------------------------------------------- */
+
/**
sample error callback expecting a FILE* client object
*/
@@ -520,8 +713,233 @@ static void info_callback(const char *msg, void *client_data) {
/* -------------------------------------------------------------------------- */
+static opj_image_t* convert_gray_to_rgb(opj_image_t* original)
+{
+ int 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 -> j2k_to_image: 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 = 1; compno < original->numcomps; ++compno) {
+ l_new_components[compno+2].bpp = original->comps[compno].bpp;
+ l_new_components[compno+2].dx = original->comps[compno].dx;
+ l_new_components[compno+2].dy = original->comps[compno].dy;
+ l_new_components[compno+2].h = original->comps[compno].h;
+ l_new_components[compno+2].w = original->comps[compno].w;
+ l_new_components[compno+2].prec = original->comps[compno].prec;
+ l_new_components[compno+2].sgnd = original->comps[compno].sgnd;
+ l_new_components[compno+2].x0 = original->comps[compno].x0;
+ l_new_components[compno+2].y0 = original->comps[compno].y0;
+ }
+
+ l_new_image = opj_image_create(original->numcomps + 2, l_new_components, CLRSPC_SRGB);
+ free(l_new_components);
+ if (l_new_image == NULL) {
+ fprintf(stderr, "ERROR -> j2k_to_image: 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].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(int));
+ memcpy(l_new_image->comps[1].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(int));
+ memcpy(l_new_image->comps[2].data, original->comps[0].data, original->comps[0].w * original->comps[0].h * sizeof(int));
+
+ for(compno = 1; compno < original->numcomps; ++compno) {
+ l_new_image->comps[compno+2].factor = original->comps[compno].factor;
+ l_new_image->comps[compno+2].resno_decoded = original->comps[compno].resno_decoded;
+ memcpy(l_new_image->comps[compno+2].data, original->comps[compno].data, original->comps[compno].w * original->comps[compno].h * sizeof(int));
+ }
+ opj_image_destroy(original);
+ return l_new_image;
+}
+
+/* -------------------------------------------------------------------------- */
+
+static opj_image_t* upsample_image_components(opj_image_t* original)
+{
+ opj_image_t* l_new_image = NULL;
+ opj_image_cmptparm_t* l_new_components = NULL;
+ opj_bool l_upsample_need = OPJ_FALSE;
+ int compno;
+
+ for (compno = 0; compno < original->numcomps; ++compno) {
+ if (original->comps[compno].factor > 0) {
+ fprintf(stderr, "ERROR -> j2k_to_image: -upsample not supported with reduction\n");
+ opj_image_destroy(original);
+ return NULL;
+ }
+ if ((original->comps[compno].dx > 1) || (original->comps[compno].dy > 1)) {
+ l_upsample_need = OPJ_TRUE;
+ break;
+ }
+ }
+ if (!l_upsample_need) {
+ return original;
+ }
+ /* Upsample is needed */
+ l_new_components = (opj_image_cmptparm_t*)malloc(original->numcomps * sizeof(opj_image_cmptparm_t));
+ if (l_new_components == NULL) {
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to allocate memory for upsampled components!\n");
+ opj_image_destroy(original);
+ return NULL;
+ }
+
+ for (compno = 0; compno < original->numcomps; ++compno) {
+ opj_image_cmptparm_t* l_new_cmp = &(l_new_components[compno]);
+ opj_image_comp_t* l_org_cmp = &(original->comps[compno]);
+
+ l_new_cmp->bpp = l_org_cmp->bpp;
+ l_new_cmp->prec = l_org_cmp->prec;
+ l_new_cmp->sgnd = l_org_cmp->sgnd;
+ l_new_cmp->x0 = original->x0;
+ l_new_cmp->y0 = original->y0;
+ l_new_cmp->dx = 1;
+ l_new_cmp->dy = 1;
+ l_new_cmp->w = l_org_cmp->w; /* should be original->x1 - original->x0 for dx==1 */
+ l_new_cmp->h = l_org_cmp->h; /* should be original->y1 - original->y0 for dy==0 */
+
+ if (l_org_cmp->dx > 1) {
+ l_new_cmp->w = original->x1 - original->x0;
+ }
+
+ if (l_org_cmp->dy > 1) {
+ l_new_cmp->h = original->y1 - original->y0;
+ }
+ }
+
+ l_new_image = opj_image_create(original->numcomps, l_new_components, original->color_space);
+ free(l_new_components);
+ if (l_new_image == NULL) {
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to allocate memory for upsampled components!\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;
+
+ for (compno = 0; compno < original->numcomps; ++compno) {
+ opj_image_comp_t* l_new_cmp = &(l_new_image->comps[compno]);
+ opj_image_comp_t* l_org_cmp = &(original->comps[compno]);
+
+ l_new_cmp->factor = l_org_cmp->factor;
+ l_new_cmp->resno_decoded = l_org_cmp->resno_decoded;
+
+ if ((l_org_cmp->dx > 1) || (l_org_cmp->dy > 1)) {
+ const int* l_src = l_org_cmp->data;
+ int* l_dst = l_new_cmp->data;
+ int y;
+ int xoff, yoff;
+
+ /* need to take into account dx & dy */
+ xoff = l_org_cmp->dx * l_org_cmp->x0 - original->x0;
+ yoff = l_org_cmp->dy * l_org_cmp->y0 - original->y0;
+ if ((xoff >= l_org_cmp->dx) || (yoff >= l_org_cmp->dy)) {
+ fprintf(stderr, "ERROR -> j2k_to_image: Invalid image/component parameters found when upsampling\n");
+ opj_image_destroy(original);
+ opj_image_destroy(l_new_image);
+ return NULL;
+ }
+
+ for (y = 0; y < yoff; ++y) {
+ memset(l_dst, 0, l_new_cmp->w * sizeof(int));
+ l_dst += l_new_cmp->w;
+ }
+
+ if(l_new_cmp->h > (l_org_cmp->dy - 1)) { /* check subtraction overflow for really small images */
+ for (; y < l_new_cmp->h - (l_org_cmp->dy - 1); y += l_org_cmp->dy) {
+ int x, dy;
+ int xorg;
+
+ xorg = 0;
+ for (x = 0; x < xoff; ++x) {
+ l_dst[x] = 0;
+ }
+ if (l_new_cmp->w > (l_org_cmp->dx - 1)) { /* check subtraction overflow for really small images */
+ for (; x < l_new_cmp->w - (l_org_cmp->dx - 1); x += l_org_cmp->dx, ++xorg) {
+ int dx;
+ for (dx = 0; dx < l_org_cmp->dx; ++dx) {
+ l_dst[x + dx] = l_src[xorg];
+ }
+ }
+ }
+ for (; x < l_new_cmp->w; ++x) {
+ l_dst[x] = l_src[xorg];
+ }
+ l_dst += l_new_cmp->w;
+
+ for (dy = 1; dy < l_org_cmp->dy; ++dy) {
+ memcpy(l_dst, l_dst - l_new_cmp->w, l_new_cmp->w * sizeof(int));
+ l_dst += l_new_cmp->w;
+ }
+ l_src += l_org_cmp->w;
+ }
+ }
+ if (y < l_new_cmp->h) {
+ int x;
+ int xorg;
+
+ xorg = 0;
+ for (x = 0; x < xoff; ++x) {
+ l_dst[x] = 0;
+ }
+ if (l_new_cmp->w > (l_org_cmp->dx - 1)) { /* check subtraction overflow for really small images */
+ for (; x < l_new_cmp->w - (l_org_cmp->dx - 1); x += l_org_cmp->dx, ++xorg) {
+ int dx;
+ for (dx = 0; dx < l_org_cmp->dx; ++dx) {
+ l_dst[x + dx] = l_src[xorg];
+ }
+ }
+ }
+ for (; x < l_new_cmp->w; ++x) {
+ l_dst[x] = l_src[xorg];
+ }
+ l_dst += l_new_cmp->w;
+ ++y;
+ for (; y < l_new_cmp->h; ++y) {
+ memcpy(l_dst, l_dst - l_new_cmp->w, l_new_cmp->w * sizeof(int));
+ l_dst += l_new_cmp->w;
+ }
+ }
+ }
+ else {
+ memcpy(l_new_cmp->data, l_org_cmp->data, l_org_cmp->w * l_org_cmp->h * sizeof(int));
+ }
+ }
+ opj_image_destroy(original);
+ return l_new_image;
+}
+
+/* -------------------------------------------------------------------------- */
+
int main(int argc, char **argv) {
- opj_dparameters_t parameters; /* decompression parameters */
+ opj_decompress_parameters parameters; /* decompression parameters */
img_fol_t img_fol;
opj_event_mgr_t event_mgr; /* event manager */
opj_image_t *image = NULL;
@@ -543,7 +961,7 @@ int main(int argc, char **argv) {
event_mgr.info_handler = info_callback;
/* set decoding parameters to default values */
- opj_set_default_decoder_parameters(&parameters);
+ set_default_parameters(&parameters);
/* Initialize indexfilename and img_fol */
*indexfilename = 0;
@@ -551,6 +969,7 @@ int main(int argc, char **argv) {
/* parse input and get user encoding parameters */
if(parse_cmdline_decoder(argc, argv, &parameters,&img_fol, indexfilename) == 1) {
+ destroy_parameters(&parameters);
return 1;
}
@@ -564,6 +983,7 @@ int main(int argc, char **argv) {
dirptr->filename = (char**) malloc(num_images*sizeof(char*));
if(!dirptr->filename_buf){
+ destroy_parameters(&parameters);
return 1;
}
for(i=0;i<num_images;i++){
@@ -571,10 +991,12 @@ int main(int argc, char **argv) {
}
}
if(load_images(dirptr,img_fol.imgdirpath)==1){
+ destroy_parameters(&parameters);
return 1;
}
if (num_images==0){
fprintf(stdout,"Folder is empty\n");
+ destroy_parameters(&parameters);
return 1;
}
}else{
@@ -598,6 +1020,7 @@ int main(int argc, char **argv) {
fsrc = fopen(parameters.infile, "rb");
if (!fsrc) {
fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile);
+ destroy_parameters(&parameters);
return 1;
}
fseek(fsrc, 0, SEEK_END);
@@ -609,6 +1032,7 @@ int main(int argc, char **argv) {
free(src);
fclose(fsrc);
fprintf(stderr, "\nERROR: fread return a number of element different from the expected.\n");
+ destroy_parameters(&parameters);
return 1;
}
fclose(fsrc);
@@ -628,7 +1052,7 @@ int main(int argc, char **argv) {
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
- opj_setup_decoder(dinfo, &parameters);
+ opj_setup_decoder(dinfo, &parameters.core);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
@@ -643,6 +1067,7 @@ int main(int argc, char **argv) {
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
free(src);
+ destroy_parameters(&parameters);
return 1;
}
@@ -671,7 +1096,7 @@ int main(int argc, char **argv) {
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using the current image and user parameters */
- opj_setup_decoder(dinfo, &parameters);
+ opj_setup_decoder(dinfo, &parameters.core);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
@@ -686,6 +1111,7 @@ int main(int argc, char **argv) {
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
free(src);
+ destroy_parameters(&parameters);
return 1;
}
@@ -714,7 +1140,7 @@ int main(int argc, char **argv) {
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
- opj_setup_decoder(dinfo, &parameters);
+ opj_setup_decoder(dinfo, &parameters.core);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length);
@@ -729,6 +1155,7 @@ int main(int argc, char **argv) {
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
free(src);
+ destroy_parameters(&parameters);
return 1;
}
@@ -755,20 +1182,89 @@ int main(int argc, char **argv) {
free(src);
src = NULL;
- if(image->color_space == CLRSPC_SYCC)
- {
- color_sycc_to_rgb(image);
- }
+ if(image->color_space == CLRSPC_SYCC)
+ {
+ color_sycc_to_rgb(image);
+ }
- if(image->icc_profile_buf)
- {
+ if(image->icc_profile_buf)
+ {
#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2)
- color_apply_icc_profile(image);
+ color_apply_icc_profile(image);
#endif
-
- free(image->icc_profile_buf);
- image->icc_profile_buf = NULL; image->icc_profile_len = 0;
- }
+ free(image->icc_profile_buf);
+ image->icc_profile_buf = NULL; image->icc_profile_len = 0;
+ }
+
+ /* Force output precision */
+ /* ---------------------- */
+ if (parameters.precision != NULL)
+ {
+ int compno;
+ for (compno = 0; compno < image->numcomps; ++compno)
+ {
+ int precno = compno;
+ int prec;
+
+ if (precno >= parameters.nb_precision) {
+ precno = parameters.nb_precision - 1U;
+ }
+
+ prec = parameters.precision[precno].prec;
+ if (prec == 0) {
+ prec = image->comps[compno].prec;
+ }
+
+ switch (parameters.precision[precno].mode) {
+ case OPJ_PREC_MODE_CLIP:
+ clip_component(&(image->comps[compno]), prec);
+ break;
+ case OPJ_PREC_MODE_SCALE:
+ scale_component(&(image->comps[compno]), prec);
+ break;
+ default:
+ break;
+ }
+
+ }
+ }
+
+ /* Upsample components */
+ /* ------------------- */
+ if (parameters.upsample)
+ {
+ image = upsample_image_components(image);
+ if (image == NULL) {
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to upsample image components!\n");
+ destroy_parameters(&parameters);
+ opj_destroy_decompress(dinfo);
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* Force RGB output */
+ /* ---------------- */
+ if (parameters.force_rgb)
+ {
+ switch (image->color_space) {
+ case CLRSPC_SRGB:
+ break;
+ case CLRSPC_GRAY:
+ image = convert_gray_to_rgb(image);
+ break;
+ default:
+ fprintf(stderr, "ERROR -> j2k_to_image: don't know how to convert image to RGB colorspace!\n");
+ opj_image_destroy(image);
+ image = NULL;
+ break;
+ }
+ if (image == NULL) {
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to convert to RGB image!\n");
+ destroy_parameters(&parameters);
+ opj_destroy_decompress(dinfo);
+ return EXIT_FAILURE;
+ }
+ }
/* create output image */
/* ------------------- */
@@ -854,6 +1350,7 @@ int main(int argc, char **argv) {
opj_image_destroy(image);
}
+ destroy_parameters(&parameters);
return 0;
}
/*end main*/