[vlc-commits] picture: inline AllocatePicture() and use overflow helpers

Rémi Denis-Courmont git at videolan.org
Sun Feb 11 09:17:11 CET 2018


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Feb 10 21:08:26 2018 +0200| [8f5352c1182f16e88c88c87e84c4f4e37878e43e] | committer: Rémi Denis-Courmont

picture: inline AllocatePicture() and use overflow helpers

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8f5352c1182f16e88c88c87e84c4f4e37878e43e
---

 src/misc/picture.c | 79 +++++++++++++++++++++---------------------------------
 1 file changed, 31 insertions(+), 48 deletions(-)

diff --git a/src/misc/picture.c b/src/misc/picture.c
index 678ab7b535..8af4b250f9 100644
--- a/src/misc/picture.c
+++ b/src/misc/picture.c
@@ -39,48 +39,6 @@
 #include <vlc_image.h>
 #include <vlc_block.h>
 
-#define PICTURE_SW_SIZE_MAX (1<<28) /* 256MB: 8K * 8K * 4*/
-
-/**
- * Allocate a new picture in the heap.
- *
- * This function allocates a fake direct buffer in memory, which can be
- * used exactly like a video buffer. The video output thread then manages
- * how it gets displayed.
- */
-static int AllocatePicture( picture_t *p_pic )
-{
-    /* Calculate how big the new image should be */
-    size_t i_bytes = 0;
-    for( int i = 0; i < p_pic->i_planes; i++ )
-    {
-        const plane_t *p = &p_pic->p[i];
-
-        if( (size_t)p->i_pitch > (SIZE_MAX - i_bytes)/p->i_lines )
-            return VLC_ENOMEM;
-        i_bytes += p->i_pitch * p->i_lines;
-    }
-
-    if( i_bytes >= PICTURE_SW_SIZE_MAX )
-        return VLC_ENOMEM;
-
-    uint8_t *p_data = aligned_alloc( 16, i_bytes );
-    if( i_bytes > 0 && p_data == NULL )
-        return VLC_EGENERIC;
-
-    /* Fill the p_pixels field for each plane */
-    p_pic->p[0].p_pixels = p_data;
-    for( int i = 1; i < p_pic->i_planes; i++ )
-        p_pic->p[i].p_pixels = &p_pic->p[i-1].p_pixels[ p_pic->p[i-1].i_lines *
-                                                        p_pic->p[i-1].i_pitch ];
-
-    return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- *
- *****************************************************************************/
-
 static void PictureDestroyContext( picture_t *p_picture )
 {
     picture_context_t *ctx = p_picture->context;
@@ -102,8 +60,7 @@ static void picture_DestroyFromResource( picture_t *p_picture )
 }
 
 /**
- * Destroys a picture allocated with picture_NewFromFormat()
- * (and thus AllocatePicture()).
+ * Destroys a picture allocated with picture_NewFromFormat().
  */
 static void picture_Destroy( picture_t *p_picture )
 {
@@ -285,6 +242,8 @@ picture_t *picture_NewFromResource( const video_format_t *p_fmt, const picture_r
     return p_picture;
 }
 
+#define PICTURE_SW_SIZE_MAX (UINT32_C(1) << 28) /* 256MB: 8K * 8K * 4*/
+
 picture_t *picture_NewFromFormat(const video_format_t *restrict fmt)
 {
     picture_priv_t *priv = picture_NewPrivate(fmt);
@@ -293,14 +252,38 @@ picture_t *picture_NewFromFormat(const video_format_t *restrict fmt)
 
     picture_t *pic = &priv->picture;
 
-    if( AllocatePicture( pic ) )
+    /* Calculate how big the new image should be */
+    size_t plane_sizes[PICTURE_PLANE_MAX];
+    size_t pic_size = 0;
+
+    for (int i = 0; i < pic->i_planes; i++)
     {
-        free( pic );
-        return NULL;
+        const plane_t *p = &pic->p[i];
+
+        if (unlikely(mul_overflow(p->i_pitch, p->i_lines, &plane_sizes[i]))
+         || unlikely(add_overflow(pic_size, plane_sizes[i], &pic_size)))
+            goto error;
     }
-    priv->gc.destroy = picture_Destroy;
 
+    if (unlikely(pic_size >= PICTURE_SW_SIZE_MAX))
+        goto error;
+
+    uint8_t *buf = aligned_alloc(16, pic_size);
+    if (unlikely(pic_size > 0 && buf == NULL))
+        goto error;
+
+    /* Fill the p_pixels field for each plane */
+    for (int i = 0; i < pic->i_planes; i++)
+    {
+        pic->p[i].p_pixels = buf;
+        buf += plane_sizes[i];
+    }
+
+    priv->gc.destroy = picture_Destroy;
     return pic;
+error:
+    free(pic);
+    return NULL;
 }
 
 picture_t *picture_New( vlc_fourcc_t i_chroma, int i_width, int i_height, int i_sar_num, int i_sar_den )



More information about the vlc-commits mailing list