From patchwork Tue Dec 3 21:27:12 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Lubar X-Patchwork-Id: 16572 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 6EE0F44A009 for ; Tue, 3 Dec 2019 23:27:37 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5401668B43F; Tue, 3 Dec 2019 23:27:37 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from rs224.mailgun.us (rs224.mailgun.us [209.61.151.224]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7651768B0C2 for ; Tue, 3 Dec 2019 23:27:30 +0200 (EET) DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=lubar.me; q=dns/txt; s=k1; t=1575408450; h=Content-Type: To: Subject: Message-ID: Date: From: In-Reply-To: References: MIME-Version: Sender; bh=OtuGij+CUeu16CJMJz38482FHviINrRzk0lLR4MGGqY=; b=Hzll/5ZRCjbJ7tPUsxdrRDnBlnsd+XzDJTjnKLOwp22Gcy0kg8emb+72u/4tVMNmojEbm7Bm pvhtVhGaHYgZg5/Jray/MQCt+E1oHCi6dpWx7slc82KOYuKBUgQkSJ+l9IXG2wn5OZ63VyU/ DTH7daROAF5+QEm7e3lVRFkyFoU= X-Mailgun-Sending-Ip: 209.61.151.224 X-Mailgun-Sid: WyIwZGQ3YyIsICJmZm1wZWctZGV2ZWxAZmZtcGVnLm9yZyIsICI4NTUwZiJd Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) by mxa.mailgun.org with ESMTP id 5de6d33e.7ff4e3fe5270-smtp-out-n01; Tue, 03 Dec 2019 21:27:26 -0000 (UTC) Received: by mail-wr1-f42.google.com with SMTP id g17so5730628wro.2 for ; Tue, 03 Dec 2019 13:27:26 -0800 (PST) X-Gm-Message-State: APjAAAXVbVM+jbPRfcJ0c36+YERVleYk4qq7qkyzP9lOElZJpL6b2VCR HpYNJ0MDie+oPWMFD+vYhX/SHxLANGjteNfiDWk= X-Google-Smtp-Source: APXvYqwnfAJqZ20bU2bRaZEKMBkSDXtvIeCPKQKq94ud/qJvdH2142/LAy7dVHMynCFZtZ1hHKHzNQEBxTob2BNELXY= X-Received: by 2002:a05:6000:118d:: with SMTP id g13mr130607wrx.141.1575408444120; Tue, 03 Dec 2019 13:27:24 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Ben Lubar Date: Tue, 3 Dec 2019 15:27:12 -0600 X-Gmail-Original-Message-ID: Message-ID: To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH v2] avformat, avcodec: add dfcmv demuxer and decoder X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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" A few example CMV files can be found in the data/initial_movies folder of Dwarf Fortress (http://www.bay12games.com/dwarves/). The demuxer does not currently handle audio cues. There are warning messages logged for each audio file that should be played. As far as I know, the only two existing CMV files with audio cues in them are in the examples folder mentioned above. (Reformatted to hopefully make the patch not break in GMail's weird forced word wrapping) Signed-off-by: Ben Lubar --- Changelog | 1 + configure | 1 + doc/general.texi | 2 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 1 + libavcodec/codec_desc.c | 7 + libavcodec/dfcmv.c | 1133 ++++++++++++++++++++++++++++++++++++++ libavcodec/version.h | 4 +- libavformat/Makefile | 1 + libavformat/allformats.c | 1 + libavformat/dfcmv.c | 232 ++++++++ libavformat/version.h | 2 +- 13 files changed, 1384 insertions(+), 3 deletions(-) create mode 100644 libavcodec/dfcmv.c create mode 100644 libavformat/dfcmv.c diff --git a/Changelog b/Changelog index f30f398a9f..eed4fa8a50 100644 --- a/Changelog +++ b/Changelog @@ -27,6 +27,7 @@ version : - axcorrelate filter - mvdv decoder - mvha decoder +- Dwarf Fortress CMV demuxer and decoder version 4.2: diff --git a/configure b/configure index ca7137f341..622deed689 100755 --- a/configure +++ b/configure @@ -3258,6 +3258,7 @@ caf_demuxer_select="iso_media riffdec" caf_muxer_select="iso_media" dash_muxer_select="mp4_muxer" dash_demuxer_deps="libxml2" +dfcmv_demuxer_deps="zlib" dirac_demuxer_select="dirac_parser" dts_demuxer_select="dca_parser" dtshd_demuxer_select="dca_parser" diff --git a/doc/general.texi b/doc/general.texi index a5b77e0de1..bbc90a2f58 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -429,6 +429,7 @@ library: @tab Video format used by CD+G karaoke disks @item Phantom Cine @tab @tab X @item Cineform HD @tab @tab X +@item Dwarf Fortress Curses MoVie (.cmv files) @tab @tab X @item Commodore CDXL @tab @tab X @tab Amiga CD video format @item Core Audio Format @tab X @tab X @@ -843,6 +844,7 @@ following image formats are supported: @item Delphine Software International CIN video @tab @tab X @tab Codec used in Delphine Software International games. @item Discworld II BMV Video @tab @tab X +@item Dwarf Fortess Curses MoVie (CMV) @tab @tab X @item Canopus Lossless Codec @tab @tab X @item Cinepak @tab @tab X @item Cirrus Logic AccuPak @tab X @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index c1f35b40d8..24e146e90f 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -267,6 +267,7 @@ OBJS-$(CONFIG_DDS_DECODER) += dds.o OBJS-$(CONFIG_DIRAC_DECODER) += diracdec.o dirac.o diracdsp.o diractab.o \ dirac_arith.o dirac_dwt.o dirac_vlc.o OBJS-$(CONFIG_DFA_DECODER) += dfa.o +OBJS-$(CONFIG_DFCMV_DECODER) += dfcmv.o OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o OBJS-$(CONFIG_DOLBY_E_DECODER) += dolby_e.o kbdwin.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index c33edf23c9..8571cce906 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -83,6 +83,7 @@ extern AVCodec ff_cscd_decoder; extern AVCodec ff_cyuv_decoder; extern AVCodec ff_dds_decoder; extern AVCodec ff_dfa_decoder; +extern AVCodec ff_dfcmv_decoder; extern AVCodec ff_dirac_decoder; extern AVCodec ff_dnxhd_encoder; extern AVCodec ff_dnxhd_decoder; diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 735a3c2d76..bd0446fe92 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -410,6 +410,7 @@ enum AVCodecID { AV_CODEC_ID_SCREENPRESSO, AV_CODEC_ID_RSCC, AV_CODEC_ID_AVS2, + AV_CODEC_ID_DFCMV, AV_CODEC_ID_Y41P = 0x8000, AV_CODEC_ID_AVRP, diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 570bd2f382..4ce8416b8e 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1403,6 +1403,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("AVS2-P2/IEEE1857.4"), .props = AV_CODEC_PROP_LOSSY, }, + { + .id = AV_CODEC_ID_DFCMV, + .type = AVMEDIA_TYPE_VIDEO, + .name = "dfcmv", + .long_name = NULL_IF_CONFIG_SMALL("Dwarf Fortress Curses MoVie"), + .props = AV_CODEC_PROP_INTRA_ONLY, + }, { .id = AV_CODEC_ID_Y41P, .type = AVMEDIA_TYPE_VIDEO, diff --git a/libavcodec/dfcmv.c b/libavcodec/dfcmv.c new file mode 100644 index 0000000000..9a1f4ac4d8 --- /dev/null +++ b/libavcodec/dfcmv.c @@ -0,0 +1,1133 @@ +#include "avcodec.h" +#include "internal.h" +#include "thread.h" +#include "libavutil/imgutils.h" + +typedef struct DFCMVCodecContext { + uint32_t width, height; + uint32_t half_frame_size; + uint32_t frame_size; +} DFCMVCodecContext; + +static av_cold int dfcmv_init_decoder(AVCodecContext *avctx) { + DFCMVCodecContext *cmv = avctx->priv_data; + int ret; + + ret = av_image_check_size(avctx->width, avctx->height, 0, avctx); + if (ret < 0) { + return ret; + } + + cmv->width = avctx->width / 10; + cmv->height = avctx->height / 12; + cmv->half_frame_size = cmv->width * cmv->height; + cmv->frame_size = 2 * cmv->half_frame_size; + avctx->pix_fmt = AV_PIX_FMT_PAL8; + + return 0; +} + +static const uint32_t dfcmv_palette[32] = { + 0xff000000, 0xff000080, 0xff008000, 0xff008080, + 0xff800000, 0xff800080, 0xff808000, 0xffc0c0c0, + 0xff808080, 0xff0000ff, 0xff00ff00, 0xff00ffff, + 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff, + 0xff000000, 0xff000060, 0xff006000, 0xff006060, + 0xff600000, 0xff600060, 0xff606000, 0xff909090, + 0xff606060, 0xff0000c0, 0xff00c000, 0xff00c0c0, + 0xffc00000, 0xffc000c0, 0xffc0c000, 0xffc0c0c0, +}; + +// 2 bpp, palette = bg,fg,fg_faded,unused; 10x12 pixels per sprite; +// padded by 12 bits per row to 32 bits +static const uint32_t dfcmv_sprites[256][12] = { + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x005550, 0x010004, 0x010004, 0x011044, 0x020008, + 0x02aaa8, 0x028528, 0x02aaa8, 0x00aaa0, 0x002a00, 0x002800, + }, + { + 0x000000, 0x005550, 0x015554, 0x015554, 0x014514, 0x025558, + 0x02aaa8, 0x029068, 0x02aaa8, 0x00aaa0, 0x002a00, 0x002800, + }, + { + 0x000000, 0x000000, 0x001010, 0x005454, 0x005554, 0x005554, + 0x005554, 0x001550, 0x000540, 0x000100, 0x000000, 0x000000, + }, + { + 0x000000, 0x000100, 0x000540, 0x001550, 0x005554, 0x005554, + 0x001550, 0x000540, 0x000100, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000500, 0x001540, 0x001540, 0x015554, 0x015054, + 0x015054, 0x000500, 0x000500, 0x005550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000500, 0x001540, 0x005550, 0x015554, 0x015554, + 0x005550, 0x000500, 0x000500, 0x005550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x001540, 0x005550, + 0x005550, 0x001540, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x055555, 0x055555, 0x055555, 0x055555, 0x054015, 0x050005, + 0x050005, 0x054015, 0x055555, 0x055555, 0x055555, 0x055555, + }, + { + 0x000000, 0x000000, 0x001540, 0x005550, 0x005050, 0x004010, + 0x004010, 0x005050, 0x005550, 0x001540, 0x000000, 0x000000, + }, + { + 0x055555, 0x055555, 0x054015, 0x050005, 0x050505, 0x051545, + 0x051545, 0x050505, 0x050005, 0x054015, 0x055555, 0x055555, + }, + { + 0x000000, 0x005540, 0x005400, 0x004540, 0x004150, 0x000554, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001540, 0x005050, 0x005050, 0x005050, 0x001540, + 0x000500, 0x005550, 0x000500, 0x000500, 0x000000, 0x000000, + }, + { + 0x000000, 0x015500, 0x010500, 0x010500, 0x015500, 0x000500, + 0x000500, 0x000550, 0x000554, 0x000150, 0x000000, 0x000000, + }, + { + 0x000000, 0x015550, 0x014050, 0x015550, 0x014050, 0x014050, + 0x014050, 0x015050, 0x015054, 0x005054, 0x000014, 0x000000, + }, + { + 0x000000, 0x000000, 0x000500, 0x014514, 0x005550, 0x015054, + 0x015054, 0x005550, 0x014514, 0x000500, 0x000000, 0x000000, + }, + { + 0x000000, 0x000004, 0x000014, 0x000054, 0x000554, 0x005554, + 0x000554, 0x000054, 0x000014, 0x000004, 0x000000, 0x000000, + }, + { + 0x000000, 0x004000, 0x005000, 0x005400, 0x005540, 0x005554, + 0x005540, 0x005400, 0x005000, 0x004000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000500, 0x001540, 0x005550, 0x000500, 0x000500, + 0x000500, 0x005550, 0x001540, 0x000500, 0x000000, 0x000000, + }, + { + 0x000000, 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, + 0x000000, 0x000000, 0x005050, 0x005050, 0x000000, 0x000000, + }, + { + 0x000000, 0x015550, 0x014514, 0x014514, 0x014514, 0x014550, + 0x014500, 0x014500, 0x014500, 0x014500, 0x000000, 0x000000, + }, + { + 0x000000, 0x005550, 0x014050, 0x000140, 0x001540, 0x005050, + 0x005050, 0x001540, 0x001400, 0x005014, 0x005550, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x005554, 0x005554, 0x005554, 0x000000, 0x000000, + }, + { + 0x000000, 0x000500, 0x001540, 0x005550, 0x000500, 0x000500, + 0x000500, 0x005550, 0x001540, 0x000500, 0x005550, 0x000000, + }, + { + 0x000000, 0x000500, 0x001540, 0x005550, 0x000500, 0x000500, + 0x000500, 0x000500, 0x000500, 0x000500, 0x000000, 0x000000, + }, + { + 0x000000, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + 0x000500, 0x005550, 0x001540, 0x000500, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000500, 0x001400, 0x005554, + 0x001400, 0x000500, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000140, 0x000050, 0x005554, + 0x000050, 0x000140, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000014, 0x000014, + 0x000014, 0x005554, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x001040, 0x005050, 0x015554, + 0x005050, 0x001040, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000100, 0x000100, 0x000540, 0x000540, + 0x001550, 0x001550, 0x005554, 0x005554, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x005554, 0x005554, 0x001550, 0x001550, + 0x000540, 0x000540, 0x000100, 0x000100, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000140, 0x000550, 0x000550, 0x000550, 0x000140, + 0x000140, 0x000000, 0x000140, 0x000140, 0x000000, 0x000000, + }, + { + 0x000000, 0x005050, 0x005050, 0x005050, 0x001040, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x001450, 0x001450, 0x005554, 0x001450, 0x001450, + 0x001450, 0x005554, 0x001450, 0x001450, 0x000000, 0x000000, + }, + { + 0x000140, 0x000140, 0x001550, 0x000014, 0x000014, 0x000550, + 0x001400, 0x001400, 0x000554, 0x000140, 0x000140, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x001014, 0x001414, 0x000500, + 0x000140, 0x000050, 0x001414, 0x001404, 0x000000, 0x000000, + }, + { + 0x000000, 0x000150, 0x000514, 0x000514, 0x000150, 0x004554, + 0x005514, 0x001414, 0x001514, 0x005150, 0x000000, 0x000000, + }, + { + 0x000000, 0x000140, 0x000140, 0x000140, 0x000050, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x001400, 0x000500, 0x000140, 0x000050, 0x000050, + 0x000050, 0x000140, 0x000500, 0x001400, 0x000000, 0x000000, + }, + { + 0x000000, 0x000050, 0x000140, 0x000500, 0x001400, 0x001400, + 0x001400, 0x000500, 0x000140, 0x000050, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x005050, 0x001540, 0x015554, + 0x001540, 0x005050, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000500, 0x000500, 0x005550, + 0x000500, 0x000500, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000540, 0x000540, 0x000050, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x005555, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000540, 0x000540, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x004000, 0x005000, 0x001400, 0x000500, + 0x000140, 0x000050, 0x000014, 0x000004, 0x000000, 0x000000, + }, + { + 0x000000, 0x001550, 0x005014, 0x005414, 0x005514, 0x005114, + 0x005154, 0x005054, 0x005014, 0x001550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000100, 0x000140, 0x000154, 0x000140, 0x000140, + 0x000140, 0x000140, 0x000140, 0x001554, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x001414, 0x001414, 0x001400, 0x000500, + 0x000140, 0x000050, 0x001414, 0x001554, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x001414, 0x001400, 0x001400, 0x000540, + 0x001400, 0x001400, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001400, 0x001500, 0x001540, 0x001450, 0x001414, + 0x005554, 0x001400, 0x001400, 0x005500, 0x000000, 0x000000, + }, + { + 0x000000, 0x001554, 0x000014, 0x000014, 0x000014, 0x000554, + 0x001400, 0x001400, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000540, 0x000050, 0x000014, 0x000014, 0x000554, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x005554, 0x005014, 0x005014, 0x005000, 0x001400, + 0x000500, 0x000140, 0x000140, 0x000140, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x001414, 0x001414, 0x001454, 0x000550, + 0x001514, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x001414, 0x001414, 0x001414, 0x001550, + 0x000500, 0x000500, 0x000140, 0x000150, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000540, 0x000540, 0x000000, + 0x000000, 0x000540, 0x000540, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000540, 0x000540, 0x000000, + 0x000000, 0x000540, 0x000540, 0x000500, 0x000140, 0x000000, + }, + { + 0x000000, 0x001400, 0x000500, 0x000140, 0x000050, 0x000014, + 0x000050, 0x000140, 0x000500, 0x001400, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005550, 0x000000, + 0x005550, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000050, 0x000140, 0x000500, 0x001400, 0x005000, + 0x001400, 0x000500, 0x000140, 0x000050, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x001414, 0x001400, 0x000500, 0x000140, + 0x000140, 0x000000, 0x000140, 0x000140, 0x000000, 0x000000, + }, + { + 0x000000, 0x001550, 0x005014, 0x005014, 0x005514, 0x005514, + 0x005514, 0x000014, 0x000014, 0x001550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000140, 0x000550, 0x001414, 0x001414, 0x001414, + 0x001554, 0x001414, 0x001414, 0x001414, 0x000000, 0x000000, + }, + { + 0x000000, 0x001554, 0x005050, 0x005050, 0x005050, 0x001550, + 0x005050, 0x005050, 0x005050, 0x001554, 0x000000, 0x000000, + }, + { + 0x000000, 0x001540, 0x005050, 0x005014, 0x000014, 0x000014, + 0x000014, 0x005014, 0x005050, 0x001540, 0x000000, 0x000000, + }, + { + 0x000000, 0x000554, 0x001450, 0x005050, 0x005050, 0x005050, + 0x005050, 0x005050, 0x001450, 0x000554, 0x000000, 0x000000, + }, + { + 0x000000, 0x005554, 0x004050, 0x000050, 0x001050, 0x001550, + 0x001050, 0x000050, 0x004050, 0x005554, 0x000000, 0x000000, + }, + { + 0x000000, 0x005554, 0x005050, 0x004050, 0x001050, 0x001550, + 0x001050, 0x000050, 0x000050, 0x000154, 0x000000, 0x000000, + }, + { + 0x000000, 0x001540, 0x005050, 0x005014, 0x000014, 0x000014, + 0x005414, 0x005014, 0x005050, 0x005540, 0x000000, 0x000000, + }, + { + 0x000000, 0x001414, 0x001414, 0x001414, 0x001414, 0x001554, + 0x001414, 0x001414, 0x001414, 0x001414, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x000140, 0x000140, 0x000140, 0x000140, + 0x000140, 0x000140, 0x000140, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x005500, 0x001400, 0x001400, 0x001400, 0x001400, + 0x001414, 0x001414, 0x001410, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x005054, 0x005050, 0x001450, 0x001450, 0x000550, + 0x001450, 0x001450, 0x005050, 0x005054, 0x000000, 0x000000, + }, + { + 0x000000, 0x000154, 0x000050, 0x000050, 0x000050, 0x000050, + 0x004050, 0x005050, 0x005050, 0x005554, 0x000000, 0x000000, + }, + { + 0x000000, 0x005014, 0x005454, 0x005554, 0x005554, 0x005114, + 0x005014, 0x005014, 0x005014, 0x005014, 0x000000, 0x000000, + }, + { + 0x000000, 0x005014, 0x005014, 0x005054, 0x005154, 0x005554, + 0x005514, 0x005414, 0x005014, 0x005014, 0x000000, 0x000000, + }, + { + 0x000000, 0x000540, 0x001450, 0x005014, 0x005014, 0x005014, + 0x005014, 0x005014, 0x001450, 0x000540, 0x000000, 0x000000, + }, + { + 0x000000, 0x001554, 0x005050, 0x005050, 0x005050, 0x001550, + 0x000050, 0x000050, 0x000050, 0x000154, 0x000000, 0x000000, + }, + { + 0x000000, 0x000540, 0x001450, 0x005014, 0x005014, 0x005014, + 0x005414, 0x005514, 0x001550, 0x001400, 0x005500, 0x000000, + }, + { + 0x000000, 0x001554, 0x005050, 0x005050, 0x005050, 0x001550, + 0x001450, 0x005050, 0x005050, 0x005054, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x001414, 0x001414, 0x000014, 0x000150, + 0x000500, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001554, 0x001144, 0x000140, 0x000140, 0x000140, + 0x000140, 0x000140, 0x000140, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001414, 0x001414, 0x001414, 0x001414, 0x001414, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001414, 0x001414, 0x001414, 0x001414, 0x001414, + 0x001414, 0x001414, 0x000550, 0x000140, 0x000000, 0x000000, + }, + { + 0x000000, 0x005014, 0x005014, 0x005014, 0x005014, 0x005114, + 0x005114, 0x001450, 0x001450, 0x001450, 0x000000, 0x000000, + }, + { + 0x000000, 0x001414, 0x001414, 0x001414, 0x000550, 0x000140, + 0x000550, 0x001414, 0x001414, 0x001414, 0x000000, 0x000000, + }, + { + 0x000000, 0x001414, 0x001414, 0x001414, 0x001410, 0x000550, + 0x000140, 0x000140, 0x000140, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x005554, 0x005414, 0x000504, 0x000500, 0x000140, + 0x000050, 0x004050, 0x005014, 0x005554, 0x000000, 0x000000, + }, + { + 0x000000, 0x001540, 0x000140, 0x000140, 0x000140, 0x000140, + 0x000140, 0x000140, 0x000140, 0x001540, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000004, 0x000014, 0x000050, 0x000140, + 0x000500, 0x001400, 0x005000, 0x004000, 0x000000, 0x000000, + }, + { + 0x000000, 0x001540, 0x001400, 0x001400, 0x001400, 0x001400, + 0x001400, 0x001400, 0x001400, 0x001540, 0x000000, 0x000000, + }, + { + 0x000100, 0x000540, 0x001450, 0x005014, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x055555, 0x000000, + }, + { + 0x000140, 0x000140, 0x000500, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000550, 0x001400, + 0x001550, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x000000, 0x000054, 0x000050, 0x000050, 0x001550, 0x005050, + 0x005050, 0x005050, 0x005050, 0x001514, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000550, 0x001414, + 0x000014, 0x000014, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001500, 0x001400, 0x001400, 0x001550, 0x001414, + 0x001414, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000550, 0x001414, + 0x001554, 0x000014, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000540, 0x001450, 0x000050, 0x000050, 0x000554, + 0x000050, 0x000050, 0x000050, 0x000154, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005150, 0x001414, + 0x001414, 0x001414, 0x001550, 0x001400, 0x001414, 0x000550, + }, + { + 0x000000, 0x000054, 0x000050, 0x000050, 0x001450, 0x005150, + 0x005050, 0x005050, 0x005050, 0x005054, 0x000000, 0x000000, + }, + { + 0x000000, 0x000500, 0x000500, 0x000000, 0x000550, 0x000500, + 0x000500, 0x000500, 0x000500, 0x005550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001400, 0x001400, 0x000000, 0x001540, 0x001400, + 0x001400, 0x001400, 0x001400, 0x001414, 0x001414, 0x000550, + }, + { + 0x000000, 0x000054, 0x000050, 0x000050, 0x005050, 0x001450, + 0x000550, 0x001450, 0x005050, 0x005054, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x000500, 0x000500, 0x000500, 0x000500, + 0x000500, 0x000500, 0x000500, 0x005550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x001554, 0x005114, + 0x005114, 0x005114, 0x005114, 0x005014, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000554, 0x001414, + 0x001414, 0x001414, 0x001414, 0x001414, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000550, 0x001414, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x001514, 0x005050, + 0x005050, 0x005050, 0x005050, 0x001550, 0x000050, 0x000154, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005150, 0x001414, + 0x001414, 0x001414, 0x001414, 0x001550, 0x001400, 0x005500, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x001454, 0x005450, + 0x005150, 0x000050, 0x000050, 0x000154, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000550, 0x001414, + 0x000050, 0x000500, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000040, 0x000050, 0x001554, 0x000050, + 0x000050, 0x000050, 0x001450, 0x000540, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x001414, 0x001414, + 0x001414, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x001414, 0x001414, + 0x001414, 0x001414, 0x000550, 0x000140, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005014, 0x005014, + 0x005114, 0x005114, 0x001450, 0x001450, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005014, 0x001450, + 0x000540, 0x000540, 0x001450, 0x005014, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005050, 0x005050, + 0x005050, 0x005050, 0x001540, 0x001400, 0x000500, 0x000154, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x001554, 0x001404, + 0x000500, 0x000050, 0x001014, 0x001554, 0x000000, 0x000000, + }, + { + 0x000000, 0x001500, 0x000140, 0x000140, 0x000050, 0x000014, + 0x000050, 0x000140, 0x000140, 0x001500, 0x000000, 0x000000, + }, + { + 0x000000, 0x000500, 0x000500, 0x000500, 0x000500, 0x000000, + 0x000500, 0x000500, 0x000500, 0x000500, 0x000000, 0x000000, + }, + { + 0x000000, 0x000054, 0x000140, 0x000140, 0x000500, 0x001400, + 0x000500, 0x000140, 0x000140, 0x000054, 0x000000, 0x000000, + }, + { + 0x000000, 0x014150, 0x004514, 0x005414, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000100, 0x000540, 0x001450, + 0x005014, 0x005014, 0x005554, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x001414, 0x001414, 0x000014, 0x000014, + 0x000014, 0x001414, 0x001414, 0x000550, 0x000140, 0x000154, + }, + { + 0x000000, 0x001414, 0x001414, 0x000000, 0x001414, 0x001414, + 0x001414, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x001400, 0x000500, 0x000140, 0x000000, 0x000550, 0x001414, + 0x001554, 0x000014, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000140, 0x000550, 0x001414, 0x000000, 0x000550, 0x001400, + 0x001550, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x000000, 0x001414, 0x001414, 0x000000, 0x000550, 0x001400, + 0x001550, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x000014, 0x000050, 0x000140, 0x000000, 0x000550, 0x001400, + 0x001550, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x000540, 0x001450, 0x001450, 0x000540, 0x000554, 0x001400, + 0x001550, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000550, 0x001414, + 0x000014, 0x000014, 0x001414, 0x000550, 0x000140, 0x000154, + }, + { + 0x000140, 0x000550, 0x001414, 0x000000, 0x000550, 0x001414, + 0x001554, 0x000014, 0x000014, 0x001550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001414, 0x001414, 0x000000, 0x000550, 0x001414, + 0x001554, 0x000014, 0x000014, 0x001550, 0x000000, 0x000000, + }, + { + 0x000014, 0x000050, 0x000140, 0x000000, 0x000550, 0x001414, + 0x001554, 0x000014, 0x000014, 0x001550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001450, 0x001450, 0x000000, 0x000550, 0x000500, + 0x000500, 0x000500, 0x000500, 0x005550, 0x000000, 0x000000, + }, + { + 0x000100, 0x000540, 0x001450, 0x000000, 0x000550, 0x000500, + 0x000500, 0x000500, 0x000500, 0x005550, 0x000000, 0x000000, + }, + { + 0x000050, 0x000140, 0x000500, 0x000000, 0x000550, 0x000500, + 0x000500, 0x000500, 0x000500, 0x005550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001414, 0x000000, 0x000140, 0x000550, 0x001414, + 0x001414, 0x001554, 0x001414, 0x001414, 0x000000, 0x000000, + }, + { + 0x000550, 0x001414, 0x001414, 0x000550, 0x000550, 0x001414, + 0x001414, 0x001554, 0x001414, 0x001414, 0x000000, 0x000000, + }, + { + 0x001400, 0x000500, 0x000140, 0x001554, 0x001014, 0x000014, + 0x000554, 0x000014, 0x001014, 0x001554, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005554, 0x014500, + 0x015550, 0x000514, 0x000514, 0x015454, 0x000000, 0x000000, + }, + { + 0x000000, 0x015540, 0x001550, 0x001414, 0x001414, 0x015554, + 0x001414, 0x001414, 0x001414, 0x015414, 0x000000, 0x000000, + }, + { + 0x000140, 0x000550, 0x001414, 0x000000, 0x000550, 0x001414, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x001414, 0x001414, 0x000000, 0x000550, 0x001414, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000014, 0x000050, 0x000140, 0x000000, 0x000550, 0x001414, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000140, 0x000550, 0x001414, 0x000000, 0x001414, 0x001414, + 0x001414, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x000014, 0x000050, 0x000140, 0x000000, 0x001414, 0x001414, + 0x001414, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x000000, 0x005050, 0x005050, 0x000000, 0x005050, 0x005050, + 0x005050, 0x005050, 0x001540, 0x001400, 0x000500, 0x000154, + }, + { + 0x001414, 0x000000, 0x000550, 0x001414, 0x001414, 0x001414, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x001414, 0x000000, 0x001414, 0x001414, 0x001414, 0x001414, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000140, 0x000140, 0x000550, 0x001414, 0x000014, + 0x000014, 0x001414, 0x000550, 0x000140, 0x000140, 0x000000, + }, + { + 0x001540, 0x005050, 0x000050, 0x000050, 0x000050, 0x001554, + 0x000050, 0x000050, 0x000014, 0x005554, 0x000000, 0x000000, + }, + { + 0x001414, 0x001414, 0x001414, 0x001414, 0x000550, 0x001554, + 0x000140, 0x001554, 0x000140, 0x000140, 0x000000, 0x000000, + }, + { + 0x000154, 0x000404, 0x000404, 0x000404, 0x000154, 0x000404, + 0x005504, 0x001404, 0x011404, 0x005004, 0x000000, 0x000000, + }, + { + 0x005400, 0x014500, 0x000500, 0x000500, 0x005550, 0x000500, + 0x000500, 0x000500, 0x000514, 0x000150, 0x000000, 0x000000, + }, + { + 0x001400, 0x000500, 0x000140, 0x000000, 0x000550, 0x001400, + 0x001550, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x001400, 0x000500, 0x000140, 0x000000, 0x000550, 0x000500, + 0x000500, 0x000500, 0x000500, 0x005550, 0x000000, 0x000000, + }, + { + 0x001400, 0x000500, 0x000140, 0x000000, 0x000550, 0x001414, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x001400, 0x000500, 0x000140, 0x000000, 0x001414, 0x001414, + 0x001414, 0x001414, 0x001414, 0x005150, 0x000000, 0x000000, + }, + { + 0x000000, 0x005150, 0x001514, 0x000000, 0x000554, 0x001414, + 0x001414, 0x001414, 0x001414, 0x001414, 0x000000, 0x000000, + }, + { + 0x005150, 0x001514, 0x000000, 0x005014, 0x005054, 0x005154, + 0x005514, 0x005414, 0x005014, 0x005014, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x001414, 0x001414, 0x005550, 0x000000, + 0x005554, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x001414, 0x001414, 0x000550, 0x000000, + 0x005554, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000140, 0x000140, 0x000000, 0x000140, 0x000050, + 0x000014, 0x000014, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x001554, + 0x000014, 0x000014, 0x000014, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x001554, + 0x001400, 0x001400, 0x001400, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x004010, 0x005014, 0x001414, 0x000514, 0x000140, + 0x005450, 0x014014, 0x005004, 0x001400, 0x015500, 0x000000, + }, + { + 0x000000, 0x014050, 0x005054, 0x001450, 0x000550, 0x015140, + 0x015450, 0x014514, 0x014144, 0x015540, 0x014000, 0x000000, + }, + { + 0x000000, 0x000140, 0x000140, 0x000000, 0x000140, 0x000140, + 0x000550, 0x000550, 0x000550, 0x000140, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x014140, 0x005050, + 0x001414, 0x001414, 0x005050, 0x014140, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x001414, 0x005050, + 0x014140, 0x014140, 0x005050, 0x001414, 0x000000, 0x000000, + }, + { + 0x001041, 0x004104, 0x010410, 0x041041, 0x004104, 0x010410, + 0x041041, 0x004104, 0x010410, 0x041041, 0x004104, 0x010410, + }, + { + 0x011111, 0x044444, 0x011111, 0x044444, 0x011111, 0x044444, + 0x011111, 0x044444, 0x011111, 0x044444, 0x011111, 0x044444, + }, + { + 0x051451, 0x014514, 0x045145, 0x051451, 0x014514, 0x045145, + 0x051451, 0x014514, 0x045145, 0x051451, 0x014514, 0x045145, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000555, + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x000555, 0x000500, + 0x000500, 0x000555, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x005055, + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x005555, + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000555, 0x000500, + 0x000500, 0x000555, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x005055, 0x005000, + 0x005000, 0x005055, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005555, 0x005000, + 0x005000, 0x005055, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x005055, 0x005000, + 0x005000, 0x005555, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x005555, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x000555, 0x000500, + 0x000500, 0x000555, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000555, + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x055500, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x055555, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x055555, + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x055500, + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x055555, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x055555, + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x055500, 0x000500, + 0x000500, 0x055500, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x055050, + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x055050, 0x000050, + 0x000050, 0x055550, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x055550, 0x000050, + 0x000050, 0x055050, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x055055, 0x000000, + 0x000000, 0x055555, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x055555, 0x000000, + 0x000000, 0x055055, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x055050, 0x000050, + 0x000050, 0x055050, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x055555, 0x000000, + 0x000000, 0x055555, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x055055, 0x000000, + 0x000000, 0x055055, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x015555, 0x000000, + 0x000000, 0x015555, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x055555, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x055555, 0x000000, + 0x000000, 0x055555, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x055555, + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x055550, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x055500, 0x000500, + 0x000500, 0x055500, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x055500, 0x000500, + 0x000500, 0x055500, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x055550, + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x055055, + 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, 0x005050, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x055555, 0x000000, + 0x000000, 0x055555, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000555, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x055500, + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x055555, 0x055555, 0x055555, 0x055555, 0x055555, 0x055555, + 0x055555, 0x055555, 0x055555, 0x055555, 0x055555, 0x055555, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x055555, 0x055555, 0x055555, 0x055555, 0x055555, 0x055555, + }, + { + 0x000555, 0x000555, 0x000555, 0x000555, 0x000555, 0x000555, + 0x000555, 0x000555, 0x000555, 0x000555, 0x000555, 0x000555, + }, + { + 0x055400, 0x055400, 0x055400, 0x055400, 0x055400, 0x055400, + 0x055400, 0x055400, 0x055400, 0x055400, 0x055400, 0x055400, + }, + { + 0x055555, 0x055555, 0x055555, 0x055555, 0x055555, 0x055555, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005150, 0x005514, + 0x001414, 0x001414, 0x005514, 0x005150, 0x000000, 0x000000, + }, + { + 0x000000, 0x000550, 0x001414, 0x001414, 0x000514, 0x001414, + 0x001414, 0x001414, 0x000554, 0x000014, 0x000050, 0x000000, + }, + { + 0x000000, 0x001554, 0x001414, 0x001414, 0x000014, 0x000014, + 0x000014, 0x000014, 0x000014, 0x000014, 0x000000, 0x000000, + }, + { + 0x000000, 0x005554, 0x001450, 0x001450, 0x001450, 0x001450, + 0x001450, 0x001450, 0x001450, 0x005050, 0x000000, 0x000000, + }, + { + 0x000000, 0x001554, 0x001014, 0x001050, 0x000050, 0x000140, + 0x000050, 0x001050, 0x001014, 0x001554, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005550, 0x000414, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005050, 0x005050, + 0x005050, 0x005050, 0x005050, 0x014550, 0x000050, 0x000014, + }, + { + 0x000000, 0x000000, 0x000000, 0x005150, 0x001514, 0x000500, + 0x000500, 0x000500, 0x000500, 0x005400, 0x000000, 0x000000, + }, + { + 0x000000, 0x001554, 0x000140, 0x000550, 0x001414, 0x001414, + 0x001414, 0x000550, 0x000140, 0x001554, 0x000000, 0x000000, + }, + { + 0x000000, 0x001550, 0x005014, 0x005014, 0x005014, 0x005554, + 0x005014, 0x005014, 0x005014, 0x001550, 0x000000, 0x000000, + }, + { + 0x000000, 0x005550, 0x014014, 0x014014, 0x014014, 0x014014, + 0x005050, 0x005050, 0x005050, 0x015054, 0x000000, 0x000000, + }, + { + 0x000000, 0x001540, 0x000050, 0x000140, 0x000550, 0x001414, + 0x001414, 0x001414, 0x001414, 0x000550, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x005150, 0x014514, 0x014514, + 0x014514, 0x005450, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x005000, 0x001550, 0x005514, 0x005114, + 0x005154, 0x001550, 0x000014, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x001540, 0x000050, 0x000014, 0x000014, 0x001554, + 0x000014, 0x000014, 0x000050, 0x001540, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000550, 0x001414, 0x001414, 0x001414, + 0x001414, 0x001414, 0x001414, 0x001414, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x001554, 0x000000, 0x000000, 0x001554, + 0x000000, 0x000000, 0x001554, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000140, 0x000140, 0x001554, 0x000140, + 0x000140, 0x000000, 0x001554, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000050, 0x000140, 0x000500, 0x000500, 0x000140, + 0x000050, 0x000000, 0x001554, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000500, 0x000140, 0x000050, 0x000050, 0x000140, + 0x000500, 0x000000, 0x001554, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x005400, 0x014500, 0x014500, 0x000500, + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + }, + { + 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, 0x000500, + 0x000500, 0x000514, 0x000514, 0x000150, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000140, 0x000140, 0x000000, 0x001554, + 0x000000, 0x000140, 0x000140, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x014150, 0x014514, 0x005414, 0x000000, + 0x014150, 0x014514, 0x005414, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x005500, 0x014140, 0x014140, 0x014140, 0x005500, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x005400, 0x005400, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x001400, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x054000, 0x004000, 0x004000, 0x004000, 0x004040, + 0x004140, 0x004500, 0x005400, 0x005000, 0x000000, 0x000000, + }, + { + 0x000000, 0x001450, 0x005140, 0x005140, 0x005140, 0x005140, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x001540, 0x005000, 0x001400, 0x000500, 0x005540, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x005500, 0x005500, 0x005500, 0x005500, + 0x005500, 0x005500, 0x005500, 0x005500, 0x000000, 0x000000, + }, + { + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, + }, +}; + +static av_cold int dfcmv_close_decoder(AVCodecContext *avctx) { + return 0; +} + +static int dfcmv_decode(AVCodecContext *avctx, void *data, + int *got_frame, AVPacket *avpkt) { + DFCMVCodecContext *cmv = avctx->priv_data; + ThreadFrame frame = { .f = data }; + AVFrame *p = data; + uint8_t attr; + uint8_t sprite_id; + uint32_t sprite_row; + uint8_t palette[3]; + uint32_t frame_idx; + int ret; + int x, y, x0, y0, x1, y1; + + if (avpkt->size < cmv->frame_size) { + av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n"); + return AVERROR_INVALIDDATA; + } + + if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0) { + return ret; + } + + for (y = 0; y < cmv->height; y++) { + y0 = y * 12; + for (x = 0; x < cmv->width; x++) { + x0 = x * 10; + attr = avpkt->data[cmv->half_frame_size + x * cmv->height + y]; + palette[0] = (attr >> 3) & 7; + palette[1] = (attr & 7) | ((attr >> 3) & (1 << 3)); + palette[2] = palette[1] + 16; + + for (y1 = 0; y1 < 12; y1++) { + sprite_id = avpkt->data[x * cmv->height + y]; + sprite_row = dfcmv_sprites[sprite_id][y1]; + for (x1 = 0; x1 < 10; x1++) { + frame_idx = (x0 + x1) + (y0 + y1) * p->linesize[0]; + p->data[0][frame_idx] = palette[sprite_row & 3]; + sprite_row = sprite_row >> 2; + } + } + } + } + memcpy(p->data[1], dfcmv_palette, sizeof(dfcmv_palette)); + p->pict_type = AV_PICTURE_TYPE_I; + p->key_frame = 1; + *got_frame = 1; + + return cmv->frame_size; +} + +AVCodec ff_dfcmv_decoder = { + .name = "dfcmv", + .long_name = NULL_IF_CONFIG_SMALL("Dwarf Fortress Curses MoVie"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_DFCMV, + .priv_data_size = sizeof(DFCMVCodecContext), + .init = dfcmv_init_decoder, + .close = dfcmv_close_decoder, + .decode = dfcmv_decode, +}; diff --git a/libavcodec/version.h b/libavcodec/version.h index 8b9c27378c..94bcbae2d6 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,8 +28,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 64 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 65 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavformat/Makefile b/libavformat/Makefile index 52f29b1a6d..5850ff3b1c 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -149,6 +149,7 @@ OBJS-$(CONFIG_DAUD_DEMUXER) += dauddec.o OBJS-$(CONFIG_DAUD_MUXER) += daudenc.o OBJS-$(CONFIG_DCSTR_DEMUXER) += dcstr.o OBJS-$(CONFIG_DFA_DEMUXER) += dfa.o +OBJS-$(CONFIG_DFCMV_DEMUXER) += dfcmv.o OBJS-$(CONFIG_DHAV_DEMUXER) += dhav.o OBJS-$(CONFIG_DIRAC_DEMUXER) += diracdec.o rawdec.o OBJS-$(CONFIG_DIRAC_MUXER) += rawenc.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index ff9bdb906f..f2668ded74 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -111,6 +111,7 @@ extern AVInputFormat ff_daud_demuxer; extern AVOutputFormat ff_daud_muxer; extern AVInputFormat ff_dcstr_demuxer; extern AVInputFormat ff_dfa_demuxer; +extern AVInputFormat ff_dfcmv_demuxer; extern AVInputFormat ff_dhav_demuxer; extern AVInputFormat ff_dirac_demuxer; extern AVOutputFormat ff_dirac_muxer; diff --git a/libavformat/dfcmv.c b/libavformat/dfcmv.c new file mode 100644 index 0000000000..0e8e465b0e --- /dev/null +++ b/libavformat/dfcmv.c @@ -0,0 +1,232 @@ +#include +#include "libavutil/avstring.h" +#include "libavutil/intreadwrite.h" +#include "avformat.h" +#include "internal.h" + +#define DFCMV_VERSION_0 10000 +#define DFCMV_VERSION_1 10001 + +typedef struct DFCMVContext { + int64_t total_frames; + uint32_t frame_size; + AVBufferRef *buffered_frames; + int buf_start, buf_end; +} DFCMVContext; + +static int dfcmv_probe(const AVProbeData *p) +{ + if (AV_RL32(p->buf) == DFCMV_VERSION_0 || + AV_RL32(p->buf) == DFCMV_VERSION_1) { + return AVPROBE_SCORE_MAX; + } + + return 0; +} + +static int dfcmv_read_header(AVFormatContext *s) +{ + int i, j; + uint32_t version; + uint32_t columns, rows; + uint32_t delay_rate; + uint32_t sound_count; + uint8_t *sound_names; + uint32_t sound_timing[200][16]; + AVStream *st; + DFCMVContext *cmv = s->priv_data; + AVIOContext *pb = s->pb; + + version = avio_rl32(pb); + if (version != DFCMV_VERSION_0 && version != DFCMV_VERSION_1) { + av_log(s, AV_LOG_ERROR, "cmv file has invalid version number %u\n", + version); + return AVERROR_INVALIDDATA; + } + + columns = avio_rl32(pb); + rows = avio_rl32(pb); + if (columns == 0 || rows == 0) { + av_log(s, AV_LOG_ERROR, "cmv file has invalid size %ux%u\n", + columns, rows); + return AVERROR_INVALIDDATA; + } + cmv->frame_size = columns * rows * 2; + + delay_rate = avio_rl32(pb); + if (delay_rate == 0) { + av_log(s, AV_LOG_WARNING, "cmv file claims to have infinite" + " frames per second; assuming 50 frames per second\n"); + delay_rate = 2; + } + + st = avformat_new_stream(s, NULL); + if (!st) { + return AVERROR(ENOMEM); + } + avpriv_set_pts_info(st, 64, delay_rate, 100); + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; + st->codecpar->codec_id = AV_CODEC_ID_DFCMV; + st->codecpar->width = columns * 10; + st->codecpar->height = rows * 12; + st->start_time = 0; + + if (version >= DFCMV_VERSION_1) { + sound_count = avio_rl32(pb); + + sound_names = av_calloc(sound_count, 50); + if (!sound_names) { + return AVERROR(ENOMEM); + } + + if (avio_read(pb, sound_names, sound_count * 50) + != sound_count * 50) { + av_free(sound_names); + return AVERROR(EIO); + } + + if (avio_read(pb, (uint8_t *)sound_timing, 4 * 200 * 16) + != 4 * 200 * 16) { + av_free(sound_names); + return AVERROR(EIO); + } + + for (i = 0; i < sound_count; i++) { + if (!sound_names[50 * i]) { + av_free(sound_names); + av_log(s, AV_LOG_WARNING, "cmv file contains" + " empty sound name\n"); + return AVERROR_INVALIDDATA; + } + if (av_strnlen(&sound_names[50 * i], 50) == 50) { + av_free(sound_names); + av_log(s, AV_LOG_WARNING, "cmv file contains" + " unterminated sound name\n"); + return AVERROR_INVALIDDATA; + } + } + + for (i = 0; i < 200; i++) { + for (j = 0; j < 16; j++) { + if (sound_timing[i][j] < sound_count) { + av_log(s, AV_LOG_WARNING, "cmv: todo: play sound" + " %s at frame %d (channel %d)\n", + &sound_names[50 * sound_timing[i][j]], i, j); + } + } + } + } + + return 0; +} + +static int dfcmv_load_chunk(AVFormatContext *s) { + int ret; + int64_t pos; + uint32_t compressed_size, max_size; + DFCMVContext *cmv = s->priv_data; + AVIOContext *pb = s->pb; + AVBufferRef *buf; + z_stream zstream = { 0 }; + + pos = avio_tell(pb); + + compressed_size = avio_rl32(pb); + + if (avio_feof(pb)) { + return avio_tell(pb) == pos ? AVERROR_EOF : AVERROR(EIO); + } + + max_size = cmv->frame_size * 200; + + cmv->buffered_frames = av_buffer_alloc(max_size); + if (!cmv->buffered_frames) { + return AVERROR(ENOMEM); + } + + buf = av_buffer_alloc(compressed_size); + if (!buf) { + return AVERROR(ENOMEM); + } + + if (avio_read(pb, buf->data, compressed_size) != compressed_size) { + av_buffer_unref(&buf); + return AVERROR(EIO); + } + + if (inflateInit(&zstream) != Z_OK) { + av_buffer_unref(&buf); + return -1; + } + + zstream.next_in = buf->data; + zstream.avail_in = buf->size; + zstream.next_out = cmv->buffered_frames->data; + zstream.avail_out = max_size; + + ret = inflate(&zstream, Z_FINISH); + + inflateEnd(&zstream); + av_buffer_unref(&buf); + + if (ret != Z_STREAM_END || zstream.avail_out % cmv->frame_size != 0) { + return -1; + } + + cmv->buf_start = 0; + cmv->buf_end = (max_size - zstream.avail_out) / cmv->frame_size; + + if (cmv->buf_end == 0) { + return -1; + } + + return 0; +} + +static int dfcmv_read_packet(AVFormatContext *s, AVPacket *pkt) +{ + DFCMVContext *cmv = s->priv_data; + int ret; + + if (cmv->buf_start == cmv->buf_end) { + av_buffer_unref(&cmv->buffered_frames); + + if ((ret = dfcmv_load_chunk(s)) < 0) { + return ret; + } + } + + av_init_packet(pkt); + pkt->buf = av_buffer_ref(cmv->buffered_frames); + if (!pkt->buf) { + return AVERROR(ENOMEM); + } + pkt->data = pkt->buf->data + (cmv->frame_size * cmv->buf_start); + pkt->size = cmv->frame_size; + pkt->pts = cmv->total_frames; + pkt->duration = 0; + cmv->total_frames++; + cmv->buf_start++; + + return 0; +} + +static int dfcmv_close(AVFormatContext *s) +{ + DFCMVContext *cmv = s->priv_data; + + av_buffer_unref(&cmv->buffered_frames); + + return 0; +} + +AVInputFormat ff_dfcmv_demuxer = { + .name = "dfcmv", + .long_name = NULL_IF_CONFIG_SMALL("Dwarf Fortress Curses MoVie"), + .priv_data_size = sizeof(DFCMVContext), + .read_probe = dfcmv_probe, + .read_header = dfcmv_read_header, + .read_packet = dfcmv_read_packet, + .read_close = dfcmv_close, + .extensions = "cmv", +}; diff --git a/libavformat/version.h b/libavformat/version.h index bac54aed9d..f72fb9478a 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 35 +#define LIBAVFORMAT_VERSION_MINOR 36 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \