aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Hoops2011-07-02 21:02:58 -0400
committerJohannes Schickel2012-03-20 01:06:48 +0100
commit4516b5ea24e6c0056984a65fe4fff33553931487 (patch)
tree96f303d33ed30fef9e3d39aff8e973a1225557fc
parent270f8077c2fa4f226a693d95c7653b5d358b9556 (diff)
downloadscummvm-rg350-4516b5ea24e6c0056984a65fe4fff33553931487.tar.gz
scummvm-rg350-4516b5ea24e6c0056984a65fe4fff33553931487.tar.bz2
scummvm-rg350-4516b5ea24e6c0056984a65fe4fff33553931487.zip
GRAPHICS: Convert PictDecoder to the ImageDecoder API
-rw-r--r--engines/mohawk/graphics.cpp17
-rw-r--r--engines/mohawk/myst_graphics.cpp24
-rw-r--r--engines/mohawk/myst_graphics.h2
-rw-r--r--engines/sci/graphics/maciconbar.cpp18
-rw-r--r--engines/sci/graphics/maciconbar.h2
-rw-r--r--graphics/decoders/pict.cpp (renamed from graphics/pict.cpp)405
-rw-r--r--graphics/decoders/pict.h (renamed from graphics/pict.h)32
-rw-r--r--graphics/module.mk4
8 files changed, 229 insertions, 275 deletions
diff --git a/engines/mohawk/graphics.cpp b/engines/mohawk/graphics.cpp
index a08d034ef7..0f9a62c891 100644
--- a/engines/mohawk/graphics.cpp
+++ b/engines/mohawk/graphics.cpp
@@ -58,22 +58,7 @@ void MohawkSurface::convertToTrueColor() {
assert(_palette);
- Graphics::PixelFormat pixelFormat = g_system->getScreenFormat();
- Graphics::Surface *surface = new Graphics::Surface();
- surface->create(_surface->w, _surface->h, pixelFormat);
-
- for (uint16 i = 0; i < _surface->h; i++) {
- for (uint16 j = 0; j < _surface->w; j++) {
- byte palIndex = *((byte *)_surface->pixels + i * _surface->pitch + j);
- byte r = _palette[palIndex * 3 + 0];
- byte g = _palette[palIndex * 3 + 1];
- byte b = _palette[palIndex * 3 + 2];
- if (pixelFormat.bytesPerPixel == 2)
- *((uint16 *)surface->getBasePtr(j, i)) = pixelFormat.RGBToColor(r, g, b);
- else
- *((uint32 *)surface->getBasePtr(j, i)) = pixelFormat.RGBToColor(r, g, b);
- }
- }
+ Graphics::Surface *surface = _surface->convertTo(g_system->getScreenFormat(), _palette);
// Free everything and set the new surface as the converted surface
_surface->free();
diff --git a/engines/mohawk/myst_graphics.cpp b/engines/mohawk/myst_graphics.cpp
index 151390580f..86eb4f2b1b 100644
--- a/engines/mohawk/myst_graphics.cpp
+++ b/engines/mohawk/myst_graphics.cpp
@@ -29,7 +29,7 @@
#include "common/textconsole.h"
#include "engines/util.h"
#include "graphics/jpeg.h"
-#include "graphics/pict.h"
+#include "graphics/decoders/pict.h"
namespace Mohawk {
@@ -51,10 +51,8 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
if (_vm->getFeatures() & GF_ME) {
_jpegDecoder = new Graphics::JPEG();
- _pictDecoder = new Graphics::PictDecoder(_pixelFormat);
} else {
_jpegDecoder = NULL;
- _pictDecoder = NULL;
}
_pictureFile.entries = NULL;
@@ -70,7 +68,6 @@ MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
MystGraphics::~MystGraphics() {
delete _bmpDecoder;
delete _jpegDecoder;
- delete _pictDecoder;
delete[] _pictureFile.entries;
_backBuffer->free();
@@ -138,7 +135,13 @@ MohawkSurface *MystGraphics::decodeImage(uint16 id) {
mhkSurface = new MohawkSurface(_jpegDecoder->getSurface(_pixelFormat));
delete stream;
} else if (_pictureFile.entries[i].type == 1) {
- mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(new Common::SeekableSubReadStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size)));
+ Graphics::PICTDecoder pict;
+ Common::SeekableSubReadStream subStream(&_pictureFile.picFile, _pictureFile.entries[i].offset, _pictureFile.entries[i].offset + _pictureFile.entries[i].size);
+
+ if (!pict.loadStream(subStream))
+ error("Could not decode Myst ME Mac PICT");
+
+ mhkSurface = new MohawkSurface(pict.getSurface()->convertTo(_pixelFormat));
} else
error ("Unknown Picture File type %d", _pictureFile.entries[i].type);
break;
@@ -170,9 +173,14 @@ MohawkSurface *MystGraphics::decodeImage(uint16 id) {
dataStream->seek(0);
}
- if (isPict)
- mhkSurface = new MohawkSurface(_pictDecoder->decodeImage(dataStream));
- else {
+ if (isPict) {
+ Graphics::PICTDecoder pict;
+
+ if (!pict.loadStream(*dataStream))
+ error("Could not decode Myst ME PICT");
+
+ mhkSurface = new MohawkSurface(pict.getSurface()->convertTo(_pixelFormat));
+ } else {
mhkSurface = _bmpDecoder->decodeImage(dataStream);
mhkSurface->convertToTrueColor();
}
diff --git a/engines/mohawk/myst_graphics.h b/engines/mohawk/myst_graphics.h
index e2b02db5fc..8074c9828b 100644
--- a/engines/mohawk/myst_graphics.h
+++ b/engines/mohawk/myst_graphics.h
@@ -29,7 +29,6 @@
namespace Graphics {
class JPEG;
-class PictDecoder;
}
namespace Mohawk {
@@ -70,7 +69,6 @@ protected:
private:
MohawkEngine_Myst *_vm;
MystBitmap *_bmpDecoder;
- Graphics::PictDecoder *_pictDecoder;
Graphics::JPEG *_jpegDecoder;
struct PictureFile {
diff --git a/engines/sci/graphics/maciconbar.cpp b/engines/sci/graphics/maciconbar.cpp
index bff145ad53..7ecba5a24d 100644
--- a/engines/sci/graphics/maciconbar.cpp
+++ b/engines/sci/graphics/maciconbar.cpp
@@ -31,8 +31,8 @@
#include "common/memstream.h"
#include "common/system.h"
-#include "graphics/pict.h"
#include "graphics/surface.h"
+#include "graphics/decoders/pict.h"
namespace Sci {
@@ -201,18 +201,20 @@ void GfxMacIconBar::setInventoryIcon(int16 icon) {
}
Graphics::Surface *GfxMacIconBar::loadPict(ResourceId id) {
- Graphics::PictDecoder pictDecoder(Graphics::PixelFormat::createFormatCLUT8());
+ Graphics::PICTDecoder pictDecoder;
Resource *res = g_sci->getResMan()->findResource(id, false);
if (!res || res->size == 0)
return 0;
- byte palette[256 * 3];
- Common::SeekableReadStream *stream = new Common::MemoryReadStream(res->data, res->size);
- Graphics::Surface *surface = pictDecoder.decodeImage(stream, palette);
- remapColors(surface, palette);
+ Common::MemoryReadStream stream(res->data, res->size);
+ if (!pictDecoder.loadStream(stream))
+ return 0;
+
+ Graphics::Surface *surface = new Graphics::Surface();
+ surface->copyFrom(*pictDecoder.getSurface());
+ remapColors(surface, pictDecoder.getPalette());
- delete stream;
return surface;
}
@@ -221,7 +223,7 @@ Graphics::Surface *GfxMacIconBar::createImage(uint32 iconIndex, bool isSelected)
return loadPict(ResourceId(type, iconIndex + 1));
}
-void GfxMacIconBar::remapColors(Graphics::Surface *surf, byte *palette) {
+void GfxMacIconBar::remapColors(Graphics::Surface *surf, const byte *palette) {
byte *pixels = (byte *)surf->pixels;
// Remap to the screen palette
diff --git a/engines/sci/graphics/maciconbar.h b/engines/sci/graphics/maciconbar.h
index 43de37a904..eca10b804c 100644
--- a/engines/sci/graphics/maciconbar.h
+++ b/engines/sci/graphics/maciconbar.h
@@ -61,7 +61,7 @@ private:
Graphics::Surface *loadPict(ResourceId id);
Graphics::Surface *createImage(uint32 iconIndex, bool isSelected);
- void remapColors(Graphics::Surface *surf, byte *palette);
+ void remapColors(Graphics::Surface *surf, const byte *palette);
void drawIcon(uint16 index, bool selected);
void drawSelectedImage(uint16 index);
diff --git a/graphics/pict.cpp b/graphics/decoders/pict.cpp
index 872f2f224a..9b28f4352e 100644
--- a/graphics/pict.cpp
+++ b/graphics/decoders/pict.cpp
@@ -26,9 +26,9 @@
#include "common/substream.h"
#include "common/textconsole.h"
-#include "graphics/jpeg.h"
-#include "graphics/pict.h"
#include "graphics/surface.h"
+#include "graphics/jpeg.h"
+#include "graphics/decoders/pict.h"
namespace Graphics {
@@ -36,18 +36,25 @@ namespace Graphics {
// http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-461.html
// http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-269.html
-PictDecoder::PictDecoder(PixelFormat pixelFormat) {
- _jpeg = new JPEG();
- _pixelFormat = pixelFormat;
+PICTDecoder::PICTDecoder() {
+ _outputSurface = 0;
}
-PictDecoder::~PictDecoder() {
- delete _jpeg;
+PICTDecoder::~PICTDecoder() {
+ destroy();
}
-#define OPCODE(a, b, c) _opcodes.push_back(PICTOpcode(a, &PictDecoder::b, c))
+void PICTDecoder::destroy() {
+ if (_outputSurface) {
+ _outputSurface->free();
+ delete _outputSurface;
+ _outputSurface = 0;
+ }
+}
-void PictDecoder::setupOpcodesCommon() {
+#define OPCODE(a, b, c) _opcodes.push_back(PICTOpcode(a, &PICTDecoder::b, c))
+
+void PICTDecoder::setupOpcodesCommon() {
OPCODE(0x0000, o_nop, "NOP");
OPCODE(0x0001, o_clip, "Clip");
OPCODE(0x0003, o_txFont, "TxFont");
@@ -63,14 +70,14 @@ void PictDecoder::setupOpcodesCommon() {
OPCODE(0x0C00, o_headerOp, "HeaderOp");
}
-void PictDecoder::setupOpcodesNormal() {
+void PICTDecoder::setupOpcodesNormal() {
setupOpcodesCommon();
OPCODE(0x0098, on_packBitsRect, "PackBitsRect");
OPCODE(0x009A, on_directBitsRect, "DirectBitsRect");
OPCODE(0x8200, on_compressedQuickTime, "CompressedQuickTime");
}
-void PictDecoder::setupOpcodesQuickTime() {
+void PICTDecoder::setupOpcodesQuickTime() {
setupOpcodesCommon();
OPCODE(0x0098, oq_packBitsRect, "PackBitsRect");
OPCODE(0x009A, oq_directBitsRect, "DirectBitsRect");
@@ -79,93 +86,93 @@ void PictDecoder::setupOpcodesQuickTime() {
#undef OPCODE
-void PictDecoder::o_nop(Common::SeekableReadStream *) {
+void PICTDecoder::o_nop(Common::SeekableReadStream &) {
// Nothing to do
}
-void PictDecoder::o_clip(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_clip(Common::SeekableReadStream &stream) {
// Ignore
- stream->skip(stream->readUint16BE() - 2);
+ stream.skip(stream.readUint16BE() - 2);
}
-void PictDecoder::o_txFont(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_txFont(Common::SeekableReadStream &stream) {
// Ignore
- stream->readUint16BE();
+ stream.readUint16BE();
}
-void PictDecoder::o_txFace(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_txFace(Common::SeekableReadStream &stream) {
// Ignore
- stream->readByte();
+ stream.readByte();
}
-void PictDecoder::o_pnSize(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_pnSize(Common::SeekableReadStream &stream) {
// Ignore
- stream->readUint16BE();
- stream->readUint16BE();
+ stream.readUint16BE();
+ stream.readUint16BE();
}
-void PictDecoder::o_txSize(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_txSize(Common::SeekableReadStream &stream) {
// Ignore
- stream->readUint16BE();
+ stream.readUint16BE();
}
-void PictDecoder::o_txRatio(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_txRatio(Common::SeekableReadStream &stream) {
// Ignore
- stream->readUint16BE();
- stream->readUint16BE();
- stream->readUint16BE();
- stream->readUint16BE();
+ stream.readUint16BE();
+ stream.readUint16BE();
+ stream.readUint16BE();
+ stream.readUint16BE();
}
-void PictDecoder::o_versionOp(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_versionOp(Common::SeekableReadStream &stream) {
// We only support v2 extended
- if (stream->readUint16BE() != 0x02FF)
+ if (stream.readUint16BE() != 0x02FF)
error("Unknown PICT version");
}
-void PictDecoder::o_longText(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_longText(Common::SeekableReadStream &stream) {
// Ignore
- stream->readUint16BE();
- stream->readUint16BE();
- stream->skip(stream->readByte());
+ stream.readUint16BE();
+ stream.readUint16BE();
+ stream.skip(stream.readByte());
}
-void PictDecoder::o_longComment(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_longComment(Common::SeekableReadStream &stream) {
// Ignore
- stream->readUint16BE();
- stream->skip(stream->readUint16BE());
+ stream.readUint16BE();
+ stream.skip(stream.readUint16BE());
}
-void PictDecoder::o_opEndPic(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_opEndPic(Common::SeekableReadStream &stream) {
// We've reached the end of the picture
_continueParsing = false;
}
-void PictDecoder::o_headerOp(Common::SeekableReadStream *stream) {
+void PICTDecoder::o_headerOp(Common::SeekableReadStream &stream) {
// Read the basic header, but we don't really have to do anything with it
- /* uint16 version = */ stream->readUint16BE();
- stream->readUint16BE(); // Reserved
- /* uint32 hRes = */ stream->readUint32BE();
- /* uint32 vRes = */ stream->readUint32BE();
+ /* uint16 version = */ stream.readUint16BE();
+ stream.readUint16BE(); // Reserved
+ /* uint32 hRes = */ stream.readUint32BE();
+ /* uint32 vRes = */ stream.readUint32BE();
Common::Rect origResRect;
- origResRect.top = stream->readUint16BE();
- origResRect.left = stream->readUint16BE();
- origResRect.bottom = stream->readUint16BE();
- origResRect.right = stream->readUint16BE();
- stream->readUint32BE(); // Reserved
+ origResRect.top = stream.readUint16BE();
+ origResRect.left = stream.readUint16BE();
+ origResRect.bottom = stream.readUint16BE();
+ origResRect.right = stream.readUint16BE();
+ stream.readUint32BE(); // Reserved
}
-void PictDecoder::on_packBitsRect(Common::SeekableReadStream *stream) {
+void PICTDecoder::on_packBitsRect(Common::SeekableReadStream &stream) {
// Unpack data (8bpp or lower)
unpackBitsRect(stream, true);
}
-void PictDecoder::on_directBitsRect(Common::SeekableReadStream *stream) {
+void PICTDecoder::on_directBitsRect(Common::SeekableReadStream &stream) {
// Unpack data (16bpp or higher)
unpackBitsRect(stream, false);
}
-void PictDecoder::on_compressedQuickTime(Common::SeekableReadStream *stream) {
+void PICTDecoder::on_compressedQuickTime(Common::SeekableReadStream &stream) {
// OK, here's the fun. We get to completely change how QuickDraw draws
// the data in PICT files.
@@ -173,63 +180,57 @@ 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);
}
-void PictDecoder::oq_packBitsRect(Common::SeekableReadStream *stream) {
+void PICTDecoder::oq_packBitsRect(Common::SeekableReadStream &stream) {
// Skip any data here (8bpp or lower)
skipBitsRect(stream, true);
}
-void PictDecoder::oq_directBitsRect(Common::SeekableReadStream *stream) {
+void PICTDecoder::oq_directBitsRect(Common::SeekableReadStream &stream) {
// Skip any data here (16bpp or higher)
skipBitsRect(stream, false);
}
-void PictDecoder::oq_compressedQuickTime(Common::SeekableReadStream *stream) {
+void PICTDecoder::oq_compressedQuickTime(Common::SeekableReadStream &stream) {
// Just pass the data along
decodeCompressedQuickTime(stream);
}
-Surface *PictDecoder::decodeImage(Common::SeekableReadStream *stream, byte *palette) {
- assert(stream);
+bool PICTDecoder::loadStream(Common::SeekableReadStream &stream) {
+ destroy();
// Initialize opcodes to their normal state
_opcodes.clear();
setupOpcodesNormal();
- _outputSurface = 0;
_continueParsing = true;
memset(_palette, 0, sizeof(_palette));
- uint16 fileSize = stream->readUint16BE();
+ uint16 fileSize = stream.readUint16BE();
// If we have no file size here, we probably have a PICT from a file
// and not a resource. The other two bytes are the fileSize which we
// don't actually need (and already read if from a resource).
if (!fileSize)
- stream->seek(512 + 2);
+ stream.seek(512 + 2);
- _imageRect.top = stream->readUint16BE();
- _imageRect.left = stream->readUint16BE();
- _imageRect.bottom = stream->readUint16BE();
- _imageRect.right = stream->readUint16BE();
+ _imageRect.top = stream.readUint16BE();
+ _imageRect.left = stream.readUint16BE();
+ _imageRect.bottom = stream.readUint16BE();
+ _imageRect.right = stream.readUint16BE();
_imageRect.debugPrint(0, "PICT Rect:");
// NOTE: This is only a subset of the full PICT format.
// - Only V2 (Extended) Images Supported
// - CompressedQuickTime (JPEG) compressed data is supported
// - DirectBitsRect/PackBitsRect compressed data is supported
- for (uint32 opNum = 0; !stream->eos() && !stream->err() && stream->pos() < stream->size() && _continueParsing; opNum++) {
+ for (uint32 opNum = 0; !stream.eos() && !stream.err() && stream.pos() < stream.size() && _continueParsing; opNum++) {
// PICT v2 opcodes are two bytes
- uint16 opcode = stream->readUint16BE();
+ uint16 opcode = stream.readUint16BE();
if (opNum == 0 && opcode != 0x0011)
error("Cannot find PICT version opcode");
@@ -238,7 +239,7 @@ Surface *PictDecoder::decodeImage(Common::SeekableReadStream *stream, byte *pale
// Since opcodes are word-aligned, we need to mark our starting
// position here.
- uint32 startPos = stream->pos();
+ uint32 startPos = stream.pos();
for (uint32 i = 0; i < _opcodes.size(); i++) {
if (_opcodes[i].op == opcode) {
@@ -252,76 +253,70 @@ Surface *PictDecoder::decodeImage(Common::SeekableReadStream *stream, byte *pale
}
// Align
- stream->skip((stream->pos() - startPos) & 1);
+ stream.skip((stream.pos() - startPos) & 1);
}
- // If we got a palette throughout this nonsense, go and grab it
- if (palette)
- memcpy(palette, _palette, 256 * 3);
-
return _outputSurface;
}
-PictDecoder::PixMap PictDecoder::readPixMap(Common::SeekableReadStream *stream, bool hasBaseAddr) {
+PICTDecoder::PixMap PICTDecoder::readPixMap(Common::SeekableReadStream &stream, bool hasBaseAddr) {
PixMap pixMap;
- pixMap.baseAddr = hasBaseAddr ? stream->readUint32BE() : 0;
- pixMap.rowBytes = stream->readUint16BE() & 0x3fff;
- pixMap.bounds.top = stream->readUint16BE();
- pixMap.bounds.left = stream->readUint16BE();
- pixMap.bounds.bottom = stream->readUint16BE();
- pixMap.bounds.right = stream->readUint16BE();
- pixMap.pmVersion = stream->readUint16BE();
- pixMap.packType = stream->readUint16BE();
- pixMap.packSize = stream->readUint32BE();
- pixMap.hRes = stream->readUint32BE();
- pixMap.vRes = stream->readUint32BE();
- pixMap.pixelType = stream->readUint16BE();
- pixMap.pixelSize = stream->readUint16BE();
- pixMap.cmpCount = stream->readUint16BE();
- pixMap.cmpSize = stream->readUint16BE();
- pixMap.planeBytes = stream->readUint32BE();
- pixMap.pmTable = stream->readUint32BE();
- pixMap.pmReserved = stream->readUint32BE();
+ pixMap.baseAddr = hasBaseAddr ? stream.readUint32BE() : 0;
+ pixMap.rowBytes = stream.readUint16BE() & 0x3fff;
+ pixMap.bounds.top = stream.readUint16BE();
+ pixMap.bounds.left = stream.readUint16BE();
+ pixMap.bounds.bottom = stream.readUint16BE();
+ pixMap.bounds.right = stream.readUint16BE();
+ pixMap.pmVersion = stream.readUint16BE();
+ pixMap.packType = stream.readUint16BE();
+ pixMap.packSize = stream.readUint32BE();
+ pixMap.hRes = stream.readUint32BE();
+ pixMap.vRes = stream.readUint32BE();
+ pixMap.pixelType = stream.readUint16BE();
+ pixMap.pixelSize = stream.readUint16BE();
+ pixMap.cmpCount = stream.readUint16BE();
+ pixMap.cmpSize = stream.readUint16BE();
+ pixMap.planeBytes = stream.readUint32BE();
+ pixMap.pmTable = stream.readUint32BE();
+ pixMap.pmReserved = stream.readUint32BE();
return pixMap;
}
struct PackBitsRectData {
- PictDecoder::PixMap pixMap;
+ PICTDecoder::PixMap pixMap;
Common::Rect srcRect;
Common::Rect dstRect;
uint16 mode;
};
-void PictDecoder::unpackBitsRect(Common::SeekableReadStream *stream, bool hasPalette) {
- static const PixelFormat directBitsFormat16 = PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
-
+void PICTDecoder::unpackBitsRect(Common::SeekableReadStream &stream, bool hasPalette) {
PackBitsRectData packBitsData;
packBitsData.pixMap = readPixMap(stream, !hasPalette);
// Read in the palette if there is one present
if (hasPalette) {
// See http://developer.apple.com/legacy/mac/library/documentation/mac/QuickDraw/QuickDraw-267.html
- stream->readUint32BE(); // seed
- stream->readUint16BE(); // flags
- uint16 colorCount = stream->readUint16BE() + 1;
+ stream.readUint32BE(); // seed
+ stream.readUint16BE(); // flags
+ uint16 colorCount = stream.readUint16BE() + 1;
for (uint32 i = 0; i < colorCount; i++) {
- stream->readUint16BE();
- _palette[i * 3] = stream->readUint16BE() >> 8;
- _palette[i * 3 + 1] = stream->readUint16BE() >> 8;
- _palette[i * 3 + 2] = stream->readUint16BE() >> 8;
+ stream.readUint16BE();
+ _palette[i * 3] = stream.readUint16BE() >> 8;
+ _palette[i * 3 + 1] = stream.readUint16BE() >> 8;
+ _palette[i * 3 + 2] = stream.readUint16BE() >> 8;
}
}
- packBitsData.srcRect.top = stream->readUint16BE();
- packBitsData.srcRect.left = stream->readUint16BE();
- packBitsData.srcRect.bottom = stream->readUint16BE();
- packBitsData.srcRect.right = stream->readUint16BE();
- packBitsData.dstRect.top = stream->readUint16BE();
- packBitsData.dstRect.left = stream->readUint16BE();
- packBitsData.dstRect.bottom = stream->readUint16BE();
- packBitsData.dstRect.right = stream->readUint16BE();
- packBitsData.mode = stream->readUint16BE();
+ packBitsData.srcRect.top = stream.readUint16BE();
+ packBitsData.srcRect.left = stream.readUint16BE();
+ packBitsData.srcRect.bottom = stream.readUint16BE();
+ packBitsData.srcRect.right = stream.readUint16BE();
+ packBitsData.dstRect.top = stream.readUint16BE();
+ packBitsData.dstRect.left = stream.readUint16BE();
+ packBitsData.dstRect.bottom = stream.readUint16BE();
+ packBitsData.dstRect.right = stream.readUint16BE();
+ packBitsData.mode = stream.readUint16BE();
uint16 width = packBitsData.srcRect.width();
uint16 height = packBitsData.srcRect.height();
@@ -335,9 +330,6 @@ void PictDecoder::unpackBitsRect(Common::SeekableReadStream *stream, bool hasPal
else
bytesPerPixel = packBitsData.pixMap.pixelSize / 8;
- _outputSurface = new Graphics::Surface();
- _outputSurface->create(width, height, (bytesPerPixel == 1) ? PixelFormat::createFormatCLUT8() : _pixelFormat);
-
// Ensure we have enough space in the buffer to hold an entire line's worth of pixels
uint32 lineSize = MAX<int>(width * bytesPerPixel + (8 * 2 / packBitsData.pixMap.pixelSize), packBitsData.pixMap.rowBytes);
byte *buffer = new byte[lineSize * height];
@@ -355,56 +347,48 @@ void PictDecoder::unpackBitsRect(Common::SeekableReadStream *stream, bool hasPal
// TODO: Finish this. Hasn't been needed (yet).
error("Unpacked DirectBitsRect data (not padded)");
} else if (packBitsData.pixMap.packType == 0 || packBitsData.pixMap.packType > 2) { // Packed
- uint16 byteCount = (packBitsData.pixMap.rowBytes > 250) ? stream->readUint16BE() : stream->readByte();
- unpackBitsLine(buffer + i * _outputSurface->w * bytesPerPixel, packBitsData.pixMap.rowBytes, stream->readStream(byteCount), packBitsData.pixMap.pixelSize, bytesPerPixel);
+ uint16 byteCount = (packBitsData.pixMap.rowBytes > 250) ? stream.readUint16BE() : stream.readByte();
+ unpackBitsLine(buffer + i * width * bytesPerPixel, packBitsData.pixMap.rowBytes, stream.readStream(byteCount), packBitsData.pixMap.pixelSize, bytesPerPixel);
}
}
+ _outputSurface = new Graphics::Surface();
+
switch (bytesPerPixel) {
case 1:
// Just copy to the image
+ _outputSurface->create(width, height, PixelFormat::createFormatCLUT8());
memcpy(_outputSurface->pixels, buffer, _outputSurface->w * _outputSurface->h);
break;
case 2:
// Convert from 16-bit to whatever surface we need
- for (uint16 y = 0; y < _outputSurface->h; y++) {
- for (uint16 x = 0; x < _outputSurface->w; x++) {
- byte r = 0, g = 0, b = 0;
- uint32 color = READ_BE_UINT16(buffer + (y * _outputSurface->w + x) * bytesPerPixel);
- directBitsFormat16.colorToRGB(color, r, g, b);
- if (_pixelFormat.bytesPerPixel == 2)
- *((uint16 *)_outputSurface->getBasePtr(x, y)) = _pixelFormat.RGBToColor(r, g, b);
- else
- *((uint32 *)_outputSurface->getBasePtr(x, y)) = _pixelFormat.RGBToColor(r, g, b);
- }
- }
+ _outputSurface->create(width, height, PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0));
+ for (uint16 y = 0; y < _outputSurface->h; y++)
+ for (uint16 x = 0; x < _outputSurface->w; x++)
+ WRITE_UINT16(_outputSurface->getBasePtr(x, y), READ_BE_UINT16(buffer + (y * _outputSurface->w + x) * 2));
break;
case 3:
// Convert from 24-bit (planar!) to whatever surface we need
+ _outputSurface->create(width, height, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
for (uint16 y = 0; y < _outputSurface->h; y++) {
for (uint16 x = 0; x < _outputSurface->w; x++) {
byte r = *(buffer + y * _outputSurface->w * 3 + x);
byte g = *(buffer + y * _outputSurface->w * 3 + _outputSurface->w + x);
byte b = *(buffer + y * _outputSurface->w * 3 + _outputSurface->w * 2 + x);
- if (_pixelFormat.bytesPerPixel == 2)
- *((uint16 *)_outputSurface->getBasePtr(x, y)) = _pixelFormat.RGBToColor(r, g, b);
- else
- *((uint32 *)_outputSurface->getBasePtr(x, y)) = _pixelFormat.RGBToColor(r, g, b);
+ *((uint32 *)_outputSurface->getBasePtr(x, y)) = _outputSurface->format.RGBToColor(r, g, b);
}
}
break;
case 4:
// Convert from 32-bit (planar!) to whatever surface we need
+ _outputSurface->create(width, height, Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
for (uint16 y = 0; y < _outputSurface->h; y++) {
for (uint16 x = 0; x < _outputSurface->w; x++) {
byte r = *(buffer + y * _outputSurface->w * 4 + x);
byte g = *(buffer + y * _outputSurface->w * 4 + _outputSurface->w + x);
byte b = *(buffer + y * _outputSurface->w * 4 + _outputSurface->w * 2 + x);
byte a = *(buffer + y * _outputSurface->w * 4 + _outputSurface->w * 3 + x);
- if (_pixelFormat.bytesPerPixel == 2)
- *((uint16 *)_outputSurface->getBasePtr(x, y)) = _pixelFormat.ARGBToColor(r, g, b, a);
- else
- *((uint32 *)_outputSurface->getBasePtr(x, y)) = _pixelFormat.ARGBToColor(r, g, b, a);
+ *((uint32 *)_outputSurface->getBasePtr(x, y)) = _outputSurface->format.ARGBToColor(r, g, b, a);
}
}
break;
@@ -413,7 +397,7 @@ void PictDecoder::unpackBitsRect(Common::SeekableReadStream *stream, bool hasPal
delete[] buffer;
}
-void PictDecoder::unpackBitsLine(byte *out, uint32 length, Common::SeekableReadStream *data, byte bitsPerPixel, byte bytesPerPixel) {
+void PICTDecoder::unpackBitsLine(byte *out, uint32 length, Common::SeekableReadStream *data, byte bitsPerPixel, byte bytesPerPixel) {
uint32 dataDecoded = 0;
byte bytesPerDecode = (bytesPerPixel == 2) ? 2 : 1;
@@ -426,7 +410,7 @@ void PictDecoder::unpackBitsLine(byte *out, uint32 length, Common::SeekableReadS
for (uint32 i = 0; i < runSize; i++) {
if (bytesPerDecode == 2) {
- WRITE_BE_UINT16(out, value);
+ WRITE_UINT16(out, value);
out += 2;
} else {
outputPixelBuffer(out, value, bitsPerPixel);
@@ -434,12 +418,19 @@ void PictDecoder::unpackBitsLine(byte *out, uint32 length, Common::SeekableReadS
}
dataDecoded += runSize * bytesPerDecode;
} else {
- uint32 runSize = (op + 1) * bytesPerDecode;
-
- for (uint32 i = 0; i < runSize; i++)
- outputPixelBuffer(out, data->readByte(), bitsPerPixel);
+ uint32 runSize = op + 1;
+
+ if (bytesPerDecode == 1) {
+ for (uint32 i = 0; i < runSize; i++)
+ outputPixelBuffer(out, data->readByte(), bitsPerPixel);
+ } else {
+ for (uint32 i = 0; i < runSize; i++) {
+ WRITE_UINT16(out, data->readUint16BE());
+ out += 2;
+ }
+ }
- dataDecoded += runSize;
+ dataDecoded += runSize * bytesPerDecode;
}
}
@@ -453,33 +444,52 @@ void PictDecoder::unpackBitsLine(byte *out, uint32 length, Common::SeekableReadS
delete data;
}
-void PictDecoder::skipBitsRect(Common::SeekableReadStream *stream, bool hasPalette) {
+void PICTDecoder::outputPixelBuffer(byte *&out, byte value, byte bitsPerPixel) {
+ switch (bitsPerPixel) {
+ case 1:
+ for (int i = 7; i >= 0; i--)
+ *out++ = (value >> i) & 1;
+ break;
+ case 2:
+ for (int i = 6; i >= 0; i -= 2)
+ *out++ = (value >> i) & 3;
+ break;
+ case 4:
+ *out++ = (value >> 4) & 0xf;
+ *out++ = value & 0xf;
+ break;
+ default:
+ *out++ = value;
+ }
+}
+
+void PICTDecoder::skipBitsRect(Common::SeekableReadStream &stream, bool hasPalette) {
// Step through a PackBitsRect/DirectBitsRect function
if (!hasPalette)
- stream->readUint32BE();
+ stream.readUint32BE();
- uint16 rowBytes = stream->readUint16BE();
- uint16 height = stream->readUint16BE();
- stream->readUint16BE();
- height = stream->readUint16BE() - height;
- stream->readUint16BE();
+ uint16 rowBytes = stream.readUint16BE();
+ uint16 height = stream.readUint16BE();
+ stream.readUint16BE();
+ height = stream.readUint16BE() - height;
+ stream.readUint16BE();
uint16 packType;
// Top two bits signify PixMap vs BitMap
if (rowBytes & 0xC000) {
// PixMap
- stream->readUint16BE();
- packType = stream->readUint16BE();
- stream->skip(14);
- stream->readUint16BE(); // pixelSize
- stream->skip(16);
+ stream.readUint16BE();
+ packType = stream.readUint16BE();
+ stream.skip(14);
+ stream.readUint16BE(); // pixelSize
+ stream.skip(16);
if (hasPalette) {
- stream->readUint32BE();
- stream->readUint16BE();
- stream->skip((stream->readUint16BE() + 1) * 8);
+ stream.readUint32BE();
+ stream.readUint16BE();
+ stream.skip((stream.readUint16BE() + 1) * 8);
}
rowBytes &= 0x3FFF;
@@ -488,84 +498,33 @@ void PictDecoder::skipBitsRect(Common::SeekableReadStream *stream, bool hasPalet
packType = 0;
}
- stream->skip(18);
+ 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) {
- switch (bitsPerPixel) {
- case 1:
- for (int i = 7; i >= 0; i--)
- *out++ = (value >> i) & 1;
- break;
- case 2:
- for (int i = 6; i >= 0; i -= 2)
- *out++ = (value >> i) & 3;
- break;
- case 4:
- *out++ = (value >> 4) & 0xf;
- *out++ = value & 0xf;
- break;
- default:
- *out++ = value;
+ stream.skip((rowBytes > 250) ? stream.readUint16BE() : stream.readByte());
}
}
// Compressed QuickTime details can be found here:
// http://developer.apple.com/legacy/mac/library/#documentation/QuickTime/Rm/CompressDecompress/ImageComprMgr/B-Chapter/2TheImageCompression.html
// http://developer.apple.com/legacy/mac/library/#documentation/QuickTime/Rm/CompressDecompress/ImageComprMgr/F-Chapter/6WorkingwiththeImage.html
+void PICTDecoder::decodeCompressedQuickTime(Common::SeekableReadStream &stream) {
+ JPEG jpeg;
-void PictDecoder::decodeCompressedQuickTime(Common::SeekableReadStream *stream) {
- // First, read all the fields from the opcode
- uint32 dataSize = stream->readUint32BE();
- uint32 startPos = stream->pos();
-
- /* 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); // miscellaneous stuff
- uint32 jpegSize = stream->readUint32BE();
- stream->skip(idSize - (stream->pos() - idStart)); // more useless stuff
-
- Common::SeekableReadStream *jpegStream = new Common::SeekableSubReadStream(stream, stream->pos(), stream->pos() + jpegSize);
+ uint32 dataSize = stream.readUint32BE();
+ uint32 startPos = stream.pos();
- if (!_jpeg->read(jpegStream))
- error("PictDecoder::decodeCompressedQuickTime(): Could not decode JPEG data");
+ Common::SeekableReadStream *jpegStream = new Common::SeekableSubReadStream(&stream, stream.pos() + 156, stream.pos() + dataSize);
- Graphics::Surface *jpegSurface = _jpeg->getSurface(_pixelFormat);
+ if (!jpeg.read(jpegStream))
+ error("PICTDecoder::decodeCompressedQuickTime(): Could not decode JPEG data");
- for (uint16 y = 0; y < jpegSurface->h; y++)
- memcpy(_outputSurface->getBasePtr(0 + xOffset, y + yOffset), jpegSurface->getBasePtr(0, y), jpegSurface->w * _pixelFormat.bytesPerPixel);
+ _outputSurface = jpeg.getSurface(Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
- stream->seek(startPos + dataSize);
+ stream.seek(startPos + dataSize);
delete jpegStream;
}
diff --git a/graphics/pict.h b/graphics/decoders/pict.h
index b426c6ee35..b1e45a6bc1 100644
--- a/graphics/pict.h
+++ b/graphics/decoders/pict.h
@@ -27,6 +27,7 @@
#include "common/rect.h"
#include "common/scummsys.h"
+#include "graphics/decoders/image_decoder.h"
#include "graphics/pixelformat.h"
namespace Common {
@@ -35,16 +36,20 @@ class SeekableReadStream;
namespace Graphics {
-class JPEG;
struct Surface;
-#define DECLARE_OPCODE(x) void x(Common::SeekableReadStream *stream)
+#define DECLARE_OPCODE(x) void x(Common::SeekableReadStream &stream)
-class PictDecoder {
+class PICTDecoder : public ImageDecoder {
public:
- PictDecoder(Graphics::PixelFormat pixelFormat);
- ~PictDecoder();
- Surface *decodeImage(Common::SeekableReadStream *stream, byte *palette = 0);
+ PICTDecoder();
+ ~PICTDecoder();
+
+ // ImageDecoder API
+ bool loadStream(Common::SeekableReadStream &stream);
+ void destroy();
+ const Surface *getSurface() const { return _outputSurface; }
+ const byte *getPalette() const { return _palette; }
struct PixMap {
uint32 baseAddr;
@@ -64,26 +69,23 @@ public:
uint32 pmReserved;
};
- static PixMap readPixMap(Common::SeekableReadStream *stream, bool hasBaseAddr = true);
+ static PixMap readPixMap(Common::SeekableReadStream &stream, bool hasBaseAddr = true);
private:
Common::Rect _imageRect;
- PixelFormat _pixelFormat;
- JPEG *_jpeg;
byte _palette[256 * 3];
- bool _isPaletted;
Graphics::Surface *_outputSurface;
bool _continueParsing;
// Utility Functions
- void unpackBitsRect(Common::SeekableReadStream *stream, bool hasPalette);
- void unpackBitsLine(byte *out, uint32 length, Common::SeekableReadStream *data, byte bitsPerPixel, byte bytesPerPixel);
- void skipBitsRect(Common::SeekableReadStream *stream, bool hasPalette);
- void decodeCompressedQuickTime(Common::SeekableReadStream *stream);
+ void unpackBitsRect(Common::SeekableReadStream &stream, bool hasPalette);
+ void unpackBitsLine(byte *out, uint32 length, Common::SeekableReadStream *stream, byte bitsPerPixel, byte bytesPerPixel);
+ void skipBitsRect(Common::SeekableReadStream &stream, bool hasPalette);
+ void decodeCompressedQuickTime(Common::SeekableReadStream &stream);
void outputPixelBuffer(byte *&out, byte value, byte bitsPerPixel);
// Opcodes
- typedef void (PictDecoder::*OpcodeProcPICT)(Common::SeekableReadStream *stream);
+ typedef void (PICTDecoder::*OpcodeProcPICT)(Common::SeekableReadStream &stream);
struct PICTOpcode {
PICTOpcode() { op = 0; proc = 0; desc = 0; }
PICTOpcode(uint16 o, OpcodeProcPICT p, const char *d) { op = o; proc = p; desc = d; }
diff --git a/graphics/module.mk b/graphics/module.mk
index 5c1d313ca9..08f6d0b1ec 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -14,7 +14,6 @@ MODULE_OBJS := \
iff.o \
jpeg.o \
maccursor.o \
- pict.o \
png.o \
primitives.o \
scaler.o \
@@ -26,7 +25,8 @@ MODULE_OBJS := \
VectorRendererSpec.o \
wincursor.o \
yuv_to_rgb.o \
- decoders/bmp.o
+ decoders/bmp.o \
+ decoders/pict.o
ifdef USE_SCALERS
MODULE_OBJS += \