imgutils: create misc functions for dealing with buffers
authorStefano Sabatini <stefasab@gmail.com>
Wed, 10 Dec 2014 12:20:49 +0000 (12:20 +0000)
committerVittorio Giovara <vittorio.giovara@gmail.com>
Wed, 14 Jan 2015 16:17:24 +0000 (17:17 +0100)
Move the lavc/imgconvert functions and rename them as follows:
  avpicture_get_size -> av_image_get_buffer_size()
  avpicture_fill     -> av_image_fill_arrays()
  avpicture_layout   -> av_image_copy_to_buffer()

The new functions have an align parameter, which allows to define the
linesize alignment assumed in the buffer (which is set or read).

The names of the functions are consistent with the lavu/samples API
(av_samples_get_buffer_size(), av_samples_fill_arrays()).

A redundant check has been dropped from av_image_fill_arrays().

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
doc/APIchanges
libavcodec/avcodec.h
libavcodec/avpicture.c
libavutil/imgutils.c
libavutil/imgutils.h
libavutil/version.h

index fce42e3..e1bf415 100644 (file)
@@ -22,6 +22,10 @@ API changes, most recent first:
 201x-xx-xx - xxxxxxx - lavc 56.8.0 - avcodec.h
   Add AVCodecContext.sw_pix_fmt.
 
+2014-11-xx - xxxxxxx - lavu 54.6.0 - imgutils.h
+  Add utility functions for image manipulation: av_image_get_buffer_size()
+  av_image_fill_arrays() and av_image_copy_to_buffer().
+
 2014-11-xx - xxxxxxx - lavf 56.06.3 - avformat.h
   Add AVFormatContext.avoid_negative_ts.
 
index 8a008c9..025f119 100644 (file)
@@ -4072,42 +4072,18 @@ int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, i
 void avpicture_free(AVPicture *picture);
 
 /**
- * Fill in the AVPicture fields.
- * The fields of the given AVPicture are filled in by using the 'ptr' address
- * which points to the image data buffer. Depending on the specified picture
- * format, one or multiple image data pointers and line sizes will be set.
- * If a planar format is specified, several pointers will be set pointing to
- * the different picture planes and the line sizes of the different planes
- * will be stored in the lines_sizes array.
- * Call with ptr == NULL to get the required size for the ptr buffer.
+ * Fill in the AVPicture fields, always assume a linesize alignment of 1.
  *
- * To allocate the buffer and fill in the AVPicture fields in one call,
- * use avpicture_alloc().
- *
- * @param picture AVPicture whose fields are to be filled in
- * @param ptr Buffer which will contain or contains the actual image data
- * @param pix_fmt The format in which the picture data is stored.
- * @param width the width of the image in pixels
- * @param height the height of the image in pixels
- * @return size of the image data in bytes
+ * @see av_image_fill_arrays().
  */
 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
                    enum AVPixelFormat pix_fmt, int width, int height);
 
 /**
- * Copy pixel data from an AVPicture into a buffer.
- * The data is stored compactly, without any gaps for alignment or padding
- * which may be applied by avpicture_fill().
- *
- * @see avpicture_get_size()
+ * Copy pixel data from an AVPicture into a buffer, always assume a
+ * linesize alignment of 1.
  *
- * @param[in] src AVPicture containing image data
- * @param[in] pix_fmt The format in which the picture data is stored.
- * @param[in] width the width of the image in pixels.
- * @param[in] height the height of the image in pixels.
- * @param[out] dest A buffer into which picture data will be copied.
- * @param[in] dest_size The size of 'dest'.
- * @return The number of bytes written to dest, or a negative value (error code) on error.
+ * @see av_image_copy_to_buffer().
  */
 int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt,
                      int width, int height,
@@ -4116,14 +4092,9 @@ int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt,
 /**
  * Calculate the size in bytes that a picture of the given width and height
  * would occupy if stored in the given picture format.
- * Note that this returns the size of a compact representation as generated
- * by avpicture_layout(), which can be smaller than the size required for e.g.
- * avpicture_fill().
+ * Always assume a linesize alignment of 1.
  *
- * @param pix_fmt the given picture format
- * @param width the width of the image
- * @param height the height of the image
- * @return Image data size in bytes or -1 on error (e.g. too large dimensions).
+ * @see av_image_get_buffer_size().
  */
 int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height);
 
