[FFmpeg-devel] [PATCH] avcodec: add initial exr image encoder
Andreas Rheinhardt
andreas.rheinhardt at gmail.com
Mon Feb 15 03:35:19 EET 2021
Paul B Mahol:
> On Mon, Feb 15, 2021 at 2:29 AM Andreas Rheinhardt <
> andreas.rheinhardt at gmail.com> wrote:
>
>> Paul B Mahol:
>>> Signed-off-by: Paul B Mahol <onemda at gmail.com>
>>> ---
>>> libavcodec/Makefile | 1 +
>>> libavcodec/allcodecs.c | 1 +
>>> libavcodec/exrenc.c | 209 +++++++++++++++++++++++++++++++++++++++++
>>> libavformat/img2enc.c | 2 +-
>>> 4 files changed, 212 insertions(+), 1 deletion(-)
>>> create mode 100644 libavcodec/exrenc.c
>>>
>>> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
>>> index a98ec408bb..5fb735f129 100644
>>> --- a/libavcodec/Makefile
>>> +++ b/libavcodec/Makefile
>>> @@ -321,6 +321,7 @@ OBJS-$(CONFIG_ESCAPE124_DECODER) += escape124.o
>>> OBJS-$(CONFIG_ESCAPE130_DECODER) += escape130.o
>>> OBJS-$(CONFIG_EVRC_DECODER) += evrcdec.o acelp_vectors.o
>> lsp.o
>>> OBJS-$(CONFIG_EXR_DECODER) += exr.o exrdsp.o
>>> +OBJS-$(CONFIG_EXR_ENCODER) += exrenc.o
>>> OBJS-$(CONFIG_FASTAUDIO_DECODER) += fastaudio.o
>>> OBJS-$(CONFIG_FFV1_DECODER) += ffv1dec.o ffv1.o
>>> OBJS-$(CONFIG_FFV1_ENCODER) += ffv1enc.o ffv1.o
>>> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
>>> index 16ec182a52..cb3f0e7c18 100644
>>> --- a/libavcodec/allcodecs.c
>>> +++ b/libavcodec/allcodecs.c
>>> @@ -109,6 +109,7 @@ extern AVCodec ff_eightsvx_exp_decoder;
>>> extern AVCodec ff_eightsvx_fib_decoder;
>>> extern AVCodec ff_escape124_decoder;
>>> extern AVCodec ff_escape130_decoder;
>>> +extern AVCodec ff_exr_encoder;
>>> extern AVCodec ff_exr_decoder;
>>> extern AVCodec ff_ffv1_encoder;
>>> extern AVCodec ff_ffv1_decoder;
>>> diff --git a/libavcodec/exrenc.c b/libavcodec/exrenc.c
>>> new file mode 100644
>>> index 0000000000..0954fec14a
>>> --- /dev/null
>>> +++ b/libavcodec/exrenc.c
>>> @@ -0,0 +1,209 @@
>>> +/*
>>> + * OpenEXR image format
>>> + *
>>> + * Copyright (c) 2021 Paul B Mahol
>>> + *
>>> + * This file is part of FFmpeg.
>>> + *
>>> + * FFmpeg is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU Lesser General Public
>>> + * License as published by the Free Software Foundation; either
>>> + * version 2.1 of the License, or (at your option) any later version.
>>> + *
>>> + * FFmpeg is distributed in the hope that it will be useful,
>>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>>> + * Lesser General Public License for more details.
>>> + *
>>> + * You should have received a copy of the GNU Lesser General Public
>>> + * License along with FFmpeg; if not, write to the Free Software
>>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> 02110-1301 USA
>>> + */
>>> +
>>> +#include <float.h>
>>> +
>>> +#include "libavutil/avassert.h"
>>> +#include "libavutil/opt.h"
>>> +#include "libavutil/intreadwrite.h"
>>> +#include "libavutil/imgutils.h"
>>> +#include "libavutil/pixdesc.h"
>>> +#include "avcodec.h"
>>> +#include "bytestream.h"
>>> +#include "internal.h"
>>> +
>>> +enum ExrPixelType {
>>> + EXR_UINT,
>>> + EXR_HALF,
>>> + EXR_FLOAT,
>>> + EXR_UNKNOWN,
>>> +};
>>> +
>>> +static const char abgr_chlist[4] = { 'A', 'B', 'G', 'R' };
>>> +static const char bgr_chlist[4] = { 'B', 'G', 'R', 'A' };
>>> +static const uint8_t gbra_order[4] = { 3, 1, 0, 2 };
>>> +static const uint8_t gbr_order[4] = { 1, 0, 2, 0 };
>>> +
>>> +typedef struct EXRContext {
>>> + const AVClass *class;
>>> +
>>> + int planes;
>>> + float gamma;
>>> + const char *ch_names;
>>> + const uint8_t *ch_order;
>>> + PutByteContext pb;
>>> +} EXRContext;
>>> +
>>> +static int encode_init(AVCodecContext *avctx)
>>> +{
>>> + EXRContext *s = avctx->priv_data;
>>> +
>>> + switch (avctx->pix_fmt) {
>>> + case AV_PIX_FMT_GBRPF32:
>>> + s->planes = 3;
>>> + s->ch_names = bgr_chlist;
>>> + s->ch_order = gbr_order;
>>> + break;
>>> + case AV_PIX_FMT_GBRAPF32:
>>> + s->planes = 4;
>>> + s->ch_names = abgr_chlist;
>>> + s->ch_order = gbra_order;
>>> + break;
>>> + default:
>>> + av_assert0(0);
>>> + }
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
>>> + const AVFrame *frame, int *got_packet)
>>> +{
>>> + EXRContext *s = avctx->priv_data;
>>> + PutByteContext *pb = &s->pb;
>>> + int64_t offset;
>>> + int ret;
>>> + size_t out_size = 2048LL + avctx->height * 16LL +
>>> + av_image_get_buffer_size(avctx->pix_fmt,
>>> + avctx->width,
>>> + avctx->height, 64);
>>
>> There is a potential for information loss in the int64_t -> size_t
>> conversion here.
>>
>
>
> What you propose as alternative?
>
Always use 64bits; the size parameters of ff_alloc_packet2 are int64_t,
too, after all.
- Andreas
More information about the ffmpeg-devel
mailing list