[FFmpeg-devel] Adding costume image file format support

Paul B Mahol onemda at gmail.com
Mon Feb 25 18:18:44 CET 2013


On 2/25/13, Yuntao Ou <cktao.g at gmail.com> wrote:
> I have figure out the patch. Here it is.
>
> Thanks again.
>
>

The patch have changes that are should not be part of patch.

> From 98a765847f7d576a619bb121f5a1ee04f36f4a85 Mon Sep 17 00:00:00 2001
> From: Owen-PC <owuntu at ubuntu.(none)>
> Date: Sun, 24 Feb 2013 23:30:28 -0700
> Subject: [PATCH] some change
>
> ---
>  libavcodec/Makefile     |   34 +++++++++++-------
>  libavcodec/allcodecs.c  |    3 ++
>  libavcodec/avcodec.h    |    6 +++-
>  libavcodec/codec_desc.c |   12 ++++---
>  libavcodec/utah.c       |   92 +++++++++++++++++++++++++++++++++++++++++++++++
>  libavcodec/utah.h       |   15 ++++++++
>  libavcodec/utahenc.c    |   64 +++++++++++++++++++++++++++++++++
>  libavformat/img2.c      |   15 +++++---
>  libavformat/img2dec.c   |    8 ++++-
>  libavformat/utils.c     |    4 ++-
>  10 files changed, 229 insertions(+), 24 deletions(-)
>  mode change 100644 => 100755 libavcodec/Makefile
>  mode change 100644 => 100755 libavcodec/allcodecs.c
>  mode change 100644 => 100755 libavcodec/codec_desc.c
>  create mode 100755 libavcodec/utah.c
>  create mode 100755 libavcodec/utah.h
>  create mode 100755 libavcodec/utahenc.c
>  mode change 100644 => 100755 libavformat/img2.c
>  mode change 100644 => 100755 libavformat/img2dec.c
>

[...]

> diff --git a/libavcodec/utah.c b/libavcodec/utah.c
> new file mode 100755
> index 0000000..2fbaa9f
> --- /dev/null
> +++ b/libavcodec/utah.c
> @@ -0,0 +1,92 @@
> +/*
> + * UTAH image file decoder
> + * Author: Yuntao Ou
> + */
> +
> +#include "avcodec.h"
> +#include "bytestream.h"
> +#include "utah.h"
> +#include "internal.h"
> +#include "stdio.h"
> +
> +static av_cold int utah_decode_init(AVCodecContext *avctx)
> +{
> +	printf("\n************ In utah_decode_init() of utah.c ******************\n");
> +	UTAHContext *s = avctx->priv_data;
> +
> +	avcodec_get_frame_defaults(&s->picture);
> +	avctx->coded_frame = &s->picture;
> +	return 0;
> +}
> +
> +static int utah_decode_frame(AVCodecContext *avctx,
> +                            void *data, int *got_frame,
> +                            AVPacket *avpkt)
> +{
> +	printf("\n************* In utah_decode_frame() of utah.c *****************\n");
> +	int width;
> +	int height;
> +	int maxVal;
> +
> +	const uint8_t * buf = avpkt->data;
> +	int buf_size		= avpkt->size;
> +	UTAHContext *s 		= avctx->priv_data;
> +	AVFrame *picture	= data;
> +	AVFrame *p	= &s->picture;
> +

Does not check for overreads.

> +	if (bytestream_get_byte(&buf) != 'U' ||
> +		bytestream_get_byte(&buf) != 'T' ||
> +		bytestream_get_byte(&buf) != 'A' ||
> +		bytestream_get_byte(&buf) != 'H' ) {
> +		av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
> +		return AVERROR_INVALIDDATA;
> +	}
> +	// TODO: make a .utah generator.
> +	width = bytestream_get_le32(&buf);
> +	height = bytestream_get_le32(&buf);
> +	maxVal = bytestream_get_le32(&buf);
> +	if (p->data[0])
> +		avctx->release_buffer(avctx, p);
> +
> +	int fsize = width*height;
> +	avctx->width = width;
> +	avctx->height = height > 0 ? height : -height;
> +	avctx->pix_fmt = AV_PIX_FMT_RGBA;
> +	for (int i=0; i<fsize; i++)
> +	{
> +		static uint8_t temp;
> +		temp = bytestream_get_byte(&buf);
> +		temp = temp | 0x03; // Ignore alpha channel
> +		p->data[1][i] = temp;

RGBA pif fmt have p->data[1] set to NULL returned by get_buffer(). So this code
in best case just crash or in worst case reads from some computer
memory which is not memory
of image. Not mentioning other bugs present in code.

> +	}
> +	*picture = s->picture;
> +	*got_frame = 1;
> +
> +	printf("\n************* End of utah_decode_frame() of utah.c *****************\n");
> +
> +	return buf_size;
> +}
> +
> +static av_cold int utah_decode_end(AVCodecContext *avctx)
> +{
> +	printf("\n************* In utah_decode_end() of utah.c *****************\n");
> +	
> +	UTAHContext * c = avctx->priv_data;
> +
> +	if(c->picture.data[0])
> +		avctx->release_buffer(avctx, &c->picture);
> +	printf("\n************* utah_decode_end() of utah.c succeed *****************\n");
> +	return 0;
> +}
> +
> +AVCodec ff_utah_decoder = {
> +	.name			= "utah",
> +	.type			= AVMEDIA_TYPE_VIDEO,
> +	.type			= AV_CODEC_ID_UTAH,
> +	.priv_data_size	= sizeof(UTAHContext),
> +	.init			= utah_decode_init,
> +	.close			= utah_decode_end,
> +	.decode			= utah_decode_frame,
> +	.capabilities	= CODEC_CAP_DR1,
> +	.long_name	= NULL_IF_CONFIG_SMALL("UTAH (Built for CS 3505 in U of U) image"),
> +};
> diff --git a/libavcodec/utah.h b/libavcodec/utah.h
> new file mode 100755
> index 0000000..b4e4164
> --- /dev/null
> +++ b/libavcodec/utah.h
> @@ -0,0 +1,15 @@
> +/*
> + * internals for UTAH codecs
> + * Author: Yuntao Ou
> + */
> +
> +#ifndef AVCODEC_UTAH_H
> +#define AVCODEC_UTAH_H
> +
> +#include "avcodec.h"
> +
> +typedef struct UTAHContext{
> +	AVFrame picture;
> +} UTAHContext;
> +
> +#endif //AVCODEC_UTAH_H
> diff --git a/libavcodec/utahenc.c b/libavcodec/utahenc.c
> new file mode 100755
> index 0000000..89800d3
> --- /dev/null
> +++ b/libavcodec/utahenc.c
> @@ -0,0 +1,64 @@
> +/*
> + * UTAH image format encoder
> + * Author: Yuntao
> + */
> +
> +#include "avcodec.h"
> +#include "bytestream.h"
> +#include "utah.h"
> +#include "internal.h"
> +#include "stdio.h"
> +
> +static av_cold int utah_encode_init(AVCodecContext *avctx){
> +	printf("\n****** Begin utah_encode_init() in utahenc.c ********\n");
> +	UTAHContext * s = avctx->priv_data;
> +	
> +	avcodec_get_frame_defaults(&s->picture);
> +	avctx->coded_frame = &s->picture;
> +	
> +	avctx->bits_per_coded_sample = 8;
> +	return 0;
> +}
> +
> +static int utah_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
> +			    const AVFrame *pict, int *got_packet)
> +{
> +	printf("\n******* Begin utah_encode_frame() in utahenc.c *******\n");
> +	UTAHContext * s = avctx->priv_data;
> +	AVFrame * const p = &s->picture;
> +	int bit_count = avctx->bits_per_coded_sample;
> +	int maxVal = 2;
> +	*p = *pict;
> +	uint8_t * pal = NULL;
> +	uint8_t *buf;
> +	buf = pkt->data;
> +	bytestream_put_byte(&buf, 'U');
> +	bytestream_put_byte(&buf, 'T');
> +	bytestream_put_byte(&buf, 'A');
> +	bytestream_put_byte(&buf, 'H');			// UTAH image magic number.
> +	bytestream_put_le32(&buf, avctx->width);
> +	bytestream_put_le32(&buf, avctx->height);
> +	bytestream_put_le32(&buf, maxVal);
> +	pal = p->data[1];
> +	for(int i=0; i<avctx->height; i++){
> +		for(int j=0; j<avctx->width; j++){
> +			bytestream_put_byte(&buf, pal[i * avctx->width + j]);

Same as for decoder, p->data[1] is filled for PAL format and not for RGBA, also
its size is 1024 and not height * width.


[...]


More information about the ffmpeg-devel mailing list