diff options
author | Strangerke | 2013-06-26 23:11:34 +0200 |
---|---|---|
committer | Strangerke | 2013-06-26 23:11:34 +0200 |
commit | 6e2d567bca53b6ffee771b4105e2e73dbd73f5b4 (patch) | |
tree | 9880f0c496263ffb6928248d495ce4172dabed18 /video/codecs/cinepak.cpp | |
parent | ac387835e4527c1814919093b4e4bc9798d5742d (diff) | |
parent | 6716fa39a6fb2a3925576288c256688c5aadd7e9 (diff) | |
download | scummvm-rg350-6e2d567bca53b6ffee771b4105e2e73dbd73f5b4.tar.gz scummvm-rg350-6e2d567bca53b6ffee771b4105e2e73dbd73f5b4.tar.bz2 scummvm-rg350-6e2d567bca53b6ffee771b4105e2e73dbd73f5b4.zip |
Merge branch 'master' of https://github.com/scummvm/scummvm into mortevielle
Conflicts:
engines/engines.mk
Diffstat (limited to 'video/codecs/cinepak.cpp')
-rw-r--r-- | video/codecs/cinepak.cpp | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/video/codecs/cinepak.cpp b/video/codecs/cinepak.cpp index c197e0cc35..bcf0cf1180 100644 --- a/video/codecs/cinepak.cpp +++ b/video/codecs/cinepak.cpp @@ -34,16 +34,12 @@ namespace Video { -// Convert a color from YUV to RGB colorspace, Cinepak style. -inline static void CPYUV2RGB(byte y, byte u, byte v, byte &r, byte &g, byte &b) { - r = CLIP<int>(y + 2 * (v - 128), 0, 255); - g = CLIP<int>(y - (u - 128) / 2 - (v - 128), 0, 255); - b = CLIP<int>(y + 2 * (u - 128), 0, 255); -} - #define PUT_PIXEL(offset, lum, u, v) \ if (_pixelFormat.bytesPerPixel != 1) { \ - CPYUV2RGB(lum, u, v, r, g, b); \ + byte r = _clipTable[lum + (v << 1)]; \ + byte g = _clipTable[lum - (u >> 1) - v]; \ + byte b = _clipTable[lum + (u << 1)]; \ + \ if (_pixelFormat.bytesPerPixel == 2) \ *((uint16 *)_curFrame.surface->pixels + offset) = _pixelFormat.RGBToColor(r, g, b); \ else \ @@ -60,6 +56,21 @@ CinepakDecoder::CinepakDecoder(int bitsPerPixel) : Codec() { _pixelFormat = Graphics::PixelFormat::createFormatCLUT8(); else _pixelFormat = g_system->getScreenFormat(); + + // Create a lookup for the clip function + // This dramatically improves the performance of the color conversion + _clipTableBuf = new byte[1024]; + + for (uint i = 0; i < 1024; i++) { + if (i <= 512) + _clipTableBuf[i] = 0; + else if (i >= 768) + _clipTableBuf[i] = 255; + else + _clipTableBuf[i] = i - 512; + } + + _clipTable = _clipTableBuf + 512; } CinepakDecoder::~CinepakDecoder() { @@ -69,6 +80,7 @@ CinepakDecoder::~CinepakDecoder() { } delete[] _curFrame.strips; + delete[] _clipTableBuf; } const Graphics::Surface *CinepakDecoder::decodeImage(Common::SeekableReadStream *stream) { @@ -82,15 +94,14 @@ const Graphics::Surface *CinepakDecoder::decodeImage(Common::SeekableReadStream if (_curFrame.strips == NULL) _curFrame.strips = new CinepakStrip[_curFrame.stripCount]; - debug (4, "Cinepak Frame: Width = %d, Height = %d, Strip Count = %d", _curFrame.width, _curFrame.height, _curFrame.stripCount); + debug(4, "Cinepak Frame: Width = %d, Height = %d, Strip Count = %d", _curFrame.width, _curFrame.height, _curFrame.stripCount); // Borrowed from FFMPEG. This should cut out the extra data Cinepak for Sega has (which is useless). // The theory behind this is that this is here to confuse standard Cinepak decoders. But, we won't let that happen! ;) if (_curFrame.length != (uint32)stream->size()) { - uint16 temp = stream->readUint16BE(); - if (temp == 0xFE00) + if (stream->readUint16BE() == 0xFE00) stream->readUint32BE(); - else if (temp != _curFrame.width) + else if ((stream->size() % _curFrame.length) == 0) stream->seek(-2, SEEK_CUR); } @@ -191,14 +202,14 @@ void CinepakDecoder::loadCodebook(Common::SeekableReadStream *stream, uint16 str codebook[i].y[j] = stream->readByte(); if (n == 6) { - codebook[i].u = stream->readByte() + 128; - codebook[i].v = stream->readByte() + 128; + codebook[i].u = stream->readSByte(); + codebook[i].v = stream->readSByte(); } else { // This codebook type indicates either greyscale or // palettized video. For greyscale, default us to - // 128 for both u and v. - codebook[i].u = 128; - codebook[i].v = 128; + // 0 for both u and v. + codebook[i].u = 0; + codebook[i].v = 0; } } } @@ -208,7 +219,6 @@ void CinepakDecoder::decodeVectors(Common::SeekableReadStream *stream, uint16 st uint32 flag = 0, mask = 0; uint32 iy[4]; int32 startPos = stream->pos(); - byte r = 0, g = 0, b = 0; for (uint16 y = _curFrame.strips[strip].rect.top; y < _curFrame.strips[strip].rect.bottom; y += 4) { iy[0] = _curFrame.strips[strip].rect.left + y * _curFrame.width; |