[Scummvm-git-logs] scummvm master -> 8ffa7379014916eff11005ae324ec24c68abd4bf

bgK bastien.bouclet at gmail.com
Sun Apr 28 07:59:19 CEST 2019


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

Summary:
0d5d04ca3a IMAGE: Allow setting the output pixel format to the JPEG decoder
9f98cddf8d IMAGE: Don't perform color conversion when decoding PNGs
8ffa737901 IMAGE: Remove decoding JPEG directly to RGB565


Commit: 0d5d04ca3a5473f24f45112bb40a009679024acc
    https://github.com/scummvm/scummvm/commit/0d5d04ca3a5473f24f45112bb40a009679024acc
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2019-04-28T07:59:14+02:00

Commit Message:
IMAGE: Allow setting the output pixel format to the JPEG decoder

Changed paths:
    engines/glk/picture.cpp
    engines/groovie/roq.cpp
    engines/titanic/support/image_decoders.cpp
    graphics/yuv_to_rgb.h
    image/codecs/mjpeg.cpp
    image/jpeg.cpp
    image/jpeg.h


diff --git a/engines/glk/picture.cpp b/engines/glk/picture.cpp
index a47d8bf..3064444 100644
--- a/engines/glk/picture.cpp
+++ b/engines/glk/picture.cpp
@@ -125,6 +125,7 @@ Picture *Pictures::load(uint32 id) {
 		palette = png.getPalette();
 		palCount = png.getPaletteColorCount();
 	} else if (f.open(Common::String::format("pic%u.jpg", id))) {
+		jpg.setOutputPixelFormat(g_system->getScreenFormat());
 		jpg.loadStream(f);
 		img = jpg.getSurface();
 	} else if (f.open(Common::String::format("pic%u.raw", id))) {
diff --git a/engines/groovie/roq.cpp b/engines/groovie/roq.cpp
index c1b6c44..2e9a394 100644
--- a/engines/groovie/roq.cpp
+++ b/engines/groovie/roq.cpp
@@ -470,6 +470,7 @@ bool ROQPlayer::processBlockStill(ROQBlockHeader &blockHeader) {
 	debugC(5, kDebugVideo, "Groovie::ROQ: Processing still (JPEG) block");
 
 	Image::JPEGDecoder jpg;
+	jpg.setOutputPixelFormat(_vm->_pixelFormat);
 
 	uint32 startPos = _file->pos();
 	Common::SeekableSubReadStream subStream(_file, startPos, startPos + blockHeader.size, DisposeAfterUse::NO);
@@ -478,7 +479,9 @@ bool ROQPlayer::processBlockStill(ROQBlockHeader &blockHeader) {
 	const Graphics::Surface *srcSurf = jpg.getSurface();
 	_currBuf->free();
 	delete _currBuf;
-	_currBuf = srcSurf->convertTo(_vm->_pixelFormat);
+
+	_currBuf = new Graphics::Surface();
+	_currBuf->copyFrom(*srcSurf);
 
 	_file->seek(startPos + blockHeader.size);
 	return true;
diff --git a/engines/titanic/support/image_decoders.cpp b/engines/titanic/support/image_decoders.cpp
index 3819b85..7c902b2 100644
--- a/engines/titanic/support/image_decoders.cpp
+++ b/engines/titanic/support/image_decoders.cpp
@@ -20,6 +20,7 @@
  *
  */
 
+#include "common/system.h"
 #include "titanic/support/image_decoders.h"
 
 namespace Titanic {
@@ -29,7 +30,8 @@ void CJPEGDecode::decode(OSVideoSurface &surface, const CString &name) {
 	StdCWadFile file;
 	file.open(name);
 
-	// Use the ScucmmVM deoder to decode it
+	// Use the ScummVM decoder to decode it
+	setOutputPixelFormat(g_system->getScreenFormat());
 	loadStream(*file.readStream());
 	const Graphics::Surface *srcSurf = getSurface();
 
@@ -38,15 +40,14 @@ void CJPEGDecode::decode(OSVideoSurface &surface, const CString &name) {
 			|| surface.getHeight() != srcSurf->h)
 		surface.recreate(srcSurf->w, srcSurf->h, 16);
 
-	// Convert the decoded surface to the correct pixel format, and then copy it over
+	// Copy the decoded surface
 	surface.lock();
-	Graphics::Surface *convertedSurface = srcSurf->convertTo(surface._rawSurface->format);
 
-	Common::copy((byte *)convertedSurface->getPixels(), (byte *)convertedSurface->getPixels() +
+	assert(srcSurf->format == surface._rawSurface->format);
+
+	Common::copy((const byte *)srcSurf->getPixels(), (const byte *)srcSurf->getPixels() +
 		surface.getPitch() * surface.getHeight(), (byte *)surface._rawSurface->getPixels());
 
-	convertedSurface->free();
-	delete convertedSurface;
 	surface.unlock();
 }
 
diff --git a/graphics/yuv_to_rgb.h b/graphics/yuv_to_rgb.h
index a1e61ec..3d11f35 100644
--- a/graphics/yuv_to_rgb.h
+++ b/graphics/yuv_to_rgb.h
@@ -24,9 +24,6 @@
  * @file
  * YUV to RGB conversion.
  *
- * Used in graphics:
- * - JPEGDecoder
- *
  * Used in video:
  * - BinkDecoder
  * - Indeo3Decoder
diff --git a/image/codecs/mjpeg.cpp b/image/codecs/mjpeg.cpp
index 6e7faf1..c5f8153 100644
--- a/image/codecs/mjpeg.cpp
+++ b/image/codecs/mjpeg.cpp
@@ -200,6 +200,7 @@ const Graphics::Surface *MJPEGDecoder::decodeFrame(Common::SeekableReadStream &s
 
 	Common::MemoryReadStream convertedStream(data, outputSize, DisposeAfterUse::YES);
 	JPEGDecoder jpeg;
+	jpeg.setOutputPixelFormat(_pixelFormat);
 
 	if (!jpeg.loadStream(convertedStream)) {
 		warning("Failed to decode MJPEG frame");
@@ -211,7 +212,10 @@ const Graphics::Surface *MJPEGDecoder::decodeFrame(Common::SeekableReadStream &s
 		delete _surface;
 	}
 
-	_surface = jpeg.getSurface()->convertTo(_pixelFormat);
+	_surface = new Graphics::Surface();
+	_surface->copyFrom(*jpeg.getSurface());
+
+	assert(_surface->format == _pixelFormat);
 
 	return _surface;
 }
diff --git a/image/jpeg.cpp b/image/jpeg.cpp
index 1ce45f2..5cc348f 100644
--- a/image/jpeg.cpp
+++ b/image/jpeg.cpp
@@ -30,6 +30,7 @@
 #include "common/endian.h"
 #include "common/stream.h"
 #include "common/textconsole.h"
+#include "common/util.h"
 #include "graphics/pixelformat.h"
 
 #ifdef USE_JPEG
@@ -44,13 +45,24 @@ extern "C" {
 
 namespace Image {
 
-JPEGDecoder::JPEGDecoder() : _surface(), _colorSpace(kColorSpaceRGBA) {
+JPEGDecoder::JPEGDecoder() :
+		_surface(),
+		_colorSpace(kColorSpaceRGB),
+		_requestedPixelFormat(getByteOrderRgbPixelFormat()) {
 }
 
 JPEGDecoder::~JPEGDecoder() {
 	destroy();
 }
 
+Graphics::PixelFormat JPEGDecoder::getByteOrderRgbPixelFormat() const {
+#ifdef SCUMM_BIG_ENDIAN
+	return Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0);
+#else
+	return Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
+#endif
+}
+
 const Graphics::Surface *JPEGDecoder::getSurface() const {
 	return &_surface;
 }
@@ -171,6 +183,44 @@ void outputMessage(j_common_ptr cinfo) {
 	debug(3, "libjpeg: %s", buffer);
 }
 
+J_COLOR_SPACE fromScummvmPixelFormat(const Graphics::PixelFormat &format) {
+	struct PixelFormatMapping {
+		Graphics::PixelFormat pixelFormat;
+		J_COLOR_SPACE bigEndianColorSpace;
+		J_COLOR_SPACE littleEndianColorSpace;
+	};
+
+	static const PixelFormatMapping mappings[] = {
+#ifdef JCS_EXTENSIONS
+		{ Graphics::PixelFormat(4, 8, 8, 8, 0, 24, 16,  8,  0), JCS_EXT_RGBX, JCS_EXT_XBGR },
+		{ Graphics::PixelFormat(4, 8, 8, 8, 0,  0,  8, 16, 24), JCS_EXT_XBGR, JCS_EXT_RGBX },
+		{ Graphics::PixelFormat(4, 8, 8, 8, 0, 16,  8,  0, 24), JCS_EXT_XRGB, JCS_EXT_BGRX },
+		{ Graphics::PixelFormat(4, 8, 8, 8, 0,  8, 16, 24,  0), JCS_EXT_BGRX, JCS_EXT_XRGB },
+		{ Graphics::PixelFormat(3, 8, 8, 8, 0, 16,  8,  0,  0), JCS_EXT_RGB,  JCS_EXT_BGR  },
+		{ Graphics::PixelFormat(3, 8, 8, 8, 0,  0,  8, 16,  0), JCS_EXT_BGR,  JCS_EXT_RGB  },
+#endif
+#ifdef JCS_ALPHA_EXTENSIONS
+		{ Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0), JCS_EXT_RGBA, JCS_EXT_ABGR },
+		{ Graphics::PixelFormat(4, 8, 8, 8, 8,  0,  8, 16, 24), JCS_EXT_ABGR, JCS_EXT_RGBA },
+		{ Graphics::PixelFormat(4, 8, 8, 8, 8, 16,  8,  0, 24), JCS_EXT_ARGB, JCS_EXT_BGRA },
+		{ Graphics::PixelFormat(4, 8, 8, 8, 8,  8, 16, 24,  0), JCS_EXT_BGRA, JCS_EXT_ARGB },
+#endif
+		{ Graphics::PixelFormat(2, 5, 6, 5, 0, 11,  5,  0,  0), JCS_RGB565,   JCS_RGB565   }
+	};
+
+	for (uint i = 0; i < ARRAYSIZE(mappings); i++) {
+		if (mappings[i].pixelFormat == format) {
+#ifdef SCUMM_BIG_ENDIAN
+			return mappings[i].bigEndianColorSpace;
+#else
+			return mappings[i].littleEndianColorSpace;
+#endif
+		}
+	}
+
+	return JCS_UNKNOWN;
+}
+
 } // End of anonymous namespace
 #endif
 
@@ -198,10 +248,19 @@ bool JPEGDecoder::loadStream(Common::SeekableReadStream &stream) {
 
 	// We can request YUV output because Groovie requires it
 	switch (_colorSpace) {
-	case kColorSpaceRGBA:
-		cinfo.out_color_space = JCS_RGB;
-		break;
+	case kColorSpaceRGB: {
+		J_COLOR_SPACE colorSpace = fromScummvmPixelFormat(_requestedPixelFormat);
+
+		if (colorSpace == JCS_UNKNOWN) {
+			// When libjpeg-turbo is not available or an unhandled pixel
+			// format was requested, ask libjpeg to decode to byte order RGB
+			// as it's always available.
+			colorSpace = JCS_RGB;
+		}
 
+		cinfo.out_color_space = colorSpace;
+		break;
+	}
 	case kColorSpaceYUV:
 		cinfo.out_color_space = JCS_YCbCr;
 		break;
@@ -212,11 +271,16 @@ bool JPEGDecoder::loadStream(Common::SeekableReadStream &stream) {
 
 	// Allocate buffers for the output data
 	switch (_colorSpace) {
-	case kColorSpaceRGBA:
-		// We use RGBA8888 in this scenario
-		_surface.create(cinfo.output_width, cinfo.output_height, Graphics::PixelFormat(4, 8, 8, 8, 0, 24, 16, 8, 0));
+	case kColorSpaceRGB: {
+		Graphics::PixelFormat outputPixelFormat;
+		if (cinfo.out_color_space == JCS_RGB) {
+			outputPixelFormat = getByteOrderRgbPixelFormat();
+		} else {
+			outputPixelFormat = _requestedPixelFormat;
+		}
+		_surface.create(cinfo.output_width, cinfo.output_height, outputPixelFormat);
 		break;
-
+	}
 	case kColorSpaceYUV:
 		// We use YUV with 3 bytes per pixel otherwise.
 		// This is pretty ugly since our PixelFormat cannot express YUV...
@@ -225,8 +289,7 @@ bool JPEGDecoder::loadStream(Common::SeekableReadStream &stream) {
 	}
 
 	// Allocate buffer for one scanline
-	assert(cinfo.output_components == 3);
-	JDIMENSION pitch = cinfo.output_width * cinfo.output_components;
+	JDIMENSION pitch = cinfo.output_width * _surface.format.bytesPerPixel;
 	assert(_surface.pitch >= pitch);
 	JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, pitch, 1);
 
@@ -236,38 +299,17 @@ bool JPEGDecoder::loadStream(Common::SeekableReadStream &stream) {
 
 		jpeg_read_scanlines(&cinfo, buffer, 1);
 
-		const byte *src = buffer[0];
-		switch (_colorSpace) {
-		case kColorSpaceRGBA: {
-			for (int remaining = cinfo.output_width; remaining > 0; --remaining) {
-				byte r = *src++;
-				byte g = *src++;
-				byte b = *src++;
-				// We need to insert a alpha value of 255 (opaque) here.
-#ifdef SCUMM_BIG_ENDIAN
-				*dst++ = r;
-				*dst++ = g;
-				*dst++ = b;
-				*dst++ = 0xFF;
-#else
-				*dst++ = 0xFF;
-				*dst++ = b;
-				*dst++ = g;
-				*dst++ = r;
-#endif
-			}
-			} break;
-
-		case kColorSpaceYUV:
-			memcpy(dst, src, pitch);
-			break;
-		}
+		memcpy(dst, buffer[0], pitch);
 	}
 
 	// We are done with decompressing, thus free all the data
 	jpeg_finish_decompress(&cinfo);
 	jpeg_destroy_decompress(&cinfo);
 
+	if (_colorSpace == kColorSpaceRGB && _surface.format != _requestedPixelFormat) {
+		_surface.convertToInPlace(_requestedPixelFormat); // Slow path
+	}
+
 	return true;
 #else
 	return false;
diff --git a/image/jpeg.h b/image/jpeg.h
index ac0d22d..08b5c01 100644
--- a/image/jpeg.h
+++ b/image/jpeg.h
@@ -60,11 +60,11 @@ public:
 	// Special API for JPEG
 	enum ColorSpace {
 		/**
-		 * Output 32bit RGBA data.
+		 * Output RGB data in the pixel format specified using `setOutputPixelFormat`.
 		 *
 		 * This is the default output.
 		 */
-		kColorSpaceRGBA,
+		kColorSpaceRGB,
 
 		/**
 		 * Output (interleaved) YUV data.
@@ -86,15 +86,25 @@ public:
 	 * Request the output color space. This can be used to obtain raw YUV
 	 * data from the JPEG file. But this might not work for all files!
 	 *
-	 * The decoder itself defaults to RGBA.
+	 * The decoder itself defaults to RGB.
 	 *
 	 * @param outSpace The color space to output.
 	 */
 	void setOutputColorSpace(ColorSpace outSpace) { _colorSpace = outSpace; }
 
+	/**
+	 * Request the output pixel format. The JPEG decoder provides high performance
+	 * color conversion routines for some pixel formats. This setting allows to use
+	 * them and avoid costly subsequent color conversion.
+	 */
+	void setOutputPixelFormat(const Graphics::PixelFormat &format) { _requestedPixelFormat = format; }
+
 private:
 	Graphics::Surface _surface;
 	ColorSpace _colorSpace;
+	Graphics::PixelFormat _requestedPixelFormat;
+
+	Graphics::PixelFormat getByteOrderRgbPixelFormat() const;
 };
 
 } // End of namespace Image


Commit: 9f98cddf8dc015e0cdc6b57e303b693bba3cc1fc
    https://github.com/scummvm/scummvm/commit/9f98cddf8dc015e0cdc6b57e303b693bba3cc1fc
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2019-04-28T07:59:14+02:00

Commit Message:
IMAGE: Don't perform color conversion when decoding PNGs

Changed paths:
    image/png.cpp
    image/png.h


diff --git a/image/png.cpp b/image/png.cpp
index 50a53b0..d835171 100644
--- a/image/png.cpp
+++ b/image/png.cpp
@@ -39,7 +39,11 @@
 
 namespace Image {
 
-PNGDecoder::PNGDecoder() : _outputSurface(0), _palette(0), _paletteColorCount(0), _skipSignature(false) {
+PNGDecoder::PNGDecoder() :
+        _outputSurface(0),
+        _palette(0),
+        _paletteColorCount(0),
+        _skipSignature(false) {
 }
 
 PNGDecoder::~PNGDecoder() {
@@ -56,6 +60,14 @@ void PNGDecoder::destroy() {
 	_palette = NULL;
 }
 
+Graphics::PixelFormat PNGDecoder::getByteOrderRgbaPixelFormat() const {
+#ifdef SCUMM_BIG_ENDIAN
+	return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
+#else
+	return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
+#endif
+}
+
 #ifdef USE_PNG
 // libpng-error-handling:
 void pngError(png_structp pngptr, png_const_charp errorMsg) {
@@ -166,13 +178,11 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
 		_outputSurface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
 		png_set_packing(pngPtr);
 	} else {
-		bool isAlpha = (colorType & PNG_COLOR_MASK_ALPHA);
 		if (png_get_valid(pngPtr, infoPtr, PNG_INFO_tRNS)) {
-			isAlpha = true;
 			png_set_expand(pngPtr);
 		}
-		_outputSurface->create(width, height, Graphics::PixelFormat(4,
-		                       8, 8, 8, isAlpha ? 8 : 0, 24, 16, 8, 0));
+
+		_outputSurface->create(width, height, getByteOrderRgbaPixelFormat());
 		if (!_outputSurface->getPixels()) {
 			error("Could not allocate memory for output image.");
 		}
@@ -184,17 +194,8 @@ bool PNGDecoder::loadStream(Common::SeekableReadStream &stream) {
 			colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
 			png_set_gray_to_rgb(pngPtr);
 
-		// PNGs are Big-Endian:
-#ifdef SCUMM_LITTLE_ENDIAN
-		png_set_bgr(pngPtr);
-		png_set_swap_alpha(pngPtr);
-		if (colorType != PNG_COLOR_TYPE_RGB_ALPHA)
-			png_set_filler(pngPtr, 0xff, PNG_FILLER_BEFORE);
-#else
 		if (colorType != PNG_COLOR_TYPE_RGB_ALPHA)
 			png_set_filler(pngPtr, 0xff, PNG_FILLER_AFTER);
-#endif
-
 	}
 
 	// After the transformations have been registered, the image data is read again.
diff --git a/image/png.h b/image/png.h
index cdc3e3f..adbc6d7 100644
--- a/image/png.h
+++ b/image/png.h
@@ -33,6 +33,7 @@
 
 #include "common/scummsys.h"
 #include "common/textconsole.h"
+#include "graphics/pixelformat.h"
 #include "image/image_decoder.h"
 
 namespace Common {
@@ -57,7 +58,10 @@ public:
 	const byte *getPalette() const { return _palette; }
 	uint16 getPaletteColorCount() const { return _paletteColorCount; }
 	void setSkipSignature(bool skip) { _skipSignature = skip; }
+
 private:
+	Graphics::PixelFormat getByteOrderRgbaPixelFormat() const;
+
 	byte *_palette;
 	uint16 _paletteColorCount;
 


Commit: 8ffa7379014916eff11005ae324ec24c68abd4bf
    https://github.com/scummvm/scummvm/commit/8ffa7379014916eff11005ae324ec24c68abd4bf
Author: Bastien Bouclet (bastien.bouclet at gmail.com)
Date: 2019-04-28T07:59:14+02:00

Commit Message:
IMAGE: Remove decoding JPEG directly to RGB565

It's not supported by ancient versions of libjpeg-turbo, and there is no
way to detect if support is available without doing a compilation
test...

Changed paths:
    image/jpeg.cpp


diff --git a/image/jpeg.cpp b/image/jpeg.cpp
index 5cc348f..2a528d5 100644
--- a/image/jpeg.cpp
+++ b/image/jpeg.cpp
@@ -197,15 +197,17 @@ J_COLOR_SPACE fromScummvmPixelFormat(const Graphics::PixelFormat &format) {
 		{ Graphics::PixelFormat(4, 8, 8, 8, 0, 16,  8,  0, 24), JCS_EXT_XRGB, JCS_EXT_BGRX },
 		{ Graphics::PixelFormat(4, 8, 8, 8, 0,  8, 16, 24,  0), JCS_EXT_BGRX, JCS_EXT_XRGB },
 		{ Graphics::PixelFormat(3, 8, 8, 8, 0, 16,  8,  0,  0), JCS_EXT_RGB,  JCS_EXT_BGR  },
-		{ Graphics::PixelFormat(3, 8, 8, 8, 0,  0,  8, 16,  0), JCS_EXT_BGR,  JCS_EXT_RGB  },
+		{ Graphics::PixelFormat(3, 8, 8, 8, 0,  0,  8, 16,  0), JCS_EXT_BGR,  JCS_EXT_RGB  }
+#endif
+#if defined(JCS_EXTENSIONS) and defined(JCS_ALPHA_EXTENSIONS)
+		,
 #endif
 #ifdef JCS_ALPHA_EXTENSIONS
 		{ Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16,  8,  0), JCS_EXT_RGBA, JCS_EXT_ABGR },
 		{ Graphics::PixelFormat(4, 8, 8, 8, 8,  0,  8, 16, 24), JCS_EXT_ABGR, JCS_EXT_RGBA },
 		{ Graphics::PixelFormat(4, 8, 8, 8, 8, 16,  8,  0, 24), JCS_EXT_ARGB, JCS_EXT_BGRA },
-		{ Graphics::PixelFormat(4, 8, 8, 8, 8,  8, 16, 24,  0), JCS_EXT_BGRA, JCS_EXT_ARGB },
+		{ Graphics::PixelFormat(4, 8, 8, 8, 8,  8, 16, 24,  0), JCS_EXT_BGRA, JCS_EXT_ARGB }
 #endif
-		{ Graphics::PixelFormat(2, 5, 6, 5, 0, 11,  5,  0,  0), JCS_RGB565,   JCS_RGB565   }
 	};
 
 	for (uint i = 0; i < ARRAYSIZE(mappings); i++) {





More information about the Scummvm-git-logs mailing list