index a50bbc4..6bde0f8 100644 (file)
 int avpicture_fill(AVPicture *picture, uint8_t *ptr,
                    enum AVPixelFormat pix_fmt, int width, int height)
 {
-    int ret;
-
-    if ((ret = av_image_check_size(width, height, 0, NULL)) < 0)
-        return ret;
-
-    if ((ret = av_image_fill_linesizes(picture->linesize, pix_fmt, width)) < 0)
-        return ret;
-
-    return av_image_fill_pointers(picture->data, pix_fmt,
-                                  height, ptr, picture->linesize);
+    return av_image_fill_arrays(picture->data, picture->linesize,
+                                ptr, pix_fmt, width, height, 1);
 }
 
 int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt,
                      int width, int height,
                      unsigned char *dest, int dest_size)
 {
-    int i, j, nb_planes = 0, linesizes[4];
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
-    int size = avpicture_get_size(pix_fmt, width, height);
-
-    if (size > dest_size || size < 0)
-        return AVERROR(EINVAL);
-
-    for (i = 0; i < desc->nb_components; i++)
-        nb_planes = FFMAX(desc->comp[i].plane, nb_planes);
-
-    nb_planes++;
-
-    av_image_fill_linesizes(linesizes, pix_fmt, width);
-    for (i = 0; i < nb_planes; i++) {
-        int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
-        const unsigned char *s = src->data[i];
-        h = (height + (1 << shift) - 1) >> shift;
-
-        for (j = 0; j < h; j++) {
-            memcpy(dest, s, linesizes[i]);
-            dest += linesizes[i];
-            s += src->linesize[i];
-        }
-    }
-
-    if (desc->flags & AV_PIX_FMT_FLAG_PAL)
-        memcpy((unsigned char *)(((size_t)dest + 3) & ~3),
-               src->data[1], 256 * 4);
-
-    return size;
+    return av_image_copy_to_buffer(dest, dest_size,
+                                   src->data, src->linesize,
+                                   pix_fmt, width, height, 1);
 }
 
 int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
 {
-    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
-    AVPicture dummy_pict;
-    int ret;
-
-    if (!desc)
-        return AVERROR(EINVAL);
-    if ((ret = av_image_check_size(width, height, 0, NULL)) < 0)
-        return ret;
-    if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
-        // do not include palette for these pseudo-paletted formats
-        return width * height;
-    return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
+    return av_image_get_buffer_size(pix_fmt, width, height, 1);
 }
 
 int avpicture_alloc(AVPicture *picture,
index fc367d9..948a6f7 100644 (file)
@@ -24,6 +24,7 @@
 #include "common.h"
 #include "imgutils.h"
 #include "internal.h"
+#include "intreadwrite.h"
 #include "log.h"
 #include "mathematics.h"
 #include "pixdesc.h"
@@ -298,3 +299,83 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
         }
     }
 }
