[trunk] fixed component precision upscaling in opj_decompress (fixes issue 458)
authorMatthieu Darbois <mayeut@users.noreply.github.com>
Mon, 22 Dec 2014 15:50:32 +0000 (15:50 +0000)
committerMatthieu Darbois <mayeut@users.noreply.github.com>
Mon, 22 Dec 2014 15:50:32 +0000 (15:50 +0000)
src/bin/jp2/convert.c
tests/nonregression/md5refs.txt
tests/nonregression/test_suite.ctest.in

index d56f3904b9a9a3c87fa46cbfac809e63933ea276..7f4593b0f14b0bf279c3ce5161c56bee8bd82099 100644 (file)
@@ -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;
index 40043c08fac561151d7828cfca641682475dbbbe..eb04c0ba377a75468d04702f99e34d0efc665712 100644 (file)
@@ -175,3 +175,7 @@ d5ecef537edf294af83826763c0cf860  issue411-ycc422.jp2_1.pgx
 07480962d25b3d8cce18096648963c8a  issue411-ycc420.jp2_0.pgx
 149a69831b42401f20b8f7492ef99d97  issue411-ycc420.jp2_1.pgx
 ec8d1c99db9763a8ba489df4f41dda53  issue411-ycc420.jp2_2.pgx
+3c7ff2e4bdae849167be36589f32bcd5  issue458.jp2_0.pgx
+f004b48eafb2e52529cc9c7b6a3ff5d2  issue458.jp2_1.pgx
+3127bd0a591d113c3c2428c8d2c14ec8  issue458.jp2_2.pgx
+dacaf60e4c430916a8c2a9ebec32e71c  issue458.jp2_3.pgx
index 7f5d6f085ff554198b5601c986cfa36d6cb75d2a..0cd5387f8ae46fa69cbb971dd7151b031956678d 100644 (file)
@@ -258,6 +258,9 @@ opj_decompress -i @INPUT_NR_PATH@/issue411-ycc420.jp2 -o @TEMP_PATH@/issue411-yc
 !opj_decompress -i @INPUT_NR_PATH@/issue427-null-image-size.jp2 -o @TEMP_PATH@/issue427-null-image-size.jp2.pgx
 # issue 427 illegal tile offset
 !opj_decompress -i @INPUT_NR_PATH@/issue427-illegal-tile-offset.jp2 -o @TEMP_PATH@/issue427-illegal-tile-offset.jp2.pgx
+# issue 458 component precision upscaling
+opj_decompress -i @INPUT_NR_PATH@/issue458.jp2 -o @TEMP_PATH@/issue458.jp2.pgx
+
 
 # decode with specific area
 # prec=12; nb_c=1