[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