aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Hoops2011-09-25 20:55:33 -0400
committerMatthew Hoops2011-10-07 11:32:35 -0400
commit75d2a43302e5f59bed2678ab21a41586d1c6a6eb (patch)
treeba5cf2d8ef05fee5d226e11c47a953306e7b6f46
parented13991f37a1f0ea93e516d7a916438ed6521eea (diff)
downloadscummvm-rg350-75d2a43302e5f59bed2678ab21a41586d1c6a6eb.tar.gz
scummvm-rg350-75d2a43302e5f59bed2678ab21a41586d1c6a6eb.tar.bz2
scummvm-rg350-75d2a43302e5f59bed2678ab21a41586d1c6a6eb.zip
GRAPHICS: Add support for multiple CompressedQuickTime calls
-rw-r--r--graphics/pict.cpp68
1 files changed, 62 insertions, 6 deletions
diff --git a/graphics/pict.cpp b/graphics/pict.cpp
index 718214cb22..a4cc67f01c 100644
--- a/graphics/pict.cpp
+++ b/graphics/pict.cpp
@@ -173,6 +173,11 @@ void PictDecoder::on_compressedQuickTime(Common::SeekableReadStream *stream) {
_opcodes.clear();
setupOpcodesQuickTime();
+ // We set up the surface for JPEG here too
+ if (!_outputSurface)
+ _outputSurface = new Graphics::Surface();
+ _outputSurface->create(_imageRect.width(), _imageRect.height(), _pixelFormat);
+
// We'll decode the first QuickTime data from here, but the QuickTime-specific
// opcodes will take over from here on out. Normal opcodes, signing off.
decodeCompressedQuickTime(stream);
@@ -427,8 +432,50 @@ void PictDecoder::unpackBitsLine(byte *out, uint32 length, Common::SeekableReadS
}
void PictDecoder::skipBitsRect(Common::SeekableReadStream *stream, bool hasPalette) {
- // TODO
- error("TODO: PICT-QuickTime mode: skip PackBitsRect/DirectBitsRect");
+ // Step through a PackBitsRect/DirectBitsRect function
+
+ if (!hasPalette)
+ stream->readUint32BE();
+
+ uint16 rowBytes = stream->readUint16BE();
+ uint16 height = stream->readUint16BE();
+ stream->readUint16BE();
+ height = stream->readUint16BE() - height;
+ stream->readUint16BE();
+
+ uint16 packType;
+ uint16 pixelSize;
+
+ // Top two bits signify PixMap vs BitMap
+ if (rowBytes & 0xC000) {
+ // PixMap
+ stream->readUint16BE();
+ packType = stream->readUint16BE();
+ stream->skip(14);
+ pixelSize = stream->readUint16BE();
+ stream->skip(16);
+
+ if (hasPalette) {
+ stream->readUint32BE();
+ stream->readUint16BE();
+ stream->skip((stream->readUint16BE() + 1) * 8);
+ }
+
+ rowBytes &= 0x3FFF;
+ } else {
+ // BitMap
+ packType = 0;
+ pixelSize = 1;
+ }
+
+ stream->skip(18);
+
+ for (uint16 i = 0; i < height; i++) {
+ if (packType == 1 || packType == 2 || rowBytes < 8)
+ error("Unpacked PackBitsRect data");
+ else if (packType == 0 || packType > 2)
+ stream->skip((rowBytes > 250) ? stream->readUint16BE() : stream->readByte());
+ }
}
void PictDecoder::outputPixelBuffer(byte *&out, byte value, byte bitsPerPixel) {
@@ -461,33 +508,42 @@ void PictDecoder::decodeCompressedQuickTime(Common::SeekableReadStream *stream)
/* uint16 version = */ stream->readUint16BE();
+ // Read in the display matrix
uint32 matrix[3][3];
for (uint32 i = 0; i < 3; i++)
for (uint32 j = 0; j < 3; j++)
matrix[i][j] = stream->readUint32BE();
+ // We currently only support offseting images vertically from the matrix
+ uint16 xOffset = 0;
+ uint16 yOffset = matrix[2][1] >> 16;
+
uint32 matteSize = stream->readUint32BE();
stream->skip(8); // matte rect
/* uint16 transferMode = */ stream->readUint16BE();
stream->skip(8); // src rect
/* uint32 accuracy = */ stream->readUint32BE();
uint32 maskSize = stream->readUint32BE();
-
+
+ // Skip the matte and mask
stream->skip(matteSize + maskSize);
// Now we've reached the image descriptor, so read the relevant data from that
uint32 idStart = stream->pos();
uint32 idSize = stream->readUint32BE();
- stream->skip(40);
+ stream->skip(40); // miscellaneous stuff
uint32 jpegSize = stream->readUint32BE();
- stream->skip(idSize - (stream->pos() - idStart));
+ stream->skip(idSize - (stream->pos() - idStart)); // more useless stuff
Common::SeekableReadStream *jpegStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + jpegSize);
if (!_jpeg->read(jpegStream))
error("PictDecoder::decodeCompressedQuickTime(): Could not decode JPEG data");
- _outputSurface = _jpeg->getSurface(_pixelFormat);
+ Graphics::Surface *jpegSurface = _jpeg->getSurface(_pixelFormat);
+
+ for (uint16 y = 0; y < jpegSurface->h; y++)
+ memcpy(_outputSurface->getBasePtr(0 + xOffset, y + yOffset), jpegSurface->getBasePtr(0, y), jpegSurface->w * _pixelFormat.bytesPerPixel);
stream->seek(startPos + dataSize);
delete jpegStream;