summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthieu Darbois <mayeut@users.noreply.github.com>2014-12-22 15:50:32 +0000
committerMatthieu Darbois <mayeut@users.noreply.github.com>2014-12-22 15:50:32 +0000
commit59b844347c19c143e965ac767dc928a98c97fb17 (patch)
tree3e093e66ef9753aea35019be1ec26093d07ce0e9 /src
parentbde5ba6ae831424695e8b677a5e554e0b0275c20 (diff)
[trunk] fixed component precision upscaling in opj_decompress (fixes issue 458)
Diffstat (limited to 'src')
-rw-r--r--src/bin/jp2/convert.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/src/bin/jp2/convert.c b/src/bin/jp2/convert.c
index d56f3904..7f4593b0 100644
--- a/src/bin/jp2/convert.c
+++ b/src/bin/jp2/convert.c
@@ -102,43 +102,51 @@ void clip_component(opj_image_comp_t* component, OPJ_UINT32 precision)
}
/* Component precision scaling */
+static void scale_component_up(opj_image_comp_t* component, OPJ_UINT32 precision)
+{
+ OPJ_SIZE_T i, len;
+
+ len = (OPJ_SIZE_T)component->w * (OPJ_SIZE_T)component->h;
+ if (component->sgnd) {
+ OPJ_INT64 newMax = (1U << (precision - 1));
+ OPJ_INT64 oldMax = (1U << (component->prec - 1));
+ OPJ_INT32* l_data = component->data;
+ for (i = 0; i < len; ++i) {
+ l_data[i] = (OPJ_INT32)(((OPJ_INT64)l_data[i] * newMax) / oldMax);
+ }
+ } else {
+ OPJ_UINT64 newMax = (1U << precision) - 1U;
+ OPJ_UINT64 oldMax = (1U << component->prec) - 1U;
+ OPJ_UINT32* l_data = (OPJ_UINT32*)component->data;
+ for (i = 0; i < len; ++i) {
+ l_data[i] = (OPJ_UINT32)(((OPJ_UINT64)l_data[i] * newMax) / oldMax);
+ }
+ }
+ component->prec = precision;
+}
void scale_component(opj_image_comp_t* component, OPJ_UINT32 precision)
{
int shift;
- OPJ_SIZE_T i;
- OPJ_SIZE_T len;
+ OPJ_SIZE_T i, len;
if (component->prec == precision) {
return;
}
if (component->prec < precision) {
- shift = (int)(precision - component->prec);
- } else {
- shift = (int)(component->prec - precision);
+ scale_component_up(component, precision);
+ return;
}
+ shift = (int)(component->prec - precision);
len = (OPJ_SIZE_T)component->w * (OPJ_SIZE_T)component->h;
-
if (component->sgnd) {
OPJ_INT32* l_data = component->data;
- if (component->prec < precision) {
- for (i = 0; i < len; ++i) {
- l_data[i] <<= shift;
- }
- } else {
- for (i = 0; i < len; ++i) {
- l_data[i] >>= shift;
- }
+ for (i = 0; i < len; ++i) {
+ l_data[i] >>= shift;
}
} else {
OPJ_UINT32* l_data = (OPJ_UINT32*)component->data;
- if (component->prec < precision) {
- for (i = 0; i < len; ++i) {
- l_data[i] <<= shift;
- }
- } else {
- for (i = 0; i < len; ++i) {
- l_data[i] >>= shift;
- }
+ for (i = 0; i < len; ++i) {
+ l_data[i] >>= shift;
}
}
component->prec = precision;