[Scummvm-git-logs] scummvm master -> d1aa5ae9d7fba289972b16a0b89e44370a6d0421

lephilousophe lephilousophe at users.noreply.github.com
Sat Apr 10 08:59:12 UTC 2021


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
bb34721dd4 IMAGE: added GIFDecoder using libgif
d1aa5ae9d7 TWINE: updated prepareGIF to finally use the GIFDecoder


Commit: bb34721dd4ccf8e1413f8949bb511307e81eb1a0
    https://github.com/scummvm/scummvm/commit/bb34721dd4ccf8e1413f8949bb511307e81eb1a0
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-04-10T10:59:09+02:00

Commit Message:
IMAGE: added GIFDecoder using libgif

Changed paths:
  A image/gif.cpp
  A image/gif.h
  A test/.gitignore
  A test/image/gif.h
    .github/workflows/ci.yml
    .travis.yml
    configure
    devtools/create_project/create_project.cpp
    image/module.mk
    test/module.mk


diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 201f1ab876..d851cd44ea 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,21 +15,21 @@ jobs:
             arch: x86
             # fribidi is disabled due to timeouts when installing the package
             configFlags: --enable-faad --enable-mpeg2 --enable-discord --disable-fribidi
-            vcpkgPackages: 'curl discord-rpc faad2 fluidsynth freetype glew libflac libjpeg-turbo libmad libmpeg2 libogg libpng libtheora libvorbis sdl2 sdl2-net zlib'
+            vcpkgPackages: 'curl discord-rpc faad2 fluidsynth freetype glew libflac libjpeg-turbo libmad libmpeg2 libogg libpng libtheora libvorbis sdl2 sdl2-net zlib giflib'
             useNasm: 'true'
           - platform: x64
             arch: x64
             triplet: x64-windows
             # fribidi is disabled due to timeouts when installing the package
             configFlags: --enable-faad --enable-mpeg2 --enable-discord --disable-fribidi
-            vcpkgPackages: 'curl discord-rpc faad2 fluidsynth freetype glew libflac libjpeg-turbo libmad libmpeg2 libogg libpng libtheora libvorbis sdl2 sdl2-net zlib'
+            vcpkgPackages: 'curl discord-rpc faad2 fluidsynth freetype glew libflac libjpeg-turbo libmad libmpeg2 libogg libpng libtheora libvorbis sdl2 sdl2-net zlib giflib'
           - platform: arm64
             arch: arm64
             triplet: arm64-windows
             # fribidi is disabled due to https://github.com/microsoft/vcpkg/issues/11248 [fribidi] Fribidi doesn't cross-compile on x86-64 to target arm/arm64
             # Note that fribidi is also disabled on arm64 in devtools/create_project/msvc.cpp
             configFlags: --enable-faad --enable-mpeg2 --enable-discord --disable-fribidi --disable-opengl
-            vcpkgPackages: 'curl discord-rpc faad2 fluidsynth freetype libflac libjpeg-turbo libmad libmpeg2 libogg libpng libtheora libvorbis sdl2 sdl2-net zlib'
+            vcpkgPackages: 'curl discord-rpc faad2 fluidsynth freetype libflac libjpeg-turbo libmad libmpeg2 libogg libpng libtheora libvorbis sdl2 sdl2-net zlib giflib'
     env:
       CONFIGURATION: Release
       PLATFORM: ${{ matrix.platform }}
@@ -103,7 +103,7 @@ jobs:
           - platform: macosx
             buildFlags: -scheme ScummVM-macOS
             configFlags: --disable-nasm --enable-faad --enable-mpeg2
-            brewPackages: a52dec faad2 flac fluid-synth freetype fribidi glew mad libmpeg2 libogg libpng libvorbis sdl2 sdl2_net theora
+            brewPackages: a52dec faad2 flac fluid-synth freetype fribidi glew mad libmpeg2 libogg libpng libvorbis sdl2 sdl2_net theora giflib
           - platform: ios7
             buildFlags: -scheme ScummVM-iOS CODE_SIGN_IDENTITY="" CODE_SIGNING_ALLOWED=NO
             configFlags: --disable-nasm --disable-opengl --disable-theora --disable-taskbar --disable-tts --disable-fribidi
diff --git a/.travis.yml b/.travis.yml
index e54265f378..b6d7026908 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -32,6 +32,7 @@ addons:
     - libsndio-dev
     - libreadline-dev
     - libglew-dev
+    - libgif-dev
 
 branches:
  only:
diff --git a/configure b/configure
index 95ccbe92db..8bc644ad08 100755
--- a/configure
+++ b/configure
@@ -154,6 +154,7 @@ _sparkle=auto
 _osxdockplugin=auto
 _jpeg=auto
 _png=auto
+_gif=auto
 _theoradec=auto
 _faad=auto
 _fluidsynth=auto
@@ -272,6 +273,7 @@ add_feature jpeg "JPEG" "_jpeg"
 add_feature mpeg2 "mpeg2" "_mpeg2"
 add_feature opengl_game_shaders "OpenGL with shaders" "_opengl_game_shaders"
 add_feature png "PNG" "_png"
+add_feature png "GIF" "_gif"
 add_feature theoradec "libtheoradec" "_theoradec"
 add_feature tinygl "TinyGL" "_tinygl"
 add_feature vorbis "Vorbis file support" "_vorbis _tremor"
@@ -1111,6 +1113,8 @@ for ac_option in $@; do
 	--enable-jpeg)                _jpeg=yes              ;;
 	--disable-png)                _png=no                ;;
 	--enable-png)                 _png=yes               ;;
+	--disable-gif)                _gif=no                ;;
+	--enable-gif)                 _gif=yes               ;;
 	--disable-theoradec)          _theoradec=no          ;;
 	--enable-theoradec)           _theoradec=yes         ;;
 	--disable-faad)               _faad=no               ;;
@@ -4477,6 +4481,37 @@ fi
 define_in_config_if_yes "$_png" 'USE_PNG'
 echo "$_png"
 
+#
+# Check for GIF
+#
+echocheck "GIF >= 5.0.0"
+if test "$_pkg_config" = "yes" && $_pkgconfig --exists libgif; then
+	append_var GIF_LIBS "`$_pkgconfig --libs libgif`"
+	append_var GIF_CFLAGS "`$_pkgconfig --cflags libgif`"
+else
+	append_var GIF_LIBS "-lgif"
+fi
+if test "$_gif" = auto ; then
+	_gif=no
+	cat > $TMPC << EOF
+#include <gif_lib.h>
+int main(void) {
+#if GIFLIB_MAJOR >= 5
+#else
+  syntax error
+#endif
+  return 0;
+}
+EOF
+	cc_check $GIF_CFLAGS $GIF_LIBS && _gif=yes
+fi
+if test "$_gif" = yes ; then
+	append_var LIBS "$GIF_LIBS"
+	append_var INCLUDES "$GIF_CFLAGS"
+fi
+define_in_config_if_yes "$_gif" 'USE_GIF'
+echo "$_gif"
+
 #
 # Check for Theora Decoder
 #
diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp
index d597233ca9..b30be619c1 100644
--- a/devtools/create_project/create_project.cpp
+++ b/devtools/create_project/create_project.cpp
@@ -1043,6 +1043,7 @@ const Feature s_features[] = {
 	{    "tremor",      "USE_TREMOR", true, false, "Tremor support" },
 	{      "flac",        "USE_FLAC", true, true,  "FLAC support" },
 	{       "png",         "USE_PNG", true, true,  "libpng support" },
+	{       "gif",         "USE_GIF", true, false, "libgif support" },
 	{      "faad",        "USE_FAAD", true, false, "AAC support" },
 	{     "mpeg2",       "USE_MPEG2", true, false, "MPEG-2 support" },
 	{    "theora",   "USE_THEORADEC", true, true,  "Theora decoding support" },
diff --git a/image/gif.cpp b/image/gif.cpp
new file mode 100644
index 0000000000..0b1cec87d9
--- /dev/null
+++ b/image/gif.cpp
@@ -0,0 +1,145 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "image/gif.h"
+
+#include "common/array.h"
+#include "common/stream.h"
+#include "common/textconsole.h"
+#include "common/util.h"
+#include "graphics/surface.h"
+#include "graphics/pixelformat.h"
+
+#ifdef USE_GIF
+#include <gif_lib.h>
+#endif
+
+namespace Image {
+
+GIFDecoder::GIFDecoder() : _outputSurface(0), _palette(0), _colorCount(0) {
+}
+
+GIFDecoder::~GIFDecoder() {
+	destroy();
+}
+
+#ifdef USE_GIF
+static int gifReadFromStream(GifFileType *gif, GifByteType *bytes, int size) {
+	Common::SeekableReadStream *stream = (Common::SeekableReadStream *)gif->UserData;
+	return stream->read(bytes, size);
+}
+#endif
+
+bool GIFDecoder::loadStream(Common::SeekableReadStream &stream) {
+	destroy();
+
+#ifdef USE_GIF
+	int error = 0;
+	GifFileType *gif = DGifOpen(&stream, gifReadFromStream, &error);
+	if (!gif) {
+		warning("GIF open failed with error %s", GifErrorString(error));
+		return false;
+	}
+
+	const int errcode = DGifSlurp(gif);
+	if (errcode != GIF_OK) {
+		warning("GIF failed to load");
+		DGifCloseFile(gif, 0);
+		return false;
+	}
+
+	if (gif->ImageCount <= 0) {
+		warning("GIF doesn't contain valid image data");
+		DGifCloseFile(gif, 0);
+		return false;
+	}
+
+	if (gif->ImageCount > 1) {
+		warning("GIF contains more than one frame - only loading the first one");
+	}
+
+	const SavedImage *gifImage = gif->SavedImages;
+
+	const int width = gif->SWidth;
+	const int height = gif->SHeight;
+
+	const ColorMapObject *colorMap = gif->SColorMap;
+	_transparentColor = NO_TRANSPARENT_COLOR;
+	for (int i = 0; i < gif->ExtensionBlockCount; ++i) {
+		const ExtensionBlock &eb = gif->ExtensionBlocks[i];
+		GraphicsControlBlock gcb;
+		DGifExtensionToGCB(eb.ByteCount, eb.Bytes, &gcb);
+		if (gcb.TransparentColor != NO_TRANSPARENT_COLOR) {
+			_transparentColor = gcb.TransparentColor;
+			break;
+		}
+	}
+
+	_colorCount = colorMap->ColorCount;
+	_outputSurface = new Graphics::Surface();
+	_palette = new uint8[_colorCount * 3];
+
+	const Graphics::PixelFormat format = Graphics::PixelFormat::createFormatCLUT8();
+	for (int i = 0; i < _colorCount; ++i) {
+		_palette[(i * 3) + 0] = colorMap->Colors[i].Red;
+		_palette[(i * 3) + 1] = colorMap->Colors[i].Green;
+		_palette[(i * 3) + 2] = colorMap->Colors[i].Blue;
+	}
+
+	// TODO: support transparency
+
+	_outputSurface->create(width, height, format);
+	const uint8 *in = (const uint8 *)gifImage->RasterBits;
+	uint8 *pixelPtr = (uint8 *)_outputSurface->getBasePtr(0, 0);
+	if (gif->Image.Interlace) {
+		const int interlacedOffset[] = {0, 4, 2, 1};
+		const int interlacedJumps[] = {8, 8, 4, 2};
+		for (int i = 0; i < 4; ++i) {
+			for (int row = interlacedOffset[i]; row < height; row += interlacedJumps[i]) {
+				memcpy(pixelPtr + width * row, in, width);
+				in += width;
+			}
+		}
+	} else {
+		memcpy(pixelPtr, in, width * height);
+	}
+
+	DGifCloseFile(gif, 0);
+	return true;
+#else
+	return false;
+#endif
+}
+
+void GIFDecoder::destroy() {
+	if (_outputSurface) {
+		_outputSurface->free();
+		delete _outputSurface;
+		_outputSurface = 0;
+	}
+	if (_palette) {
+		delete[] _palette;
+		_palette = 0;
+	}
+}
+
+} // End of namespace Image
diff --git a/image/gif.h b/image/gif.h
new file mode 100644
index 0000000000..9a88acf460
--- /dev/null
+++ b/image/gif.h
@@ -0,0 +1,71 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef IMAGE_GIF_H
+#define IMAGE_GIF_H
+
+#include "image/image_decoder.h"
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Graphics {
+struct Surface;
+}
+
+namespace Image {
+
+/**
+ * @defgroup image_gif GIF decoder
+ * @ingroup image
+ *
+ * @brief Decoder for images encoded as Graphics Interchange Format (GIF).
+ *
+ * This decoder has a dependency on the libgif library.
+ *
+ * Used in engines:
+ * - TwinE
+ * @{
+ */
+class GIFDecoder : public ImageDecoder {
+public:
+	GIFDecoder();
+	~GIFDecoder();
+
+	bool loadStream(Common::SeekableReadStream &stream) override;
+	void destroy() override;
+	const byte *getPalette() const override { return _palette; }
+	uint16 getPaletteColorCount() const override { return _colorCount; }
+	const Graphics::Surface *getSurface() const override { return _outputSurface; }
+	int getTransparentColor() const { return _transparentColor; }
+private:
+	Graphics::Surface *_outputSurface;
+	uint8 *_palette;
+	uint16 _colorCount;
+	int _transparentColor;
+};
+
+/** @} */
+} // End of namespace Image
+
+#endif
diff --git a/image/module.mk b/image/module.mk
index 23424e5ced..c3a4535b29 100644
--- a/image/module.mk
+++ b/image/module.mk
@@ -3,6 +3,7 @@ MODULE := image
 MODULE_OBJS := \
 	bmp.o \
 	cel_3do.o \
+	gif.o \
 	iff.o \
 	jpeg.o \
 	pcx.o \
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000000..44a6cb3e88
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1 @@
+/engine-data
diff --git a/test/image/gif.h b/test/image/gif.h
new file mode 100644
index 0000000000..f371d0f138
--- /dev/null
+++ b/test/image/gif.h
@@ -0,0 +1,41 @@
+#include <cxxtest/TestSuite.h>
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include "common/memstream.h"
+#include "image/gif.h"
+#include "graphics/surface.h"
+
+class GIFDecoderTestSuite : public CxxTest::TestSuite {
+public:
+	void test_load_gif_2x2() {
+#ifdef USE_GIF
+		const uint8 gifBuf[63] = {
+			0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x02, 0x00, 0x02, 0x00, 0xa1,
+			0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x14, 0x82, 0x31,
+			0xff, 0xff, 0xff, 0x21, 0xfe, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74,
+			0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d,
+			0x50, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+			0x00, 0x02, 0x03, 0x54, 0x06, 0x05, 0x00, 0x3b
+		};
+
+		Image::GIFDecoder decoder;
+		Common::MemoryReadStream stream(gifBuf, sizeof(gifBuf));
+		const bool status = decoder.loadStream(stream);
+		TS_ASSERT(status);
+		if (!status) {
+			return;
+		}
+		const Graphics::Surface *surface = decoder.getSurface();
+		TS_ASSERT(surface != 0);
+		if (surface == 0) {
+			return;
+		}
+		TS_ASSERT_EQUALS(surface->w, 2);
+		TS_ASSERT_EQUALS(surface->h, 2);
+		TS_ASSERT_EQUALS(surface->format.bytesPerPixel, 1);
+#endif
+	}
+};
diff --git a/test/module.mk b/test/module.mk
index e0fa9d3e61..db5bad8461 100644
--- a/test/module.mk
+++ b/test/module.mk
@@ -5,7 +5,7 @@
 #
 ######################################################################
 
-TESTS        := $(srcdir)/test/common/*.h $(srcdir)/test/audio/*.h $(srcdir)/test/math/*.h
+TESTS        := $(srcdir)/test/common/*.h $(srcdir)/test/audio/*.h $(srcdir)/test/math/*.h $(srcdir)/test/image/*.h
 TEST_LIBS    :=
 
 ifdef POSIX
@@ -27,7 +27,7 @@ TEST_LIBS += test/null_osystem.o \
 	backends/modular-backend.o
 endif
 
-TEST_LIBS +=	audio/libaudio.a math/libmath.a common/libcommon.a
+TEST_LIBS +=	audio/libaudio.a math/libmath.a common/libcommon.a image/libimage.a graphics/libgraphics.a
 
 ifeq ($(ENABLE_WINTERMUTE), STATIC_PLUGIN)
 	TESTS += $(srcdir)/test/engines/wintermute/*.h


Commit: d1aa5ae9d7fba289972b16a0b89e44370a6d0421
    https://github.com/scummvm/scummvm/commit/d1aa5ae9d7fba289972b16a0b89e44370a6d0421
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2021-04-10T10:59:09+02:00

Commit Message:
TWINE: updated prepareGIF to finally use the GIFDecoder

Changed paths:
    engines/twine/flamovies.cpp


diff --git a/engines/twine/flamovies.cpp b/engines/twine/flamovies.cpp
index c279bcd685..75454b28c9 100644
--- a/engines/twine/flamovies.cpp
+++ b/engines/twine/flamovies.cpp
@@ -23,6 +23,7 @@
 #include "twine/flamovies.h"
 #include "common/file.h"
 #include "common/system.h"
+#include "image/gif.h"
 #include "twine/audio/music.h"
 #include "twine/audio/sound.h"
 #include "twine/input.h"
@@ -270,8 +271,6 @@ void FlaMovies::processFrame() {
 FlaMovies::FlaMovies(TwinEEngine *engine) : _engine(engine) {}
 
 void FlaMovies::prepareGIF(int index) {
-	// TODO: version 87a 640x480
-#if 0
 	Image::GIFDecoder decoder;
 	Common::SeekableReadStream *stream = HQR::makeReadStream(Resources::HQR_FLAGIF_FILE, index);
 	if (stream == nullptr) {
@@ -284,16 +283,13 @@ void FlaMovies::prepareGIF(int index) {
 		return;
 	}
 	const Graphics::Surface *surface = decoder.getSurface();
-	const bool state = Graphics::crossBlit((uint8*)_engine->imageBuffer.getPixels(), (const uint8*)surface->getPixels(), _engine->imageBuffer.pitch, surface->pitch, surface->w, surface->h, _engine->imageBuffer.format, surface->format);
-	if (!state) {
-		error("Failed to blit");
-	}
-	_engine->frontVideoBuffer.transBlitFrom(_engine->imageBuffer, _engine->imageBuffer.getBounds(), _engine->frontVideoBuffer.getBounds());
-	debug(2, "Show gif with id %i from FLA_GIF.HQR", index);
-	_engine->flip();
+	_engine->setPalette(0, decoder.getPaletteColorCount(), decoder.getPalette());
+	g_system->copyRectToScreen(surface->getPixels(), surface->pitch, 0, 0, surface->w, surface->h);
+	g_system->updateScreen();
+	debug(2, "Show gif with id %i from %s", index, Resources::HQR_FLAGIF_FILE);
 	delete stream;
-	g_system->delayMillis(5000);
-#endif
+	_engine->delaySkip(5000);
+	_engine->setPalette(_engine->_screens->paletteRGBA);
 }
 
 void FlaMovies::playGIFMovie(const char *flaName) {




More information about the Scummvm-git-logs mailing list