+
+int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
+                         const uint8_t *src, enum AVPixelFormat pix_fmt,
+                         int width, int height, int align)
+{
+    int ret, i;
+
+    ret = av_image_check_size(width, height, 0, NULL);
+    if (ret < 0)
+        return ret;
+
+    ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width);
+    if (ret < 0)
+        return ret;
+
+    for (i = 0; i < 4; i++)
+        dst_linesize[i] = FFALIGN(dst_linesize[i], align);
+
+    return av_image_fill_pointers(dst_data, pix_fmt, height, src, dst_linesize);
+}
+
+int av_image_get_buffer_size(enum AVPixelFormat pix_fmt,
+                             int width, int height, int align)
+{
+    uint8_t *data[4];
+    int linesize[4];
+    int ret;
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+    if (!desc)
+        return AVERROR_BUG;
+
+    ret = av_image_check_size(width, height, 0, NULL);
+    if (ret < 0)
+        return ret;
+
+    // do not include palette for these pseudo-paletted formats
+    if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
+        return width * height;
+
+    return av_image_fill_arrays(data, linesize, NULL, pix_fmt,
+                                width, height, align);
+}
+
+int av_image_copy_to_buffer(uint8_t *dst, int dst_size,
+                            const uint8_t * const src_data[4],
+                            const int src_linesize[4],
+                            enum AVPixelFormat pix_fmt,
+                            int width, int height, int align)
+{
+    int i, j, nb_planes = 0, linesize[4];
+    int size = av_image_get_buffer_size(pix_fmt, width, height, align);
+    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+
+    if (size > dst_size || size < 0 || !desc)
+        return AVERROR(EINVAL);
+
+    for (i = 0; i < desc->nb_components; i++)
+        nb_planes = FFMAX(desc->comp[i].plane, nb_planes);
+
+    nb_planes++;
+
+    av_image_fill_linesizes(linesize, pix_fmt, width);
+    for (i = 0; i < nb_planes; i++) {
+        int h, shift = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
+        const uint8_t *src = src_data[i];
+        h = (height + (1 << shift) - 1) >> shift;
+
+        for (j = 0; j < h; j++) {
+            memcpy(dst, src, linesize[i]);
+            dst += FFALIGN(linesize[i], align);
+            src += src_linesize[i];
+        }
+    }
+
+    if (desc->flags & AV_PIX_FMT_FLAG_PAL)
+        memcpy((unsigned char *)(((size_t)dst + 3) & ~3),
+               src_data[1], 256 * 4);
+
+    return size;
+}
index 50fa815..efb4eb2 100644 (file)
@@ -118,6 +118,65 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
                    enum AVPixelFormat pix_fmt, int width, int height);
 
 /**
+ * Setup the data pointers and linesizes based on the specified image
+ * parameters and the provided array.
+ *
+ * The fields of the given image are filled in by using the src
+ * address which points to the image data buffer. Depending on the
+ * specified pixel format, one or multiple image data pointers and
+ * line sizes will be set.  If a planar format is specified, several
+ * pointers will be set pointing to the different picture planes and
+ * the line sizes of the different planes will be stored in the
+ * lines_sizes array. Call with src == NULL to get the required
+ * size for the src buffer.
+ *
+ * To allocate the buffer and fill in the dst_data and dst_linesize in
+ * one call, use av_image_alloc().
+ *
+ * @param dst_data      data pointers to be filled in
+ * @param dst_linesizes linesizes for the image in dst_data to be filled in
+ * @param src           buffer which will contain or contains the actual image data, can be NULL
+ * @param pix_fmt       the pixel format of the image
+ * @param width         the width of the image in pixels
+ * @param height        the height of the image in pixels
+ * @param align         the value used in src for linesize alignment
+ * @return the size in bytes required for src, a negative error code
+ * in case of failure
+ */
+int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],
+                         const uint8_t *src,
+                         enum PixelFormat pix_fmt, int width, int height, int align);
+
+/**
+ * Return the size in bytes of the amount of data required to store an
+ * image with the given parameters.
+ *
+ * @param[in] align the assumed linesize alignment
+ */
+int av_image_get_buffer_size(enum PixelFormat pix_fmt, int width, int height, int align);
+
+/**
+ * Copy image data from an image into a buffer.
+ *
+ * av_image_get_buffer_size() can be used to compute the required size
+ * for the buffer to fill.
+ *
+ * @param dst           a buffer into which picture data will be copied
+ * @param dst_size      the size in bytes of dst
+ * @param src_data      pointers containing the source image data
+ * @param src_linesizes linesizes for the image in src_data
+ * @param pix_fmt       the pixel format of the source image
+ * @param width         the width of the source image in pixels
+ * @param height        the height of the source image in pixels
+ * @param align         the assumed linesize alignment for dst
+ * @return the number of bytes written to dst, or a negative value
+ * (error code) on error
+ */
+int av_image_copy_to_buffer(uint8_t *dst, int dst_size,
+                            const uint8_t * const src_data[4], const int src_linesize[4],
+                            enum PixelFormat pix_fmt, int width, int height, int align);
+
+/**
  * Check if the given dimension of an image is valid, meaning that all
  * bytes of the image can be addressed with a signed int.
  *
index b40009e..215ecb2 100644 (file)
@@ -54,7 +54,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR 54
-#define LIBAVUTIL_VERSION_MINOR  5
+#define LIBAVUTIL_VERSION_MINOR  6
 #define LIBAVUTIL_VERSION_MICRO  0
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \