diff options
author | Matthew Hoops | 2011-09-25 20:55:33 -0400 |
---|---|---|
committer | Matthew Hoops | 2011-09-25 20:55:33 -0400 |
commit | 8897c17884c846f225f751f4b2838dd0e15c7faa (patch) | |
tree | eee2dd465611c2e3f75559fc7873ff2d71d54c5c | |
parent | 161b4c9f2ba245249c16401bb0b0099e01b2273f (diff) | |
download | scummvm-rg350-8897c17884c846f225f751f4b2838dd0e15c7faa.tar.gz scummvm-rg350-8897c17884c846f225f751f4b2838dd0e15c7faa.tar.bz2 scummvm-rg350-8897c17884c846f225f751f4b2838dd0e15c7faa.zip |
GRAPHICS: Add support for multiple CompressedQuickTime calls
Several pegasus demos now show up correctly. Yay! :)
-rw-r--r-- | graphics/pict.cpp | 68 |
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; |