diff options
author | Colin Snover | 2017-08-24 16:41:51 -0500 |
---|---|---|
committer | Colin Snover | 2017-08-24 20:36:08 -0500 |
commit | 4a39f85c1b283fe17531cfab4ba9b0cb7a6bd928 (patch) | |
tree | d2391491a9b6d8117959d7ab736076f04bf1114e /image | |
parent | d39a9272bf0334e5e98801ba06df89b4f59b79b8 (diff) | |
download | scummvm-rg350-4a39f85c1b283fe17531cfab4ba9b0cb7a6bd928.tar.gz scummvm-rg350-4a39f85c1b283fe17531cfab4ba9b0cb7a6bd928.tar.bz2 scummvm-rg350-4a39f85c1b283fe17531cfab4ba9b0cb7a6bd928.zip |
IMAGE: Implement handling of key color in Indeo transparency
This should also improve performance by eliminating unnecessary
writes to the output bitmap for opaque pixels and by simplifying
the rendering loop.
Diffstat (limited to 'image')
-rw-r--r-- | image/codecs/indeo/indeo.cpp | 3 | ||||
-rw-r--r-- | image/codecs/indeo/indeo.h | 1 | ||||
-rw-r--r-- | image/codecs/indeo4.cpp | 36 |
3 files changed, 18 insertions, 22 deletions
diff --git a/image/codecs/indeo/indeo.cpp b/image/codecs/indeo/indeo.cpp index 27db365cf0..34377537d7 100644 --- a/image/codecs/indeo/indeo.cpp +++ b/image/codecs/indeo/indeo.cpp @@ -444,7 +444,8 @@ IVI45DecContext::IVI45DecContext() : _gb(nullptr), _frameNum(0), _frameType(0), _bRefBuf(0), _rvmapSel(0), _inImf(false), _inQ(false), _picGlobQuant(0), _unknown1(0), _gopHdrSize(0), _gopFlags(0), _lockWord(0), _hasBFrames(false), _hasTransp(false), _usesTiling(false), _usesHaar(false), _usesFullpel(false), - _gopInvalid(false), _isIndeo4(false), _pFrame(nullptr), _gotPFrame(false) { + _gopInvalid(false), _isIndeo4(false), _transKeyColor(0), _pFrame(nullptr), + _gotPFrame(false) { Common::fill(&_bufInvalid[0], &_bufInvalid[4], 0); Common::copy(&_ff_ivi_rvmap_tabs[0], &_ff_ivi_rvmap_tabs[9], &_rvmapTabs[0]); diff --git a/image/codecs/indeo/indeo.h b/image/codecs/indeo/indeo.h index 6c2a6b17a2..d9740ecf61 100644 --- a/image/codecs/indeo/indeo.h +++ b/image/codecs/indeo/indeo.h @@ -420,6 +420,7 @@ public: int _bufInvalid[4]; bool _isIndeo4; + uint32 _transKeyColor; AVFrame * _pFrame; bool _gotPFrame; diff --git a/image/codecs/indeo4.cpp b/image/codecs/indeo4.cpp index 65aed6a559..bc777cfb85 100644 --- a/image/codecs/indeo4.cpp +++ b/image/codecs/indeo4.cpp @@ -26,6 +26,7 @@ * written, produced, and directed by Alan Smithee */ +#include "common/algorithm.h" #include "common/debug.h" #include "common/memstream.h" #include "common/rect.h" @@ -111,6 +112,12 @@ int Indeo4Decoder::decodePictureHeader() { _ctx._hasBFrames = true; _ctx._hasTransp = _ctx._gb->getBit(); + if (_ctx._hasTransp && _surface.format.aBits() == 0) { + // Surface is 4 bytes per pixel, but only RGB. So promote the + // surface to full RGBA, and convert all the existing pixels + _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); + _surface.convertToInPlace(_pixelFormat); + } // unknown bit: Mac decoder ignores this bit, XANIM returns error if (_ctx._gb->getBit()) { @@ -605,8 +612,6 @@ int Indeo4Decoder::decodeRLETransparency(VLC_TYPE (*table)[2]) { bool runIsOpaque = _ctx._gb->getBit(); bool nextRunIsOpaque = !runIsOpaque; - const uint32 opacityMask = 0xFF << _pixelFormat.aShift; - uint32 *pixel = (uint32 *)_surface.getPixels(); const int surfacePixelPitch = _surface.pitch / _surface.format.bytesPerPixel; const int surfacePadding = surfacePixelPitch - _surface.w; @@ -655,14 +660,12 @@ int Indeo4Decoder::decodeRLETransparency(VLC_TYPE (*table)[2]) { } while (value > 0) { - if (runIsOpaque) { - *pixel = *pixel | opacityMask; - } else { - *pixel = *pixel & ~opacityMask; + const int length = MIN<int>(value, endOfVisibleRow - pixel); + if (!runIsOpaque) { + Common::fill(pixel, pixel + length, _ctx._transKeyColor); } - - --value; - ++pixel; + value -= length; + pixel += length; if (pixel == endOfVisibleRow) { pixel += surfacePadding; @@ -715,11 +718,9 @@ int Indeo4Decoder::decodeTransparency() { if (_ctx._gb->getBit()) { /* @350 */ /* @358 */ - int unknown = (_ctx._gb->getBits(8) << 16) | (_ctx._gb->getBits(8) << 8) | (_ctx._gb->getBits(8)); - debug(4, "Indeo4: Unknown is %08x", unknown); + _ctx._transKeyColor = _surface.format.ARGBToColor(0, _ctx._gb->getBits(8), _ctx._gb->getBits(8), _ctx._gb->getBits(8)); + debug(4, "Indeo4: Key color is %08x", _ctx._transKeyColor); /* @477 */ - // This unknown value gets written out to IVIPicture.field_f8 and does - // not seem to have any obvious effect on the transparency rendering } if (_ctx._gb->getBit() == 0) { /* @4D9 */ @@ -767,13 +768,6 @@ int Indeo4Decoder::decodeTransparency() { assert(!_ctx._isScalable); assert(!_ctx._usesTiling); - if (_surface->format.aBits() == 0) { - // Surface is 4 bytes per pixel, but only RGB. So promote the - // surface to full RGBA, and convert all the existing pixels - _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); - _surface->convertToInPlace(_pixelFormat); - } - assert(_surface.format.bytesPerPixel == 4); assert((_surface.pitch % 4) == 0); @@ -788,7 +782,7 @@ int Indeo4Decoder::decodeTransparency() { // It should only be necessary to draw transparency here since the // data from the YUV planes gets drawn to the output surface on each // frame, which resets the surface pixels to be fully opaque - _surface.fillRect(Common::Rect(_surface.w, _surface.h), 0); + _surface.fillRect(Common::Rect(_surface.w, _surface.h), _ctx._transKeyColor); } // No alignment here |