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()).
pull/59/head
Stefano Sabatini 13 years ago
parent fd91a3ec44
commit e6674e46ec
  1. 6
      doc/APIchanges
  2. 48
      libavcodec/avcodec.h
  3. 53
      libavcodec/imgconvert.c
  4. 2
      libavcodec/version.h
  5. 71
      libavutil/imgutils.c
  6. 59
      libavutil/imgutils.h
  7. 2
      libavutil/version.h

@ -15,6 +15,12 @@ libavutil: 2011-04-18
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
version moved from avutil.h to version.h

@ -4261,42 +4261,19 @@ int avpicture_alloc(AVPicture *picture, enum PixelFormat pix_fmt, int width, int
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.
*
* 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
* Fill in the AVPicture fields, always assume a linesize alignment of
* 1.
*
* @see av_image_fill_arrays()
*/
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
enum PixelFormat 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 PixelFormat pix_fmt, int width, int height,
unsigned char *dest, int dest_size);
@ -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
* 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().
*
* @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).
* Always assume a linesize alignment of 1.
*
* @see av_image_get_buffer_size().
*/
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)
int avpicture_fill(AVPicture *picture, uint8_t *ptr,
enum PixelFormat 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 PixelFormat 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_descriptors[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 & 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;
return av_image_copy_to_buffer(dest, dest_size,
src->data, src->linesize,
pix_fmt, width, height, 1);
}
int avpicture_get_size(enum PixelFormat pix_fmt, int width, int height)
{
AVPicture dummy_pict;
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);
return av_image_get_buffer_size(pix_fmt, width, height, 1);
}
static int get_pix_fmt_depth(int *min, int *max, enum PixelFormat pix_fmt)

@ -28,7 +28,7 @@
#define LIBAVCODEC_VERSION_MAJOR 54
#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, \
LIBAVCODEC_VERSION_MINOR, \

@ -23,6 +23,7 @@
#include "imgutils.h"
#include "internal.h"
#include "intreadwrite.h"
#include "log.h"
#include "pixdesc.h"
@ -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],
const uint8_t *src_data[4], const int src_linesizes[4],
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
* bytes of the image can be addressed with a signed int.

@ -31,7 +31,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 51
#define LIBAVUTIL_VERSION_MINOR 62
#define LIBAVUTIL_VERSION_MINOR 63
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \

Loading…
Cancel
Save