Commit e6674e46 authored by Stefano Sabatini's avatar Stefano Sabatini

lavu/imgutils: create misc functions for dealing with buffers

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()).
parent fd91a3ec
...@@ -15,6 +15,12 @@ libavutil: 2011-04-18 ...@@ -15,6 +15,12 @@ libavutil: 2011-04-18
API changes, most recent first: API changes, most recent first:
2012-06-26 - xxxxxxx - lavu 51.63.100 - imgutils.h
Add functions to libavutil/imgutils.h:
av_image_get_buffer_size()
av_image_fill_arrays()
av_image_copy_to_buffer()
2012-06-24 - xxxxxxx - lavu 51.62.100 - version.h 2012-06-24 - xxxxxxx - lavu 51.62.100 - version.h
version moved from avutil.h to version.h version moved from avutil.h to version.h
......
...@@ -4261,42 +4261,19 @@ int avpicture_alloc(AVPicture *picture, enum PixelFormat pix_fmt, int width, int ...@@ -4261,42 +4261,19 @@ int avpicture_alloc(AVPicture *picture, enum PixelFormat pix_fmt, int width, int
void avpicture_free(AVPicture *picture); void avpicture_free(AVPicture *picture);
/** /**
* Fill in the AVPicture fields. * Fill in the AVPicture fields, always assume a linesize alignment of
* The fields of the given AVPicture are filled in by using the 'ptr' address * 1.
* 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. * @see av_image_fill_arrays()
* 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.
*
* 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
*/ */
int avpicture_fill(AVPicture *picture, uint8_t *ptr, int avpicture_fill(AVPicture *picture, uint8_t *ptr,
enum PixelFormat pix_fmt, int width, int height); enum PixelFormat pix_fmt, int width, int height);
/** /**
* Copy pixel data from an AVPicture into a buffer. * Copy pixel data from an AVPicture into a buffer, always assume a
* The data is stored compactly, without any gaps for alignment or padding * linesize alignment of 1.
* which may be applied by avpicture_fill().
*
* @see avpicture_get_size()
* *
* @param[in] src AVPicture containing image data * @see av_image_copy_to_buffer()
* @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.
*/ */
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height, int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
unsigned char *dest, int dest_size); unsigned char *dest, int dest_size);
...@@ -4304,14 +4281,9 @@ int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, ...@@ -4304,14 +4281,9 @@ int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width,
/** /**
* Calculate the size in bytes that a picture of the given width and height * Calculate the size in bytes that a picture of the given width and height
* would occupy if stored in the given picture format. * would occupy if stored in the given picture format.
* Note that this returns the size of a compact representation as generated * Always assume a linesize alignment of 1.
* by avpicture_layout(), which can be smaller than the size required for e.g. *
* avpicture_fill(). * @see av_image_get_buffer_size().
*
* @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).
*/ */
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height); int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height);
......
...@@ -296,62 +296,21 @@ int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt) ...@@ -296,62 +296,21 @@ int ff_is_hwaccel_pix_fmt(enum PixelFormat pix_fmt)
int avpicture_fill(AVPicture *picture, uint8_t *ptr, int avpicture_fill(AVPicture *picture, uint8_t *ptr,
enum PixelFormat pix_fmt, int width, int height) enum PixelFormat pix_fmt, int width, int height)
{ {
int ret; return av_image_fill_arrays(picture->data, picture->linesize,
ptr, pix_fmt, width, height, 1);
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);
} }
int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height, int avpicture_layout(const AVPicture* src, enum PixelFormat pix_fmt, int width, int height,
unsigned char *dest, int dest_size) unsigned char *dest, int dest_size)
{ {
int i, j, nb_planes = 0, linesizes[4]; return av_image_copy_to_buffer(dest, dest_size,
const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; src->data, src->linesize,
int size = avpicture_get_size(pix_fmt, width, height); pix_fmt, width, height, 1);
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 & PIX_FMT_PAL) {
uint32_t *d32 = (unsigned char *)(((size_t)dest + 3) & ~3);
for (i = 0; i<256; i++)
AV_WL32(d32 + i, AV_RN32(src->data[1] + 4*i));
}
return size;
} }
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height) int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
{ {
AVPicture dummy_pict; return av_image_get_buffer_size(pix_fmt, width, height, 1);
if (av_image_check_size(width, height, 0, NULL) < 0)
return AVERROR(EINVAL);
if (av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_PSEUDOPAL)
// do not include palette for these pseudo-paletted formats
return width * height;
return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
} }
static int get_pix_fmt_depth(int *min, int *max, enum PixelFormat pix_fmt) static int get_pix_fmt_depth(int *min, int *max, enum PixelFormat pix_fmt)
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#define LIBAVCODEC_VERSION_MAJOR 54 #define LIBAVCODEC_VERSION_MAJOR 54
#define LIBAVCODEC_VERSION_MINOR 29 #define LIBAVCODEC_VERSION_MINOR 29
#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_MICRO 101
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \ LIBAVCODEC_VERSION_MINOR, \
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "imgutils.h" #include "imgutils.h"
#include "internal.h" #include "internal.h"
#include "intreadwrite.h"
#include "log.h" #include "log.h"
#include "pixdesc.h" #include "pixdesc.h"
...@@ -276,3 +277,73 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], ...@@ -276,3 +277,73 @@ 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 PixelFormat pix_fmt, int width, int height, int align)
{
int ret, i;
if ((ret = av_image_check_size(width, height, 0, NULL)) < 0)
return ret;
if ((ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width)) < 0)
return ret;
for (i = 0; i < 4; i++)
dst_linesize[i] = FFALIGN(dst_linesize[i], align);
if ((ret = av_image_fill_pointers(dst_data, pix_fmt, width, NULL, dst_linesize)) < 0)
return ret;
return av_image_fill_pointers(dst_data, pix_fmt, height, src, dst_linesize);
}
int av_image_get_buffer_size(enum PixelFormat pix_fmt, int width, int height, int align)
{
uint8_t *data[4];
int linesize[4];
if (av_image_check_size(width, height, 0, NULL) < 0)
return AVERROR(EINVAL);
if (av_pix_fmt_descriptors[pix_fmt].flags & PIX_FMT_PSEUDOPAL)
// do not include palette for these pseudo-paletted formats
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 PixelFormat pix_fmt, int width, int height, int align)
{
int i, j, nb_planes = 0, linesize[4];
const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
int size = av_image_get_buffer_size(pix_fmt, width, height, align);
if (size > dst_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(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 & PIX_FMT_PAL) {
uint32_t *d32 = (uint8_t *)(((size_t)dst + 3) & ~3);
for (i = 0; i<256; i++)
AV_WL32(d32 + i, AV_RN32(src_data[1] + 4*i));
}
return size;
}
...@@ -116,6 +116,65 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], ...@@ -116,6 +116,65 @@ void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4],
const uint8_t *src_data[4], const int src_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4],
enum PixelFormat pix_fmt, int width, int height); enum PixelFormat 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 * Check if the given dimension of an image is valid, meaning that all
* bytes of the image can be addressed with a signed int. * bytes of the image can be addressed with a signed int.
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
*/ */
#define LIBAVUTIL_VERSION_MAJOR 51 #define LIBAVUTIL_VERSION_MAJOR 51
#define LIBAVUTIL_VERSION_MINOR 62 #define LIBAVUTIL_VERSION_MINOR 63
#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment