IMAGE: Make Codec take a stream reference; change function name to decodeFrame
This commit is contained in:
parent
e6717aaf43
commit
08ea14a8d0
30 changed files with 290 additions and 291 deletions
|
@ -39,12 +39,12 @@ struct CDToonsDiff {
|
||||||
Common::Rect rect;
|
Common::Rect rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
static Common::Rect readRect(Common::SeekableReadStream *stream) {
|
static Common::Rect readRect(Common::SeekableReadStream &stream) {
|
||||||
Common::Rect rect;
|
Common::Rect rect;
|
||||||
rect.top = stream->readUint16BE();
|
rect.top = stream.readUint16BE();
|
||||||
rect.left = stream->readUint16BE();
|
rect.left = stream.readUint16BE();
|
||||||
rect.bottom = stream->readUint16BE();
|
rect.bottom = stream.readUint16BE();
|
||||||
rect.right = stream->readUint16BE();
|
rect.right = stream.readUint16BE();
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,14 +67,14 @@ CDToonsDecoder::~CDToonsDecoder() {
|
||||||
delete[] i->_value.data;
|
delete[] i->_value.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *stream) {
|
Graphics::Surface *CDToonsDecoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
uint16 u0 = stream->readUint16BE(); // always 9?
|
uint16 u0 = stream.readUint16BE(); // always 9?
|
||||||
uint16 frameId = stream->readUint16BE();
|
uint16 frameId = stream.readUint16BE();
|
||||||
uint16 blocksValidUntil = stream->readUint16BE();
|
uint16 blocksValidUntil = stream.readUint16BE();
|
||||||
byte u6 = stream->readByte();
|
byte u6 = stream.readByte();
|
||||||
byte backgroundColor = stream->readByte();
|
byte backgroundColor = stream.readByte();
|
||||||
debugN(5, "CDToons frame %d, size %d, unknown %04x (at 0), blocks valid until %d, unknown 6 is %02x, bkg color is %02x\n",
|
debugN(5, "CDToons frame %d, size %d, unknown %04x (at 0), blocks valid until %d, unknown 6 is %02x, bkg color is %02x\n",
|
||||||
frameId, stream->size(), u0, blocksValidUntil, u6, backgroundColor);
|
frameId, stream.size(), u0, blocksValidUntil, u6, backgroundColor);
|
||||||
|
|
||||||
Common::Rect clipRect = readRect(stream);
|
Common::Rect clipRect = readRect(stream);
|
||||||
debugN(9, "CDToons clipRect: (%d, %d) to (%d, %d)\n",
|
debugN(9, "CDToons clipRect: (%d, %d) to (%d, %d)\n",
|
||||||
|
@ -84,31 +84,31 @@ Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *strea
|
||||||
debugN(9, "CDToons dirtyRect: (%d, %d) to (%d, %d)\n",
|
debugN(9, "CDToons dirtyRect: (%d, %d) to (%d, %d)\n",
|
||||||
dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
|
dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom);
|
||||||
|
|
||||||
uint32 flags = stream->readUint32BE();
|
uint32 flags = stream.readUint32BE();
|
||||||
if (flags & 0x80)
|
if (flags & 0x80)
|
||||||
error("CDToons: frame already processed?");
|
error("CDToons: frame already processed?");
|
||||||
debugN(5, "CDToons flags: %08x\n", flags);
|
debugN(5, "CDToons flags: %08x\n", flags);
|
||||||
|
|
||||||
uint16 blockCount = stream->readUint16BE();
|
uint16 blockCount = stream.readUint16BE();
|
||||||
uint16 blockOffset = stream->readUint16BE();
|
uint16 blockOffset = stream.readUint16BE();
|
||||||
debugN(9, "CDToons: %d blocks at 0x%04x\n",
|
debugN(9, "CDToons: %d blocks at 0x%04x\n",
|
||||||
blockCount, blockOffset);
|
blockCount, blockOffset);
|
||||||
|
|
||||||
// max block id?
|
// max block id?
|
||||||
uint16 u32 = stream->readUint16BE();
|
uint16 u32 = stream.readUint16BE();
|
||||||
debugN(5, "CDToons unknown at 32: %04x\n", u32);
|
debugN(5, "CDToons unknown at 32: %04x\n", u32);
|
||||||
|
|
||||||
byte actionCount = stream->readByte();
|
byte actionCount = stream.readByte();
|
||||||
byte u35 = stream->readByte();
|
byte u35 = stream.readByte();
|
||||||
|
|
||||||
uint16 paletteId = stream->readUint16BE();
|
uint16 paletteId = stream.readUint16BE();
|
||||||
byte paletteSet = stream->readByte();
|
byte paletteSet = stream.readByte();
|
||||||
debugN(9, "CDToons palette id %04x, palette byte %02x\n",
|
debugN(9, "CDToons palette id %04x, palette byte %02x\n",
|
||||||
paletteId, paletteSet);
|
paletteId, paletteSet);
|
||||||
|
|
||||||
byte u39 = stream->readByte();
|
byte u39 = stream.readByte();
|
||||||
uint16 u40 = stream->readUint16BE();
|
uint16 u40 = stream.readUint16BE();
|
||||||
uint16 u42 = stream->readUint16BE();
|
uint16 u42 = stream.readUint16BE();
|
||||||
debugN(5, "CDToons: unknown at 35 is %02x, unknowns at 39: %02x, %04x, %04x\n",
|
debugN(5, "CDToons: unknown at 35 is %02x, unknowns at 39: %02x, %04x, %04x\n",
|
||||||
u35, u39, u40, u42);
|
u35, u39, u40, u42);
|
||||||
|
|
||||||
|
@ -116,41 +116,41 @@ Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *strea
|
||||||
|
|
||||||
for (uint i = 0; i < actionCount; i++) {
|
for (uint i = 0; i < actionCount; i++) {
|
||||||
CDToonsAction action;
|
CDToonsAction action;
|
||||||
action.blockId = stream->readUint16BE();
|
action.blockId = stream.readUint16BE();
|
||||||
action.rect = readRect(stream);
|
action.rect = readRect(stream);
|
||||||
debugN(9, "CDToons action: render block %d at (%d, %d) to (%d, %d)\n",
|
debugN(9, "CDToons action: render block %d at (%d, %d) to (%d, %d)\n",
|
||||||
action.blockId, action.rect.left, action.rect.top, action.rect.right, action.rect.bottom);
|
action.blockId, action.rect.left, action.rect.top, action.rect.right, action.rect.bottom);
|
||||||
actions.push_back(action);
|
actions.push_back(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->pos() > blockOffset)
|
if (stream.pos() > blockOffset)
|
||||||
error("CDToons header ended at 0x%08x, but blocks should have started at 0x%08x",
|
error("CDToons header ended at 0x%08x, but blocks should have started at 0x%08x",
|
||||||
stream->pos(), blockOffset);
|
stream.pos(), blockOffset);
|
||||||
|
|
||||||
if (stream->pos() != blockOffset)
|
if (stream.pos() != blockOffset)
|
||||||
error("CDToons had %d unknown bytes after header", blockOffset - stream->pos());
|
error("CDToons had %d unknown bytes after header", blockOffset - stream.pos());
|
||||||
|
|
||||||
for (uint i = 0; i < blockCount; i++) {
|
for (uint i = 0; i < blockCount; i++) {
|
||||||
uint16 blockId = stream->readUint16BE();
|
uint16 blockId = stream.readUint16BE();
|
||||||
if (blockId >= 1200)
|
if (blockId >= 1200)
|
||||||
error("CDToons: block id %d was too high", blockId);
|
error("CDToons: block id %d was too high", blockId);
|
||||||
if (_blocks.contains(blockId))
|
if (_blocks.contains(blockId))
|
||||||
error("CDToons: new block %d was already seen", blockId);
|
error("CDToons: new block %d was already seen", blockId);
|
||||||
|
|
||||||
CDToonsBlock block;
|
CDToonsBlock block;
|
||||||
block.flags = stream->readUint16BE();
|
block.flags = stream.readUint16BE();
|
||||||
// flag 1 = palette, flag 2 = data?
|
// flag 1 = palette, flag 2 = data?
|
||||||
if (block.flags & 0x8000)
|
if (block.flags & 0x8000)
|
||||||
error("CDToons: block already processed?");
|
error("CDToons: block already processed?");
|
||||||
block.size = stream->readUint32BE();
|
block.size = stream.readUint32BE();
|
||||||
if (block.size < 14)
|
if (block.size < 14)
|
||||||
error("CDToons: block size was %d, too small", block.size);
|
error("CDToons: block size was %d, too small", block.size);
|
||||||
block.size -= 14;
|
block.size -= 14;
|
||||||
block.startFrame = stream->readUint16BE();
|
block.startFrame = stream.readUint16BE();
|
||||||
block.endFrame = stream->readUint16BE();
|
block.endFrame = stream.readUint16BE();
|
||||||
block.unknown12 = stream->readUint16BE();
|
block.unknown12 = stream.readUint16BE();
|
||||||
block.data = new byte[block.size];
|
block.data = new byte[block.size];
|
||||||
stream->read(block.data, block.size);
|
stream.read(block.data, block.size);
|
||||||
|
|
||||||
debugN(9, "CDToons block id 0x%04x of size 0x%08x, flags %04x, from frame %d to %d, unknown at 12 is %04x\n",
|
debugN(9, "CDToons block id 0x%04x of size 0x%08x, flags %04x, from frame %d to %d, unknown at 12 is %04x\n",
|
||||||
blockId, block.size, block.flags, block.startFrame, block.endFrame, block.unknown12);
|
blockId, block.size, block.flags, block.startFrame, block.endFrame, block.unknown12);
|
||||||
|
@ -162,16 +162,16 @@ Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *strea
|
||||||
Common::Array<CDToonsDiff> diffs;
|
Common::Array<CDToonsDiff> diffs;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int32 nextPos = stream->pos();
|
int32 nextPos = stream.pos();
|
||||||
uint32 tag = stream->readUint32BE();
|
uint32 tag = stream.readUint32BE();
|
||||||
uint32 size = stream->readUint32BE();
|
uint32 size = stream.readUint32BE();
|
||||||
nextPos += size;
|
nextPos += size;
|
||||||
|
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case MKTAG('D','i','f','f'):
|
case MKTAG('D','i','f','f'):
|
||||||
{
|
{
|
||||||
debugN(5, "CDToons: Diff\n");
|
debugN(5, "CDToons: Diff\n");
|
||||||
uint16 count = stream->readUint16BE();
|
uint16 count = stream.readUint16BE();
|
||||||
|
|
||||||
Common::Rect diffClipRect = readRect(stream);
|
Common::Rect diffClipRect = readRect(stream);
|
||||||
debugN(9, "CDToons diffClipRect: (%d, %d) to (%d, %d)\n",
|
debugN(9, "CDToons diffClipRect: (%d, %d) to (%d, %d)\n",
|
||||||
|
@ -182,14 +182,14 @@ Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *strea
|
||||||
CDToonsDiff diff;
|
CDToonsDiff diff;
|
||||||
|
|
||||||
diff.rect = readRect(stream);
|
diff.rect = readRect(stream);
|
||||||
diff.size = stream->readUint32BE();
|
diff.size = stream.readUint32BE();
|
||||||
if (diff.size < 20)
|
if (diff.size < 20)
|
||||||
error("CDToons: Diff block size was %d, too small", diff.size);
|
error("CDToons: Diff block size was %d, too small", diff.size);
|
||||||
|
|
||||||
uint16 diffWidth = stream->readUint16BE();
|
uint16 diffWidth = stream.readUint16BE();
|
||||||
uint16 diffHeight = stream->readUint16BE();
|
uint16 diffHeight = stream.readUint16BE();
|
||||||
uint16 unknown16 = stream->readUint16BE();
|
uint16 unknown16 = stream.readUint16BE();
|
||||||
uint16 unknown18 = stream->readUint16BE();
|
uint16 unknown18 = stream.readUint16BE();
|
||||||
diff.size -= 8;
|
diff.size -= 8;
|
||||||
|
|
||||||
if (diffWidth != diff.rect.width() || diffHeight != diff.rect.height())
|
if (diffWidth != diff.rect.width() || diffHeight != diff.rect.height())
|
||||||
|
@ -199,7 +199,7 @@ Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *strea
|
||||||
unknown16, unknown18);
|
unknown16, unknown18);
|
||||||
|
|
||||||
diff.data = new byte[diff.size];
|
diff.data = new byte[diff.size];
|
||||||
stream->read(diff.data, diff.size);
|
stream.read(diff.data, diff.size);
|
||||||
diffs.push_back(diff);
|
diffs.push_back(diff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,8 +212,8 @@ Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *strea
|
||||||
|
|
||||||
if (xFrmBegin)
|
if (xFrmBegin)
|
||||||
error("CDToons: duplicate XFrm");
|
error("CDToons: duplicate XFrm");
|
||||||
xFrmBegin = stream->readByte();
|
xFrmBegin = stream.readByte();
|
||||||
xFrmCount = stream->readByte();
|
xFrmCount = stream.readByte();
|
||||||
debugN(9, "CDToons XFrm: run %d actions from %d\n", xFrmCount, xFrmBegin - 1);
|
debugN(9, "CDToons XFrm: run %d actions from %d\n", xFrmCount, xFrmBegin - 1);
|
||||||
|
|
||||||
// TODO: don't ignore (if xFrmCount is non-zero)
|
// TODO: don't ignore (if xFrmCount is non-zero)
|
||||||
|
@ -248,7 +248,7 @@ Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *strea
|
||||||
if (!(flags & 0x40))
|
if (!(flags & 0x40))
|
||||||
error("CDToons: useless FrtR?");
|
error("CDToons: useless FrtR?");
|
||||||
|
|
||||||
uint16 count = stream->readUint16BE();
|
uint16 count = stream.readUint16BE();
|
||||||
debugN(9, "CDToons FrtR: %d dirty rectangles\n", count);
|
debugN(9, "CDToons FrtR: %d dirty rectangles\n", count);
|
||||||
for (uint i = 0; i < count; i++) {
|
for (uint i = 0; i < count; i++) {
|
||||||
Common::Rect dirtyRectFrtR = readRect(stream);
|
Common::Rect dirtyRectFrtR = readRect(stream);
|
||||||
|
@ -263,7 +263,7 @@ Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *strea
|
||||||
if (!(flags & 0x20))
|
if (!(flags & 0x20))
|
||||||
error("CDToons: useless BckR?");
|
error("CDToons: useless BckR?");
|
||||||
|
|
||||||
uint16 count = stream->readUint16BE();
|
uint16 count = stream.readUint16BE();
|
||||||
debugN(9, "CDToons BckR: %d subentries\n", count);
|
debugN(9, "CDToons BckR: %d subentries\n", count);
|
||||||
for (uint i = 0; i < count; i++) {
|
for (uint i = 0; i < count; i++) {
|
||||||
Common::Rect dirtyRectBckR = readRect(stream);
|
Common::Rect dirtyRectBckR = readRect(stream);
|
||||||
|
@ -276,15 +276,15 @@ Graphics::Surface *CDToonsDecoder::decodeImage(Common::SeekableReadStream *strea
|
||||||
warning("Unknown CDToons tag '%s'", tag2str(tag));
|
warning("Unknown CDToons tag '%s'", tag2str(tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->pos() > nextPos)
|
if (stream.pos() > nextPos)
|
||||||
error("CDToons ran off the end of a block while reading it (at %d, next block at %d)",
|
error("CDToons ran off the end of a block while reading it (at %d, next block at %d)",
|
||||||
stream->pos(), nextPos);
|
stream.pos(), nextPos);
|
||||||
if (stream->pos() != nextPos) {
|
if (stream.pos() != nextPos) {
|
||||||
warning("CDToons had %d unknown bytes after block", nextPos - stream->pos());
|
warning("CDToons had %d unknown bytes after block", nextPos - stream.pos());
|
||||||
stream->seek(nextPos);
|
stream.seek(nextPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->pos() == stream->size())
|
if (stream.pos() == stream.size())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
CDToonsDecoder(uint16 width, uint16 height);
|
CDToonsDecoder(uint16 width, uint16 height);
|
||||||
~CDToonsDecoder();
|
~CDToonsDecoder();
|
||||||
|
|
||||||
Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
|
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
|
||||||
bool containsPalette() const { return true; }
|
bool containsPalette() const { return true; }
|
||||||
const byte *getPalette() { _dirtyPalette = false; return _palette; }
|
const byte *getPalette() { _dirtyPalette = false; return _palette; }
|
||||||
|
|
|
@ -83,13 +83,13 @@ CinepakDecoder::~CinepakDecoder() {
|
||||||
delete[] _clipTableBuf;
|
delete[] _clipTableBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *CinepakDecoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *CinepakDecoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
_curFrame.flags = stream->readByte();
|
_curFrame.flags = stream.readByte();
|
||||||
_curFrame.length = (stream->readByte() << 16);
|
_curFrame.length = (stream.readByte() << 16);
|
||||||
_curFrame.length |= stream->readUint16BE();
|
_curFrame.length |= stream.readUint16BE();
|
||||||
_curFrame.width = stream->readUint16BE();
|
_curFrame.width = stream.readUint16BE();
|
||||||
_curFrame.height = stream->readUint16BE();
|
_curFrame.height = stream.readUint16BE();
|
||||||
_curFrame.stripCount = stream->readUint16BE();
|
_curFrame.stripCount = stream.readUint16BE();
|
||||||
|
|
||||||
if (_curFrame.strips == NULL)
|
if (_curFrame.strips == NULL)
|
||||||
_curFrame.strips = new CinepakStrip[_curFrame.stripCount];
|
_curFrame.strips = new CinepakStrip[_curFrame.stripCount];
|
||||||
|
@ -98,11 +98,11 @@ const Graphics::Surface *CinepakDecoder::decodeImage(Common::SeekableReadStream
|
||||||
|
|
||||||
// Borrowed from FFMPEG. This should cut out the extra data Cinepak for Sega has (which is useless).
|
// Borrowed from FFMPEG. This should cut out the extra data Cinepak for Sega has (which is useless).
|
||||||
// The theory behind this is that this is here to confuse standard Cinepak decoders. But, we won't let that happen! ;)
|
// The theory behind this is that this is here to confuse standard Cinepak decoders. But, we won't let that happen! ;)
|
||||||
if (_curFrame.length != (uint32)stream->size()) {
|
if (_curFrame.length != (uint32)stream.size()) {
|
||||||
if (stream->readUint16BE() == 0xFE00)
|
if (stream.readUint16BE() == 0xFE00)
|
||||||
stream->readUint32BE();
|
stream.readUint32BE();
|
||||||
else if ((stream->size() % _curFrame.length) == 0)
|
else if ((stream.size() % _curFrame.length) == 0)
|
||||||
stream->seek(-2, SEEK_CUR);
|
stream.seek(-2, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_curFrame.surface) {
|
if (!_curFrame.surface) {
|
||||||
|
@ -121,29 +121,29 @@ const Graphics::Surface *CinepakDecoder::decodeImage(Common::SeekableReadStream
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_curFrame.strips[i].id = stream->readUint16BE();
|
_curFrame.strips[i].id = stream.readUint16BE();
|
||||||
_curFrame.strips[i].length = stream->readUint16BE() - 12; // Subtract the 12 byte header
|
_curFrame.strips[i].length = stream.readUint16BE() - 12; // Subtract the 12 byte header
|
||||||
_curFrame.strips[i].rect.top = _y; stream->readUint16BE(); // Ignore, substitute with our own.
|
_curFrame.strips[i].rect.top = _y; stream.readUint16BE(); // Ignore, substitute with our own.
|
||||||
_curFrame.strips[i].rect.left = 0; stream->readUint16BE(); // Ignore, substitute with our own
|
_curFrame.strips[i].rect.left = 0; stream.readUint16BE(); // Ignore, substitute with our own
|
||||||
_curFrame.strips[i].rect.bottom = _y + stream->readUint16BE();
|
_curFrame.strips[i].rect.bottom = _y + stream.readUint16BE();
|
||||||
_curFrame.strips[i].rect.right = _curFrame.width; stream->readUint16BE(); // Ignore, substitute with our own
|
_curFrame.strips[i].rect.right = _curFrame.width; stream.readUint16BE(); // Ignore, substitute with our own
|
||||||
|
|
||||||
// Sanity check. Because Cinepak is based on 4x4 blocks, the width and height of each strip needs to be divisible by 4.
|
// Sanity check. Because Cinepak is based on 4x4 blocks, the width and height of each strip needs to be divisible by 4.
|
||||||
assert(!(_curFrame.strips[i].rect.width() % 4) && !(_curFrame.strips[i].rect.height() % 4));
|
assert(!(_curFrame.strips[i].rect.width() % 4) && !(_curFrame.strips[i].rect.height() % 4));
|
||||||
|
|
||||||
uint32 pos = stream->pos();
|
uint32 pos = stream.pos();
|
||||||
|
|
||||||
while ((uint32)stream->pos() < (pos + _curFrame.strips[i].length) && !stream->eos()) {
|
while ((uint32)stream.pos() < (pos + _curFrame.strips[i].length) && !stream.eos()) {
|
||||||
byte chunkID = stream->readByte();
|
byte chunkID = stream.readByte();
|
||||||
|
|
||||||
if (stream->eos())
|
if (stream.eos())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Chunk Size is 24-bit, ignore the first 4 bytes
|
// Chunk Size is 24-bit, ignore the first 4 bytes
|
||||||
uint32 chunkSize = stream->readByte() << 16;
|
uint32 chunkSize = stream.readByte() << 16;
|
||||||
chunkSize += stream->readUint16BE() - 4;
|
chunkSize += stream.readUint16BE() - 4;
|
||||||
|
|
||||||
int32 startPos = stream->pos();
|
int32 startPos = stream.pos();
|
||||||
|
|
||||||
switch (chunkID) {
|
switch (chunkID) {
|
||||||
case 0x20:
|
case 0x20:
|
||||||
|
@ -168,8 +168,8 @@ const Graphics::Surface *CinepakDecoder::decodeImage(Common::SeekableReadStream
|
||||||
return _curFrame.surface;
|
return _curFrame.surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream->pos() != startPos + (int32)chunkSize)
|
if (stream.pos() != startPos + (int32)chunkSize)
|
||||||
stream->seek(startPos + chunkSize);
|
stream.seek(startPos + chunkSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
_y = _curFrame.strips[i].rect.bottom;
|
_y = _curFrame.strips[i].rect.bottom;
|
||||||
|
@ -178,32 +178,32 @@ const Graphics::Surface *CinepakDecoder::decodeImage(Common::SeekableReadStream
|
||||||
return _curFrame.surface;
|
return _curFrame.surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CinepakDecoder::loadCodebook(Common::SeekableReadStream *stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize) {
|
void CinepakDecoder::loadCodebook(Common::SeekableReadStream &stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize) {
|
||||||
CinepakCodebook *codebook = (codebookType == 1) ? _curFrame.strips[strip].v1_codebook : _curFrame.strips[strip].v4_codebook;
|
CinepakCodebook *codebook = (codebookType == 1) ? _curFrame.strips[strip].v1_codebook : _curFrame.strips[strip].v4_codebook;
|
||||||
|
|
||||||
int32 startPos = stream->pos();
|
int32 startPos = stream.pos();
|
||||||
uint32 flag = 0, mask = 0;
|
uint32 flag = 0, mask = 0;
|
||||||
|
|
||||||
for (uint16 i = 0; i < 256; i++) {
|
for (uint16 i = 0; i < 256; i++) {
|
||||||
if ((chunkID & 0x01) && !(mask >>= 1)) {
|
if ((chunkID & 0x01) && !(mask >>= 1)) {
|
||||||
if ((stream->pos() - startPos + 4) > (int32)chunkSize)
|
if ((stream.pos() - startPos + 4) > (int32)chunkSize)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
flag = stream->readUint32BE();
|
flag = stream.readUint32BE();
|
||||||
mask = 0x80000000;
|
mask = 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(chunkID & 0x01) || (flag & mask)) {
|
if (!(chunkID & 0x01) || (flag & mask)) {
|
||||||
byte n = (chunkID & 0x04) ? 4 : 6;
|
byte n = (chunkID & 0x04) ? 4 : 6;
|
||||||
if ((stream->pos() - startPos + n) > (int32)chunkSize)
|
if ((stream.pos() - startPos + n) > (int32)chunkSize)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (byte j = 0; j < 4; j++)
|
for (byte j = 0; j < 4; j++)
|
||||||
codebook[i].y[j] = stream->readByte();
|
codebook[i].y[j] = stream.readByte();
|
||||||
|
|
||||||
if (n == 6) {
|
if (n == 6) {
|
||||||
codebook[i].u = stream->readSByte();
|
codebook[i].u = stream.readSByte();
|
||||||
codebook[i].v = stream->readSByte();
|
codebook[i].v = stream.readSByte();
|
||||||
} else {
|
} else {
|
||||||
// This codebook type indicates either greyscale or
|
// This codebook type indicates either greyscale or
|
||||||
// palettized video. For greyscale, default us to
|
// palettized video. For greyscale, default us to
|
||||||
|
@ -215,10 +215,10 @@ void CinepakDecoder::loadCodebook(Common::SeekableReadStream *stream, uint16 str
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CinepakDecoder::decodeVectors(Common::SeekableReadStream *stream, uint16 strip, byte chunkID, uint32 chunkSize) {
|
void CinepakDecoder::decodeVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize) {
|
||||||
uint32 flag = 0, mask = 0;
|
uint32 flag = 0, mask = 0;
|
||||||
uint32 iy[4];
|
uint32 iy[4];
|
||||||
int32 startPos = stream->pos();
|
int32 startPos = stream.pos();
|
||||||
|
|
||||||
for (uint16 y = _curFrame.strips[strip].rect.top; y < _curFrame.strips[strip].rect.bottom; y += 4) {
|
for (uint16 y = _curFrame.strips[strip].rect.top; y < _curFrame.strips[strip].rect.bottom; y += 4) {
|
||||||
iy[0] = _curFrame.strips[strip].rect.left + y * _curFrame.width;
|
iy[0] = _curFrame.strips[strip].rect.left + y * _curFrame.width;
|
||||||
|
@ -228,28 +228,28 @@ void CinepakDecoder::decodeVectors(Common::SeekableReadStream *stream, uint16 st
|
||||||
|
|
||||||
for (uint16 x = _curFrame.strips[strip].rect.left; x < _curFrame.strips[strip].rect.right; x += 4) {
|
for (uint16 x = _curFrame.strips[strip].rect.left; x < _curFrame.strips[strip].rect.right; x += 4) {
|
||||||
if ((chunkID & 0x01) && !(mask >>= 1)) {
|
if ((chunkID & 0x01) && !(mask >>= 1)) {
|
||||||
if ((stream->pos() - startPos + 4) > (int32)chunkSize)
|
if ((stream.pos() - startPos + 4) > (int32)chunkSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flag = stream->readUint32BE();
|
flag = stream.readUint32BE();
|
||||||
mask = 0x80000000;
|
mask = 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(chunkID & 0x01) || (flag & mask)) {
|
if (!(chunkID & 0x01) || (flag & mask)) {
|
||||||
if (!(chunkID & 0x02) && !(mask >>= 1)) {
|
if (!(chunkID & 0x02) && !(mask >>= 1)) {
|
||||||
if ((stream->pos() - startPos + 4) > (int32)chunkSize)
|
if ((stream.pos() - startPos + 4) > (int32)chunkSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
flag = stream->readUint32BE();
|
flag = stream.readUint32BE();
|
||||||
mask = 0x80000000;
|
mask = 0x80000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((chunkID & 0x02) || (~flag & mask)) {
|
if ((chunkID & 0x02) || (~flag & mask)) {
|
||||||
if ((stream->pos() - startPos + 1) > (int32)chunkSize)
|
if ((stream.pos() - startPos + 1) > (int32)chunkSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get the codebook
|
// Get the codebook
|
||||||
CinepakCodebook codebook = _curFrame.strips[strip].v1_codebook[stream->readByte()];
|
CinepakCodebook codebook = _curFrame.strips[strip].v1_codebook[stream.readByte()];
|
||||||
|
|
||||||
PUT_PIXEL(iy[0] + 0, codebook.y[0], codebook.u, codebook.v);
|
PUT_PIXEL(iy[0] + 0, codebook.y[0], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[0] + 1, codebook.y[0], codebook.u, codebook.v);
|
PUT_PIXEL(iy[0] + 1, codebook.y[0], codebook.u, codebook.v);
|
||||||
|
@ -271,28 +271,28 @@ void CinepakDecoder::decodeVectors(Common::SeekableReadStream *stream, uint16 st
|
||||||
PUT_PIXEL(iy[3] + 2, codebook.y[3], codebook.u, codebook.v);
|
PUT_PIXEL(iy[3] + 2, codebook.y[3], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[3] + 3, codebook.y[3], codebook.u, codebook.v);
|
PUT_PIXEL(iy[3] + 3, codebook.y[3], codebook.u, codebook.v);
|
||||||
} else if (flag & mask) {
|
} else if (flag & mask) {
|
||||||
if ((stream->pos() - startPos + 4) > (int32)chunkSize)
|
if ((stream.pos() - startPos + 4) > (int32)chunkSize)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CinepakCodebook codebook = _curFrame.strips[strip].v4_codebook[stream->readByte()];
|
CinepakCodebook codebook = _curFrame.strips[strip].v4_codebook[stream.readByte()];
|
||||||
PUT_PIXEL(iy[0] + 0, codebook.y[0], codebook.u, codebook.v);
|
PUT_PIXEL(iy[0] + 0, codebook.y[0], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[0] + 1, codebook.y[1], codebook.u, codebook.v);
|
PUT_PIXEL(iy[0] + 1, codebook.y[1], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[1] + 0, codebook.y[2], codebook.u, codebook.v);
|
PUT_PIXEL(iy[1] + 0, codebook.y[2], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[1] + 1, codebook.y[3], codebook.u, codebook.v);
|
PUT_PIXEL(iy[1] + 1, codebook.y[3], codebook.u, codebook.v);
|
||||||
|
|
||||||
codebook = _curFrame.strips[strip].v4_codebook[stream->readByte()];
|
codebook = _curFrame.strips[strip].v4_codebook[stream.readByte()];
|
||||||
PUT_PIXEL(iy[0] + 2, codebook.y[0], codebook.u, codebook.v);
|
PUT_PIXEL(iy[0] + 2, codebook.y[0], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[0] + 3, codebook.y[1], codebook.u, codebook.v);
|
PUT_PIXEL(iy[0] + 3, codebook.y[1], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[1] + 2, codebook.y[2], codebook.u, codebook.v);
|
PUT_PIXEL(iy[1] + 2, codebook.y[2], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[1] + 3, codebook.y[3], codebook.u, codebook.v);
|
PUT_PIXEL(iy[1] + 3, codebook.y[3], codebook.u, codebook.v);
|
||||||
|
|
||||||
codebook = _curFrame.strips[strip].v4_codebook[stream->readByte()];
|
codebook = _curFrame.strips[strip].v4_codebook[stream.readByte()];
|
||||||
PUT_PIXEL(iy[2] + 0, codebook.y[0], codebook.u, codebook.v);
|
PUT_PIXEL(iy[2] + 0, codebook.y[0], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[2] + 1, codebook.y[1], codebook.u, codebook.v);
|
PUT_PIXEL(iy[2] + 1, codebook.y[1], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[3] + 0, codebook.y[2], codebook.u, codebook.v);
|
PUT_PIXEL(iy[3] + 0, codebook.y[2], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[3] + 1, codebook.y[3], codebook.u, codebook.v);
|
PUT_PIXEL(iy[3] + 1, codebook.y[3], codebook.u, codebook.v);
|
||||||
|
|
||||||
codebook = _curFrame.strips[strip].v4_codebook[stream->readByte()];
|
codebook = _curFrame.strips[strip].v4_codebook[stream.readByte()];
|
||||||
PUT_PIXEL(iy[2] + 2, codebook.y[0], codebook.u, codebook.v);
|
PUT_PIXEL(iy[2] + 2, codebook.y[0], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[2] + 3, codebook.y[1], codebook.u, codebook.v);
|
PUT_PIXEL(iy[2] + 3, codebook.y[1], codebook.u, codebook.v);
|
||||||
PUT_PIXEL(iy[3] + 2, codebook.y[2], codebook.u, codebook.v);
|
PUT_PIXEL(iy[3] + 2, codebook.y[2], codebook.u, codebook.v);
|
||||||
|
|
|
@ -71,7 +71,7 @@ public:
|
||||||
CinepakDecoder(int bitsPerPixel = 24);
|
CinepakDecoder(int bitsPerPixel = 24);
|
||||||
~CinepakDecoder();
|
~CinepakDecoder();
|
||||||
|
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
|
Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -80,8 +80,8 @@ private:
|
||||||
Graphics::PixelFormat _pixelFormat;
|
Graphics::PixelFormat _pixelFormat;
|
||||||
byte *_clipTable, *_clipTableBuf;
|
byte *_clipTable, *_clipTableBuf;
|
||||||
|
|
||||||
void loadCodebook(Common::SeekableReadStream *stream, uint16 strip, byte codebookType, byte chunkID, uint32 chunkSize);
|
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 decodeVectors(Common::SeekableReadStream &stream, uint16 strip, byte chunkID, uint32 chunkSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Image
|
} // End of namespace Image
|
||||||
|
|
|
@ -59,9 +59,8 @@ public:
|
||||||
* containing the decoded frame.
|
* containing the decoded frame.
|
||||||
*
|
*
|
||||||
* @return a pointer to the decoded frame
|
* @return a pointer to the decoded frame
|
||||||
* @note stream is not deleted
|
|
||||||
*/
|
*/
|
||||||
virtual const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream) = 0;
|
virtual const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the format that the surface returned from decodeImage() will
|
* Get the format that the surface returned from decodeImage() will
|
||||||
|
|
|
@ -165,24 +165,24 @@ void Indeo3Decoder::allocFrames() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *Indeo3Decoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *Indeo3Decoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
// Not Indeo 3? Fail
|
// Not Indeo 3? Fail
|
||||||
if (!isIndeo3(*stream))
|
if (!isIndeo3(stream))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
stream->seek(12);
|
stream.seek(12);
|
||||||
uint32 frameDataLen = stream->readUint32LE();
|
uint32 frameDataLen = stream.readUint32LE();
|
||||||
|
|
||||||
// Less data than the frame should have? Fail
|
// Less data than the frame should have? Fail
|
||||||
if (stream->size() < (int)(frameDataLen - 16))
|
if (stream.size() < (int)(frameDataLen - 16))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
stream->seek(16); // Behind header
|
stream.seek(16); // Behind header
|
||||||
stream->skip(2); // Unknown
|
stream.skip(2); // Unknown
|
||||||
|
|
||||||
uint16 flags1 = stream->readUint16LE();
|
uint16 flags1 = stream.readUint16LE();
|
||||||
uint32 flags3 = stream->readUint32LE();
|
uint32 flags3 = stream.readUint32LE();
|
||||||
uint8 flags2 = stream->readByte();
|
uint8 flags2 = stream.readByte();
|
||||||
|
|
||||||
// Finding the reference frame
|
// Finding the reference frame
|
||||||
if (flags1 & 0x200) {
|
if (flags1 & 0x200) {
|
||||||
|
@ -196,22 +196,22 @@ const Graphics::Surface *Indeo3Decoder::decodeImage(Common::SeekableReadStream *
|
||||||
if (flags3 == 0x80)
|
if (flags3 == 0x80)
|
||||||
return _surface;
|
return _surface;
|
||||||
|
|
||||||
stream->skip(3);
|
stream.skip(3);
|
||||||
|
|
||||||
uint16 fHeight = stream->readUint16LE();
|
uint16 fHeight = stream.readUint16LE();
|
||||||
uint16 fWidth = stream->readUint16LE();
|
uint16 fWidth = stream.readUint16LE();
|
||||||
|
|
||||||
uint32 chromaHeight = ((fHeight >> 2) + 3) & 0x7FFC;
|
uint32 chromaHeight = ((fHeight >> 2) + 3) & 0x7FFC;
|
||||||
uint32 chromaWidth = ((fWidth >> 2) + 3) & 0x7FFC;
|
uint32 chromaWidth = ((fWidth >> 2) + 3) & 0x7FFC;
|
||||||
|
|
||||||
uint32 offs;
|
uint32 offs;
|
||||||
uint32 offsY = stream->readUint32LE() + 16;
|
uint32 offsY = stream.readUint32LE() + 16;
|
||||||
uint32 offsU = stream->readUint32LE() + 16;
|
uint32 offsU = stream.readUint32LE() + 16;
|
||||||
uint32 offsV = stream->readUint32LE() + 16;
|
uint32 offsV = stream.readUint32LE() + 16;
|
||||||
|
|
||||||
stream->skip(4);
|
stream.skip(4);
|
||||||
|
|
||||||
uint32 hPos = stream->pos();
|
uint32 hPos = stream.pos();
|
||||||
|
|
||||||
if (offsY < hPos) {
|
if (offsY < hPos) {
|
||||||
warning("Indeo3Decoder::decodeImage: offsY < hPos");
|
warning("Indeo3Decoder::decodeImage: offsY < hPos");
|
||||||
|
@ -226,11 +226,11 @@ const Graphics::Surface *Indeo3Decoder::decodeImage(Common::SeekableReadStream *
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 dataSize = stream->size() - hPos;
|
uint32 dataSize = stream.size() - hPos;
|
||||||
|
|
||||||
byte *inData = new byte[dataSize];
|
byte *inData = new byte[dataSize];
|
||||||
|
|
||||||
if (stream->read(inData, dataSize) != dataSize) {
|
if (stream.read(inData, dataSize) != dataSize) {
|
||||||
delete[] inData;
|
delete[] inData;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -239,23 +239,23 @@ const Graphics::Surface *Indeo3Decoder::decodeImage(Common::SeekableReadStream *
|
||||||
byte *buf_pos;
|
byte *buf_pos;
|
||||||
|
|
||||||
// Luminance Y
|
// Luminance Y
|
||||||
stream->seek(offsY);
|
stream.seek(offsY);
|
||||||
buf_pos = inData + offsY + 4 - hPos;
|
buf_pos = inData + offsY + 4 - hPos;
|
||||||
offs = stream->readUint32LE();
|
offs = stream.readUint32LE();
|
||||||
decodeChunk(_cur_frame->Ybuf, _ref_frame->Ybuf, fWidth, fHeight,
|
decodeChunk(_cur_frame->Ybuf, _ref_frame->Ybuf, fWidth, fHeight,
|
||||||
buf_pos + offs * 2, flags2, hdr_pos, buf_pos, MIN<int>(fWidth, 160));
|
buf_pos + offs * 2, flags2, hdr_pos, buf_pos, MIN<int>(fWidth, 160));
|
||||||
|
|
||||||
// Chrominance U
|
// Chrominance U
|
||||||
stream->seek(offsU);
|
stream.seek(offsU);
|
||||||
buf_pos = inData + offsU + 4 - hPos;
|
buf_pos = inData + offsU + 4 - hPos;
|
||||||
offs = stream->readUint32LE();
|
offs = stream.readUint32LE();
|
||||||
decodeChunk(_cur_frame->Vbuf, _ref_frame->Vbuf, chromaWidth, chromaHeight,
|
decodeChunk(_cur_frame->Vbuf, _ref_frame->Vbuf, chromaWidth, chromaHeight,
|
||||||
buf_pos + offs * 2, flags2, hdr_pos, buf_pos, MIN<int>(chromaWidth, 40));
|
buf_pos + offs * 2, flags2, hdr_pos, buf_pos, MIN<int>(chromaWidth, 40));
|
||||||
|
|
||||||
// Chrominance V
|
// Chrominance V
|
||||||
stream->seek(offsV);
|
stream.seek(offsV);
|
||||||
buf_pos = inData + offsV + 4 - hPos;
|
buf_pos = inData + offsV + 4 - hPos;
|
||||||
offs = stream->readUint32LE();
|
offs = stream.readUint32LE();
|
||||||
decodeChunk(_cur_frame->Ubuf, _ref_frame->Ubuf, chromaWidth, chromaHeight,
|
decodeChunk(_cur_frame->Ubuf, _ref_frame->Ubuf, chromaWidth, chromaHeight,
|
||||||
buf_pos + offs * 2, flags2, hdr_pos, buf_pos, MIN<int>(chromaWidth, 40));
|
buf_pos + offs * 2, flags2, hdr_pos, buf_pos, MIN<int>(chromaWidth, 40));
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
Indeo3Decoder(uint16 width, uint16 height);
|
Indeo3Decoder(uint16 width, uint16 height);
|
||||||
~Indeo3Decoder();
|
~Indeo3Decoder();
|
||||||
|
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const;
|
Graphics::PixelFormat getPixelFormat() const;
|
||||||
|
|
||||||
static bool isIndeo3(Common::SeekableReadStream &stream);
|
static bool isIndeo3(Common::SeekableReadStream &stream);
|
||||||
|
|
|
@ -147,20 +147,20 @@ static const byte s_mjpegValACChrominance[] = {
|
||||||
0xf9, 0xfa
|
0xf9, 0xfa
|
||||||
};
|
};
|
||||||
|
|
||||||
const Graphics::Surface *MJPEGDecoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *MJPEGDecoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
// We need to reconstruct an actual JPEG stream here, then feed it to the JPEG decoder
|
// We need to reconstruct an actual JPEG stream here, then feed it to the JPEG decoder
|
||||||
// Yes, this is a pain.
|
// Yes, this is a pain.
|
||||||
|
|
||||||
stream->readUint32BE(); // Skip nonsense JPEG header
|
stream.readUint32BE(); // Skip nonsense JPEG header
|
||||||
uint16 inputSkip = stream->readUint16BE() + 4;
|
uint16 inputSkip = stream.readUint16BE() + 4;
|
||||||
uint32 tag = stream->readUint32BE();
|
uint32 tag = stream.readUint32BE();
|
||||||
|
|
||||||
if (tag != MKTAG('A', 'V', 'I', '1')) {
|
if (tag != MKTAG('A', 'V', 'I', '1')) {
|
||||||
warning("Invalid MJPEG tag found");
|
warning("Invalid MJPEG tag found");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 outputSize = stream->size() - inputSkip + sizeof(s_jpegHeader) + DHT_SEGMENT_SIZE;
|
uint32 outputSize = stream.size() - inputSkip + sizeof(s_jpegHeader) + DHT_SEGMENT_SIZE;
|
||||||
byte *data = (byte *)malloc(outputSize);
|
byte *data = (byte *)malloc(outputSize);
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
|
@ -193,8 +193,8 @@ const Graphics::Surface *MJPEGDecoder::decodeImage(Common::SeekableReadStream *s
|
||||||
dataOffset += 162;
|
dataOffset += 162;
|
||||||
|
|
||||||
// Write the actual data
|
// Write the actual data
|
||||||
stream->seek(inputSkip);
|
stream.seek(inputSkip);
|
||||||
stream->read(data + dataOffset, stream->size() - inputSkip);
|
stream.read(data + dataOffset, stream.size() - inputSkip);
|
||||||
|
|
||||||
Common::MemoryReadStream convertedStream(data, outputSize, DisposeAfterUse::YES);
|
Common::MemoryReadStream convertedStream(data, outputSize, DisposeAfterUse::YES);
|
||||||
JPEGDecoder jpeg;
|
JPEGDecoder jpeg;
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
MJPEGDecoder();
|
MJPEGDecoder();
|
||||||
~MJPEGDecoder();
|
~MJPEGDecoder();
|
||||||
|
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
|
Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -52,13 +52,13 @@ MPEGDecoder::~MPEGDecoder() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *MPEGDecoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *MPEGDecoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
uint32 framePeriod;
|
uint32 framePeriod;
|
||||||
decodePacket(stream, framePeriod);
|
decodePacket(stream, framePeriod);
|
||||||
return _surface;
|
return _surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MPEGDecoder::decodePacket(Common::SeekableReadStream *packet, uint32 &framePeriod, Graphics::Surface *dst) {
|
bool MPEGDecoder::decodePacket(Common::SeekableReadStream &packet, uint32 &framePeriod, Graphics::Surface *dst) {
|
||||||
// Decode as much as we can out of this packet
|
// Decode as much as we can out of this packet
|
||||||
uint32 size = 0xFFFFFFFF;
|
uint32 size = 0xFFFFFFFF;
|
||||||
mpeg2_state_t state;
|
mpeg2_state_t state;
|
||||||
|
@ -70,7 +70,7 @@ bool MPEGDecoder::decodePacket(Common::SeekableReadStream *packet, uint32 &frame
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_BUFFER:
|
case STATE_BUFFER:
|
||||||
size = packet->read(_buffer, BUFFER_SIZE);
|
size = packet.read(_buffer, BUFFER_SIZE);
|
||||||
mpeg2_buffer(_mpegDecoder, _buffer, _buffer + size);
|
mpeg2_buffer(_mpegDecoder, _buffer, _buffer + size);
|
||||||
break;
|
break;
|
||||||
case STATE_SLICE:
|
case STATE_SLICE:
|
||||||
|
|
|
@ -72,11 +72,11 @@ public:
|
||||||
~MPEGDecoder();
|
~MPEGDecoder();
|
||||||
|
|
||||||
// Codec interface
|
// Codec interface
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
|
Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
|
||||||
|
|
||||||
// MPEGPSDecoder call
|
// MPEGPSDecoder call
|
||||||
bool decodePacket(Common::SeekableReadStream *packet, uint32 &framePeriod, Graphics::Surface *dst = 0);
|
bool decodePacket(Common::SeekableReadStream &packet, uint32 &framePeriod, Graphics::Surface *dst = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Graphics::PixelFormat _pixelFormat;
|
Graphics::PixelFormat _pixelFormat;
|
||||||
|
|
|
@ -39,7 +39,7 @@ MSRLEDecoder::~MSRLEDecoder() {
|
||||||
delete _surface;
|
delete _surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *MSRLEDecoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *MSRLEDecoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
if (_bitsPerPixel == 8) {
|
if (_bitsPerPixel == 8) {
|
||||||
decode8(stream);
|
decode8(stream);
|
||||||
} else
|
} else
|
||||||
|
@ -48,7 +48,7 @@ const Graphics::Surface *MSRLEDecoder::decodeImage(Common::SeekableReadStream *s
|
||||||
return _surface;
|
return _surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSRLEDecoder::decode8(Common::SeekableReadStream *stream) {
|
void MSRLEDecoder::decode8(Common::SeekableReadStream &stream) {
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
int y = _surface->h - 1;
|
int y = _surface->h - 1;
|
||||||
|
@ -60,9 +60,9 @@ void MSRLEDecoder::decode8(Common::SeekableReadStream *stream) {
|
||||||
byte *output = data + ((height - 1) * width);
|
byte *output = data + ((height - 1) * width);
|
||||||
byte *output_end = data + ((height) * width);
|
byte *output_end = data + ((height) * width);
|
||||||
|
|
||||||
while (!stream->eos()) {
|
while (!stream.eos()) {
|
||||||
byte count = stream->readByte();
|
byte count = stream.readByte();
|
||||||
byte value = stream->readByte();
|
byte value = stream.readByte();
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
|
@ -84,8 +84,8 @@ void MSRLEDecoder::decode8(Common::SeekableReadStream *stream) {
|
||||||
} else if (value == 2) {
|
} else if (value == 2) {
|
||||||
// Skip
|
// Skip
|
||||||
|
|
||||||
count = stream->readByte();
|
count = stream.readByte();
|
||||||
value = stream->readByte();
|
value = stream.readByte();
|
||||||
|
|
||||||
y -= value;
|
y -= value;
|
||||||
x += count;
|
x += count;
|
||||||
|
@ -101,15 +101,15 @@ void MSRLEDecoder::decode8(Common::SeekableReadStream *stream) {
|
||||||
// Copy data
|
// Copy data
|
||||||
|
|
||||||
if (output + value > output_end) {
|
if (output + value > output_end) {
|
||||||
stream->skip(value);
|
stream.skip(value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < value; i++)
|
for (int i = 0; i < value; i++)
|
||||||
*output++ = stream->readByte();
|
*output++ = stream.readByte();
|
||||||
|
|
||||||
if (value & 1)
|
if (value & 1)
|
||||||
stream->skip(1);
|
stream.skip(1);
|
||||||
|
|
||||||
x += value;
|
x += value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
MSRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel);
|
MSRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel);
|
||||||
~MSRLEDecoder();
|
~MSRLEDecoder();
|
||||||
|
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
|
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -46,7 +46,7 @@ private:
|
||||||
|
|
||||||
Graphics::Surface *_surface;
|
Graphics::Surface *_surface;
|
||||||
|
|
||||||
void decode8(Common::SeekableReadStream *stream);
|
void decode8(Common::SeekableReadStream &stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Image
|
} // End of namespace Image
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
namespace Image {
|
namespace Image {
|
||||||
|
|
||||||
#define CHECK_STREAM_PTR(n) \
|
#define CHECK_STREAM_PTR(n) \
|
||||||
if ((stream->pos() + n) > stream->size() ) { \
|
if ((stream.pos() + n) > stream.size() ) { \
|
||||||
warning ("MS Video-1: Stream out of bounds (%d >= %d)", stream->pos() + n, stream->size()); \
|
warning ("MS Video-1: Stream out of bounds (%d >= %d)", stream.pos() + n, stream.size()); \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ MSVideo1Decoder::~MSVideo1Decoder() {
|
||||||
delete _surface;
|
delete _surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSVideo1Decoder::decode8(Common::SeekableReadStream *stream) {
|
void MSVideo1Decoder::decode8(Common::SeekableReadStream &stream) {
|
||||||
byte colors[8];
|
byte colors[8];
|
||||||
byte *pixels = (byte *)_surface->getPixels();
|
byte *pixels = (byte *)_surface->getPixels();
|
||||||
uint16 stride = _surface->w;
|
uint16 stride = _surface->w;
|
||||||
|
@ -73,8 +73,8 @@ void MSVideo1Decoder::decode8(Common::SeekableReadStream *stream) {
|
||||||
|
|
||||||
/* get the next two bytes in the encoded data stream */
|
/* get the next two bytes in the encoded data stream */
|
||||||
CHECK_STREAM_PTR(2);
|
CHECK_STREAM_PTR(2);
|
||||||
byte byte_a = stream->readByte();
|
byte byte_a = stream.readByte();
|
||||||
byte byte_b = stream->readByte();
|
byte byte_b = stream.readByte();
|
||||||
|
|
||||||
/* check if the decode is finished */
|
/* check if the decode is finished */
|
||||||
if (byte_a == 0 && byte_b == 0 && totalBlocks == 0) {
|
if (byte_a == 0 && byte_b == 0 && totalBlocks == 0) {
|
||||||
|
@ -87,8 +87,8 @@ void MSVideo1Decoder::decode8(Common::SeekableReadStream *stream) {
|
||||||
uint16 flags = (byte_b << 8) | byte_a;
|
uint16 flags = (byte_b << 8) | byte_a;
|
||||||
|
|
||||||
CHECK_STREAM_PTR(2);
|
CHECK_STREAM_PTR(2);
|
||||||
colors[0] = stream->readByte();
|
colors[0] = stream.readByte();
|
||||||
colors[1] = stream->readByte();
|
colors[1] = stream.readByte();
|
||||||
|
|
||||||
for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
|
for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
|
||||||
for (byte pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
|
for (byte pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
|
||||||
|
@ -101,7 +101,7 @@ void MSVideo1Decoder::decode8(Common::SeekableReadStream *stream) {
|
||||||
|
|
||||||
CHECK_STREAM_PTR(8);
|
CHECK_STREAM_PTR(8);
|
||||||
for (byte i = 0; i < 8; i++)
|
for (byte i = 0; i < 8; i++)
|
||||||
colors[i] = stream->readByte();
|
colors[i] = stream.readByte();
|
||||||
|
|
||||||
for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
|
for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
|
||||||
for (byte pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
|
for (byte pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
|
||||||
|
@ -125,7 +125,7 @@ void MSVideo1Decoder::decode8(Common::SeekableReadStream *stream) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *MSVideo1Decoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *MSVideo1Decoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
if (_bitsPerPixel == 8)
|
if (_bitsPerPixel == 8)
|
||||||
decode8(stream);
|
decode8(stream);
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
MSVideo1Decoder(uint16 width, uint16 height, byte bitsPerPixel);
|
MSVideo1Decoder(uint16 width, uint16 height, byte bitsPerPixel);
|
||||||
~MSVideo1Decoder();
|
~MSVideo1Decoder();
|
||||||
|
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
|
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -46,8 +46,8 @@ private:
|
||||||
|
|
||||||
Graphics::Surface *_surface;
|
Graphics::Surface *_surface;
|
||||||
|
|
||||||
void decode8(Common::SeekableReadStream *stream);
|
void decode8(Common::SeekableReadStream &stream);
|
||||||
//void decode16(Common::SeekableReadStream *stream);
|
//void decode16(Common::SeekableReadStream &stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Image
|
} // End of namespace Image
|
||||||
|
|
|
@ -48,8 +48,8 @@ QTRLEDecoder::QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel) : Cod
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_STREAM_PTR(n) \
|
#define CHECK_STREAM_PTR(n) \
|
||||||
if ((stream->pos() + n) > stream->size()) { \
|
if ((stream.pos() + n) > stream.size()) { \
|
||||||
warning("QTRLE Problem: stream out of bounds (%d > %d)", stream->pos() + n, stream->size()); \
|
warning("QTRLE Problem: stream out of bounds (%d > %d)", stream.pos() + n, stream.size()); \
|
||||||
return; \
|
return; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,14 +59,14 @@ QTRLEDecoder::QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel) : Cod
|
||||||
return; \
|
return; \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
void QTRLEDecoder::decode1(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
|
void QTRLEDecoder::decode1(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange) {
|
||||||
uint32 pixelPtr = 0;
|
uint32 pixelPtr = 0;
|
||||||
byte *rgb = (byte *)_surface->getPixels();
|
byte *rgb = (byte *)_surface->getPixels();
|
||||||
|
|
||||||
while (linesToChange) {
|
while (linesToChange) {
|
||||||
CHECK_STREAM_PTR(2);
|
CHECK_STREAM_PTR(2);
|
||||||
byte skip = stream->readByte();
|
byte skip = stream.readByte();
|
||||||
int8 rleCode = stream->readSByte();
|
int8 rleCode = stream.readSByte();
|
||||||
|
|
||||||
if (rleCode == 0)
|
if (rleCode == 0)
|
||||||
break;
|
break;
|
||||||
|
@ -83,8 +83,8 @@ void QTRLEDecoder::decode1(Common::SeekableReadStream *stream, uint32 rowPtr, ui
|
||||||
rleCode = -rleCode;
|
rleCode = -rleCode;
|
||||||
// get the next 2 bytes from the stream, treat them as groups of 8 pixels, and output them rleCode times */
|
// get the next 2 bytes from the stream, treat them as groups of 8 pixels, and output them rleCode times */
|
||||||
CHECK_STREAM_PTR(2);
|
CHECK_STREAM_PTR(2);
|
||||||
byte pi0 = stream->readByte();
|
byte pi0 = stream.readByte();
|
||||||
byte pi1 = stream->readByte();
|
byte pi1 = stream.readByte();
|
||||||
CHECK_PIXEL_PTR(rleCode * 2);
|
CHECK_PIXEL_PTR(rleCode * 2);
|
||||||
|
|
||||||
while (rleCode--) {
|
while (rleCode--) {
|
||||||
|
@ -98,25 +98,25 @@ void QTRLEDecoder::decode1(Common::SeekableReadStream *stream, uint32 rowPtr, ui
|
||||||
CHECK_PIXEL_PTR(rleCode);
|
CHECK_PIXEL_PTR(rleCode);
|
||||||
|
|
||||||
while (rleCode--)
|
while (rleCode--)
|
||||||
rgb[pixelPtr++] = stream->readByte();
|
rgb[pixelPtr++] = stream.readByte();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTRLEDecoder::decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange, byte bpp) {
|
void QTRLEDecoder::decode2_4(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange, byte bpp) {
|
||||||
uint32 pixelPtr = 0;
|
uint32 pixelPtr = 0;
|
||||||
byte *rgb = (byte *)_surface->getPixels();
|
byte *rgb = (byte *)_surface->getPixels();
|
||||||
byte numPixels = (bpp == 4) ? 8 : 16;
|
byte numPixels = (bpp == 4) ? 8 : 16;
|
||||||
|
|
||||||
while (linesToChange--) {
|
while (linesToChange--) {
|
||||||
CHECK_STREAM_PTR(2);
|
CHECK_STREAM_PTR(2);
|
||||||
pixelPtr = rowPtr + (numPixels * (stream->readByte() - 1));
|
pixelPtr = rowPtr + (numPixels * (stream.readByte() - 1));
|
||||||
|
|
||||||
for (int8 rleCode = stream->readSByte(); rleCode != -1; rleCode = stream->readSByte()) {
|
for (int8 rleCode = stream.readSByte(); rleCode != -1; rleCode = stream.readSByte()) {
|
||||||
if (rleCode == 0) {
|
if (rleCode == 0) {
|
||||||
// there's another skip code in the stream
|
// there's another skip code in the stream
|
||||||
CHECK_STREAM_PTR(1);
|
CHECK_STREAM_PTR(1);
|
||||||
pixelPtr += (numPixels * (stream->readByte() - 1));
|
pixelPtr += (numPixels * (stream.readByte() - 1));
|
||||||
} else if (rleCode < 0) {
|
} else if (rleCode < 0) {
|
||||||
// decode the run length code
|
// decode the run length code
|
||||||
rleCode = -rleCode;
|
rleCode = -rleCode;
|
||||||
|
@ -127,10 +127,10 @@ void QTRLEDecoder::decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr,
|
||||||
byte pi[16]; // 16 palette indices
|
byte pi[16]; // 16 palette indices
|
||||||
|
|
||||||
for (int8 i = numPixels - 1; i >= 0; i--) {
|
for (int8 i = numPixels - 1; i >= 0; i--) {
|
||||||
pi[numPixels - 1 - i] = (stream->readByte() >> ((i * bpp) & 0x07)) & ((1 << bpp) - 1);
|
pi[numPixels - 1 - i] = (stream.readByte() >> ((i * bpp) & 0x07)) & ((1 << bpp) - 1);
|
||||||
|
|
||||||
if ((i & ((numPixels >> 2) - 1)) == 0)
|
if ((i & ((numPixels >> 2) - 1)) == 0)
|
||||||
stream->readByte();
|
stream.readByte();
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_PIXEL_PTR(rleCode * numPixels);
|
CHECK_PIXEL_PTR(rleCode * numPixels);
|
||||||
|
@ -145,7 +145,7 @@ void QTRLEDecoder::decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr,
|
||||||
CHECK_PIXEL_PTR(rleCode * (numPixels >> 2));
|
CHECK_PIXEL_PTR(rleCode * (numPixels >> 2));
|
||||||
|
|
||||||
while (rleCode--) {
|
while (rleCode--) {
|
||||||
byte temp = stream->readByte();
|
byte temp = stream.readByte();
|
||||||
if (bpp == 4) {
|
if (bpp == 4) {
|
||||||
rgb[pixelPtr++] = (temp >> 4) & 0x0f;
|
rgb[pixelPtr++] = (temp >> 4) & 0x0f;
|
||||||
rgb[pixelPtr++] = temp & 0x0f;
|
rgb[pixelPtr++] = temp & 0x0f;
|
||||||
|
@ -163,19 +163,19 @@ void QTRLEDecoder::decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTRLEDecoder::decode8(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
|
void QTRLEDecoder::decode8(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange) {
|
||||||
uint32 pixelPtr = 0;
|
uint32 pixelPtr = 0;
|
||||||
byte *rgb = (byte *)_surface->getPixels();
|
byte *rgb = (byte *)_surface->getPixels();
|
||||||
|
|
||||||
while (linesToChange--) {
|
while (linesToChange--) {
|
||||||
CHECK_STREAM_PTR(2);
|
CHECK_STREAM_PTR(2);
|
||||||
pixelPtr = rowPtr + 4 * (stream->readByte() - 1);
|
pixelPtr = rowPtr + 4 * (stream.readByte() - 1);
|
||||||
|
|
||||||
for (int8 rleCode = stream->readSByte(); rleCode != -1; rleCode = stream->readSByte()) {
|
for (int8 rleCode = stream.readSByte(); rleCode != -1; rleCode = stream.readSByte()) {
|
||||||
if (rleCode == 0) {
|
if (rleCode == 0) {
|
||||||
// there's another skip code in the stream
|
// there's another skip code in the stream
|
||||||
CHECK_STREAM_PTR(1);
|
CHECK_STREAM_PTR(1);
|
||||||
pixelPtr += 4 * (stream->readByte() - 1);
|
pixelPtr += 4 * (stream.readByte() - 1);
|
||||||
} else if (rleCode < 0) {
|
} else if (rleCode < 0) {
|
||||||
// decode the run length code
|
// decode the run length code
|
||||||
rleCode = -rleCode;
|
rleCode = -rleCode;
|
||||||
|
@ -186,7 +186,7 @@ void QTRLEDecoder::decode8(Common::SeekableReadStream *stream, uint32 rowPtr, ui
|
||||||
byte pi[4]; // 4 palette indexes
|
byte pi[4]; // 4 palette indexes
|
||||||
|
|
||||||
for (byte i = 0; i < 4; i++)
|
for (byte i = 0; i < 4; i++)
|
||||||
pi[i] = stream->readByte();
|
pi[i] = stream.readByte();
|
||||||
|
|
||||||
CHECK_PIXEL_PTR(rleCode * 4);
|
CHECK_PIXEL_PTR(rleCode * 4);
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ void QTRLEDecoder::decode8(Common::SeekableReadStream *stream, uint32 rowPtr, ui
|
||||||
CHECK_PIXEL_PTR(rleCode);
|
CHECK_PIXEL_PTR(rleCode);
|
||||||
|
|
||||||
while (rleCode--)
|
while (rleCode--)
|
||||||
rgb[pixelPtr++] = stream->readByte();
|
rgb[pixelPtr++] = stream.readByte();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,25 +208,25 @@ void QTRLEDecoder::decode8(Common::SeekableReadStream *stream, uint32 rowPtr, ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
|
void QTRLEDecoder::decode16(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange) {
|
||||||
uint32 pixelPtr = 0;
|
uint32 pixelPtr = 0;
|
||||||
uint16 *rgb = (uint16 *)_surface->getPixels();
|
uint16 *rgb = (uint16 *)_surface->getPixels();
|
||||||
|
|
||||||
while (linesToChange--) {
|
while (linesToChange--) {
|
||||||
CHECK_STREAM_PTR(2);
|
CHECK_STREAM_PTR(2);
|
||||||
pixelPtr = rowPtr + stream->readByte() - 1;
|
pixelPtr = rowPtr + stream.readByte() - 1;
|
||||||
|
|
||||||
for (int8 rleCode = stream->readSByte(); rleCode != -1; rleCode = stream->readSByte()) {
|
for (int8 rleCode = stream.readSByte(); rleCode != -1; rleCode = stream.readSByte()) {
|
||||||
if (rleCode == 0) {
|
if (rleCode == 0) {
|
||||||
// there's another skip code in the stream
|
// there's another skip code in the stream
|
||||||
CHECK_STREAM_PTR(1);
|
CHECK_STREAM_PTR(1);
|
||||||
pixelPtr += stream->readByte() - 1;
|
pixelPtr += stream.readByte() - 1;
|
||||||
} else if (rleCode < 0) {
|
} else if (rleCode < 0) {
|
||||||
// decode the run length code
|
// decode the run length code
|
||||||
rleCode = -rleCode;
|
rleCode = -rleCode;
|
||||||
CHECK_STREAM_PTR(2);
|
CHECK_STREAM_PTR(2);
|
||||||
|
|
||||||
uint16 rgb16 = stream->readUint16BE();
|
uint16 rgb16 = stream.readUint16BE();
|
||||||
|
|
||||||
CHECK_PIXEL_PTR(rleCode);
|
CHECK_PIXEL_PTR(rleCode);
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, u
|
||||||
|
|
||||||
// copy pixels directly to output
|
// copy pixels directly to output
|
||||||
while (rleCode--)
|
while (rleCode--)
|
||||||
rgb[pixelPtr++] = stream->readUint16BE();
|
rgb[pixelPtr++] = stream.readUint16BE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,28 +246,28 @@ void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
|
void QTRLEDecoder::decode24(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange) {
|
||||||
uint32 pixelPtr = 0;
|
uint32 pixelPtr = 0;
|
||||||
uint32 *rgb = (uint32 *)_surface->getPixels();
|
uint32 *rgb = (uint32 *)_surface->getPixels();
|
||||||
|
|
||||||
while (linesToChange--) {
|
while (linesToChange--) {
|
||||||
CHECK_STREAM_PTR(2);
|
CHECK_STREAM_PTR(2);
|
||||||
pixelPtr = rowPtr + stream->readByte() - 1;
|
pixelPtr = rowPtr + stream.readByte() - 1;
|
||||||
|
|
||||||
for (int8 rleCode = stream->readSByte(); rleCode != -1; rleCode = stream->readSByte()) {
|
for (int8 rleCode = stream.readSByte(); rleCode != -1; rleCode = stream.readSByte()) {
|
||||||
if (rleCode == 0) {
|
if (rleCode == 0) {
|
||||||
// there's another skip code in the stream
|
// there's another skip code in the stream
|
||||||
CHECK_STREAM_PTR(1);
|
CHECK_STREAM_PTR(1);
|
||||||
pixelPtr += stream->readByte() - 1;
|
pixelPtr += stream.readByte() - 1;
|
||||||
} else if (rleCode < 0) {
|
} else if (rleCode < 0) {
|
||||||
// decode the run length code
|
// decode the run length code
|
||||||
rleCode = -rleCode;
|
rleCode = -rleCode;
|
||||||
|
|
||||||
CHECK_STREAM_PTR(3);
|
CHECK_STREAM_PTR(3);
|
||||||
|
|
||||||
byte r = stream->readByte();
|
byte r = stream.readByte();
|
||||||
byte g = stream->readByte();
|
byte g = stream.readByte();
|
||||||
byte b = stream->readByte();
|
byte b = stream.readByte();
|
||||||
uint32 color = _surface->format.RGBToColor(r, g, b);
|
uint32 color = _surface->format.RGBToColor(r, g, b);
|
||||||
|
|
||||||
CHECK_PIXEL_PTR(rleCode);
|
CHECK_PIXEL_PTR(rleCode);
|
||||||
|
@ -280,9 +280,9 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u
|
||||||
|
|
||||||
// copy pixels directly to output
|
// copy pixels directly to output
|
||||||
while (rleCode--) {
|
while (rleCode--) {
|
||||||
byte r = stream->readByte();
|
byte r = stream.readByte();
|
||||||
byte g = stream->readByte();
|
byte g = stream.readByte();
|
||||||
byte b = stream->readByte();
|
byte b = stream.readByte();
|
||||||
rgb[pixelPtr++] = _surface->format.RGBToColor(r, g, b);
|
rgb[pixelPtr++] = _surface->format.RGBToColor(r, g, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,29 +292,29 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
|
void QTRLEDecoder::decode32(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange) {
|
||||||
uint32 pixelPtr = 0;
|
uint32 pixelPtr = 0;
|
||||||
uint32 *rgb = (uint32 *)_surface->getPixels();
|
uint32 *rgb = (uint32 *)_surface->getPixels();
|
||||||
|
|
||||||
while (linesToChange--) {
|
while (linesToChange--) {
|
||||||
CHECK_STREAM_PTR(2);
|
CHECK_STREAM_PTR(2);
|
||||||
pixelPtr = rowPtr + stream->readByte() - 1;
|
pixelPtr = rowPtr + stream.readByte() - 1;
|
||||||
|
|
||||||
for (int8 rleCode = stream->readSByte(); rleCode != -1; rleCode = stream->readSByte()) {
|
for (int8 rleCode = stream.readSByte(); rleCode != -1; rleCode = stream.readSByte()) {
|
||||||
if (rleCode == 0) {
|
if (rleCode == 0) {
|
||||||
// there's another skip code in the stream
|
// there's another skip code in the stream
|
||||||
CHECK_STREAM_PTR(1);
|
CHECK_STREAM_PTR(1);
|
||||||
pixelPtr += stream->readByte() - 1;
|
pixelPtr += stream.readByte() - 1;
|
||||||
} else if (rleCode < 0) {
|
} else if (rleCode < 0) {
|
||||||
// decode the run length code
|
// decode the run length code
|
||||||
rleCode = -rleCode;
|
rleCode = -rleCode;
|
||||||
|
|
||||||
CHECK_STREAM_PTR(4);
|
CHECK_STREAM_PTR(4);
|
||||||
|
|
||||||
byte a = stream->readByte();
|
byte a = stream.readByte();
|
||||||
byte r = stream->readByte();
|
byte r = stream.readByte();
|
||||||
byte g = stream->readByte();
|
byte g = stream.readByte();
|
||||||
byte b = stream->readByte();
|
byte b = stream.readByte();
|
||||||
uint32 color = _surface->format.ARGBToColor(a, r, g, b);
|
uint32 color = _surface->format.ARGBToColor(a, r, g, b);
|
||||||
|
|
||||||
CHECK_PIXEL_PTR(rleCode);
|
CHECK_PIXEL_PTR(rleCode);
|
||||||
|
@ -327,10 +327,10 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u
|
||||||
|
|
||||||
// copy pixels directly to output
|
// copy pixels directly to output
|
||||||
while (rleCode--) {
|
while (rleCode--) {
|
||||||
byte a = stream->readByte();
|
byte a = stream.readByte();
|
||||||
byte r = stream->readByte();
|
byte r = stream.readByte();
|
||||||
byte g = stream->readByte();
|
byte g = stream.readByte();
|
||||||
byte b = stream->readByte();
|
byte b = stream.readByte();
|
||||||
rgb[pixelPtr++] = _surface->format.ARGBToColor(a, r, g, b);
|
rgb[pixelPtr++] = _surface->format.ARGBToColor(a, r, g, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,29 +340,29 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *QTRLEDecoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *QTRLEDecoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
uint16 startLine = 0;
|
uint16 startLine = 0;
|
||||||
uint16 height = _surface->h;
|
uint16 height = _surface->h;
|
||||||
|
|
||||||
// check if this frame is even supposed to change
|
// check if this frame is even supposed to change
|
||||||
if (stream->size() < 8)
|
if (stream.size() < 8)
|
||||||
return _surface;
|
return _surface;
|
||||||
|
|
||||||
// start after the chunk size
|
// start after the chunk size
|
||||||
stream->readUint32BE();
|
stream.readUint32BE();
|
||||||
|
|
||||||
// fetch the header
|
// fetch the header
|
||||||
uint16 header = stream->readUint16BE();
|
uint16 header = stream.readUint16BE();
|
||||||
|
|
||||||
// if a header is present, fetch additional decoding parameters
|
// if a header is present, fetch additional decoding parameters
|
||||||
if (header & 8) {
|
if (header & 8) {
|
||||||
if (stream->size() < 14)
|
if (stream.size() < 14)
|
||||||
return _surface;
|
return _surface;
|
||||||
|
|
||||||
startLine = stream->readUint16BE();
|
startLine = stream.readUint16BE();
|
||||||
stream->readUint16BE(); // Unknown
|
stream.readUint16BE(); // Unknown
|
||||||
height = stream->readUint16BE();
|
height = stream.readUint16BE();
|
||||||
stream->readUint16BE(); // Unknown
|
stream.readUint16BE(); // Unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 rowPtr = _surface->w * startLine;
|
uint32 rowPtr = _surface->w * startLine;
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel);
|
QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel);
|
||||||
~QTRLEDecoder();
|
~QTRLEDecoder();
|
||||||
|
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const;
|
Graphics::PixelFormat getPixelFormat() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -47,12 +47,12 @@ private:
|
||||||
|
|
||||||
Graphics::Surface *_surface;
|
Graphics::Surface *_surface;
|
||||||
|
|
||||||
void decode1(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
|
void decode1(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
|
||||||
void decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange, byte bpp);
|
void decode2_4(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange, byte bpp);
|
||||||
void decode8(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
|
void decode8(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
|
||||||
void decode16(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
|
void decode16(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
|
||||||
void decode24(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
|
void decode24(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
|
||||||
void decode32(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
|
void decode32(Common::SeekableReadStream &stream, uint32 rowPtr, uint32 linesToChange);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Image
|
} // End of namespace Image
|
||||||
|
|
|
@ -61,7 +61,7 @@ RPZADecoder::~RPZADecoder() {
|
||||||
WRITE_UINT16((uint16 *)_surface->getPixels() + blockPtr, color); \
|
WRITE_UINT16((uint16 *)_surface->getPixels() + blockPtr, color); \
|
||||||
blockPtr++
|
blockPtr++
|
||||||
|
|
||||||
const Graphics::Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *RPZADecoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
uint16 colorA = 0, colorB = 0;
|
uint16 colorA = 0, colorB = 0;
|
||||||
uint16 color4[4];
|
uint16 color4[4];
|
||||||
|
|
||||||
|
@ -73,40 +73,40 @@ const Graphics::Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *st
|
||||||
uint16 tb;
|
uint16 tb;
|
||||||
|
|
||||||
// First byte is always 0xe1. Warn if it's different
|
// First byte is always 0xe1. Warn if it's different
|
||||||
byte firstByte = stream->readByte();
|
byte firstByte = stream.readByte();
|
||||||
if (firstByte != 0xe1)
|
if (firstByte != 0xe1)
|
||||||
warning("First RPZA chunk byte is 0x%02x instead of 0xe1", firstByte);
|
warning("First RPZA chunk byte is 0x%02x instead of 0xe1", firstByte);
|
||||||
|
|
||||||
// Get chunk size, ingnoring first byte
|
// Get chunk size, ingnoring first byte
|
||||||
uint32 chunkSize = stream->readUint16BE() << 8;
|
uint32 chunkSize = stream.readUint16BE() << 8;
|
||||||
chunkSize += stream->readByte();
|
chunkSize += stream.readByte();
|
||||||
|
|
||||||
// If length mismatch use size from MOV file and try to decode anyway
|
// If length mismatch use size from MOV file and try to decode anyway
|
||||||
if (chunkSize != (uint32)stream->size()) {
|
if (chunkSize != (uint32)stream.size()) {
|
||||||
warning("MOV chunk size != encoded chunk size; using MOV chunk size");
|
warning("MOV chunk size != encoded chunk size; using MOV chunk size");
|
||||||
chunkSize = stream->size();
|
chunkSize = stream.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number of 4x4 blocks in frame
|
// Number of 4x4 blocks in frame
|
||||||
int32 totalBlocks = ((_surface->w + 3) / 4) * ((_surface->h + 3) / 4);
|
int32 totalBlocks = ((_surface->w + 3) / 4) * ((_surface->h + 3) / 4);
|
||||||
|
|
||||||
// Process chunk data
|
// Process chunk data
|
||||||
while ((uint32)stream->pos() < chunkSize) {
|
while ((uint32)stream.pos() < chunkSize) {
|
||||||
byte opcode = stream->readByte(); // Get opcode
|
byte opcode = stream.readByte(); // Get opcode
|
||||||
byte numBlocks = (opcode & 0x1f) + 1; // Extract block counter from opcode
|
byte numBlocks = (opcode & 0x1f) + 1; // Extract block counter from opcode
|
||||||
|
|
||||||
// If opcode MSbit is 0, we need more data to decide what to do
|
// If opcode MSbit is 0, we need more data to decide what to do
|
||||||
if ((opcode & 0x80) == 0) {
|
if ((opcode & 0x80) == 0) {
|
||||||
colorA = (opcode << 8) | stream->readByte();
|
colorA = (opcode << 8) | stream.readByte();
|
||||||
opcode = 0;
|
opcode = 0;
|
||||||
if (stream->readByte() & 0x80) {
|
if (stream.readByte() & 0x80) {
|
||||||
// Must behave as opcode 110xxxxx, using colorA computed
|
// Must behave as opcode 110xxxxx, using colorA computed
|
||||||
// above. Use fake opcode 0x20 to enter switch block at
|
// above. Use fake opcode 0x20 to enter switch block at
|
||||||
// the right place
|
// the right place
|
||||||
opcode = 0x20;
|
opcode = 0x20;
|
||||||
numBlocks = 1;
|
numBlocks = 1;
|
||||||
}
|
}
|
||||||
stream->seek(-1, SEEK_CUR);
|
stream.seek(-1, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (opcode & 0xe0) {
|
switch (opcode & 0xe0) {
|
||||||
|
@ -116,7 +116,7 @@ const Graphics::Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *st
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xa0: // Fill blocks with one color
|
case 0xa0: // Fill blocks with one color
|
||||||
colorA = stream->readUint16BE();
|
colorA = stream.readUint16BE();
|
||||||
while (numBlocks--) {
|
while (numBlocks--) {
|
||||||
blockPtr = rowPtr + pixelPtr;
|
blockPtr = rowPtr + pixelPtr;
|
||||||
for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
|
for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
|
||||||
|
@ -131,9 +131,9 @@ const Graphics::Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *st
|
||||||
|
|
||||||
// Fill blocks with 4 colors
|
// Fill blocks with 4 colors
|
||||||
case 0xc0:
|
case 0xc0:
|
||||||
colorA = stream->readUint16BE();
|
colorA = stream.readUint16BE();
|
||||||
case 0x20:
|
case 0x20:
|
||||||
colorB = stream->readUint16BE();
|
colorB = stream.readUint16BE();
|
||||||
|
|
||||||
// Sort out the colors
|
// Sort out the colors
|
||||||
color4[0] = colorB;
|
color4[0] = colorB;
|
||||||
|
@ -162,7 +162,7 @@ const Graphics::Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *st
|
||||||
while (numBlocks--) {
|
while (numBlocks--) {
|
||||||
blockPtr = rowPtr + pixelPtr;
|
blockPtr = rowPtr + pixelPtr;
|
||||||
for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
|
for (byte pixel_y = 0; pixel_y < 4; pixel_y++) {
|
||||||
byte index = stream->readByte();
|
byte index = stream.readByte();
|
||||||
for (byte pixel_x = 0; pixel_x < 4; pixel_x++) {
|
for (byte pixel_x = 0; pixel_x < 4; pixel_x++) {
|
||||||
byte idx = (index >> (2 * (3 - pixel_x))) & 0x03;
|
byte idx = (index >> (2 * (3 - pixel_x))) & 0x03;
|
||||||
PUT_PIXEL(color4[idx]);
|
PUT_PIXEL(color4[idx]);
|
||||||
|
@ -180,7 +180,7 @@ const Graphics::Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *st
|
||||||
for (byte pixel_x = 0; pixel_x < 4; pixel_x++) {
|
for (byte pixel_x = 0; pixel_x < 4; pixel_x++) {
|
||||||
// We already have color of upper left pixel
|
// We already have color of upper left pixel
|
||||||
if (pixel_y != 0 || pixel_x != 0)
|
if (pixel_y != 0 || pixel_x != 0)
|
||||||
colorA = stream->readUint16BE();
|
colorA = stream.readUint16BE();
|
||||||
|
|
||||||
PUT_PIXEL(colorA);
|
PUT_PIXEL(colorA);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
RPZADecoder(uint16 width, uint16 height);
|
RPZADecoder(uint16 width, uint16 height);
|
||||||
~RPZADecoder();
|
~RPZADecoder();
|
||||||
|
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); }
|
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
namespace Image {
|
namespace Image {
|
||||||
|
|
||||||
#define GET_BLOCK_COUNT() \
|
#define GET_BLOCK_COUNT() \
|
||||||
(opcode & 0x10) ? (1 + stream->readByte()) : 1 + (opcode & 0x0F);
|
(opcode & 0x10) ? (1 + stream.readByte()) : 1 + (opcode & 0x0F);
|
||||||
|
|
||||||
#define ADVANCE_BLOCK() \
|
#define ADVANCE_BLOCK() \
|
||||||
{ \
|
{ \
|
||||||
|
@ -55,7 +55,7 @@ SMCDecoder::~SMCDecoder() {
|
||||||
delete _surface;
|
delete _surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *SMCDecoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
byte *pixels = (byte *)_surface->getPixels();
|
byte *pixels = (byte *)_surface->getPixels();
|
||||||
|
|
||||||
uint32 numBlocks = 0;
|
uint32 numBlocks = 0;
|
||||||
|
@ -77,9 +77,9 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
uint32 colorOctetIndex = 0;
|
uint32 colorOctetIndex = 0;
|
||||||
uint32 colorTableIndex = 0; // indices to color pair, quad, or octet tables
|
uint32 colorTableIndex = 0; // indices to color pair, quad, or octet tables
|
||||||
|
|
||||||
int32 chunkSize = stream->readUint32BE() & 0x00FFFFFF;
|
int32 chunkSize = stream.readUint32BE() & 0x00FFFFFF;
|
||||||
if (chunkSize != stream->size())
|
if (chunkSize != stream.size())
|
||||||
warning("MOV chunk size != SMC chunk size (%d != %d); ignoring SMC chunk size", chunkSize, stream->size());
|
warning("MOV chunk size != SMC chunk size (%d != %d); ignoring SMC chunk size", chunkSize, stream.size());
|
||||||
|
|
||||||
int32 totalBlocks = ((_surface->w + 3) / 4) * ((_surface->h + 3) / 4);
|
int32 totalBlocks = ((_surface->w + 3) / 4) * ((_surface->h + 3) / 4);
|
||||||
|
|
||||||
|
@ -88,8 +88,8 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
// sanity checks
|
// sanity checks
|
||||||
|
|
||||||
// make sure stream ptr hasn't gone out of bounds
|
// make sure stream ptr hasn't gone out of bounds
|
||||||
if (stream->pos() > stream->size()) {
|
if (stream.pos() > stream.size()) {
|
||||||
warning("SMC decoder just went out of bounds (stream ptr = %d, chunk size = %d)", stream->pos(), stream->size());
|
warning("SMC decoder just went out of bounds (stream ptr = %d, chunk size = %d)", stream.pos(), stream.size());
|
||||||
return _surface;
|
return _surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
return _surface;
|
return _surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte opcode = stream->readByte();
|
byte opcode = stream.readByte();
|
||||||
|
|
||||||
switch (opcode & 0xF0) {
|
switch (opcode & 0xF0) {
|
||||||
// skip n blocks
|
// skip n blocks
|
||||||
|
@ -192,7 +192,7 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
case 0x60:
|
case 0x60:
|
||||||
case 0x70:
|
case 0x70:
|
||||||
numBlocks = GET_BLOCK_COUNT();
|
numBlocks = GET_BLOCK_COUNT();
|
||||||
pixel = stream->readByte();
|
pixel = stream.readByte();
|
||||||
|
|
||||||
while (numBlocks--) {
|
while (numBlocks--) {
|
||||||
blockPtr = rowPtr + pixelPtr;
|
blockPtr = rowPtr + pixelPtr;
|
||||||
|
@ -216,7 +216,7 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
// fetch the next 2 colors from bytestream and store in next
|
// fetch the next 2 colors from bytestream and store in next
|
||||||
// available entry in the color pair table
|
// available entry in the color pair table
|
||||||
for (byte i = 0; i < CPAIR; i++) {
|
for (byte i = 0; i < CPAIR; i++) {
|
||||||
pixel = stream->readByte();
|
pixel = stream.readByte();
|
||||||
colorTableIndex = CPAIR * colorPairIndex + i;
|
colorTableIndex = CPAIR * colorPairIndex + i;
|
||||||
_colorPairs[colorTableIndex] = pixel;
|
_colorPairs[colorTableIndex] = pixel;
|
||||||
}
|
}
|
||||||
|
@ -229,10 +229,10 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
if (colorPairIndex == COLORS_PER_TABLE)
|
if (colorPairIndex == COLORS_PER_TABLE)
|
||||||
colorPairIndex = 0;
|
colorPairIndex = 0;
|
||||||
} else
|
} else
|
||||||
colorTableIndex = CPAIR * stream->readByte();
|
colorTableIndex = CPAIR * stream.readByte();
|
||||||
|
|
||||||
while (numBlocks--) {
|
while (numBlocks--) {
|
||||||
colorFlags = stream->readUint16BE();
|
colorFlags = stream.readUint16BE();
|
||||||
uint16 flagMask = 0x8000;
|
uint16 flagMask = 0x8000;
|
||||||
blockPtr = rowPtr + pixelPtr;
|
blockPtr = rowPtr + pixelPtr;
|
||||||
for (byte y = 0; y < 4; y++) {
|
for (byte y = 0; y < 4; y++) {
|
||||||
|
@ -262,7 +262,7 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
// fetch the next 4 colors from bytestream and store in next
|
// fetch the next 4 colors from bytestream and store in next
|
||||||
// available entry in the color quad table
|
// available entry in the color quad table
|
||||||
for (byte i = 0; i < CQUAD; i++) {
|
for (byte i = 0; i < CQUAD; i++) {
|
||||||
pixel = stream->readByte();
|
pixel = stream.readByte();
|
||||||
colorTableIndex = CQUAD * colorQuadIndex + i;
|
colorTableIndex = CQUAD * colorQuadIndex + i;
|
||||||
_colorQuads[colorTableIndex] = pixel;
|
_colorQuads[colorTableIndex] = pixel;
|
||||||
}
|
}
|
||||||
|
@ -275,10 +275,10 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
if (colorQuadIndex == COLORS_PER_TABLE)
|
if (colorQuadIndex == COLORS_PER_TABLE)
|
||||||
colorQuadIndex = 0;
|
colorQuadIndex = 0;
|
||||||
} else
|
} else
|
||||||
colorTableIndex = CQUAD * stream->readByte();
|
colorTableIndex = CQUAD * stream.readByte();
|
||||||
|
|
||||||
while (numBlocks--) {
|
while (numBlocks--) {
|
||||||
colorFlags = stream->readUint32BE();
|
colorFlags = stream.readUint32BE();
|
||||||
|
|
||||||
// flag mask actually acts as a bit shift count here
|
// flag mask actually acts as a bit shift count here
|
||||||
byte flagMask = 30;
|
byte flagMask = 30;
|
||||||
|
@ -306,7 +306,7 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
// fetch the next 8 colors from bytestream and store in next
|
// fetch the next 8 colors from bytestream and store in next
|
||||||
// available entry in the color octet table
|
// available entry in the color octet table
|
||||||
for (byte i = 0; i < COCTET; i++) {
|
for (byte i = 0; i < COCTET; i++) {
|
||||||
pixel = stream->readByte();
|
pixel = stream.readByte();
|
||||||
colorTableIndex = COCTET * colorOctetIndex + i;
|
colorTableIndex = COCTET * colorOctetIndex + i;
|
||||||
_colorOctets[colorTableIndex] = pixel;
|
_colorOctets[colorTableIndex] = pixel;
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,7 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
if (colorOctetIndex == COLORS_PER_TABLE)
|
if (colorOctetIndex == COLORS_PER_TABLE)
|
||||||
colorOctetIndex = 0;
|
colorOctetIndex = 0;
|
||||||
} else
|
} else
|
||||||
colorTableIndex = COCTET * stream->readByte();
|
colorTableIndex = COCTET * stream.readByte();
|
||||||
|
|
||||||
while (numBlocks--) {
|
while (numBlocks--) {
|
||||||
/*
|
/*
|
||||||
|
@ -331,7 +331,7 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
|
|
||||||
// build the color flags
|
// build the color flags
|
||||||
byte flagData[6];
|
byte flagData[6];
|
||||||
stream->read(flagData, 6);
|
stream.read(flagData, 6);
|
||||||
|
|
||||||
colorFlagsA = ((READ_BE_UINT16(flagData) & 0xFFF0) << 8) | (READ_BE_UINT16(flagData + 2) >> 4);
|
colorFlagsA = ((READ_BE_UINT16(flagData) & 0xFFF0) << 8) | (READ_BE_UINT16(flagData + 2) >> 4);
|
||||||
colorFlagsB = ((READ_BE_UINT16(flagData + 4) & 0xFFF0) << 8) | ((flagData[1] & 0xF) << 8) |
|
colorFlagsB = ((READ_BE_UINT16(flagData + 4) & 0xFFF0) << 8) | ((flagData[1] & 0xF) << 8) |
|
||||||
|
@ -369,7 +369,7 @@ const Graphics::Surface *SMCDecoder::decodeImage(Common::SeekableReadStream *str
|
||||||
blockPtr = rowPtr + pixelPtr;
|
blockPtr = rowPtr + pixelPtr;
|
||||||
for (byte y = 0; y < 4; y++) {
|
for (byte y = 0; y < 4; y++) {
|
||||||
for (byte x = 0; x < 4; x++)
|
for (byte x = 0; x < 4; x++)
|
||||||
pixels[blockPtr++] = stream->readByte();
|
pixels[blockPtr++] = stream.readByte();
|
||||||
|
|
||||||
blockPtr += rowInc;
|
blockPtr += rowInc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public:
|
||||||
SMCDecoder(uint16 width, uint16 height);
|
SMCDecoder(uint16 width, uint16 height);
|
||||||
~SMCDecoder();
|
~SMCDecoder();
|
||||||
|
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
|
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -91,10 +91,10 @@ SVQ1Decoder::~SVQ1Decoder() {
|
||||||
|
|
||||||
#define ALIGN(x, a) (((x)+(a)-1)&~((a)-1))
|
#define ALIGN(x, a) (((x)+(a)-1)&~((a)-1))
|
||||||
|
|
||||||
const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *SVQ1Decoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
debug(1, "SVQ1Decoder::decodeImage()");
|
debug(1, "SVQ1Decoder::decodeImage()");
|
||||||
|
|
||||||
Common::BitStream32BEMSB frameData(*stream);
|
Common::BitStream32BEMSB frameData(stream);
|
||||||
|
|
||||||
uint32 frameCode = frameData.getBits(22);
|
uint32 frameCode = frameData.getBits(22);
|
||||||
debug(1, " frameCode: %d", frameCode);
|
debug(1, " frameCode: %d", frameCode);
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
SVQ1Decoder(uint16 width, uint16 height);
|
SVQ1Decoder(uint16 width, uint16 height);
|
||||||
~SVQ1Decoder();
|
~SVQ1Decoder();
|
||||||
|
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const { return _surface->format; }
|
Graphics::PixelFormat getPixelFormat() const { return _surface->format; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -163,9 +163,9 @@ void TrueMotion1Decoder::genVectorTable16(const byte *selVectorTable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrueMotion1Decoder::decodeHeader(Common::SeekableReadStream *stream) {
|
void TrueMotion1Decoder::decodeHeader(Common::SeekableReadStream &stream) {
|
||||||
_buf = new byte[stream->size()];
|
_buf = new byte[stream.size()];
|
||||||
stream->read(_buf, stream->size());
|
stream.read(_buf, stream.size());
|
||||||
|
|
||||||
byte headerBuffer[128]; // logical maximum size of the header
|
byte headerBuffer[128]; // logical maximum size of the header
|
||||||
const byte *selVectorTable;
|
const byte *selVectorTable;
|
||||||
|
@ -243,7 +243,7 @@ void TrueMotion1Decoder::decodeHeader(Common::SeekableReadStream *stream) {
|
||||||
_indexStream = _mbChangeBits + _mbChangeBitsRowSize * (_height >> 2);
|
_indexStream = _mbChangeBits + _mbChangeBitsRowSize * (_height >> 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
_indexStreamSize = stream->size() - (_indexStream - _buf);
|
_indexStreamSize = stream.size() - (_indexStream - _buf);
|
||||||
|
|
||||||
_lastDeltaset = _header.deltaset;
|
_lastDeltaset = _header.deltaset;
|
||||||
_lastVectable = _header.vectable;
|
_lastVectable = _header.vectable;
|
||||||
|
@ -397,7 +397,7 @@ void TrueMotion1Decoder::decode16() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *TrueMotion1Decoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *TrueMotion1Decoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
decodeHeader(stream);
|
decodeHeader(stream);
|
||||||
|
|
||||||
if (compressionTypes[_header.compression].algorithm == ALGO_NOP) {
|
if (compressionTypes[_header.compression].algorithm == ALGO_NOP) {
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
TrueMotion1Decoder(uint16 width, uint16 height);
|
TrueMotion1Decoder(uint16 width, uint16 height);
|
||||||
~TrueMotion1Decoder();
|
~TrueMotion1Decoder();
|
||||||
|
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
|
|
||||||
// Always return RGB565
|
// Always return RGB565
|
||||||
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); }
|
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); }
|
||||||
|
@ -96,7 +96,7 @@ private:
|
||||||
} _header;
|
} _header;
|
||||||
|
|
||||||
void selectDeltaTables(int deltaTableIndex);
|
void selectDeltaTables(int deltaTableIndex);
|
||||||
void decodeHeader(Common::SeekableReadStream *stream);
|
void decodeHeader(Common::SeekableReadStream &stream);
|
||||||
void decode16();
|
void decode16();
|
||||||
int makeYdt16Entry(int p1, int p2);
|
int makeYdt16Entry(int p1, int p2);
|
||||||
int makeCdt16Entry(int p1, int p2);
|
int makeCdt16Entry(int p1, int p2);
|
||||||
|
|
|
@ -59,8 +59,8 @@ void JPEGDecoder::destroy() {
|
||||||
_surface.free();
|
_surface.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *JPEGDecoder::decodeImage(Common::SeekableReadStream *stream) {
|
const Graphics::Surface *JPEGDecoder::decodeFrame(Common::SeekableReadStream &stream) {
|
||||||
if (!loadStream(*stream))
|
if (!loadStream(stream))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return getSurface();
|
return getSurface();
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
virtual const Graphics::Surface *getSurface() const;
|
virtual const Graphics::Surface *getSurface() const;
|
||||||
|
|
||||||
// Codec API
|
// Codec API
|
||||||
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
|
const Graphics::Surface *decodeFrame(Common::SeekableReadStream &stream);
|
||||||
Graphics::PixelFormat getPixelFormat() const;
|
Graphics::PixelFormat getPixelFormat() const;
|
||||||
|
|
||||||
// Special API for JPEG
|
// Special API for JPEG
|
||||||
|
|
|
@ -711,7 +711,7 @@ AVIDecoder::AVIVideoTrack::~AVIVideoTrack() {
|
||||||
void AVIDecoder::AVIVideoTrack::decodeFrame(Common::SeekableReadStream *stream) {
|
void AVIDecoder::AVIVideoTrack::decodeFrame(Common::SeekableReadStream *stream) {
|
||||||
if (stream) {
|
if (stream) {
|
||||||
if (_videoCodec)
|
if (_videoCodec)
|
||||||
_lastFrame = _videoCodec->decodeImage(stream);
|
_lastFrame = _videoCodec->decodeFrame(*stream);
|
||||||
} else {
|
} else {
|
||||||
// Empty frame
|
// Empty frame
|
||||||
_lastFrame = 0;
|
_lastFrame = 0;
|
||||||
|
|
|
@ -2262,7 +2262,7 @@ bool VMDDecoder::renderFrame(Common::Rect &rect) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Common::MemoryReadStream frameStream(_videoBuffer[0], _videoBufferLen[0]);
|
Common::MemoryReadStream frameStream(_videoBuffer[0], _videoBufferLen[0]);
|
||||||
const Graphics::Surface *codecSurf = _codec->decodeImage(&frameStream);
|
const Graphics::Surface *codecSurf = _codec->decodeFrame(frameStream);
|
||||||
if (!codecSurf)
|
if (!codecSurf)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -725,7 +725,7 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::bufferNextFrame()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *frame = entry->_videoCodec->decodeImage(frameData);
|
const Graphics::Surface *frame = entry->_videoCodec->decodeFrame(*frameData);
|
||||||
delete frameData;
|
delete frameData;
|
||||||
|
|
||||||
// Update the palette
|
// Update the palette
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue