aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/sci/scicore/decompressor.cpp199
-rw-r--r--engines/sci/scicore/decompressor.h14
2 files changed, 99 insertions, 114 deletions
diff --git a/engines/sci/scicore/decompressor.cpp b/engines/sci/scicore/decompressor.cpp
index 5afa5dfe34..62ccd0ffbd 100644
--- a/engines/sci/scicore/decompressor.cpp
+++ b/engines/sci/scicore/decompressor.cpp
@@ -35,18 +35,20 @@ namespace Sci {
int Decompressor::unpack(Common::ReadStream *src, Common::WriteStream *dest, uint32 nPacked,
uint32 nUnpacked) {
- init(src, dest, nPacked, nUnpacked);
+ return copyBytes(src, dest, nPacked);
+}
+
+int Decompressor::copyBytes(Common::ReadStream *src, Common::WriteStream *dest, uint32 nSize) {
byte buff[1024];
uint32 chunk;
- while (_szPacked && !_src->ioFailed() && !_dest->ioFailed()) {
- chunk = MIN<uint32>(1024, _szPacked);
- _src->read(buff, chunk);
- _dest->write(buff, chunk);
- _szPacked -= chunk;
+ while (nSize && !src->ioFailed() && !dest->ioFailed()) {
+ chunk = MIN<uint32>(1024, nSize);
+ src->read(buff, chunk);
+ dest->write(buff, chunk);
+ nSize -= chunk;
}
- return _src->ioFailed() || _dest->ioFailed() ? 1 : 0;
+ return src->ioFailed() || dest->ioFailed() ? 1 : 0;
}
-
void Decompressor::init(Common::ReadStream *src, Common::WriteStream *dest, uint32 nPacked,
uint32 nUnpacked) {
_src = src;
@@ -147,6 +149,7 @@ int DecompressorComp3::unpack(Common::ReadStream *src, Common::WriteStream *dest
byte *buffer = NULL;
byte *buffer2 = NULL;
Common::MemoryWriteStream *pBuff = NULL;
+ Common::MemoryReadStream *pBuffIn = NULL;
switch (_compression) {
case kComp3: // Comp3 compression
@@ -155,16 +158,21 @@ int DecompressorComp3::unpack(Common::ReadStream *src, Common::WriteStream *dest
case kComp3View:
case kComp3Pic:
buffer = new byte[nUnpacked];
- buffer2 = new byte[nUnpacked];
pBuff = new Common::MemoryWriteStream(buffer, nUnpacked);
doUnpack(src, pBuff, nPacked, nUnpacked);
- if (_compression == kComp3View)
+ if (_compression == kComp3View) {
+ buffer2 = new byte[nUnpacked];
view_reorder(buffer, buffer2);
- else
- pic_reorder(buffer, buffer2, nUnpacked);
- dest->write(buffer2, nUnpacked);
+ dest->write(buffer2, nUnpacked);
+ }
+ else {
+ pBuffIn = new Common::MemoryReadStream(buffer, nUnpacked);
+ reorderPic(pBuffIn, dest, nUnpacked);
+ }
delete[] buffer2;
delete[] buffer;
+ delete pBuff;
+ delete pBuffIn;
break;
}
return 0;
@@ -243,36 +251,32 @@ int DecompressorComp3::doUnpack(Common::ReadStream *src, Common::WriteStream *de
return _dwWrote ? 0 : 1;
}
-enum {
- PIC_OP_SET_COLOR = 0xf0,
- PIC_OP_DISABLE_VISUAL = 0xf1,
- PIC_OP_SET_PRIORITY = 0xf2,
- PIC_OP_DISABLE_PRIORITY = 0xf3,
- PIC_OP_SHORT_PATTERNS = 0xf4,
- PIC_OP_MEDIUM_LINES = 0xf5,
- PIC_OP_LONG_LINES = 0xf6,
- PIC_OP_SHORT_LINES = 0xf7,
- PIC_OP_FILL = 0xf8,
- PIC_OP_SET_PATTERN = 0xf9,
- PIC_OP_ABSOLUTE_PATTERN = 0xfa,
- PIC_OP_SET_CONTROL = 0xfb,
- PIC_OP_DISABLE_CONTROL = 0xfc,
- PIC_OP_MEDIUM_PATTERNS = 0xfd,
- PIC_OP_OPX = 0xfe,
- PIC_OP_TERMINATE = 0xff
-};
-
-enum {
- PIC_OPX_SET_PALETTE_ENTRIES = 0,
- PIC_OPX_EMBEDDED_VIEW = 1,
- PIC_OPX_SET_PALETTE = 2,
- PIC_OPX_PRIORITY_TABLE_EQDIST = 3,
- PIC_OPX_PRIORITY_TABLE_EXPLICIT = 4
-};
-
#define PAL_SIZE 1284
-#define CEL_HEADER_SIZE 7
#define EXTRA_MAGIC_SIZE 15
+#define VIEW_HEADER_COLORS_8BIT 0x80
+
+void DecompressorComp3::decodeRLE(Common::ReadStream *src, Common::WriteStream *dest, byte *pixeldata, uint16 size) {
+ int pos = 0;
+ byte nextbyte;
+ while (pos < size) {
+ nextbyte = src->readByte();
+ dest->writeByte(nextbyte);
+ pos ++;
+ switch (nextbyte & 0xC0) {
+ case 0x40 :
+ case 0x00 :
+ dest->write(pixeldata, nextbyte);
+ pixeldata += nextbyte;
+ pos += nextbyte;
+ break;
+ case 0xC0 :
+ break;
+ case 0x80 :
+ dest->writeByte(*pixeldata++);
+ break;
+ }
+ }
+}
void DecompressorComp3::decode_rle(byte **rledata, byte **pixeldata, byte *outbuffer, int size) {
int pos = 0;
@@ -339,80 +343,53 @@ int DecompressorComp3::rle_size(byte *rledata, int dsize) {
return size;
}
-void DecompressorComp3::pic_reorder(byte *inbuffer, byte *outbuffer, int dsize) {
- int view_size;
- int view_start;
- int cdata_size;
- int i;
- byte *seeker = inbuffer;
- byte *writer;
- char viewdata[CEL_HEADER_SIZE];
- byte *cdata, *cdata_start;
+void DecompressorComp3::reorderPic(Common::ReadStream *src, Common::WriteStream *dest, int dsize) {
+ int view_size, view_start, cdata_size;
+ byte viewdata[7];
+ byte *cdata = NULL;
+ byte *extra = NULL;
- writer = outbuffer;
-
- *writer++ = PIC_OP_OPX;
- *writer++ = PIC_OPX_SET_PALETTE;
-
- for (i = 0; i < 256; i++) /* Palette translation map */
- *writer++ = i;
-
- WRITE_LE_UINT16(writer, 0); /* Palette stamp */
- writer += 2;
- WRITE_LE_UINT16(writer, 0);
- writer += 2;
-
- view_size = READ_LE_UINT16(seeker);
- seeker += 2;
- view_start = READ_LE_UINT16(seeker);
- seeker += 2;
- cdata_size = READ_LE_UINT16(seeker);
- seeker += 2;
-
- memcpy(viewdata, seeker, sizeof(viewdata));
- seeker += sizeof(viewdata);
-
- memcpy(writer, seeker, 4*256); /* Palette */
- seeker += 4*256;
- writer += 4*256;
-
- if (view_start != PAL_SIZE + 2) { /* +2 for the opcode */
- memcpy(writer, seeker, view_start-PAL_SIZE-2);
- seeker += view_start - PAL_SIZE - 2;
- writer += view_start - PAL_SIZE - 2;
- }
-
- if (dsize != view_start+EXTRA_MAGIC_SIZE+view_size) {
- memcpy(outbuffer+view_size+view_start+EXTRA_MAGIC_SIZE, seeker,
- dsize-view_size-view_start-EXTRA_MAGIC_SIZE);
- seeker += dsize-view_size-view_start-EXTRA_MAGIC_SIZE;
+ // Setting palette
+ dest->writeByte(PIC_OP_OPX);
+ dest->writeByte(PIC_OPX_SET_PALETTE);
+
+ for (int i = 0; i < 256; i++) // Palette translation map
+ dest->writeByte(i);
+ dest->writeUint32LE(0); //Palette timestamp
+
+ view_size = src->readUint16LE();
+ view_start = src->readUint16LE();
+ cdata_size = src->readUint16LE();
+ src->read(viewdata, sizeof(viewdata));
+ // Copy palette colors
+ copyBytes(src, dest, 1024);
+ // copy drawing opcodes
+ if (view_start != PAL_SIZE + 2)
+ copyBytes(src, dest, view_start - PAL_SIZE - 2);
+ // storing extra opcodes to be pasted after the cel
+ if (dsize != view_start + EXTRA_MAGIC_SIZE + view_size) {
+ extra = new byte[dsize - view_size - view_start - EXTRA_MAGIC_SIZE];
+ src->read(extra, dsize - view_size - view_start - EXTRA_MAGIC_SIZE);
}
-
- cdata_start = cdata = (byte *)malloc(cdata_size);
- memcpy(cdata, seeker, cdata_size);
- seeker += cdata_size;
-
- writer = outbuffer + view_start;
- *writer++ = PIC_OP_OPX;
- *writer++ = PIC_OPX_EMBEDDED_VIEW;
- *writer++ = 0;
- *writer++ = 0;
- *writer++ = 0;
- WRITE_LE_UINT16(writer, view_size + 8);
- writer += 2;
-
- memcpy(writer, viewdata, sizeof(viewdata));
- writer += sizeof(viewdata);
-
- *writer++ = 0;
-
- decode_rle(&seeker, &cdata, writer, view_size);
-
- free(cdata_start);
+ // Writing picture cel opcode and header
+ dest->writeByte(PIC_OP_OPX);
+ dest->writeByte(PIC_OPX_EMBEDDED_VIEW);
+ dest->writeByte(0);
+ dest->writeUint16LE(0);
+ dest->writeUint16LE(view_size + 8);
+ dest->write(viewdata, sizeof(viewdata));
+ dest->writeByte(0);
+ // Unpacking RLE cel data
+ cdata = new byte[cdata_size];
+ src->read(cdata, cdata_size);
+ decodeRLE(src, dest, cdata, view_size);
+ // writing stored extra opcodes
+ if (extra)
+ dest->write(extra, dsize - view_size - view_start - EXTRA_MAGIC_SIZE);
+ delete[] extra;
+ delete[] cdata;
}
-#define VIEW_HEADER_COLORS_8BIT 0x80
-
void DecompressorComp3::build_cel_headers(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max) {
for (int c = 0; c < max; c++) {
memcpy(*writer, *seeker, 6);
diff --git a/engines/sci/scicore/decompressor.h b/engines/sci/scicore/decompressor.h
index 39c3b412cb..2c9c203cdd 100644
--- a/engines/sci/scicore/decompressor.h
+++ b/engines/sci/scicore/decompressor.h
@@ -79,6 +79,7 @@ protected:
*/
virtual void putByte(byte b);
virtual void fetchBits();
+ int copyBytes(Common::ReadStream *src, Common::WriteStream *dest, uint32 nSize);
uint32 _dwBits;
byte _nBits;
@@ -120,20 +121,27 @@ public:
uint32 nUnpacked);
protected:
+ enum {
+ PIC_OPX_EMBEDDED_VIEW = 1,
+ PIC_OPX_SET_PALETTE = 2,
+ PIC_OP_OPX = 0xfe,
+ };
// actual unpacking procedure
int doUnpack(Common::ReadStream *src, Common::WriteStream *dest, uint32 nPacked,
uint32 nUnpacked);
// functions to post-process view and pic resources
+ void decodeRLE(Common::ReadStream *src, Common::WriteStream *dest, byte *pixeldata, uint16 size);
+ void reorderPic(Common::ReadStream *src, Common::WriteStream *dest, int dsize);
+ //
void decode_rle(byte **rledata, byte **pixeldata, byte *outbuffer, int size);
int rle_size(byte *rledata, int dsize);
- void pic_reorder(byte *inbuffer, byte *outbuffer, int dsize);
void build_cel_headers(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max);
void view_reorder(byte *inbuffer, byte *outbuffer);
-
+ // decompressor data
struct tokenlist {
byte data;
uint16 next;
- } _tokens[0x1004];
+ } _tokens[0x1004];
byte _stak[0x1014];
byte _lastchar;
uint16 _stakptr;