From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id ACD9F43BE0 for ; Mon, 22 Aug 2022 10:00:28 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1458968B9C0; Mon, 22 Aug 2022 13:00:27 +0300 (EEST) Received: from mx.sdf.org (mx.sdf.org [205.166.94.24]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 214B268B9AB for ; Mon, 22 Aug 2022 13:00:19 +0300 (EEST) Received: from 15fc8db07f19f8c510f57cfd648a18df ([1.136.254.131]) (authenticated (0 bits)) by mx.sdf.org (8.15.2/8.14.5) with ESMTPSA id 27MA0EHt027507 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits) verified NO) for ; Mon, 22 Aug 2022 10:00:17 GMT Date: Mon, 22 Aug 2022 20:00:10 +1000 From: Peter Ross To: ffmpeg-devel@ffmpeg.org Message-ID: References: MIME-Version: 1.0 In-Reply-To: Subject: [FFmpeg-devel] [PATCH 2/2] avcodec/ildadec: ILDA Image Data Transfer Format 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 Content-Type: multipart/mixed; boundary="===============2649864952698768614==" Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: --===============2649864952698768614== Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="L7THENj5y2qEDruU" Content-Disposition: inline --L7THENj5y2qEDruU Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Signed-off-by: Peter Ross --- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/codec_desc.c | 7 + libavcodec/codec_id.h | 1 + libavcodec/ildadec.c | 297 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 307 insertions(+) create mode 100644 libavcodec/ildadec.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index cb80f73d99..943144ef7d 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -435,6 +435,7 @@ OBJS-$(CONFIG_IDCIN_DECODER) +=3D idcinvideo.o OBJS-$(CONFIG_IDF_DECODER) +=3D bintext.o cga_data.o OBJS-$(CONFIG_IFF_ILBM_DECODER) +=3D iff.o OBJS-$(CONFIG_ILBC_DECODER) +=3D ilbcdec.o +OBJS-$(CONFIG_ILDA_DECODER) +=3D ildadec.o OBJS-$(CONFIG_IMC_DECODER) +=3D imc.o OBJS-$(CONFIG_IMM4_DECODER) +=3D imm4.o OBJS-$(CONFIG_IMM5_DECODER) +=3D imm5.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 6939a4e25f..42a891bf77 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -171,6 +171,7 @@ extern const FFCodec ff_huffyuv_decoder; extern const FFCodec ff_hymt_decoder; extern const FFCodec ff_idcin_decoder; extern const FFCodec ff_iff_ilbm_decoder; +extern const FFCodec ff_ilda_decoder; extern const FFCodec ff_imm4_decoder; extern const FFCodec ff_imm5_decoder; extern const FFCodec ff_indeo2_decoder; diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 06dfe55d0f..177a25a5ce 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1909,6 +1909,13 @@ static const AVCodecDescriptor codec_descriptors[] = =3D { .long_name =3D NULL_IF_CONFIG_SMALL("WBMP (Wireless Application Pr= otocol Bitmap) image"), .props =3D AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, + { + .id =3D AV_CODEC_ID_ILDA, + .type =3D AVMEDIA_TYPE_VIDEO, + .name =3D "ilda", + .long_name =3D NULL_IF_CONFIG_SMALL("ILDA Image Data Transfer Form= at"), + .props =3D AV_CODEC_PROP_LOSSY, + }, =20 /* various PCM "codecs" */ { diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h index 2247bc0309..0152cc57a8 100644 --- a/libavcodec/codec_id.h +++ b/libavcodec/codec_id.h @@ -318,6 +318,7 @@ enum AVCodecID { AV_CODEC_ID_PHM, AV_CODEC_ID_RADIANCE_HDR, AV_CODEC_ID_WBMP, + AV_CODEC_ID_ILDA, =20 /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO =3D 0x10000, ///< A dummy id pointing at t= he start of audio codecs diff --git a/libavcodec/ildadec.c b/libavcodec/ildadec.c new file mode 100644 index 0000000000..b5810c911d --- /dev/null +++ b/libavcodec/ildadec.c @@ -0,0 +1,297 @@ +/* + * ILDA Image Data Transfer Format decoder + * Copyright (C) 2020 Peter Ross + * + * 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-130= 1 USA + */ + +/** + * @file + * ILDA Image Data Transfer Format decoder + */ + +#include "libavutil/attributes.h" +#include "libavutil/common.h" +#include "libavutil/frame.h" +#include "libavutil/imgutils.h" +#include "libavutil/internal.h" +#include "libavutil/intreadwrite.h" +#include "avcodec.h" +#include "codec_internal.h" +#include "internal.h" +#include "mathops.h" + +static const uint8_t default_palette[64][3]=3D{ + {255,0,0}, + {255,16,0}, + {255,32,0}, + {255,48,0}, + {255,64,0}, + {255,80,0}, + {255,96,0}, + {255,112,0}, + {255,128,0}, + {255,144,0}, + {255,160,0}, + {255,176,0}, + {255,192,0}, + {255,208,0}, + {255,224,0}, + {255,240,0}, + {255,255,0}, + {224,255,0}, + {192,255,0}, + {160,255,0}, + {128,255,0}, + {96,255,0}, + {64,255,0}, + {32,255,0}, + {0,255,0}, + {0,255,36}, + {0,255,73}, + {0,255,109}, + {0,255,146}, + {0,255,182}, + {0,255,219}, + {0,255,255}, + {0,227,255}, + {0,198,255}, + {0,170,255}, + {0,142,255}, + {0,113,255}, + {0,85,255}, + {0,56,255}, + {0,28,255}, + {0,0,255}, + {32,0,255}, + {64,0,255}, + {96,0,255}, + {128,0,255}, + {160,0,255}, + {192,0,255}, + {224,0,255}, + {255,0,255}, + {255,32,255}, + {255,64,255}, + {255,96,255}, + {255,128,255}, + {255,160,255}, + {255,192,255}, + {255,224,255}, + {255,255,255}, + {255,224,224}, + {255,192,192}, + {255,160,160}, + {255,128,128}, + {255,96,96}, + {255,64,64}, + {255,32,32}, +}; + +typedef struct { + AVFrame * frame; + uint8_t palette[256][3]; +} ILDAContext; + +static av_cold int decode_init(AVCodecContext *avctx) +{ + ILDAContext *s =3D avctx->priv_data; + + if (!avctx->width || !avctx->height) { + int ret =3D ff_set_dimensions(avctx, 1024, 1024); + if (ret < 0) + return ret; + } + + avctx->pix_fmt =3D AV_PIX_FMT_RGB24; + + s->frame =3D av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + + memcpy(s->palette, default_palette, sizeof(default_palette)); + memset(s->palette + FF_ARRAY_ELEMS(default_palette), 0xFF, sizeof(s->p= alette) - sizeof(default_palette)); + return 0; +}; + +static void draw_point(uint8_t *const pixels, int linesize, int width, int= height, + int x, int y, + const uint8_t *const rgbcolor) +{ + for (int j =3D FFMAX(y - 1, 0); j < FFMIN(y + 1, height); j++) + for (int i =3D FFMAX(x - 1, 0); i < FFMIN(x + 1, width); i++) { + pixels[j * linesize + i * 3 + 0] =3D rgbcolor[0]; + pixels[j * linesize + i * 3 + 1] =3D rgbcolor[1]; + pixels[j * linesize + i * 3 + 2] =3D rgbcolor[2]; + } + +} + +static void draw_line(uint8_t *const pixels, int linesize, + int x0, int y0, int x1, int y1, const uint8_t *const= rgbcolor) +{ + int dx =3D FFABS(x1 - x0), sx =3D x0 < x1 ? 1 : -1; + int dy =3D FFABS(y1 - y0), sy =3D y0 < y1 ? 1 : -1; + int err =3D (dx > dy ? dx : -dy) / 2, e2; + + for (;;) { + pixels[y0 * linesize + x0 * 3 + 0] =3D rgbcolor[0]; + pixels[y0 * linesize + x0 * 3 + 1] =3D rgbcolor[1]; + pixels[y0 * linesize + x0 * 3 + 2] =3D rgbcolor[2]; + + if (x0 =3D=3D x1 && y0 =3D=3D y1) + break; + + e2 =3D err; + + if (e2 >-dx) { + err -=3D dy; + x0 +=3D sx; + } + + if (e2 < dy) { + err +=3D dx; + y0 +=3D sy; + } + } +} + +static int decode_indexed(AVCodecContext *avctx, const uint8_t *buf, + const uint8_t *buf_end, int nb_entries, int zaxi= s, int truecolor) +{ + ILDAContext *s =3D avctx->priv_data; + int ret, x0, y0; + uint8_t * dst; + + ret =3D ff_reget_buffer(avctx, s->frame, 0); + if (ret < 0) + return ret; + + dst =3D s->frame->data[0]; + for (int i =3D 0; i < avctx->height; i++) { + memset(dst, 0, avctx->width * 3); + dst +=3D s->frame->linesize[0]; + } + + if (nb_entries < 2 || buf_end - buf < 6 + zaxis + truecolor) + return 0; + +#define coord(x) sign_extend(AV_RB16(buf + x), 16) +#define get_x ((32768 + coord(0)) * avctx->width) / 65536 +#define get_y (-(coord(2) - 32767) * avctx->height) / 65536 + + x0 =3D get_x; + y0 =3D get_y; + buf +=3D 6 + zaxis + truecolor; + + for (int i =3D 1; i < nb_entries && buf_end - buf >=3D 6 + zaxis + tru= ecolor; i++) { + int x1 =3D get_x; + int y1 =3D get_y; + uint8_t rgb[3]; + uint8_t * color; + if (truecolor) { + rgb[0] =3D buf[7 + zaxis]; + rgb[1] =3D buf[6 + zaxis]; + rgb[2] =3D buf[5 + zaxis]; + color =3D rgb; + } else + color =3D s->palette[buf[5 + zaxis]]; + + if (!(buf[4 + zaxis] & 0x40)) { + if (x0 !=3D x1 || y0 !=3D y1) + draw_line(s->frame->data[0], s->frame->linesize[0], x0, y0= , x1, y1, color); + else + draw_point(s->frame->data[0], s->frame->linesize[0], avctx= ->width, avctx->height, x0, y0, color); + } + + x0 =3D x1; + y0 =3D y1; + + buf +=3D 6 + zaxis + truecolor; + } + return 0; +} + +static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, + int *got_frame, AVPacket *avpkt) +{ + ILDAContext *s =3D avctx->priv_data; + uint8_t *buf =3D avpkt->data; + int buf_size =3D avpkt->size; + const uint8_t *buf_end =3D buf + buf_size; + int ret, format, nb_entries; + + if (buf_size < 32) + return -1; + + format =3D buf[7]; + nb_entries =3D AV_RB16(buf + 24); + + buf +=3D 32; + + switch (format) { + case 0: + ret =3D decode_indexed(avctx, buf, buf_end, nb_entries, 2, 0); + break; + case 1: + ret =3D decode_indexed(avctx, buf, buf_end, nb_entries, 0, 0); + break; + case 2: + memcpy(s->palette, buf, FFMIN((buf_end - buf) / 3, nb_entries) * 3= ); + return buf_size; + case 4: + ret =3D decode_indexed(avctx, buf, buf_end, nb_entries, 2, 2); + break; + case 5: + ret =3D decode_indexed(avctx, buf, buf_end, nb_entries, 0, 2); + break; + default: + avpriv_request_sample(avctx, "unsupported format %d", format); + return buf_size; + } + + if (ret < 0) + return ret; + + *got_frame =3D 1; + + ret =3D av_frame_ref(rframe, s->frame); + if (ret < 0) + return ret; + + return buf_size; +} + +static av_cold int decode_close(AVCodecContext *avctx) +{ + ILDAContext *s =3D avctx->priv_data; + + av_frame_free(&s->frame); + return 0; +} + +const FFCodec ff_ilda_decoder =3D { + .p.name =3D "anm", + .p.long_name =3D NULL_IF_CONFIG_SMALL("ILDA Image Data Transfer For= mat"), + .p.type =3D AVMEDIA_TYPE_VIDEO, + .p.id =3D AV_CODEC_ID_ILDA, + .priv_data_size =3D sizeof(ILDAContext), + .init =3D decode_init, + .close =3D decode_close, + FF_CODEC_DECODE_CB(decode_frame), + .p.capabilities =3D AV_CODEC_CAP_DR1, +}; --=20 2.35.1 -- Peter (A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B) --L7THENj5y2qEDruU Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iF0EABECAB0WIQSpB+AvpuUM0jTNINJnYHnFrEDdawUCYwNTqgAKCRBnYHnFrEDd a3aTAKCiozHuC4G3+JsF35yyQCBgvZIozgCfcr6hw6KY1ePFnDBbvDxJkAphYPM= =2ZwW -----END PGP SIGNATURE----- --L7THENj5y2qEDruU-- --===============2649864952698768614== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". --===============2649864952698768614==--