[FFmpeg-devel] [PATCH] avformat, avcodec: add dfcmv demuxer and decoder
Ben Lubar
ben at lubar.me
Tue Dec 3 08:34:17 EET 2019
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.
Signed-off-by: Ben Lubar <ben at lubar.me>
---
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 | 383 +++++++++++++++++++++++++++++++++++++++
libavcodec/version.h | 4 +-
libavformat/Makefile | 1 +
libavformat/allformats.c | 1 +
libavformat/dfcmv.c | 222 +++++++++++++++++++++++
libavformat/version.h | 2 +-
13 files changed, 624 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 <next>:
- 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
+ at 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
+ at 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..2c692ca9bd
--- /dev/null
+++ b/libavcodec/dfcmv.c
@@ -0,0 +1,383 @@
+#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 uint32_t dfcmv_palette[] = {
+ 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 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;
+ uint32_t sprite_row;
+ uint8_t palette[3];
+ 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_row = dfcmv_sprites[avpkt->data[x *
cmv->height + y]][y1];
+ for (x1 = 0; x1 < 10; x1++) {
+ p->data[0][(x0 + x1) + (y0 + y1) *
p->linesize[0]] = 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..01fc67b7c1
--- /dev/null
+++ b/libavformat/dfcmv.c
@@ -0,0 +1,222 @@
+#include <zlib.h>
+#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, \
--
2.24.0
More information about the ffmpeg-devel
mailing list