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()).

A redundant check has been dropped from av_image_fill_arrays().

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
pull/101/merge
Stefano Sabatini 10 years ago committed by Vittorio Giovara
parent cf70ba37ba
commit e2ad0b66fa
  1. 4
      doc/APIchanges
  2. 47
      libavcodec/avcodec.h
  3. 58
      libavcodec/avpicture.c
  4. 81
      libavutil/imgutils.c
  5. 59
      libavutil/imgutils.h
  6. 2
      libavutil/version.h

@ -22,6 +22,10 @@ API changes, most recent first:
201x-xx-xx - xxxxxxx - lavc 56.8.0 - avcodec.h 201x-xx-xx - xxxxxxx - lavc 56.8.0 - avcodec.h
Add AVCodecContext.sw_pix_fmt. 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 2014-11-xx - xxxxxxx - lavf 56.06.3 - avformat.h
Add AVFormatContext.avoid_negative_ts. Add AVFormatContext.avoid_negative_ts.

@ -4072,42 +4072,18 @@ int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, i
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 1.
* 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 * @see av_image_fill_arrays().
* 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
*/ */
int avpicture_fill(AVPicture *picture, uint8_t *ptr, int avpicture_fill(AVPicture *picture, uint8_t *ptr,
enum AVPixelFormat pix_fmt, int width, int height); enum AVPixelFormat 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 AVPixelFormat pix_fmt, int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt,
int width, int height, 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 * 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 AVPixelFormat pix_fmt, int width, int height); int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height);

@ -34,68 +34,22 @@
int avpicture_fill(AVPicture *picture, uint8_t *ptr, int avpicture_fill(AVPicture *picture, uint8_t *ptr,
enum AVPixelFormat pix_fmt, int width, int height) enum AVPixelFormat 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 AVPixelFormat pix_fmt, int avpicture_layout(const AVPicture* src, enum AVPixelFormat pix_fmt,
int width, int height, 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_desc_get(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 & AV_PIX_FMT_FLAG_PAL)
memcpy((unsigned char *)(((size_t)dest + 3) & ~3),
src->data[1], 256 * 4);
return size;
} }
int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height) int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
{ {
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt); return av_image_get_buffer_size(pix_fmt, width, height, 1);
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);
} }
int avpicture_alloc(AVPicture *picture, int avpicture_alloc(AVPicture *picture,

@ -24,6 +24,7 @@
#include "common.h" #include "common.h"
#include "imgutils.h" #include "imgutils.h"
#include "internal.h" #include "internal.h"
#include "intreadwrite.h"
#include "log.h" #include "log.h"
#include "mathematics.h" #include "mathematics.h"
#include "pixdesc.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;
}

@ -117,6 +117,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 AVPixelFormat pix_fmt, int width, int height); 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 * 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.

@ -54,7 +54,7 @@
*/ */
#define LIBAVUTIL_VERSION_MAJOR 54 #define LIBAVUTIL_VERSION_MAJOR 54
#define LIBAVUTIL_VERSION_MINOR 5 #define LIBAVUTIL_VERSION_MINOR 6
#define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_MICRO 0
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \

Loading…
Cancel
Save