aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--image/codecs/indeo/indeo.cpp3
-rw-r--r--image/codecs/indeo/indeo.h1
-rw-r--r--image/codecs/indeo4.cpp36
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