[FFmpeg-devel] [PATCH] avcodec: add ARBC decoder

Paul B Mahol onemda at gmail.com
Wed Jan 23 11:27:54 EET 2019


On 1/22/19, Michael Niedermayer <michael at niedermayer.cc> wrote:
> On Tue, Jan 22, 2019 at 10:55:33AM +0100, Paul B Mahol wrote:
>> Thanks Kostya for great help in reversing binary.
>>
>> Signed-off-by: Paul B Mahol <onemda at gmail.com>
>> ---
>>  libavcodec/Makefile     |   1 +
>>  libavcodec/allcodecs.c  |   1 +
>>  libavcodec/arbc.c       | 203 ++++++++++++++++++++++++++++++++++++++++
>>  libavcodec/avcodec.h    |   1 +
>>  libavcodec/codec_desc.c |   7 ++
>>  libavformat/riff.c      |   1 +
>>  6 files changed, 214 insertions(+)
>>  create mode 100644 libavcodec/arbc.c
>>
>> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
>> index bf746c143d..8e240aecf0 100644
>> --- a/libavcodec/Makefile
>> +++ b/libavcodec/Makefile
>> @@ -198,6 +198,7 @@ OBJS-$(CONFIG_APTX_HD_DECODER)         += aptx.o
>>  OBJS-$(CONFIG_APTX_HD_ENCODER)         += aptx.o
>>  OBJS-$(CONFIG_APNG_DECODER)            += png.o pngdec.o pngdsp.o
>>  OBJS-$(CONFIG_APNG_ENCODER)            += png.o pngenc.o
>> +OBJS-$(CONFIG_ARBC_DECODER)            += arbc.o
>>  OBJS-$(CONFIG_SSA_DECODER)             += assdec.o ass.o
>>  OBJS-$(CONFIG_SSA_ENCODER)             += assenc.o ass.o
>>  OBJS-$(CONFIG_ASS_DECODER)             += assdec.o ass.o
>> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
>> index fe0376e27e..5cbb09a5a4 100644
>> --- a/libavcodec/allcodecs.c
>> +++ b/libavcodec/allcodecs.c
>> @@ -41,6 +41,7 @@ extern AVCodec ff_anm_decoder;
>>  extern AVCodec ff_ansi_decoder;
>>  extern AVCodec ff_apng_encoder;
>>  extern AVCodec ff_apng_decoder;
>> +extern AVCodec ff_arbc_decoder;
>>  extern AVCodec ff_asv1_encoder;
>>  extern AVCodec ff_asv1_decoder;
>>  extern AVCodec ff_asv2_encoder;
>> diff --git a/libavcodec/arbc.c b/libavcodec/arbc.c
>> new file mode 100644
>> index 0000000000..59a1d7bf0a
>> --- /dev/null
>> +++ b/libavcodec/arbc.c
>> @@ -0,0 +1,203 @@
>> +/*
>> + * Gryphon's Anim Compressor decoder
>> + * Copyright (c) 2018 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 <stdio.h>
>> +#include <stdlib.h>
>> +#include <string.h>
>> +
>> +#include "libavutil/imgutils.h"
>> +#include "libavutil/internal.h"
>> +#include "libavutil/intreadwrite.h"
>> +#include "libavutil/mem.h"
>> +
>> +#include "avcodec.h"
>> +#include "bytestream.h"
>> +#include "internal.h"
>> +
>> +typedef struct ARBCContext {
>> +    GetByteContext gb;
>> +
>> +    AVFrame *prev_frame;
>> +} ARBCContext;
>> +
>> +static void fill_tile4(AVCodecContext *avctx, uint8_t *color, AVFrame
>> *frame)
>> +{
>> +    ARBCContext *s = avctx->priv_data;
>> +    GetByteContext *gb = &s->gb;
>> +    int nb_tiles = bytestream2_get_le16(gb);
>> +    int h = avctx->height - 1;
>> +
>> +    for (int i = 0; i < nb_tiles; i++) {
>> +        int y = bytestream2_get_byte(gb);
>> +        int x = bytestream2_get_byte(gb);
>> +        uint16_t mask = bytestream2_get_le16(gb);
>> +        int start_y = y * 4, start_x = x * 4;
>> +        int end_y = start_y + 4, end_x = start_x + 4;
>> +
>> +        for (int j = start_y; j < end_y; j++) {
>> +            for (int k = start_x; k < end_x; k++) {
>> +                if (mask & 0x8000) {
>> +                    if (j >= avctx->height || k >= avctx->width)
>> +                        continue;
>
> this would treat 1 bits differently than 0 bits when they are outside
> teh frame. That is 1 bits would not advance in the bitstream (aka not
> execute
> mask = mask << 1;
> this also differs from fill_tileX()
> is that intended ?

No, well spotted, fixed locally.


More information about the ffmpeg-devel mailing list