aboutsummaryrefslogtreecommitdiff
path: root/image
diff options
context:
space:
mode:
authorPaul Gilbert2016-11-21 20:20:23 -0500
committerPaul Gilbert2016-11-21 20:20:23 -0500
commitb3c686195fa01434124079a3c8533d6b2f8b9795 (patch)
tree9d75d4eb7b229bc2df82069adeb8d302ce5ff735 /image
parent7e35499c8964f8f5757387a310f9eb61cb227368 (diff)
downloadscummvm-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.cpp4
-rw-r--r--image/codecs/indeo/indeo.h5
-rw-r--r--image/codecs/indeo4.cpp48
-rw-r--r--image/codecs/indeo4.h5
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);