diff options
author | Matthew Hoops | 2012-12-04 20:19:00 -0500 |
---|---|---|
committer | Matthew Hoops | 2012-12-04 20:19:00 -0500 |
commit | 285e1be1353dc098cff6c67d3e61535de2bbe41d (patch) | |
tree | f3af2efa0bdc18dce31a0faab0c1526fa641effe | |
parent | dd50e98309c1f8e8bb3aaf571a09437c994a60e9 (diff) | |
download | scummvm-rg350-285e1be1353dc098cff6c67d3e61535de2bbe41d.tar.gz scummvm-rg350-285e1be1353dc098cff6c67d3e61535de2bbe41d.tar.bz2 scummvm-rg350-285e1be1353dc098cff6c67d3e61535de2bbe41d.zip |
VIDEO: Improve performance of the Cinepak decoder
-rw-r--r-- | video/codecs/cinepak.cpp | 41 | ||||
-rw-r--r-- | video/codecs/cinepak.h | 6 |
2 files changed, 30 insertions, 17 deletions
diff --git a/video/codecs/cinepak.cpp b/video/codecs/cinepak.cpp index f457d83749..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,7 +94,7 @@ 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! ;) @@ -190,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; } } } @@ -207,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; diff --git a/video/codecs/cinepak.h b/video/codecs/cinepak.h index ca4552fae6..7abda6f400 100644 --- a/video/codecs/cinepak.h +++ b/video/codecs/cinepak.h @@ -36,8 +36,9 @@ class SeekableReadStream; namespace Video { struct CinepakCodebook { - byte y[4]; - byte u, v; + // These are not in the normal YUV colorspace, but in the Cinepak YUV colorspace instead. + byte y[4]; // [0, 255] + int8 u, v; // [-128, 127] }; struct CinepakStrip { @@ -70,6 +71,7 @@ private: CinepakFrame _curFrame; int32 _y; Graphics::PixelFormat _pixelFormat; + byte *_clipTable, *_clipTableBuf; void loadCodebook(Common::SeekableReadStream *stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize); void decodeVectors(Common::SeekableReadStream *stream, uint16 strip, byte chunkID, uint32 chunkSize); |