[trunk] added an option to upsample image components in opj_decompress
Update issue 289 Issue is left open since there's still one image failing the tests.
This commit is contained in:
parent
13bcb63b73
commit
131cc98491
@ -140,6 +140,8 @@ typedef struct opj_decompress_params
|
||||
|
||||
/* force output colorspace to RGB */
|
||||
int force_rgb;
|
||||
/* upsample components according to their dx/dy values */
|
||||
int upsample;
|
||||
}opj_decompress_parameters;
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
@ -211,6 +213,8 @@ static void decode_help_display(void) {
|
||||
" A 0 value can be specified (meaning original bit depth).\n"
|
||||
" -force-rgb\n"
|
||||
" Force output image colorspace to RGB\n"
|
||||
" -upsample\n"
|
||||
" Downsampled components will be upsampled to image size\n"
|
||||
"\n");
|
||||
/* UniPG>> */
|
||||
#ifdef USE_JPWL
|
||||
@ -492,7 +496,8 @@ int parse_cmdline_decoder(int argc, char **argv, opj_decompress_parameters *para
|
||||
opj_option_t long_option[]={
|
||||
{"ImgDir", REQ_ARG, NULL ,'y'},
|
||||
{"OutFor", REQ_ARG, NULL ,'O'},
|
||||
{"force-rgb", NO_ARG, &(parameters->force_rgb), 1}
|
||||
{"force-rgb", NO_ARG, &(parameters->force_rgb), 1},
|
||||
{"upsample", NO_ARG, &(parameters->upsample), 1}
|
||||
};
|
||||
|
||||
const char optlist[] = "i:o:r:l:x:d:t:p:"
|
||||
@ -945,6 +950,166 @@ static opj_image_t* convert_gray_to_rgb(opj_image_t* 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;
|
||||
OPJ_UINT32 compno;
|
||||
|
||||
for (compno = 0U; compno < original->numcomps; ++compno) {
|
||||
if (original->comps[compno].factor > 0U) {
|
||||
fprintf(stderr, "ERROR -> opj_decompress: -upsample not supported with reduction\n");
|
||||
opj_image_destroy(original);
|
||||
return NULL;
|
||||
}
|
||||
if ((original->comps[compno].dx > 1U) || (original->comps[compno].dy > 1U)) {
|
||||
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 -> opj_decompress: failed to allocate memory for upsampled components!\n");
|
||||
opj_image_destroy(original);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (compno = 0U; 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 > 1U) {
|
||||
l_new_cmp->w = original->x1 - original->x0;
|
||||
}
|
||||
|
||||
if (l_org_cmp->dy > 1U) {
|
||||
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 -> opj_decompress: 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 = 0U; 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->alpha = l_org_cmp->alpha;
|
||||
l_new_cmp->resno_decoded = l_org_cmp->resno_decoded;
|
||||
|
||||
if ((l_org_cmp->dx > 1U) || (l_org_cmp->dy > 1U)) {
|
||||
const OPJ_INT32* l_src = l_org_cmp->data;
|
||||
OPJ_INT32* l_dst = l_new_cmp->data;
|
||||
OPJ_UINT32 y;
|
||||
OPJ_UINT32 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 -> opj_decompress: Invalid image/component parameters found when upsampling\n");
|
||||
opj_image_destroy(original);
|
||||
opj_image_destroy(l_new_image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (y = 0U; y < yoff; ++y) {
|
||||
memset(l_dst, 0U, l_new_cmp->w * sizeof(OPJ_INT32));
|
||||
l_dst += l_new_cmp->w;
|
||||
}
|
||||
|
||||
if(l_new_cmp->h > (l_org_cmp->dy - 1U)) { /* check substraction 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;
|
||||
|
||||
xorg = 0U;
|
||||
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 */
|
||||
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) {
|
||||
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 = 1U; dy < l_org_cmp->dy; ++dy) {
|
||||
memcpy(l_dst, l_dst - l_new_cmp->w, l_new_cmp->w * sizeof(OPJ_INT32));
|
||||
l_dst += l_new_cmp->w;
|
||||
}
|
||||
l_src += l_org_cmp->w;
|
||||
}
|
||||
}
|
||||
if (y < l_new_cmp->h) {
|
||||
OPJ_UINT32 x;
|
||||
OPJ_UINT32 xorg;
|
||||
|
||||
xorg = 0U;
|
||||
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 */
|
||||
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) {
|
||||
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(OPJ_INT32));
|
||||
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(OPJ_INT32));
|
||||
}
|
||||
}
|
||||
opj_image_destroy(original);
|
||||
return l_new_image;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/**
|
||||
* OPJ_DECOMPRESS MAIN
|
||||
@ -1187,6 +1352,19 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
/* Upsample components */
|
||||
/* ------------------- */
|
||||
if (parameters.upsample)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Force RGB output */
|
||||
/* ---------------- */
|
||||
if (parameters.force_rgb)
|
||||
@ -1207,7 +1385,6 @@ int main(int argc, char **argv)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -514,6 +514,7 @@ foreach(kdu_file ${kdu_j2k_conf_files})
|
||||
COMMAND opj_decompress
|
||||
-i ${INPUT_CONF}/${filenameInput}
|
||||
-o ${TEMP}/${filenameInput}.ppm
|
||||
-upsample
|
||||
)
|
||||
|
||||
if("${kdu_file}" STREQUAL "a6_mono_colr")
|
||||
|
Loading…
Reference in New Issue
Block a user