From patchwork Sat Nov 12 00:39:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Ross X-Patchwork-Id: 39248 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:999a:b0:a4:2148:650a with SMTP id ve26csp1226565pzb; Fri, 11 Nov 2022 16:39:49 -0800 (PST) X-Google-Smtp-Source: AA0mqf6XhrqpgS3Q/W0SGfS3UquutbwqaFfqUrvIiKiBRZ020NaFhYEMRY+sY+oE1hJo985D7Qqd X-Received: by 2002:a05:6402:c12:b0:461:9cbd:8fba with SMTP id co18-20020a0564020c1200b004619cbd8fbamr3715643edb.19.1668213589355; Fri, 11 Nov 2022 16:39:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668213589; cv=none; d=google.com; s=arc-20160816; b=CNQtrimOGJLpYzaaUZy9egYjHMvHNzsBKUfsYr15pAGsGMXIQKDE4Qn1uewonNde2e 5U3JU0R9gT11VaHCAMO1euPZ9MdbL8McbGyCpxwc27N4RZigU+bJVPFF2i1A5ryhwsCP 02l7JEWV1EJ1bilYoDSdCu8rAs1SAS6RHCFuWIXbijLsFY8FKEZCmik6vhQtUszRU5gz ovYw68DQtwDKNGU5irR6Xvy4ML0POBNkseuWYasf7dUgV7LFa+DTOdbUuzXDYmvaSqXH 7nEO3gWrlm3hQ6O1DhXHxRSIpPUSN/NgwYjNN+IapOPJboXG/paKpqPUu2WzZvTmTK9x K06w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:message-id:to:from:date:delivered-to; bh=wxxwV4sW0qynozTiZfemHg/RQh0iOxgJ2nB5L2CaDJI=; b=bezIw7JyiHDqT8ehoOJ47q4jXAxvv7G/nL8aDgNPAuiM6SyH1vgcu89QezViuW8AiY 7LfSTBBqV1pVWNt8rbv7wmnjmfLFEggXho3G8ZUc4Ypno/rjE3otnwkM/W+8q9CMhRx1 987+FEJoIbcWPGCu41G4YWeV3L2OHEkrz8pbuYw3mJzqW4WLlok7PYU/8wIltXXOK5Mb +VXSBZLXGrYa+lW0i0H90ypdYyfJ50fdsX3Nc+MQ8BuV/5ZQvzcsXb+ZvrMs+2l2IK7g qbcfEXaVifFuD0XYH6QGnQNrhsTqlu7REHo72H87vquU9w8Zi9tUnAr2aGRm162verEl jNcw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id g7-20020a17090670c700b0078ded36fa42si2681231ejk.292.2022.11.11.16.39.48; Fri, 11 Nov 2022 16:39:49 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id AF7BC68B17E; Sat, 12 Nov 2022 02:39:44 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mx.sdf.org (mx.sdf.org [205.166.94.24]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A87C068B0C7 for ; Sat, 12 Nov 2022 02:39:37 +0200 (EET) Received: from 4eb231a0d1b36cedda43a2a005befe4d ([1.145.165.33]) (authenticated (0 bits)) by mx.sdf.org (8.15.2/8.14.5) with ESMTPSA id 2AC0dRxM019107 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits) verified NO) for ; Sat, 12 Nov 2022 00:39:32 GMT Date: Sat, 12 Nov 2022 11:39:19 +1100 From: Peter Ross To: ffmpeg-devel@ffmpeg.org Message-ID: <1d90cbd18bffe5fc8d99ce361dec253c1728e19d.1668213509.git.pross@xvid.org> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avcodec: LEAD MCMP decoder X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: kIzz08oCzW5K Partially fixes ticket #798 --- sample: https://trac.ffmpeg.org/raw-attachment/ticket/798/DaDa_CMP.avi configure | 1 + doc/general_contents.texi | 1 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/codec_desc.c | 7 + libavcodec/codec_id.h | 1 + libavcodec/leaddata.h | 62 ++++++++ libavcodec/leaddec.c | 290 ++++++++++++++++++++++++++++++++++++++ libavformat/riff.c | 1 + 9 files changed, 365 insertions(+) create mode 100644 libavcodec/leaddata.h create mode 100644 libavcodec/leaddec.c diff --git a/configure b/configure index e6470dc03b..56af100e94 100755 --- a/configure +++ b/configure @@ -2861,6 +2861,7 @@ ipu_decoder_select="mpegvideodec" jpegls_decoder_select="mjpeg_decoder" jv_decoder_select="blockdsp" lagarith_decoder_select="llviddsp" +lead_decoder_select="idctdsp jpegtables" ljpeg_encoder_select="jpegtables" lscr_decoder_select="inflate_wrapper" magicyuv_decoder_select="llviddsp" diff --git a/doc/general_contents.texi b/doc/general_contents.texi index 8399fcb6b7..6832055316 100644 --- a/doc/general_contents.texi +++ b/doc/general_contents.texi @@ -987,6 +987,7 @@ following image formats are supported: @item Lagarith @tab @tab X @item LCL (LossLess Codec Library) MSZH @tab @tab X @item LCL (LossLess Codec Library) ZLIB @tab E @tab E +@item LEAD MCMP @tab @tab X @item LOCO @tab @tab X @item LucasArts SANM/Smush @tab @tab X @tab Used in LucasArts games / SMUSH animations. diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 94dc75a1b2..aa99eba7b7 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -463,6 +463,7 @@ OBJS-$(CONFIG_JV_DECODER) += jvdec.o OBJS-$(CONFIG_KGV1_DECODER) += kgv1dec.o OBJS-$(CONFIG_KMVC_DECODER) += kmvc.o OBJS-$(CONFIG_LAGARITH_DECODER) += lagarith.o lagarithrac.o +OBJS-$(CONFIG_LEAD_DECODER) += leaddec.o jpegquanttables.o OBJS-$(CONFIG_LJPEG_ENCODER) += ljpegenc.o mjpegenc_common.o OBJS-$(CONFIG_LOCO_DECODER) += loco.o OBJS-$(CONFIG_LSCR_DECODER) += lscrdec.o png.o pngdec.o pngdsp.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index f5ec3bc6e1..4b96443946 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -187,6 +187,7 @@ extern const FFCodec ff_jv_decoder; extern const FFCodec ff_kgv1_decoder; extern const FFCodec ff_kmvc_decoder; extern const FFCodec ff_lagarith_decoder; +extern const FFCodec ff_lead_decoder; extern const FFCodec ff_ljpeg_encoder; extern const FFCodec ff_loco_decoder; extern const FFCodec ff_lscr_decoder; diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 24a0433dba..9a1720f615 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1923,6 +1923,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("ViewQuest VQC"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_LEAD, + .type = AVMEDIA_TYPE_VIDEO, + .name = "lead", + .long_name = NULL_IF_CONFIG_SMALL("LEAD MCMP"), + .props = AV_CODEC_PROP_LOSSY, + }, /* various PCM "codecs" */ { diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h index f436a2b624..31c590278e 100644 --- a/libavcodec/codec_id.h +++ b/libavcodec/codec_id.h @@ -320,6 +320,7 @@ enum AVCodecID { AV_CODEC_ID_WBMP, AV_CODEC_ID_MEDIA100, AV_CODEC_ID_VQC, + AV_CODEC_ID_LEAD, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs diff --git a/libavcodec/leaddata.h b/libavcodec/leaddata.h new file mode 100644 index 0000000000..525b582cf7 --- /dev/null +++ b/libavcodec/leaddata.h @@ -0,0 +1,62 @@ +/* + * LEAD MCMP decoder tables + * + * 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 + */ + +#ifndef AVCODEC_LEADDATA_H +#define AVCODEC_LEADDATA_H + +#include + +static const uint8_t luma_dc_len[]={ + 2, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9 +}; + +static const uint8_t chroma_dc_len[]={ + 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 +}; + +static const uint8_t luma_ac_len[]={ + 2, 2, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 7, 8, + 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, + 12, 12, 12, 12, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16 +}; + +static const uint8_t chroma_ac_len[]={ + 2, 2, 3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 12, 12, 12, 12, 14, 15, 15, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16 +}; + +#endif /* AVCODEC_LEADDATA_H */ diff --git a/libavcodec/leaddec.c b/libavcodec/leaddec.c new file mode 100644 index 0000000000..3bda06458a --- /dev/null +++ b/libavcodec/leaddec.c @@ -0,0 +1,290 @@ +/* + * LEAD MCMP decoder + * + * 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 "avcodec.h" +#include "codec_internal.h" +#include "copy_block.h" +#include "decode.h" +#include "get_bits.h" +#include "idctdsp.h" +#include "jpegquanttables.h" +#include "jpegtables.h" +#include "leaddata.h" +#include "libavutil/thread.h" + +#define LUMA_DC_BITS 9 +#define CHROMA_DC_BITS 11 +#define LUMA_AC_BITS 10 +#define CHROMA_AC_BITS 10 + +static VLC luma_dc_vlc; +static VLC chroma_dc_vlc; +static VLC luma_ac_vlc; +static VLC chroma_ac_vlc; + +static av_cold void lead_init_static_data(void) +{ + INIT_VLC_STATIC_FROM_LENGTHS(&luma_dc_vlc, LUMA_DC_BITS, FF_ARRAY_ELEMS(luma_dc_len), + luma_dc_len, 1, + 0, 0, 0, + 0, 0, 1 << LUMA_DC_BITS); + INIT_VLC_STATIC_FROM_LENGTHS(&chroma_dc_vlc, CHROMA_DC_BITS, FF_ARRAY_ELEMS(chroma_dc_len), + chroma_dc_len, 1, + 0, 0, 0, + 0, 0, 1 << CHROMA_DC_BITS); + INIT_VLC_STATIC_FROM_LENGTHS(&luma_ac_vlc, LUMA_AC_BITS, FF_ARRAY_ELEMS(luma_ac_len), + luma_ac_len, 1, + ff_mjpeg_val_ac_luminance, 1, 1, + 0, 0, 1160); + INIT_VLC_STATIC_FROM_LENGTHS(&chroma_ac_vlc, CHROMA_AC_BITS, FF_ARRAY_ELEMS(chroma_ac_len), + chroma_ac_len, 1, + ff_mjpeg_val_ac_chrominance, 1, 1, + 0, 0, 1160); +} + +typedef struct LeadContext { + uint8_t *bitstream_buf; + unsigned int bitstream_buf_size; + IDCTDSPContext idsp; + uint8_t permutated_scantable[64]; +} LeadContext; + +static av_cold int lead_decode_init(AVCodecContext * avctx) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + LeadContext *s = avctx->priv_data; + + if (avctx->extradata_size < 20) + return AVERROR_INVALIDDATA; + + ff_idctdsp_init(&s->idsp, avctx); + ff_permute_scantable(s->permutated_scantable, ff_zigzag_direct, s->idsp.idct_permutation); + + ff_thread_once(&init_static_once, lead_init_static_data); + + return 0; +} + +static void calc_dequant(uint16_t * dequant, const uint8_t * quant_tbl, int q) +{ + for (int i = 0; i < 64; i++) + dequant[i] = av_clip(q * quant_tbl[ff_zigzag_direct[i]] / 50, 2, 32767); +} + +static int decode_block(LeadContext * s, GetBitContext * gb, + const VLCElem * dc_table, int dc_bits, const VLCElem * ac_table, int ac_bits, + int16_t * dc_pred, const uint16_t * dequant, + uint8_t * dst, int stride) +{ + int16_t block[64]; + int size; + + memset(block, 0, sizeof(block)); + + size = get_vlc2(gb, dc_table, dc_bits, 1); + if (size < 0) + return AVERROR_INVALIDDATA; + + if (size) + *dc_pred += get_xbits(gb, size); + + block[0] = (1 << 10) + *dc_pred * dequant[0]; + + for (int i = 1; i < 64; i++) { + int symbol = get_vlc2(gb, ac_table, ac_bits, 2); + if (size < 0) + return AVERROR_INVALIDDATA; + + if (!symbol) + break; + + i += symbol >> 4; + if (i >= 64) + return AVERROR_INVALIDDATA; + + size = symbol & 0xF; + if (size) + block[s->permutated_scantable[i]] = get_xbits(gb, size) * dequant[i]; + } + + s->idsp.idct_put(dst, stride, block); + return 0; +} + +static int lead_decode_frame(AVCodecContext *avctx, AVFrame * frame, + int * got_frame, AVPacket * avpkt) +{ + LeadContext *s = avctx->priv_data; + const uint8_t * buf = avpkt->data; + int ret, format, yuv20p_half = 0, fields = 1, q, size; + GetBitContext gb; + int16_t dc_pred[3] = {0, 0, 0}; + uint16_t dequant[2][64]; + + if (avpkt->size < 8) + return AVERROR_INVALIDDATA; + + format = AV_RL16(buf + 4); + switch(format) { + case 0x1000: + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + break; + case 0x2000: + avctx->pix_fmt = AV_PIX_FMT_YUV444P; + break; + case 0x2006: + avctx->pix_fmt = AV_PIX_FMT_YUV444P; + fields = 2; + break; + case 0x8000: + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + yuv20p_half = 1; + break; + default: + avpriv_request_sample(avctx, "unsupported format 0x%x", format); + return AVERROR_PATCHWELCOME; + } + + q = AV_RL16(buf + 6); + calc_dequant(dequant[0], ff_mjpeg_std_luminance_quant_tbl, q); + calc_dequant(dequant[1], ff_mjpeg_std_chrominance_quant_tbl, q); + + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + frame->key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I; + + av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size, avpkt->size - 8); + if (!s->bitstream_buf) + return AVERROR(ENOMEM); + + size = 0; + for (int i = 8; i < avpkt->size; i++) { + int src = buf[i] ^ 0x80; + s->bitstream_buf[size++] = src; + if (src == 0xFF && i + 1 < avpkt->size && (buf[i + 1] ^ 0x80) == 0x00) + i++; + } + + init_get_bits8(&gb, s->bitstream_buf, size); + + if (yuv20p_half) { + for (int mb_y = 0; mb_y < avctx->height / 16; mb_y++) + for (int mb_x = 0; mb_x < avctx->width / 16; mb_x++) + for (int b = 0; b < 4; b++) { + const VLCElem * dc_vlc = b < 2 ? luma_dc_vlc.table : chroma_dc_vlc.table; + int dc_bits = b < 2 ? LUMA_DC_BITS : CHROMA_DC_BITS; + const VLCElem * ac_vlc = b < 2 ? luma_ac_vlc.table : chroma_ac_vlc.table; + int ac_bits = b < 2 ? LUMA_AC_BITS : CHROMA_AC_BITS; + int plane = b < 2 ? 0 : b - 1; + int x, y; + + if (b < 2) { + y = 16*mb_y + 8*(b >> 1); + x = 16*mb_x + 8*(b & 1); + } else { + y = 8*mb_y; + x = 8*mb_x; + } + + ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits, + dc_pred + plane, dequant[!(b < 4)], + frame->data[plane] + y*frame->linesize[plane] + x, + (b < 2 ? 2 : 1) * frame->linesize[plane]); + if (ret < 0) + return ret; + + if (b < 2) + copy_block8(frame->data[plane] + (y + 1)*frame->linesize[plane] + x, + frame->data[plane] + y*frame->linesize[plane] + x, + 2*frame->linesize[plane], 2*frame->linesize[plane], 8); + } + } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) { + for (int mb_y = 0; mb_y < avctx->height / 16; mb_y++) + for (int mb_x = 0; mb_x < avctx->width / 16; mb_x++) + for (int b = 0; b < 6; b++) { + const VLCElem * dc_vlc = b < 4 ? luma_dc_vlc.table : chroma_dc_vlc.table; + int dc_bits = b < 4 ? LUMA_DC_BITS : CHROMA_DC_BITS; + const VLCElem * ac_vlc = b < 4 ? luma_ac_vlc.table : chroma_ac_vlc.table; + int ac_bits = b < 4 ? LUMA_AC_BITS : CHROMA_AC_BITS; + int plane = b < 4 ? 0 : b - 3; + int x, y; + + if (b < 4) { + y = 16*mb_y + 8*(b>>1); + x = 16*mb_x + 8*(b&1); + } else { + y = 8*mb_y; + x = 8*mb_x; + } + + ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits, + dc_pred + plane, dequant[!(b < 4)], + frame->data[plane] + y*frame->linesize[plane] + x, + frame->linesize[plane]); + if (ret < 0) + return ret; + } + } else { + for (int f = 0; f < fields; f++) + for (int j = 0; j < avctx->height / fields / 8; j++) + for (int i = 0; i < avctx->width / 8; i++) + for (int plane = 0; plane < 3; plane++) { + const VLCElem * dc_vlc = !plane ? luma_dc_vlc.table : chroma_dc_vlc.table; + int dc_bits = !plane ? LUMA_DC_BITS : CHROMA_DC_BITS; + const VLCElem * ac_vlc = !plane ? luma_ac_vlc.table : chroma_ac_vlc.table; + int ac_bits = !plane ? LUMA_AC_BITS : CHROMA_AC_BITS; + + ret = decode_block(s, &gb, dc_vlc, dc_bits, ac_vlc, ac_bits, + dc_pred + plane, dequant[!!plane], + frame->data[plane] + (f + 8*j*fields)*frame->linesize[plane] + 8*i, + fields * frame->linesize[plane]); + if (ret < 0) + return ret; + } + } + + *got_frame = 1; + + return avpkt->size; +} + +static av_cold int lead_decode_end(AVCodecContext * avctx) +{ + LeadContext *s = avctx->priv_data; + + av_freep(&s->bitstream_buf); + + return 0; +} + +const FFCodec ff_lead_decoder = { + .p.name = "lead", + CODEC_LONG_NAME("LEAD MCMP"), + .p.type = AVMEDIA_TYPE_VIDEO, + .p.id = AV_CODEC_ID_LEAD, + .priv_data_size = sizeof(LeadContext), + .init = lead_decode_init, + .close = lead_decode_end, + FF_CODEC_DECODE_CB(lead_decode_frame), + .p.capabilities = AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, +}; diff --git a/libavformat/riff.c b/libavformat/riff.c index 7319406b39..8401ae3668 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -501,6 +501,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_NOTCHLC, MKTAG('n', 'l', 'c', '1') }, { AV_CODEC_ID_VQC, MKTAG('V', 'Q', 'C', '1') }, { AV_CODEC_ID_VQC, MKTAG('V', 'Q', 'C', '2') }, + { AV_CODEC_ID_LEAD, MKTAG('L', 'E', 'A', 'D') }, { AV_CODEC_ID_NONE, 0 } };