opj_j2k_update_image_data(): avoid allocating image buffer if we can just reuse the...
authorEven Rouault <even.rouault@spatialys.com>
Fri, 1 Sep 2017 19:36:35 +0000 (21:36 +0200)
committerEven Rouault <even.rouault@spatialys.com>
Fri, 1 Sep 2017 20:23:29 +0000 (22:23 +0200)
src/lib/openjp2/j2k.c
src/lib/openjp2/tcd.c

index 8fb56e37d4dc8aa5504b9e34cdd2f36e0409af5e..8e4b39666507e9c27b09f0edb75c8baccabcbffe 100644 (file)
@@ -8922,30 +8922,11 @@ static OPJ_BOOL opj_j2k_update_image_data(opj_tcd_t * p_tcd,
 
     l_img_comp_dest = p_output_image->comps;
 
-    for (i = 0; i < l_image_src->numcomps; i++) {
+    for (i = 0; i < l_image_src->numcomps;
+            i++, ++l_img_comp_dest, ++l_img_comp_src,  ++l_tilec) {
         OPJ_INT32 res_x0, res_x1, res_y0, res_y1;
         OPJ_UINT32 src_data_stride;
         const OPJ_INT32* p_src_data;
-        OPJ_BOOL check_if_must_memset = OPJ_FALSE;
-
-        /* Allocate output component buffer if necessary */
-        if (!l_img_comp_dest->data) {
-            OPJ_SIZE_T l_width = l_img_comp_dest->w;
-            OPJ_SIZE_T l_height = l_img_comp_dest->h;
-
-            if ((l_height == 0U) || (l_width > (SIZE_MAX / l_height)) ||
-                    l_width * l_height > SIZE_MAX / sizeof(OPJ_INT32)) {
-                /* would overflow */
-                return OPJ_FALSE;
-            }
-            l_img_comp_dest->data = (OPJ_INT32*) opj_image_data_alloc(l_width * l_height *
-                                    sizeof(OPJ_INT32));
-            if (! l_img_comp_dest->data) {
-                return OPJ_FALSE;
-            }
-
-            check_if_must_memset = OPJ_TRUE;
-        }
 
         /* Copy info from decoded comp image to output image */
         l_img_comp_dest->resno_decoded = l_img_comp_src->resno_decoded;
@@ -9062,12 +9043,6 @@ static OPJ_BOOL opj_j2k_update_image_data(opj_tcd_t * p_tcd,
         }
         /*-----*/
 
-        if (check_if_must_memset && (l_img_comp_dest->w != l_width_dest ||
-                                     l_img_comp_dest->h != l_height_dest)) {
-            memset(l_img_comp_dest->data, 0,
-                   (OPJ_SIZE_T)l_img_comp_dest->w * l_img_comp_dest->h * sizeof(OPJ_INT32));
-        }
-
         /* Compute the input buffer offset */
         l_start_offset_src = (OPJ_SIZE_T)l_offset_x0_src + (OPJ_SIZE_T)l_offset_y0_src
                              * (OPJ_SIZE_T)src_data_stride;
@@ -9076,6 +9051,43 @@ static OPJ_BOOL opj_j2k_update_image_data(opj_tcd_t * p_tcd,
         l_start_offset_dest = (OPJ_SIZE_T)l_start_x_dest + (OPJ_SIZE_T)l_start_y_dest
                               * (OPJ_SIZE_T)l_img_comp_dest->w;
 
+        /* Allocate output component buffer if necessary */
+        if (l_img_comp_dest->data == NULL &&
+                l_start_offset_src == 0 && l_start_offset_dest == 0 &&
+                l_width_dest == l_img_comp_dest->w &&
+                l_height_dest == l_img_comp_dest->h) {
+            /* If the final image matches the tile buffer, then borrow it */
+            /* directly to save a copy */
+            if (p_tcd->whole_tile_decoding) {
+                l_img_comp_dest->data = l_tilec->data;
+                l_tilec->data = NULL;
+            } else {
+                l_img_comp_dest->data = l_tilec->data_win;
+                l_tilec->data_win = NULL;
+            }
+            continue;
+        } else if (l_img_comp_dest->data == NULL) {
+            OPJ_SIZE_T l_width = l_img_comp_dest->w;
+            OPJ_SIZE_T l_height = l_img_comp_dest->h;
+
+            if ((l_height == 0U) || (l_width > (SIZE_MAX / l_height)) ||
+                    l_width * l_height > SIZE_MAX / sizeof(OPJ_INT32)) {
+                /* would overflow */
+                return OPJ_FALSE;
+            }
+            l_img_comp_dest->data = (OPJ_INT32*) opj_image_data_alloc(l_width * l_height *
+                                    sizeof(OPJ_INT32));
+            if (! l_img_comp_dest->data) {
+                return OPJ_FALSE;
+            }
+
+            if (l_img_comp_dest->w != l_width_dest ||
+                    l_img_comp_dest->h != l_height_dest) {
+                memset(l_img_comp_dest->data, 0,
+                       (OPJ_SIZE_T)l_img_comp_dest->w * l_img_comp_dest->h * sizeof(OPJ_INT32));
+            }
+        }
+
         /* Move the output buffer to the first place where we will write*/
         l_dest_ptr = l_img_comp_dest->data + l_start_offset_dest;
 
@@ -9090,9 +9102,7 @@ static OPJ_BOOL opj_j2k_update_image_data(opj_tcd_t * p_tcd,
             }
         }
 
-        ++l_img_comp_dest;
-        ++l_img_comp_src;
-        ++l_tilec;
+
     }
 
     return OPJ_TRUE;
index 0ec85891c75201cda25e4d4a783d31ce1f71cf8a..bd5d49603b70d24fa4c5a2dca6440505cd01c726 100644 (file)
@@ -832,7 +832,7 @@ static INLINE OPJ_BOOL opj_tcd_init_tile(opj_tcd_t *p_tcd, OPJ_UINT32 p_tile_no,
         l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(
                           opj_tcd_resolution_t);
 
-        opj_aligned_free(l_tilec->data_win);
+        opj_image_data_free(l_tilec->data_win);
         l_tilec->data_win = NULL;
         l_tilec->win_x0 = 0;
         l_tilec->win_y0 = 0;
@@ -1581,7 +1581,7 @@ OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *p_tcd,
             size_t h = res->win_y1 - res->win_y0;
             size_t l_data_size;
 
-            opj_aligned_free(tilec->data_win);
+            opj_image_data_free(tilec->data_win);
             tilec->data_win = NULL;
 
             if (w > 0 && h > 0) {
@@ -1598,7 +1598,7 @@ OPJ_BOOL opj_tcd_decode_tile(opj_tcd_t *p_tcd,
                 }
                 l_data_size *= sizeof(OPJ_INT32);
 
-                tilec->data_win = opj_aligned_malloc(l_data_size);
+                tilec->data_win = opj_image_data_alloc(l_data_size);
                 if (tilec->data_win == NULL) {
                     opj_event_msg(p_manager, EVT_ERROR,
                                   "Size of tile data exceeds system limits\n");
@@ -1833,7 +1833,7 @@ static void opj_tcd_free_tile(opj_tcd_t *p_tcd)
             l_tile_comp->data_size_needed = 0;
         }
 
-        opj_aligned_free(l_tile_comp->data_win);
+        opj_image_data_free(l_tile_comp->data_win);
 
         ++l_tile_comp;
     }