[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