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/codecs/indeo4.cpp | |
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/codecs/indeo4.cpp')
-rw-r--r-- | image/codecs/indeo4.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
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; } |