diff options
author | Paul Gilbert | 2016-11-21 20:20:23 -0500 |
---|---|---|
committer | Paul Gilbert | 2016-11-21 20:20:23 -0500 |
commit | b3c686195fa01434124079a3c8533d6b2f8b9795 (patch) | |
tree | 9d75d4eb7b229bc2df82069adeb8d302ce5ff735 /image | |
parent | 7e35499c8964f8f5757387a310f9eb61cb227368 (diff) | |
download | scummvm-rg350-b3c686195fa01434124079a3c8533d6b2f8b9795.tar.gz scummvm-rg350-b3c686195fa01434124079a3c8533d6b2f8b9795.tar.bz2 scummvm-rg350-b3c686195fa01434124079a3c8533d6b2f8b9795.zip |
IMAGE: Add hack to Indeo 4 decoder to guess transparent areas
Diffstat (limited to 'image')
-rw-r--r-- | image/codecs/indeo/indeo.cpp | 4 | ||||
-rw-r--r-- | image/codecs/indeo/indeo.h | 5 | ||||
-rw-r--r-- | image/codecs/indeo4.cpp | 48 | ||||
-rw-r--r-- | image/codecs/indeo4.h | 5 |
4 files changed, 62 insertions, 0 deletions
diff --git a/image/codecs/indeo/indeo.cpp b/image/codecs/indeo/indeo.cpp index f82c4829af..a20a3ec113 100644 --- a/image/codecs/indeo/indeo.cpp +++ b/image/codecs/indeo/indeo.cpp @@ -607,6 +607,10 @@ int IndeoDecoderBase::decodeIndeoFrame() { // Free the now un-needed frame data frame->freeFrame(); + // If there's any transparency data, decode it + if (_ctx._hasTransp) + decodeTransparency(); + return 0; } diff --git a/image/codecs/indeo/indeo.h b/image/codecs/indeo/indeo.h index 068f8c9f25..dcb7330318 100644 --- a/image/codecs/indeo/indeo.h +++ b/image/codecs/indeo/indeo.h @@ -564,6 +564,11 @@ protected: virtual int decodeMbInfo(IVIBandDesc *band, IVITile *tile) = 0; /** + * Decodes optional transparency data within Indeo frames + */ + virtual void decodeTransparency() {} + + /** * Decodes the Indeo frame from the bit reader already * loaded into the context */ diff --git a/image/codecs/indeo4.cpp b/image/codecs/indeo4.cpp index 6141bf0fc8..b3a5d3a2bf 100644 --- a/image/codecs/indeo4.cpp +++ b/image/codecs/indeo4.cpp @@ -595,6 +595,54 @@ int Indeo4Decoder::decodeMbInfo(IVIBandDesc *band, IVITile *tile) { return 0; } +void Indeo4Decoder::decodeTransparency() { + // FIXME: Since I don't currently know how to decode the transparency layer, + // I'm currently doing a hack where I take the color of the top left corner, + // and mark the range of pixels of that color from the start and end of + // each line as transparent + assert(_surface->format.bytesPerPixel == 4); + byte r, g, b, a; + + 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 + Graphics::PixelFormat oldFormat = _pixelFormat; + _pixelFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0); + _surface->format = _pixelFormat; + + for (int y = 0; y < _surface->h; ++y) { + uint32 *lineP = (uint32 *)_surface->getBasePtr(0, y); + for (int x = 0; x < _surface->w; ++x, ++lineP) { + oldFormat.colorToRGB(*lineP, r, g, b); + *lineP = _pixelFormat.ARGBToColor(0xff, r, g, b); + } + } + } else { + // Working on a frame when the surface is already RGBA. In which case, + // start of by defaulting all pixels of the frame to fully opaque + for (int y = 0; y < _surface->h; ++y) { + uint32 *lineP = (uint32 *)_surface->getBasePtr(0, y); + for (int x = 0; x < _surface->w; ++x, ++lineP) + *lineP |= 0xff; + } + } + + // Use the top-left pixel as the key color, and figure out the + // equivalent value as fully transparent + uint32 keyColor = *(const uint32 *)_surface->getPixels(); + uint32 transColor = keyColor & ~0xff; + + for (int y = 0; y < _surface->h; ++y) { + uint32 *startP = (uint32 *)_surface->getBasePtr(0, y); + uint32 *endP = (uint32 *)_surface->getBasePtr(_surface->w - 1, y); + + while (startP <= endP && *startP == keyColor) + *startP++ = transColor; + while (endP > startP && *endP == keyColor) + *endP-- = transColor; + } +} + int Indeo4Decoder::scaleTileSize(int defSize, int sizeFactor) { return sizeFactor == 15 ? defSize : (sizeFactor + 1) << 5; } diff --git a/image/codecs/indeo4.h b/image/codecs/indeo4.h index 420acc3f33..8b7fdab3f9 100644 --- a/image/codecs/indeo4.h +++ b/image/codecs/indeo4.h @@ -89,6 +89,11 @@ protected: * @returns result code: 0 = OK, negative number = error */ virtual int decodeMbInfo(IVIBandDesc *band, IVITile *tile); + + /** + * Decodes optional transparency data within Indeo frames + */ + virtual void decodeTransparency(); private: int scaleTileSize(int defSize, int sizeFactor); |