[Scummvm-git-logs] scummvm master -> 604708ad9897d2eeb687982c63e46bc8c2fc7ad8
sev-
noreply at scummvm.org
Mon Apr 22 00:07:52 UTC 2024
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
f683ecbf7b IMAGE: Cache the dithered Cinepak codebooks when using VFW-style dithering
ed59ab8a3b IMAGE: Make use of aligned loads and stores when dithering Cinepak videos
2cb46c19ed IMAGE: Split Cinepak CodebookConverterRaw into 8bpp and 24bpp versions
011e468fa1 IMAGE: Handle the surface pitch in Cinepak videos
604708ad98 IMAGE: Combine lookup tables for Cinepak with VFW dithering
Commit: f683ecbf7b2ccfd73ba326570862f18d2dd98c1d
https://github.com/scummvm/scummvm/commit/f683ecbf7b2ccfd73ba326570862f18d2dd98c1d
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-04-22T02:07:47+02:00
Commit Message:
IMAGE: Cache the dithered Cinepak codebooks when using VFW-style dithering
Changed paths:
image/codecs/cinepak.cpp
image/codecs/cinepak.h
diff --git a/image/codecs/cinepak.cpp b/image/codecs/cinepak.cpp
index 1133eccd731..ad088959985 100644
--- a/image/codecs/cinepak.cpp
+++ b/image/codecs/cinepak.cpp
@@ -77,7 +77,7 @@ inline void putPixelRaw(byte *dst, const byte *clipTable, const Graphics::PixelF
*/
struct CodebookConverterRaw {
template<typename PixelInt>
- static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, PixelInt *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
+ static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, PixelInt *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
const CinepakCodebook &codebook = strip.v1_codebook[codebookIndex];
putPixelRaw(rows[0] + 0, clipTable, format, codebook.y[0], codebook.u, codebook.v);
putPixelRaw(rows[0] + 1, clipTable, format, codebook.y[0], codebook.u, codebook.v);
@@ -101,7 +101,7 @@ struct CodebookConverterRaw {
}
template<typename PixelInt>
- static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, PixelInt *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
+ static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, PixelInt *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
const CinepakCodebook &codebook1 = strip.v4_codebook[codebookIndex[0]];
putPixelRaw(rows[0] + 0, clipTable, format, codebook1.y[0], codebook1.u, codebook1.v);
putPixelRaw(rows[0] + 1, clipTable, format, codebook1.y[1], codebook1.u, codebook1.v);
@@ -129,145 +129,10 @@ struct CodebookConverterRaw {
};
/**
- * Codebook converter that dithers in VFW-style
+ * Codebook converter that dithers in QT-style or VFW-style
*/
-struct CodebookConverterDitherVFW {
- static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
- const CinepakCodebook &codebook = strip.v1_codebook[codebookIndex];
- byte blockBuffer[16];
- ditherCodebookSmooth(codebook, blockBuffer, colorMap);
- rows[0][0] = blockBuffer[0];
- rows[0][1] = blockBuffer[1];
- rows[0][2] = blockBuffer[2];
- rows[0][3] = blockBuffer[3];
- rows[1][0] = blockBuffer[4];
- rows[1][1] = blockBuffer[5];
- rows[1][2] = blockBuffer[6];
- rows[1][3] = blockBuffer[7];
- rows[2][0] = blockBuffer[8];
- rows[2][1] = blockBuffer[9];
- rows[2][2] = blockBuffer[10];
- rows[2][3] = blockBuffer[11];
- rows[3][0] = blockBuffer[12];
- rows[3][1] = blockBuffer[13];
- rows[3][2] = blockBuffer[14];
- rows[3][3] = blockBuffer[15];
- }
-
- static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
- byte blockBuffer[16];
- ditherCodebookDetail(strip.v4_codebook[codebookIndex[0]], blockBuffer, colorMap);
- rows[0][0] = blockBuffer[0];
- rows[0][1] = blockBuffer[1];
- rows[1][0] = blockBuffer[4];
- rows[1][1] = blockBuffer[5];
-
- ditherCodebookDetail(strip.v4_codebook[codebookIndex[1]], blockBuffer, colorMap);
- rows[0][2] = blockBuffer[2];
- rows[0][3] = blockBuffer[3];
- rows[1][2] = blockBuffer[6];
- rows[1][3] = blockBuffer[7];
-
- ditherCodebookDetail(strip.v4_codebook[codebookIndex[2]], blockBuffer, colorMap);
- rows[2][0] = blockBuffer[8];
- rows[2][1] = blockBuffer[9];
- rows[3][0] = blockBuffer[12];
- rows[3][1] = blockBuffer[13];
-
- ditherCodebookDetail(strip.v4_codebook[codebookIndex[3]], blockBuffer, colorMap);
- rows[2][2] = blockBuffer[10];
- rows[2][3] = blockBuffer[11];
- rows[3][2] = blockBuffer[14];
- rows[3][3] = blockBuffer[15];
- }
-
-private:
- static inline void ditherCodebookDetail(const CinepakCodebook &codebook, byte *dst, const byte *colorMap) {
- int uLookup = (byte)codebook.u * 2;
- int vLookup = (byte)codebook.v * 2;
- uint32 uv1 = s_uLookup[uLookup] | s_vLookup[vLookup];
- uint32 uv2 = s_uLookup[uLookup + 1] | s_vLookup[vLookup + 1];
-
- int yLookup1 = codebook.y[0] * 2;
- int yLookup2 = codebook.y[1] * 2;
- int yLookup3 = codebook.y[2] * 2;
- int yLookup4 = codebook.y[3] * 2;
-
- uint32 pixelGroup1 = uv2 | s_yLookup[yLookup1 + 1];
- uint32 pixelGroup2 = uv2 | s_yLookup[yLookup2 + 1];
- uint32 pixelGroup3 = uv1 | s_yLookup[yLookup3];
- uint32 pixelGroup4 = uv1 | s_yLookup[yLookup4];
- uint32 pixelGroup5 = uv1 | s_yLookup[yLookup1];
- uint32 pixelGroup6 = uv1 | s_yLookup[yLookup2];
- uint32 pixelGroup7 = uv2 | s_yLookup[yLookup3 + 1];
- uint32 pixelGroup8 = uv2 | s_yLookup[yLookup4 + 1];
-
- dst[0] = getRGBLookupEntry(colorMap, pixelGroup1 & 0xFFFF);
- dst[1] = getRGBLookupEntry(colorMap, pixelGroup2 >> 16);
- dst[2] = getRGBLookupEntry(colorMap, pixelGroup5 & 0xFFFF);
- dst[3] = getRGBLookupEntry(colorMap, pixelGroup6 >> 16);
- dst[4] = getRGBLookupEntry(colorMap, pixelGroup3 & 0xFFFF);
- dst[5] = getRGBLookupEntry(colorMap, pixelGroup4 >> 16);
- dst[6] = getRGBLookupEntry(colorMap, pixelGroup7 & 0xFFFF);
- dst[7] = getRGBLookupEntry(colorMap, pixelGroup8 >> 16);
- dst[8] = getRGBLookupEntry(colorMap, pixelGroup1 >> 16);
- dst[9] = getRGBLookupEntry(colorMap, pixelGroup6 & 0xFFFF);
- dst[10] = getRGBLookupEntry(colorMap, pixelGroup5 >> 16);
- dst[11] = getRGBLookupEntry(colorMap, pixelGroup2 & 0xFFFF);
- dst[12] = getRGBLookupEntry(colorMap, pixelGroup3 >> 16);
- dst[13] = getRGBLookupEntry(colorMap, pixelGroup8 & 0xFFFF);
- dst[14] = getRGBLookupEntry(colorMap, pixelGroup7 >> 16);
- dst[15] = getRGBLookupEntry(colorMap, pixelGroup4 & 0xFFFF);
- }
-
- static inline void ditherCodebookSmooth(const CinepakCodebook &codebook, byte *dst, const byte *colorMap) {
- int uLookup = (byte)codebook.u * 2;
- int vLookup = (byte)codebook.v * 2;
- uint32 uv1 = s_uLookup[uLookup] | s_vLookup[vLookup];
- uint32 uv2 = s_uLookup[uLookup + 1] | s_vLookup[vLookup + 1];
-
- int yLookup1 = codebook.y[0] * 2;
- int yLookup2 = codebook.y[1] * 2;
- int yLookup3 = codebook.y[2] * 2;
- int yLookup4 = codebook.y[3] * 2;
-
- uint32 pixelGroup1 = uv2 | s_yLookup[yLookup1 + 1];
- uint32 pixelGroup2 = uv1 | s_yLookup[yLookup2];
- uint32 pixelGroup3 = uv1 | s_yLookup[yLookup1];
- uint32 pixelGroup4 = uv2 | s_yLookup[yLookup2 + 1];
- uint32 pixelGroup5 = uv2 | s_yLookup[yLookup3 + 1];
- uint32 pixelGroup6 = uv1 | s_yLookup[yLookup3];
- uint32 pixelGroup7 = uv1 | s_yLookup[yLookup4];
- uint32 pixelGroup8 = uv2 | s_yLookup[yLookup4 + 1];
-
- dst[0] = getRGBLookupEntry(colorMap, pixelGroup1 & 0xFFFF);
- dst[1] = getRGBLookupEntry(colorMap, pixelGroup1 >> 16);
- dst[2] = getRGBLookupEntry(colorMap, pixelGroup2 & 0xFFFF);
- dst[3] = getRGBLookupEntry(colorMap, pixelGroup2 >> 16);
- dst[4] = getRGBLookupEntry(colorMap, pixelGroup3 & 0xFFFF);
- dst[5] = getRGBLookupEntry(colorMap, pixelGroup3 >> 16);
- dst[6] = getRGBLookupEntry(colorMap, pixelGroup4 & 0xFFFF);
- dst[7] = getRGBLookupEntry(colorMap, pixelGroup4 >> 16);
- dst[8] = getRGBLookupEntry(colorMap, pixelGroup5 >> 16);
- dst[9] = getRGBLookupEntry(colorMap, pixelGroup6 & 0xFFFF);
- dst[10] = getRGBLookupEntry(colorMap, pixelGroup7 >> 16);
- dst[11] = getRGBLookupEntry(colorMap, pixelGroup8 & 0xFFFF);
- dst[12] = getRGBLookupEntry(colorMap, pixelGroup6 >> 16);
- dst[13] = getRGBLookupEntry(colorMap, pixelGroup5 & 0xFFFF);
- dst[14] = getRGBLookupEntry(colorMap, pixelGroup8 >> 16);
- dst[15] = getRGBLookupEntry(colorMap, pixelGroup7 & 0xFFFF);
- }
-
- static inline byte getRGBLookupEntry(const byte *colorMap, uint16 index) {
- return colorMap[s_defaultPaletteLookup[CLIP<int>(index, 0, 1023)]];
- }
-};
-
-/**
- * Codebook converter that dithers in QT-style
- */
-struct CodebookConverterDitherQT {
- static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
+struct CodebookConverterDithered {
+ static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
const byte *colorPtr = strip.v1_dither + (codebookIndex << 2);
WRITE_UINT32(rows[0], READ_UINT32(colorPtr));
WRITE_UINT32(rows[1], READ_UINT32(colorPtr + 1024));
@@ -275,7 +140,7 @@ struct CodebookConverterDitherQT {
WRITE_UINT32(rows[3], READ_UINT32(colorPtr + 3072));
}
- static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const byte *colorMap, const Graphics::PixelFormat &format) {
+ static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
const byte *colorPtr = strip.v4_dither + (codebookIndex[0] << 2);
WRITE_UINT16(rows[0] + 0, READ_UINT16(colorPtr + 0));
WRITE_UINT16(rows[1] + 0, READ_UINT16(colorPtr + 2));
@@ -295,7 +160,7 @@ struct CodebookConverterDitherQT {
};
template<typename PixelInt, typename CodebookConverter>
-void decodeVectorsTmpl(CinepakFrame &frame, const byte *clipTable, const byte *colorMap, Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
+void decodeVectorsTmpl(CinepakFrame &frame, const byte *clipTable, Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
uint32 flag = 0, mask = 0;
PixelInt *iy[4];
int32 startPos = stream.pos();
@@ -330,14 +195,14 @@ void decodeVectorsTmpl(CinepakFrame &frame, const byte *clipTable, const byte *c
// Get the codebook
byte codebook = stream.readByte();
- CodebookConverter::decodeBlock1(codebook, frame.strips[strip], iy, clipTable, colorMap, frame.surface->format);
+ CodebookConverter::decodeBlock1(codebook, frame.strips[strip], iy, clipTable, frame.surface->format);
} else if (flag & mask) {
if ((stream.pos() - startPos + 4) > (int32)chunkSize)
return;
byte codebook[4];
stream.read(codebook, 4);
- CodebookConverter::decodeBlock4(codebook, frame.strips[strip], iy, clipTable, colorMap, frame.surface->format);
+ CodebookConverter::decodeBlock4(codebook, frame.strips[strip], iy, clipTable, frame.surface->format);
}
}
@@ -438,7 +303,7 @@ const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream
_curFrame.strips[i].v4_codebook[j] = _curFrame.strips[i - 1].v4_codebook[j];
}
- // Copy the QuickTime dither tables
+ // Copy the dither tables
memcpy(_curFrame.strips[i].v1_dither, _curFrame.strips[i - 1].v1_dither, 256 * 4 * 4 * 4);
memcpy(_curFrame.strips[i].v4_dither, _curFrame.strips[i - 1].v4_dither, 256 * 4 * 4 * 4);
}
@@ -513,6 +378,8 @@ void CinepakDecoder::initializeCodebook(uint16 strip, byte codebookType) {
if (_ditherType == kDitherTypeQT)
ditherCodebookQT(strip, codebookType, i);
+ else if (_ditherType == kDitherTypeVFW)
+ ditherCodebookVFW(strip, codebookType, i);
}
}
@@ -552,6 +419,8 @@ void CinepakDecoder::loadCodebook(Common::SeekableReadStream &stream, uint16 str
// Dither the codebook if we're dithering for QuickTime
if (_ditherType == kDitherTypeQT)
ditherCodebookQT(strip, codebookType, i);
+ else if (_ditherType == kDitherTypeVFW)
+ ditherCodebookVFW(strip, codebookType, i);
}
}
}
@@ -614,13 +483,99 @@ void CinepakDecoder::ditherCodebookQT(uint16 strip, byte codebookType, uint16 co
}
}
+static inline byte getRGBLookupEntry(const byte *colorMap, uint16 index) {
+ return colorMap[s_defaultPaletteLookup[CLIP<int>(index, 0, 1023)]];
+}
+
+void CinepakDecoder::ditherCodebookVFW(uint16 strip, byte codebookType, uint16 codebookIndex) {
+ if (codebookType == 1) {
+ const CinepakCodebook &codebook = _curFrame.strips[strip].v1_codebook[codebookIndex];
+ byte *output = _curFrame.strips[strip].v1_dither + (codebookIndex << 2);
+
+ int uLookup = (byte)codebook.u * 2;
+ int vLookup = (byte)codebook.v * 2;
+ uint32 uv1 = s_uLookup[uLookup] | s_vLookup[vLookup];
+ uint32 uv2 = s_uLookup[uLookup + 1] | s_vLookup[vLookup + 1];
+
+ int yLookup1 = codebook.y[0] * 2;
+ int yLookup2 = codebook.y[1] * 2;
+ int yLookup3 = codebook.y[2] * 2;
+ int yLookup4 = codebook.y[3] * 2;
+
+ uint32 pixelGroup1 = uv2 | s_yLookup[yLookup1 + 1];
+ uint32 pixelGroup2 = uv1 | s_yLookup[yLookup2];
+ uint32 pixelGroup3 = uv1 | s_yLookup[yLookup1];
+ uint32 pixelGroup4 = uv2 | s_yLookup[yLookup2 + 1];
+ uint32 pixelGroup5 = uv2 | s_yLookup[yLookup3 + 1];
+ uint32 pixelGroup6 = uv1 | s_yLookup[yLookup3];
+ uint32 pixelGroup7 = uv1 | s_yLookup[yLookup4];
+ uint32 pixelGroup8 = uv2 | s_yLookup[yLookup4 + 1];
+
+ output[0x000] = getRGBLookupEntry(_colorMap, pixelGroup1 & 0xFFFF);
+ output[0x001] = getRGBLookupEntry(_colorMap, pixelGroup1 >> 16);
+ output[0x002] = getRGBLookupEntry(_colorMap, pixelGroup2 & 0xFFFF);
+ output[0x003] = getRGBLookupEntry(_colorMap, pixelGroup2 >> 16);
+ output[0x400] = getRGBLookupEntry(_colorMap, pixelGroup3 & 0xFFFF);
+ output[0x401] = getRGBLookupEntry(_colorMap, pixelGroup3 >> 16);
+ output[0x402] = getRGBLookupEntry(_colorMap, pixelGroup4 & 0xFFFF);
+ output[0x403] = getRGBLookupEntry(_colorMap, pixelGroup4 >> 16);
+ output[0x800] = getRGBLookupEntry(_colorMap, pixelGroup5 >> 16);
+ output[0x801] = getRGBLookupEntry(_colorMap, pixelGroup6 & 0xFFFF);
+ output[0x802] = getRGBLookupEntry(_colorMap, pixelGroup7 >> 16);
+ output[0x803] = getRGBLookupEntry(_colorMap, pixelGroup8 & 0xFFFF);
+ output[0xC00] = getRGBLookupEntry(_colorMap, pixelGroup6 >> 16);
+ output[0xC01] = getRGBLookupEntry(_colorMap, pixelGroup5 & 0xFFFF);
+ output[0xC02] = getRGBLookupEntry(_colorMap, pixelGroup8 >> 16);
+ output[0xC03] = getRGBLookupEntry(_colorMap, pixelGroup7 & 0xFFFF);
+ } else {
+ const CinepakCodebook &codebook = _curFrame.strips[strip].v4_codebook[codebookIndex];
+ byte *output = _curFrame.strips[strip].v4_dither + (codebookIndex << 2);
+
+ int uLookup = (byte)codebook.u * 2;
+ int vLookup = (byte)codebook.v * 2;
+ uint32 uv1 = s_uLookup[uLookup] | s_vLookup[vLookup];
+ uint32 uv2 = s_uLookup[uLookup + 1] | s_vLookup[vLookup + 1];
+
+ int yLookup1 = codebook.y[0] * 2;
+ int yLookup2 = codebook.y[1] * 2;
+ int yLookup3 = codebook.y[2] * 2;
+ int yLookup4 = codebook.y[3] * 2;
+
+ uint32 pixelGroup1 = uv2 | s_yLookup[yLookup1 + 1];
+ uint32 pixelGroup2 = uv2 | s_yLookup[yLookup2 + 1];
+ uint32 pixelGroup3 = uv1 | s_yLookup[yLookup3];
+ uint32 pixelGroup4 = uv1 | s_yLookup[yLookup4];
+ uint32 pixelGroup5 = uv1 | s_yLookup[yLookup1];
+ uint32 pixelGroup6 = uv1 | s_yLookup[yLookup2];
+ uint32 pixelGroup7 = uv2 | s_yLookup[yLookup3 + 1];
+ uint32 pixelGroup8 = uv2 | s_yLookup[yLookup4 + 1];
+
+ output[0x000] = getRGBLookupEntry(_colorMap, pixelGroup1 & 0xFFFF);
+ output[0x001] = getRGBLookupEntry(_colorMap, pixelGroup2 >> 16);
+ output[0x400] = getRGBLookupEntry(_colorMap, pixelGroup5 & 0xFFFF);
+ output[0x401] = getRGBLookupEntry(_colorMap, pixelGroup6 >> 16);
+ output[0x002] = getRGBLookupEntry(_colorMap, pixelGroup3 & 0xFFFF);
+ output[0x003] = getRGBLookupEntry(_colorMap, pixelGroup4 >> 16);
+ output[0x402] = getRGBLookupEntry(_colorMap, pixelGroup7 & 0xFFFF);
+ output[0x403] = getRGBLookupEntry(_colorMap, pixelGroup8 >> 16);
+ output[0x800] = getRGBLookupEntry(_colorMap, pixelGroup1 >> 16);
+ output[0x801] = getRGBLookupEntry(_colorMap, pixelGroup6 & 0xFFFF);
+ output[0xC00] = getRGBLookupEntry(_colorMap, pixelGroup5 >> 16);
+ output[0xC01] = getRGBLookupEntry(_colorMap, pixelGroup2 & 0xFFFF);
+ output[0x802] = getRGBLookupEntry(_colorMap, pixelGroup3 >> 16);
+ output[0x803] = getRGBLookupEntry(_colorMap, pixelGroup8 & 0xFFFF);
+ output[0xC02] = getRGBLookupEntry(_colorMap, pixelGroup7 >> 16);
+ output[0xC03] = getRGBLookupEntry(_colorMap, pixelGroup4 & 0xFFFF);
+ }
+}
+
void CinepakDecoder::decodeVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
if (_curFrame.surface->format.bytesPerPixel == 1) {
- decodeVectorsTmpl<byte, CodebookConverterRaw>(_curFrame, _clipTable, _colorMap, stream, strip, chunkID, chunkSize);
+ decodeVectorsTmpl<byte, CodebookConverterRaw>(_curFrame, _clipTable, stream, strip, chunkID, chunkSize);
} else if (_curFrame.surface->format.bytesPerPixel == 2) {
- decodeVectorsTmpl<uint16, CodebookConverterRaw>(_curFrame, _clipTable, _colorMap, stream, strip, chunkID, chunkSize);
+ decodeVectorsTmpl<uint16, CodebookConverterRaw>(_curFrame, _clipTable, stream, strip, chunkID, chunkSize);
} else if (_curFrame.surface->format.bytesPerPixel == 4) {
- decodeVectorsTmpl<uint32, CodebookConverterRaw>(_curFrame, _clipTable, _colorMap, stream, strip, chunkID, chunkSize);
+ decodeVectorsTmpl<uint32, CodebookConverterRaw>(_curFrame, _clipTable, stream, strip, chunkID, chunkSize);
}
}
@@ -696,10 +651,7 @@ byte CinepakDecoder::findNearestRGB(int index) const {
}
void CinepakDecoder::ditherVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
- if (_ditherType == kDitherTypeVFW)
- decodeVectorsTmpl<byte, CodebookConverterDitherVFW>(_curFrame, _clipTable, _colorMap, stream, strip, chunkID, chunkSize);
- else
- decodeVectorsTmpl<byte, CodebookConverterDitherQT>(_curFrame, _clipTable, _colorMap, stream, strip, chunkID, chunkSize);
+ decodeVectorsTmpl<byte, CodebookConverterDithered>(_curFrame, _clipTable, stream, strip, chunkID, chunkSize);
}
} // End of namespace Image
diff --git a/image/codecs/cinepak.h b/image/codecs/cinepak.h
index a537ac8c3c5..c4ce7d774ff 100644
--- a/image/codecs/cinepak.h
+++ b/image/codecs/cinepak.h
@@ -101,6 +101,7 @@ private:
byte findNearestRGB(int index) const;
void ditherVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize);
void ditherCodebookQT(uint16 strip, byte codebookType, uint16 codebookIndex);
+ void ditherCodebookVFW(uint16 strip, byte codebookType, uint16 codebookIndex);
};
} // End of namespace Image
Commit: ed59ab8a3b4155a555b2ce139fb328bffbe86875
https://github.com/scummvm/scummvm/commit/ed59ab8a3b4155a555b2ce139fb328bffbe86875
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-04-22T02:07:47+02:00
Commit Message:
IMAGE: Make use of aligned loads and stores when dithering Cinepak videos
Changed paths:
image/codecs/cinepak.cpp
image/codecs/cinepak.h
diff --git a/image/codecs/cinepak.cpp b/image/codecs/cinepak.cpp
index ad088959985..4b795695877 100644
--- a/image/codecs/cinepak.cpp
+++ b/image/codecs/cinepak.cpp
@@ -133,29 +133,29 @@ struct CodebookConverterRaw {
*/
struct CodebookConverterDithered {
static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
- const byte *colorPtr = strip.v1_dither + (codebookIndex << 2);
- WRITE_UINT32(rows[0], READ_UINT32(colorPtr));
- WRITE_UINT32(rows[1], READ_UINT32(colorPtr + 1024));
- WRITE_UINT32(rows[2], READ_UINT32(colorPtr + 2048));
- WRITE_UINT32(rows[3], READ_UINT32(colorPtr + 3072));
+ const uint32 *colorPtr = (const uint32 *)(strip.v1_dither + codebookIndex);
+ *((uint32 *)rows[0]) = colorPtr[0];
+ *((uint32 *)rows[1]) = colorPtr[256];
+ *((uint32 *)rows[2]) = colorPtr[512];
+ *((uint32 *)rows[3]) = colorPtr[768];
}
static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
- const byte *colorPtr = strip.v4_dither + (codebookIndex[0] << 2);
- WRITE_UINT16(rows[0] + 0, READ_UINT16(colorPtr + 0));
- WRITE_UINT16(rows[1] + 0, READ_UINT16(colorPtr + 2));
+ const uint16 *colorPtr = (const uint16 *)(strip.v4_dither + codebookIndex[0]);
+ *((uint16 *)(rows[0] + 0)) = colorPtr[0];
+ *((uint16 *)(rows[1] + 0)) = colorPtr[1];
- colorPtr = strip.v4_dither + (codebookIndex[1] << 2);
- WRITE_UINT16(rows[0] + 2, READ_UINT16(colorPtr + 1024));
- WRITE_UINT16(rows[1] + 2, READ_UINT16(colorPtr + 1026));
+ colorPtr = (const uint16 *)(strip.v4_dither + codebookIndex[1]);
+ *((uint16 *)(rows[0] + 2)) = colorPtr[512];
+ *((uint16 *)(rows[1] + 2)) = colorPtr[513];
- colorPtr = strip.v4_dither + (codebookIndex[2] << 2);
- WRITE_UINT16(rows[2] + 0, READ_UINT16(colorPtr + 2048));
- WRITE_UINT16(rows[3] + 0, READ_UINT16(colorPtr + 2050));
+ colorPtr = (const uint16 *)(strip.v4_dither + codebookIndex[2]);
+ *((uint16 *)(rows[2] + 0)) = colorPtr[1024];
+ *((uint16 *)(rows[3] + 0)) = colorPtr[1025];
- colorPtr = strip.v4_dither + (codebookIndex[3] << 2);
- WRITE_UINT16(rows[2] + 2, READ_UINT16(colorPtr + 3072));
- WRITE_UINT16(rows[3] + 2, READ_UINT16(colorPtr + 3074));
+ colorPtr = (const uint16 *)(strip.v4_dither + codebookIndex[3]);
+ *((uint16 *)(rows[2] + 2)) = colorPtr[1536];
+ *((uint16 *)(rows[3] + 2)) = colorPtr[1537];
}
};
@@ -304,8 +304,8 @@ const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream
}
// Copy the dither tables
- memcpy(_curFrame.strips[i].v1_dither, _curFrame.strips[i - 1].v1_dither, 256 * 4 * 4 * 4);
- memcpy(_curFrame.strips[i].v4_dither, _curFrame.strips[i - 1].v4_dither, 256 * 4 * 4 * 4);
+ memcpy(_curFrame.strips[i].v1_dither, _curFrame.strips[i - 1].v1_dither, 256 * 4 * 4 * sizeof(uint32));
+ memcpy(_curFrame.strips[i].v4_dither, _curFrame.strips[i - 1].v4_dither, 256 * 4 * 4 * sizeof(uint32));
}
_curFrame.strips[i].id = stream.readUint16BE();
@@ -428,7 +428,7 @@ void CinepakDecoder::loadCodebook(Common::SeekableReadStream &stream, uint16 str
void CinepakDecoder::ditherCodebookQT(uint16 strip, byte codebookType, uint16 codebookIndex) {
if (codebookType == 1) {
const CinepakCodebook &codebook = _curFrame.strips[strip].v1_codebook[codebookIndex];
- byte *output = _curFrame.strips[strip].v1_dither + (codebookIndex << 2);
+ byte *output = (byte *)(_curFrame.strips[strip].v1_dither + codebookIndex);
byte *ditherEntry = _colorMap + createDitherTableIndex(_clipTable, codebook.y[0], codebook.u, codebook.v);
output[0x000] = ditherEntry[0x0000];
@@ -455,7 +455,7 @@ void CinepakDecoder::ditherCodebookQT(uint16 strip, byte codebookType, uint16 co
output[0xC03] = ditherEntry[0x4000];
} else {
const CinepakCodebook &codebook = _curFrame.strips[strip].v4_codebook[codebookIndex];
- byte *output = _curFrame.strips[strip].v4_dither + (codebookIndex << 2);
+ byte *output = (byte *)(_curFrame.strips[strip].v4_dither + codebookIndex);
byte *ditherEntry = _colorMap + createDitherTableIndex(_clipTable, codebook.y[0], codebook.u, codebook.v);
output[0x000] = ditherEntry[0x0000];
@@ -490,7 +490,7 @@ static inline byte getRGBLookupEntry(const byte *colorMap, uint16 index) {
void CinepakDecoder::ditherCodebookVFW(uint16 strip, byte codebookType, uint16 codebookIndex) {
if (codebookType == 1) {
const CinepakCodebook &codebook = _curFrame.strips[strip].v1_codebook[codebookIndex];
- byte *output = _curFrame.strips[strip].v1_dither + (codebookIndex << 2);
+ byte *output = (byte *)(_curFrame.strips[strip].v1_dither + codebookIndex);
int uLookup = (byte)codebook.u * 2;
int vLookup = (byte)codebook.v * 2;
@@ -529,7 +529,7 @@ void CinepakDecoder::ditherCodebookVFW(uint16 strip, byte codebookType, uint16 c
output[0xC03] = getRGBLookupEntry(_colorMap, pixelGroup7 & 0xFFFF);
} else {
const CinepakCodebook &codebook = _curFrame.strips[strip].v4_codebook[codebookIndex];
- byte *output = _curFrame.strips[strip].v4_dither + (codebookIndex << 2);
+ byte *output = (byte *)(_curFrame.strips[strip].v4_dither + codebookIndex);
int uLookup = (byte)codebook.u * 2;
int vLookup = (byte)codebook.v * 2;
diff --git a/image/codecs/cinepak.h b/image/codecs/cinepak.h
index c4ce7d774ff..f978a140ad8 100644
--- a/image/codecs/cinepak.h
+++ b/image/codecs/cinepak.h
@@ -45,7 +45,7 @@ struct CinepakStrip {
uint16 length;
Common::Rect rect;
CinepakCodebook v1_codebook[256], v4_codebook[256];
- byte v1_dither[256 * 4 * 4 * 4], v4_dither[256 * 4 * 4 * 4];
+ uint32 v1_dither[256 * 4 * 4], v4_dither[256 * 4 * 4];
};
struct CinepakFrame {
Commit: 2cb46c19eda11c6d2f720fcc342baaa29e22fdf2
https://github.com/scummvm/scummvm/commit/2cb46c19eda11c6d2f720fcc342baaa29e22fdf2
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-04-22T02:07:47+02:00
Commit Message:
IMAGE: Split Cinepak CodebookConverterRaw into 8bpp and 24bpp versions
Changed paths:
image/codecs/cinepak.cpp
image/codecs/cinepak.h
diff --git a/image/codecs/cinepak.cpp b/image/codecs/cinepak.cpp
index 4b795695877..4ebf77a6319 100644
--- a/image/codecs/cinepak.cpp
+++ b/image/codecs/cinepak.cpp
@@ -57,74 +57,90 @@ inline uint16 createDitherTableIndex(const byte *clipTable, byte y, int8 u, int8
}
/**
- * Put a raw pixel to the destination surface
+ * The default codebook converter for 24bpp: RGB output.
*/
-template<typename PixelInt>
-inline void putPixelRaw(PixelInt *dst, const byte *clipTable, const Graphics::PixelFormat &format, byte y, byte u, byte v) {
- *dst = convertYUVToColor(clipTable, format, y, u, v);
-}
-
-/**
- * Specialized putPixelRaw for palettized 8bpp output
- */
-template<>
-inline void putPixelRaw(byte *dst, const byte *clipTable, const Graphics::PixelFormat &format, byte y, byte u, byte v) {
- *dst = y;
-}
-
-/**
- * The default codebook converter: raw output.
- */
-struct CodebookConverterRaw {
+struct CodebookConverterRGB {
template<typename PixelInt>
static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, PixelInt *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
const CinepakCodebook &codebook = strip.v1_codebook[codebookIndex];
- putPixelRaw(rows[0] + 0, clipTable, format, codebook.y[0], codebook.u, codebook.v);
- putPixelRaw(rows[0] + 1, clipTable, format, codebook.y[0], codebook.u, codebook.v);
- putPixelRaw(rows[1] + 0, clipTable, format, codebook.y[0], codebook.u, codebook.v);
- putPixelRaw(rows[1] + 1, clipTable, format, codebook.y[0], codebook.u, codebook.v);
-
- putPixelRaw(rows[0] + 2, clipTable, format, codebook.y[1], codebook.u, codebook.v);
- putPixelRaw(rows[0] + 3, clipTable, format, codebook.y[1], codebook.u, codebook.v);
- putPixelRaw(rows[1] + 2, clipTable, format, codebook.y[1], codebook.u, codebook.v);
- putPixelRaw(rows[1] + 3, clipTable, format, codebook.y[1], codebook.u, codebook.v);
-
- putPixelRaw(rows[2] + 0, clipTable, format, codebook.y[2], codebook.u, codebook.v);
- putPixelRaw(rows[2] + 1, clipTable, format, codebook.y[2], codebook.u, codebook.v);
- putPixelRaw(rows[3] + 0, clipTable, format, codebook.y[2], codebook.u, codebook.v);
- putPixelRaw(rows[3] + 1, clipTable, format, codebook.y[2], codebook.u, codebook.v);
-
- putPixelRaw(rows[2] + 2, clipTable, format, codebook.y[3], codebook.u, codebook.v);
- putPixelRaw(rows[2] + 3, clipTable, format, codebook.y[3], codebook.u, codebook.v);
- putPixelRaw(rows[3] + 2, clipTable, format, codebook.y[3], codebook.u, codebook.v);
- putPixelRaw(rows[3] + 3, clipTable, format, codebook.y[3], codebook.u, codebook.v);
+
+ const PixelInt rgb0 = convertYUVToColor(clipTable, format, codebook.y[0], codebook.u, codebook.v);
+ rows[0][0] = rows[0][1] = rows[1][0] = rows[1][1] = rgb0;
+
+ const PixelInt rgb1 = convertYUVToColor(clipTable, format, codebook.y[1], codebook.u, codebook.v);
+ rows[0][2] = rows[0][3] = rows[1][2] = rows[1][3] = rgb1;
+
+ const PixelInt rgb2 = convertYUVToColor(clipTable, format, codebook.y[2], codebook.u, codebook.v);
+ rows[2][0] = rows[2][1] = rows[3][0] = rows[3][1] = rgb2;
+
+ const PixelInt rgb3 = convertYUVToColor(clipTable, format, codebook.y[3], codebook.u, codebook.v);
+ rows[2][2] = rows[2][3] = rows[3][2] = rows[3][3] = rgb3;
}
template<typename PixelInt>
static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, PixelInt *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
const CinepakCodebook &codebook1 = strip.v4_codebook[codebookIndex[0]];
- putPixelRaw(rows[0] + 0, clipTable, format, codebook1.y[0], codebook1.u, codebook1.v);
- putPixelRaw(rows[0] + 1, clipTable, format, codebook1.y[1], codebook1.u, codebook1.v);
- putPixelRaw(rows[1] + 0, clipTable, format, codebook1.y[2], codebook1.u, codebook1.v);
- putPixelRaw(rows[1] + 1, clipTable, format, codebook1.y[3], codebook1.u, codebook1.v);
+ rows[0][0] = convertYUVToColor(clipTable, format, codebook1.y[0], codebook1.u, codebook1.v);
+ rows[0][1] = convertYUVToColor(clipTable, format, codebook1.y[1], codebook1.u, codebook1.v);
+ rows[1][0] = convertYUVToColor(clipTable, format, codebook1.y[2], codebook1.u, codebook1.v);
+ rows[1][1] = convertYUVToColor(clipTable, format, codebook1.y[3], codebook1.u, codebook1.v);
const CinepakCodebook &codebook2 = strip.v4_codebook[codebookIndex[1]];
- putPixelRaw(rows[0] + 2, clipTable, format, codebook2.y[0], codebook2.u, codebook2.v);
- putPixelRaw(rows[0] + 3, clipTable, format, codebook2.y[1], codebook2.u, codebook2.v);
- putPixelRaw(rows[1] + 2, clipTable, format, codebook2.y[2], codebook2.u, codebook2.v);
- putPixelRaw(rows[1] + 3, clipTable, format, codebook2.y[3], codebook2.u, codebook2.v);
+ rows[0][2] = convertYUVToColor(clipTable, format, codebook2.y[0], codebook2.u, codebook2.v);
+ rows[0][3] = convertYUVToColor(clipTable, format, codebook2.y[1], codebook2.u, codebook2.v);
+ rows[1][2] = convertYUVToColor(clipTable, format, codebook2.y[2], codebook2.u, codebook2.v);
+ rows[1][3] = convertYUVToColor(clipTable, format, codebook2.y[3], codebook2.u, codebook2.v);
const CinepakCodebook &codebook3 = strip.v4_codebook[codebookIndex[2]];
- putPixelRaw(rows[2] + 0, clipTable, format, codebook3.y[0], codebook3.u, codebook3.v);
- putPixelRaw(rows[2] + 1, clipTable, format, codebook3.y[1], codebook3.u, codebook3.v);
- putPixelRaw(rows[3] + 0, clipTable, format, codebook3.y[2], codebook3.u, codebook3.v);
- putPixelRaw(rows[3] + 1, clipTable, format, codebook3.y[3], codebook3.u, codebook3.v);
+ rows[2][0] = convertYUVToColor(clipTable, format, codebook3.y[0], codebook3.u, codebook3.v);
+ rows[2][1] = convertYUVToColor(clipTable, format, codebook3.y[1], codebook3.u, codebook3.v);
+ rows[3][0] = convertYUVToColor(clipTable, format, codebook3.y[2], codebook3.u, codebook3.v);
+ rows[3][1] = convertYUVToColor(clipTable, format, codebook3.y[3], codebook3.u, codebook3.v);
const CinepakCodebook &codebook4 = strip.v4_codebook[codebookIndex[3]];
- putPixelRaw(rows[2] + 2, clipTable, format, codebook4.y[0], codebook4.u, codebook4.v);
- putPixelRaw(rows[2] + 3, clipTable, format, codebook4.y[1], codebook4.u, codebook4.v);
- putPixelRaw(rows[3] + 2, clipTable, format, codebook4.y[2], codebook4.u, codebook4.v);
- putPixelRaw(rows[3] + 3, clipTable, format, codebook4.y[3], codebook4.u, codebook4.v);
+ rows[2][2] = convertYUVToColor(clipTable, format, codebook4.y[0], codebook4.u, codebook4.v);
+ rows[2][3] = convertYUVToColor(clipTable, format, codebook4.y[1], codebook4.u, codebook4.v);
+ rows[3][2] = convertYUVToColor(clipTable, format, codebook4.y[2], codebook4.u, codebook4.v);
+ rows[3][3] = convertYUVToColor(clipTable, format, codebook4.y[3], codebook4.u, codebook4.v);
+ }
+};
+
+/**
+ * The default codebook converter for 8bpp: palettized output.
+ */
+struct CodebookConverterPalette {
+ static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
+ const CinepakCodebook &codebook = strip.v1_codebook[codebookIndex];
+ rows[0][0] = rows[0][1] = rows[1][0] = rows[1][1] = codebook.y[0];
+ rows[0][2] = rows[0][3] = rows[1][2] = rows[1][3] = codebook.y[1];
+ rows[2][0] = rows[2][1] = rows[3][0] = rows[3][1] = codebook.y[2];
+ rows[2][2] = rows[2][3] = rows[3][2] = rows[3][3] = codebook.y[3];
+ }
+
+ static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
+ const CinepakCodebook &codebook1 = strip.v4_codebook[codebookIndex[0]];
+ rows[0][0] = codebook1.y[0];
+ rows[0][1] = codebook1.y[1];
+ rows[1][0] = codebook1.y[2];
+ rows[1][1] = codebook1.y[3];
+
+ const CinepakCodebook &codebook2 = strip.v4_codebook[codebookIndex[1]];
+ rows[0][2] = codebook2.y[0];
+ rows[0][3] = codebook2.y[1];
+ rows[1][2] = codebook2.y[2];
+ rows[1][3] = codebook2.y[3];
+
+ const CinepakCodebook &codebook3 = strip.v4_codebook[codebookIndex[2]];
+ rows[2][0] = codebook3.y[0];
+ rows[2][1] = codebook3.y[1];
+ rows[3][0] = codebook3.y[2];
+ rows[3][1] = codebook3.y[3];
+
+ const CinepakCodebook &codebook4 = strip.v4_codebook[codebookIndex[3]];
+ rows[2][2] = codebook4.y[0];
+ rows[2][3] = codebook4.y[1];
+ rows[3][2] = codebook4.y[2];
+ rows[3][3] = codebook4.y[3];
}
};
@@ -350,8 +366,10 @@ const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream
case 0x32:
if (_ditherPalette)
ditherVectors(stream, i, chunkID, chunkSize);
+ else if (_bitsPerPixel == 8)
+ decodeVectors8(stream, i, chunkID, chunkSize);
else
- decodeVectors(stream, i, chunkID, chunkSize);
+ decodeVectors24(stream, i, chunkID, chunkSize);
break;
default:
warning("Unknown Cinepak chunk ID %02x", chunkID);
@@ -569,13 +587,15 @@ void CinepakDecoder::ditherCodebookVFW(uint16 strip, byte codebookType, uint16 c
}
}
-void CinepakDecoder::decodeVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
- if (_curFrame.surface->format.bytesPerPixel == 1) {
- decodeVectorsTmpl<byte, CodebookConverterRaw>(_curFrame, _clipTable, stream, strip, chunkID, chunkSize);
- } else if (_curFrame.surface->format.bytesPerPixel == 2) {
- decodeVectorsTmpl<uint16, CodebookConverterRaw>(_curFrame, _clipTable, stream, strip, chunkID, chunkSize);
+void CinepakDecoder::decodeVectors8(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
+ decodeVectorsTmpl<byte, CodebookConverterPalette>(_curFrame, _clipTable, stream, strip, chunkID, chunkSize);
+}
+
+void CinepakDecoder::decodeVectors24(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
+ if (_curFrame.surface->format.bytesPerPixel == 2) {
+ decodeVectorsTmpl<uint16, CodebookConverterRGB>(_curFrame, _clipTable, stream, strip, chunkID, chunkSize);
} else if (_curFrame.surface->format.bytesPerPixel == 4) {
- decodeVectorsTmpl<uint32, CodebookConverterRaw>(_curFrame, _clipTable, stream, strip, chunkID, chunkSize);
+ decodeVectorsTmpl<uint32, CodebookConverterRGB>(_curFrame, _clipTable, stream, strip, chunkID, chunkSize);
}
}
diff --git a/image/codecs/cinepak.h b/image/codecs/cinepak.h
index f978a140ad8..bcad3eb24a2 100644
--- a/image/codecs/cinepak.h
+++ b/image/codecs/cinepak.h
@@ -96,7 +96,8 @@ private:
void initializeCodebook(uint16 strip, byte codebookType);
void loadCodebook(Common::SeekableReadStream &stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize);
- void decodeVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize);
+ void decodeVectors8(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize);
+ void decodeVectors24(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize);
byte findNearestRGB(int index) const;
void ditherVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize);
Commit: 011e468fa12255f1f65a1d160c785dcb93801dfd
https://github.com/scummvm/scummvm/commit/011e468fa12255f1f65a1d160c785dcb93801dfd
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-04-22T02:07:47+02:00
Commit Message:
IMAGE: Handle the surface pitch in Cinepak videos
Changed paths:
image/codecs/cinepak.cpp
diff --git a/image/codecs/cinepak.cpp b/image/codecs/cinepak.cpp
index 4ebf77a6319..909c0af6f8e 100644
--- a/image/codecs/cinepak.cpp
+++ b/image/codecs/cinepak.cpp
@@ -61,47 +61,64 @@ inline uint16 createDitherTableIndex(const byte *clipTable, byte y, int8 u, int8
*/
struct CodebookConverterRGB {
template<typename PixelInt>
- static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, PixelInt *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
+ static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, PixelInt *dst, size_t dstPitch, const byte *clipTable, const Graphics::PixelFormat &format) {
const CinepakCodebook &codebook = strip.v1_codebook[codebookIndex];
+ const int8 u = codebook.u, v = codebook.v;
- const PixelInt rgb0 = convertYUVToColor(clipTable, format, codebook.y[0], codebook.u, codebook.v);
- rows[0][0] = rows[0][1] = rows[1][0] = rows[1][1] = rgb0;
+ const PixelInt rgb0 = convertYUVToColor(clipTable, format, codebook.y[0], u, v);
+ const PixelInt rgb1 = convertYUVToColor(clipTable, format, codebook.y[1], u, v);
- const PixelInt rgb1 = convertYUVToColor(clipTable, format, codebook.y[1], codebook.u, codebook.v);
- rows[0][2] = rows[0][3] = rows[1][2] = rows[1][3] = rgb1;
+ dst[0] = dst[1] = rgb0;
+ dst[2] = dst[3] = rgb1;
+ dst = (PixelInt *)((uint8 *)dst + dstPitch);
- const PixelInt rgb2 = convertYUVToColor(clipTable, format, codebook.y[2], codebook.u, codebook.v);
- rows[2][0] = rows[2][1] = rows[3][0] = rows[3][1] = rgb2;
+ dst[0] = dst[1] = rgb0;
+ dst[2] = dst[3] = rgb1;
+ dst = (PixelInt *)((uint8 *)dst + dstPitch);
- const PixelInt rgb3 = convertYUVToColor(clipTable, format, codebook.y[3], codebook.u, codebook.v);
- rows[2][2] = rows[2][3] = rows[3][2] = rows[3][3] = rgb3;
+ const PixelInt rgb2 = convertYUVToColor(clipTable, format, codebook.y[2], u, v);
+ const PixelInt rgb3 = convertYUVToColor(clipTable, format, codebook.y[3], u, v);
+
+ dst[0] = dst[1] = rgb2;
+ dst[2] = dst[3] = rgb3;
+ dst = (PixelInt *)((uint8 *)dst + dstPitch);
+
+ dst[0] = dst[1] = rgb2;
+ dst[2] = dst[3] = rgb3;
+ dst = (PixelInt *)((uint8 *)dst + dstPitch);
}
template<typename PixelInt>
- static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, PixelInt *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
+ static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, PixelInt *dst, size_t dstPitch, const byte *clipTable, const Graphics::PixelFormat &format) {
const CinepakCodebook &codebook1 = strip.v4_codebook[codebookIndex[0]];
- rows[0][0] = convertYUVToColor(clipTable, format, codebook1.y[0], codebook1.u, codebook1.v);
- rows[0][1] = convertYUVToColor(clipTable, format, codebook1.y[1], codebook1.u, codebook1.v);
- rows[1][0] = convertYUVToColor(clipTable, format, codebook1.y[2], codebook1.u, codebook1.v);
- rows[1][1] = convertYUVToColor(clipTable, format, codebook1.y[3], codebook1.u, codebook1.v);
-
const CinepakCodebook &codebook2 = strip.v4_codebook[codebookIndex[1]];
- rows[0][2] = convertYUVToColor(clipTable, format, codebook2.y[0], codebook2.u, codebook2.v);
- rows[0][3] = convertYUVToColor(clipTable, format, codebook2.y[1], codebook2.u, codebook2.v);
- rows[1][2] = convertYUVToColor(clipTable, format, codebook2.y[2], codebook2.u, codebook2.v);
- rows[1][3] = convertYUVToColor(clipTable, format, codebook2.y[3], codebook2.u, codebook2.v);
- const CinepakCodebook &codebook3 = strip.v4_codebook[codebookIndex[2]];
- rows[2][0] = convertYUVToColor(clipTable, format, codebook3.y[0], codebook3.u, codebook3.v);
- rows[2][1] = convertYUVToColor(clipTable, format, codebook3.y[1], codebook3.u, codebook3.v);
- rows[3][0] = convertYUVToColor(clipTable, format, codebook3.y[2], codebook3.u, codebook3.v);
- rows[3][1] = convertYUVToColor(clipTable, format, codebook3.y[3], codebook3.u, codebook3.v);
+ dst[0] = convertYUVToColor(clipTable, format, codebook1.y[0], codebook1.u, codebook1.v);
+ dst[1] = convertYUVToColor(clipTable, format, codebook1.y[1], codebook1.u, codebook1.v);
+ dst[2] = convertYUVToColor(clipTable, format, codebook2.y[0], codebook2.u, codebook2.v);
+ dst[3] = convertYUVToColor(clipTable, format, codebook2.y[1], codebook2.u, codebook2.v);
+ dst = (PixelInt *)((uint8 *)dst + dstPitch);
+
+ dst[0] = convertYUVToColor(clipTable, format, codebook1.y[2], codebook1.u, codebook1.v);
+ dst[1] = convertYUVToColor(clipTable, format, codebook1.y[3], codebook1.u, codebook1.v);
+ dst[2] = convertYUVToColor(clipTable, format, codebook2.y[2], codebook2.u, codebook2.v);
+ dst[3] = convertYUVToColor(clipTable, format, codebook2.y[3], codebook2.u, codebook2.v);
+ dst = (PixelInt *)((uint8 *)dst + dstPitch);
+ const CinepakCodebook &codebook3 = strip.v4_codebook[codebookIndex[2]];
const CinepakCodebook &codebook4 = strip.v4_codebook[codebookIndex[3]];
- rows[2][2] = convertYUVToColor(clipTable, format, codebook4.y[0], codebook4.u, codebook4.v);
- rows[2][3] = convertYUVToColor(clipTable, format, codebook4.y[1], codebook4.u, codebook4.v);
- rows[3][2] = convertYUVToColor(clipTable, format, codebook4.y[2], codebook4.u, codebook4.v);
- rows[3][3] = convertYUVToColor(clipTable, format, codebook4.y[3], codebook4.u, codebook4.v);
+
+ dst[0] = convertYUVToColor(clipTable, format, codebook3.y[0], codebook3.u, codebook3.v);
+ dst[1] = convertYUVToColor(clipTable, format, codebook3.y[1], codebook3.u, codebook3.v);
+ dst[2] = convertYUVToColor(clipTable, format, codebook4.y[0], codebook4.u, codebook4.v);
+ dst[3] = convertYUVToColor(clipTable, format, codebook4.y[1], codebook4.u, codebook4.v);
+ dst = (PixelInt *)((uint8 *)dst + dstPitch);
+
+ dst[0] = convertYUVToColor(clipTable, format, codebook3.y[2], codebook3.u, codebook3.v);
+ dst[1] = convertYUVToColor(clipTable, format, codebook3.y[3], codebook3.u, codebook3.v);
+ dst[2] = convertYUVToColor(clipTable, format, codebook4.y[2], codebook4.u, codebook4.v);
+ dst[3] = convertYUVToColor(clipTable, format, codebook4.y[3], codebook4.u, codebook4.v);
+ dst = (PixelInt *)((uint8 *)dst + dstPitch);
}
};
@@ -109,38 +126,59 @@ struct CodebookConverterRGB {
* The default codebook converter for 8bpp: palettized output.
*/
struct CodebookConverterPalette {
- static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
+ static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *dst, size_t dstPitch, const byte *clipTable, const Graphics::PixelFormat &format) {
const CinepakCodebook &codebook = strip.v1_codebook[codebookIndex];
- rows[0][0] = rows[0][1] = rows[1][0] = rows[1][1] = codebook.y[0];
- rows[0][2] = rows[0][3] = rows[1][2] = rows[1][3] = codebook.y[1];
- rows[2][0] = rows[2][1] = rows[3][0] = rows[3][1] = codebook.y[2];
- rows[2][2] = rows[2][3] = rows[3][2] = rows[3][3] = codebook.y[3];
+
+ byte y0 = codebook.y[0], y1 = codebook.y[1];
+ byte y2 = codebook.y[2], y3 = codebook.y[3];
+
+ dst[0] = dst[1] = y0;
+ dst[2] = dst[3] = y1;
+ dst += dstPitch;
+
+ dst[0] = dst[1] = y0;
+ dst[2] = dst[3] = y1;
+ dst += dstPitch;
+
+ dst[0] = dst[1] = y2;
+ dst[2] = dst[3] = y3;
+ dst += dstPitch;
+
+ dst[0] = dst[1] = y2;
+ dst[2] = dst[3] = y3;
+ dst += dstPitch;
}
- static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
+ static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *dst, size_t dstPitch, const byte *clipTable, const Graphics::PixelFormat &format) {
const CinepakCodebook &codebook1 = strip.v4_codebook[codebookIndex[0]];
- rows[0][0] = codebook1.y[0];
- rows[0][1] = codebook1.y[1];
- rows[1][0] = codebook1.y[2];
- rows[1][1] = codebook1.y[3];
-
const CinepakCodebook &codebook2 = strip.v4_codebook[codebookIndex[1]];
- rows[0][2] = codebook2.y[0];
- rows[0][3] = codebook2.y[1];
- rows[1][2] = codebook2.y[2];
- rows[1][3] = codebook2.y[3];
- const CinepakCodebook &codebook3 = strip.v4_codebook[codebookIndex[2]];
- rows[2][0] = codebook3.y[0];
- rows[2][1] = codebook3.y[1];
- rows[3][0] = codebook3.y[2];
- rows[3][1] = codebook3.y[3];
+ dst[0] = codebook1.y[0];
+ dst[1] = codebook1.y[1];
+ dst[2] = codebook2.y[0];
+ dst[3] = codebook2.y[1];
+ dst += dstPitch;
+
+ dst[0] = codebook1.y[2];
+ dst[1] = codebook1.y[3];
+ dst[2] = codebook2.y[2];
+ dst[3] = codebook2.y[3];
+ dst += dstPitch;
+ const CinepakCodebook &codebook3 = strip.v4_codebook[codebookIndex[2]];
const CinepakCodebook &codebook4 = strip.v4_codebook[codebookIndex[3]];
- rows[2][2] = codebook4.y[0];
- rows[2][3] = codebook4.y[1];
- rows[3][2] = codebook4.y[2];
- rows[3][3] = codebook4.y[3];
+
+ dst[0] = codebook3.y[0];
+ dst[1] = codebook3.y[1];
+ dst[2] = codebook4.y[0];
+ dst[3] = codebook4.y[1];
+ dst += dstPitch;
+
+ dst[0] = codebook3.y[2];
+ dst[1] = codebook3.y[3];
+ dst[2] = codebook4.y[2];
+ dst[3] = codebook4.y[3];
+ dst += dstPitch;
}
};
@@ -148,44 +186,55 @@ struct CodebookConverterPalette {
* Codebook converter that dithers in QT-style or VFW-style
*/
struct CodebookConverterDithered {
- static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
+ static inline void decodeBlock1(byte codebookIndex, const CinepakStrip &strip, byte *dst, size_t dstPitch, const byte *clipTable, const Graphics::PixelFormat &format) {
const uint32 *colorPtr = (const uint32 *)(strip.v1_dither + codebookIndex);
- *((uint32 *)rows[0]) = colorPtr[0];
- *((uint32 *)rows[1]) = colorPtr[256];
- *((uint32 *)rows[2]) = colorPtr[512];
- *((uint32 *)rows[3]) = colorPtr[768];
+
+ *((uint32 *)dst) = colorPtr[0];
+ dst += dstPitch;
+
+ *((uint32 *)dst) = colorPtr[256];
+ dst += dstPitch;
+
+ *((uint32 *)dst) = colorPtr[512];
+ dst += dstPitch;
+
+ *((uint32 *)dst) = colorPtr[768];
+ dst += dstPitch;
}
- static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *(&rows)[4], const byte *clipTable, const Graphics::PixelFormat &format) {
- const uint16 *colorPtr = (const uint16 *)(strip.v4_dither + codebookIndex[0]);
- *((uint16 *)(rows[0] + 0)) = colorPtr[0];
- *((uint16 *)(rows[1] + 0)) = colorPtr[1];
+ static inline void decodeBlock4(const byte (&codebookIndex)[4], const CinepakStrip &strip, byte *dst, size_t dstPitch, const byte *clipTable, const Graphics::PixelFormat &format) {
+ const uint16 *colorPtr1 = (const uint16 *)(strip.v4_dither + codebookIndex[0]);
+ const uint16 *colorPtr2 = (const uint16 *)(strip.v4_dither + codebookIndex[1]);
+
+ *((uint16 *)(dst + 0)) = colorPtr1[0];
+ *((uint16 *)(dst + 2)) = colorPtr2[512];
+ dst += dstPitch;
+
+ *((uint16 *)(dst + 0)) = colorPtr1[1];
+ *((uint16 *)(dst + 2)) = colorPtr2[513];
+ dst += dstPitch;
- colorPtr = (const uint16 *)(strip.v4_dither + codebookIndex[1]);
- *((uint16 *)(rows[0] + 2)) = colorPtr[512];
- *((uint16 *)(rows[1] + 2)) = colorPtr[513];
+ const uint16 *colorPtr3 = (const uint16 *)(strip.v4_dither + codebookIndex[2]);
+ const uint16 *colorPtr4 = (const uint16 *)(strip.v4_dither + codebookIndex[3]);
- colorPtr = (const uint16 *)(strip.v4_dither + codebookIndex[2]);
- *((uint16 *)(rows[2] + 0)) = colorPtr[1024];
- *((uint16 *)(rows[3] + 0)) = colorPtr[1025];
+ *((uint16 *)(dst + 0)) = colorPtr3[1024];
+ *((uint16 *)(dst + 2)) = colorPtr4[1536];
+ dst += dstPitch;
- colorPtr = (const uint16 *)(strip.v4_dither + codebookIndex[3]);
- *((uint16 *)(rows[2] + 2)) = colorPtr[1536];
- *((uint16 *)(rows[3] + 2)) = colorPtr[1537];
+ *((uint16 *)(dst + 0)) = colorPtr3[1025];
+ *((uint16 *)(dst + 2)) = colorPtr4[1537];
+ dst += dstPitch;
}
};
template<typename PixelInt, typename CodebookConverter>
void decodeVectorsTmpl(CinepakFrame &frame, const byte *clipTable, Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
uint32 flag = 0, mask = 0;
- PixelInt *iy[4];
int32 startPos = stream.pos();
+ PixelInt *dst;
for (uint16 y = frame.strips[strip].rect.top; y < frame.strips[strip].rect.bottom; y += 4) {
- iy[0] = (PixelInt *)frame.surface->getBasePtr(frame.strips[strip].rect.left, + y);
- iy[1] = iy[0] + frame.width;
- iy[2] = iy[1] + frame.width;
- iy[3] = iy[2] + frame.width;
+ dst = (PixelInt *)frame.surface->getBasePtr(frame.strips[strip].rect.left, + y);
for (uint16 x = frame.strips[strip].rect.left; x < frame.strips[strip].rect.right; x += 4) {
if ((chunkID & 0x01) && !(mask >>= 1)) {
@@ -211,19 +260,18 @@ void decodeVectorsTmpl(CinepakFrame &frame, const byte *clipTable, Common::Seeka
// Get the codebook
byte codebook = stream.readByte();
- CodebookConverter::decodeBlock1(codebook, frame.strips[strip], iy, clipTable, frame.surface->format);
+ CodebookConverter::decodeBlock1(codebook, frame.strips[strip], dst, frame.surface->pitch, clipTable, frame.surface->format);
} else if (flag & mask) {
if ((stream.pos() - startPos + 4) > (int32)chunkSize)
return;
byte codebook[4];
stream.read(codebook, 4);
- CodebookConverter::decodeBlock4(codebook, frame.strips[strip], iy, clipTable, frame.surface->format);
+ CodebookConverter::decodeBlock4(codebook, frame.strips[strip], dst, frame.surface->pitch, clipTable, frame.surface->format);
}
}
- for (byte i = 0; i < 4; i++)
- iy[i] += 4;
+ dst += 4;
}
}
}
Commit: 604708ad9897d2eeb687982c63e46bc8c2fc7ad8
https://github.com/scummvm/scummvm/commit/604708ad9897d2eeb687982c63e46bc8c2fc7ad8
Author: Cameron Cawley (ccawley2011 at gmail.com)
Date: 2024-04-22T02:07:47+02:00
Commit Message:
IMAGE: Combine lookup tables for Cinepak with VFW dithering
Changed paths:
image/codecs/cinepak.cpp
diff --git a/image/codecs/cinepak.cpp b/image/codecs/cinepak.cpp
index 909c0af6f8e..d7c5dd8e656 100644
--- a/image/codecs/cinepak.cpp
+++ b/image/codecs/cinepak.cpp
@@ -550,7 +550,7 @@ void CinepakDecoder::ditherCodebookQT(uint16 strip, byte codebookType, uint16 co
}
static inline byte getRGBLookupEntry(const byte *colorMap, uint16 index) {
- return colorMap[s_defaultPaletteLookup[CLIP<int>(index, 0, 1023)]];
+ return colorMap[CLIP<int>(index, 0, 1023)];
}
void CinepakDecoder::ditherCodebookVFW(uint16 strip, byte codebookType, uint16 codebookIndex) {
@@ -673,10 +673,10 @@ void CinepakDecoder::setDither(DitherType type, const byte *palette) {
_ditherType = type;
if (type == kDitherTypeVFW) {
- _colorMap = new byte[221];
+ _colorMap = new byte[1024];
- for (int i = 0; i < 221; i++)
- _colorMap[i] = findNearestRGB(i);
+ for (int i = 0; i < 1024; i++)
+ _colorMap[i] = findNearestRGB(s_defaultPaletteLookup[i]);
} else {
// Generate QuickTime dither table
// 4 blocks of 0x4000 bytes (RGB554 lookup)
More information about the Scummvm-git-logs
mailing list