diff --git a/doc/APIchanges b/doc/APIchanges index 4cdea9592131dcd33a0ac00511ba11012608a2f7..6d8ad740cd7ab817dfcc426c8944467bb639ef5f 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -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 diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index d9da2ad2e1d2d6974facc7058692d12e24fa3580..21a0ed90eb70501681c305760d954be19a41a5d3 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.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); diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c index e517812bbe47a1b5f4b5c1f6135e86a1534a0151..c038d893a64007959f71a907e43d3650bfbe845a 100644 --- a/libavcodec/imgconvert.c +++ b/libavcodec/imgconvert.c @@ -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) diff --git a/libavcodec/version.h b/libavcodec/version.h index d7508c432930e8909d6abca8134ccf2315fc13f0..bfc3b515cb6d4915cb86368cbc1338a0485272b3 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -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, \ diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index ef7d4138ae0213a1e42ba8fd92298383b5e9967e..8ef92a50e3f03462e1c8e5038b6fd5dc21c90724 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -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; +} diff --git a/libavutil/imgutils.h b/libavutil/imgutils.h index 9b53815fb66dd73d2581a8caef68bacd3ddbb9b3..3b1904bf3c06b6b333eb6d904d47056334efcb44 100644 --- a/libavutil/imgutils.h +++ b/libavutil/imgutils.h @@ -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. diff --git a/libavutil/version.h b/libavutil/version.h index 1e05844c1e54f1bf047a7929926faf25d3f3e09a..9a0ac897b6d89701835367f04e74d7997d16344d 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -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, \