[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