Merge branch 'pr1107'
[openjpeg.git] / src / lib / openjp2 / dwt.c
index 18270045ff49145588a23d0446a5762503cdae0e..203684d480ae486a2366c7c72e479b53a86de0c8 100644 (file)
@@ -216,6 +216,8 @@ static void opj_v4dwt_decode_step2(opj_v4_t* l, opj_v4_t* w,
 /* <summary>                                                              */
 /* This table contains the norms of the 5-3 wavelets for different bands. */
 /* </summary>                                                             */
+/* FIXME! the array should really be extended up to 33 resolution levels */
+/* See https://github.com/uclouvain/openjpeg/issues/493 */
 static const OPJ_FLOAT64 opj_dwt_norms[4][10] = {
     {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3},
     {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9},
@@ -226,6 +228,8 @@ static const OPJ_FLOAT64 opj_dwt_norms[4][10] = {
 /* <summary>                                                              */
 /* This table contains the norms of the 9-7 wavelets for different bands. */
 /* </summary>                                                             */
+/* FIXME! the array should really be extended up to 33 resolution levels */
+/* See https://github.com/uclouvain/openjpeg/issues/493 */
 static const OPJ_FLOAT64 opj_dwt_norms_real[4][10] = {
     {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
     {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
@@ -970,7 +974,7 @@ static void opj_idwt53_v(const opj_dwt_t *dwt,
 #if (defined(__SSE2__) || defined(__AVX2__))
         if (len > 1 && nb_cols == PARALLEL_COLS_53) {
             /* Same as below general case, except that thanks to SSE2/AVX2 */
-            /* we can efficently process 8/16 columns in parallel */
+            /* we can efficiently process 8/16 columns in parallel */
             opj_idwt53_v_cas0_mcols_SSE2_OR_AVX2(dwt->mem, sn, len, tiledp_col, stride);
             return;
         }
@@ -1013,7 +1017,7 @@ static void opj_idwt53_v(const opj_dwt_t *dwt,
 #if (defined(__SSE2__) || defined(__AVX2__))
         if (len > 2 && nb_cols == PARALLEL_COLS_53) {
             /* Same as below general case, except that thanks to SSE2/AVX2 */
-            /* we can efficently process 8/16 columns in parallel */
+            /* we can efficiently process 8/16 columns in parallel */
             opj_idwt53_v_cas1_mcols_SSE2_OR_AVX2(dwt->mem, sn, len, tiledp_col, stride);
             return;
         }
@@ -1229,6 +1233,14 @@ OPJ_UINT32 opj_dwt_getgain(OPJ_UINT32 orient)
 /* </summary>               */
 OPJ_FLOAT64 opj_dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient)
 {
+    /* FIXME ! This is just a band-aid to avoid a buffer overflow */
+    /* but the array should really be extended up to 33 resolution levels */
+    /* See https://github.com/uclouvain/openjpeg/issues/493 */
+    if (orient == 0 && level >= 10) {
+        level = 9;
+    } else if (orient > 0 && level >= 9) {
+        level = 8;
+    }
     return opj_dwt_norms[orient][level];
 }
 
@@ -1254,6 +1266,14 @@ OPJ_UINT32 opj_dwt_getgain_real(OPJ_UINT32 orient)
 /* </summary>               */
 OPJ_FLOAT64 opj_dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient)
 {
+    /* FIXME ! This is just a band-aid to avoid a buffer overflow */
+    /* but the array should really be extended up to 33 resolution levels */
+    /* See https://github.com/uclouvain/openjpeg/issues/493 */
+    if (orient == 0 && level >= 10) {
+        level = 9;
+    } else if (orient > 0 && level >= 9) {
+        level = 8;
+    }
     return opj_dwt_norms_real[orient][level];
 }
 
@@ -1931,7 +1951,14 @@ static OPJ_BOOL opj_dwt_decode_partial_tile(
     OPJ_UINT32 win_tcx1 = tilec->win_x1;
     OPJ_UINT32 win_tcy1 = tilec->win_y1;
 
+    if (tr_max->x0 == tr_max->x1 || tr_max->y0 == tr_max->y1) {
+        return OPJ_TRUE;
+    }
+
     sa = opj_dwt_init_sparse_array(tilec, numres);
+    if (sa == NULL) {
+        return OPJ_FALSE;
+    }
 
     if (numres == 1U) {
         OPJ_BOOL ret = opj_sparse_array_int32_read(sa,
@@ -2014,7 +2041,7 @@ static OPJ_BOOL opj_dwt_decode_partial_tile(
         tr_hl_x0 = (OPJ_UINT32)tr->bands[0].x0;
         tr_lh_y0 = (OPJ_UINT32)tr->bands[1].y0;
 
-        /* Substract the origin of the bands for this tile, to the subwindow */
+        /* Subtract the origin of the bands for this tile, to the subwindow */
         /* of interest band coordinates, so as to get them relative to the */
         /* tile */
         win_ll_x0 = opj_uint_subs(win_ll_x0, tr_ll_x0);
@@ -2641,7 +2668,14 @@ OPJ_BOOL opj_dwt_decode_partial_97(opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
     OPJ_UINT32 win_tcx1 = tilec->win_x1;
     OPJ_UINT32 win_tcy1 = tilec->win_y1;
 
+    if (tr_max->x0 == tr_max->x1 || tr_max->y0 == tr_max->y1) {
+        return OPJ_TRUE;
+    }
+
     sa = opj_dwt_init_sparse_array(tilec, numres);
+    if (sa == NULL) {
+        return OPJ_FALSE;
+    }
 
     if (numres == 1U) {
         OPJ_BOOL ret = opj_sparse_array_int32_read(sa,
@@ -2725,7 +2759,7 @@ OPJ_BOOL opj_dwt_decode_partial_97(opj_tcd_tilecomp_t* OPJ_RESTRICT tilec,
         tr_hl_x0 = (OPJ_UINT32)tr->bands[0].x0;
         tr_lh_y0 = (OPJ_UINT32)tr->bands[1].y0;
 
-        /* Substract the origin of the bands for this tile, to the subwindow */
+        /* Subtract the origin of the bands for this tile, to the subwindow */
         /* of interest band coordinates, so as to get them relative to the */
         /* tile */
         win_ll_x0 = opj_uint_subs(win_ll_x0, tr_ll_x0);