[Scummvm-git-logs] scummvm master -> 79febe2586114757c7a960a4ab5e0692a10d746e
bluegr
noreply at scummvm.org
Wed Jul 15 14:38:33 UTC 2026
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
4050c4bfee SCI: Cleanup LZW view/pic decompressors
79febe2586 SCI: Cleanup decompressor code
Commit: 4050c4bfeeddeb589b9eb04ab2995a4162c14596
https://github.com/scummvm/scummvm/commit/4050c4bfeeddeb589b9eb04ab2995a4162c14596
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2026-07-15T17:38:28+03:00
Commit Message:
SCI: Cleanup LZW view/pic decompressors
Changed paths:
engines/sci/graphics/view.cpp
engines/sci/resource/decompressor.cpp
engines/sci/resource/decompressor.h
diff --git a/engines/sci/graphics/view.cpp b/engines/sci/graphics/view.cpp
index 3bc1bc7cbe4..f6a66fa4fa1 100644
--- a/engines/sci/graphics/view.cpp
+++ b/engines/sci/graphics/view.cpp
@@ -134,7 +134,7 @@ void GfxView::initData() {
case kViewAmiga: // Amiga ECS (32 colors)
case kViewAmiga64: // Amiga AGA (64 colors)
case kViewVga: { // View-format SCI1
- // LoopCount:WORD MirrorMask:WORD Version:WORD PaletteOffset:WORD LoopOffset0:WORD LoopOffset1:WORD...
+ // LoopCount:BYTE Flags:BYTE MirrorMask:WORD Version:WORD PaletteOffset:WORD LoopOffset0:WORD LoopOffset1:WORD...
_loop.resize(_resource->getUint8At(0));
// bit 0x8000 of _resourceData[1] means palette is set
diff --git a/engines/sci/resource/decompressor.cpp b/engines/sci/resource/decompressor.cpp
index f94a2537c39..45430285f87 100644
--- a/engines/sci/resource/decompressor.cpp
+++ b/engines/sci/resource/decompressor.cpp
@@ -143,6 +143,7 @@ int16 DecompressorHuffman::getc2() {
int DecompressorLZW::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
byte *buffer = nullptr;
+ int result = SCI_ERROR_NONE;
switch (_compression) {
case kCompLZW: // SCI0 LZW compression
@@ -150,19 +151,23 @@ int DecompressorLZW::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked,
return unpackLZW(src, dest, nPacked, nUnpacked);
case kCompLZW1View:
buffer = new byte[nUnpacked];
- unpackLZW(src, buffer, nPacked, nUnpacked);
- reorderView(buffer, dest);
+ result = unpackLZW(src, buffer, nPacked, nUnpacked);
+ if (result == SCI_ERROR_NONE) {
+ unpackView(buffer, dest);
+ }
break;
case kCompLZW1Pic:
buffer = new byte[nUnpacked];
- unpackLZW(src, buffer, nPacked, nUnpacked);
- reorderPic(buffer, dest, nUnpacked);
+ result = unpackLZW(src, buffer, nPacked, nUnpacked);
+ if (result == SCI_ERROR_NONE) {
+ unpackPic(buffer, dest, nUnpacked);
+ }
break;
default:
break;
}
delete[] buffer;
- return 0;
+ return result;
}
// Decompresses SCI0 LZW and SCI01/1 LZW, depending on _compression value.
@@ -181,6 +186,7 @@ int DecompressorLZW::unpackLZW(Common::ReadStream *src, byte *dest, uint32 nPack
uint16 *stringOffsets = new uint16[4096]; // 0-257: unused
uint16 *stringLengths = new uint16[4096]; // 0-257: unused
+ bool terminatorFound = false;
while (!isFinished()) {
uint16 code = (_compression == kCompLZW) ?
getBitsLSB(codeBitLength) :
@@ -192,6 +198,7 @@ int DecompressorLZW::unpackLZW(Common::ReadStream *src, byte *dest, uint32 nPack
}
if (code == 257) { // terminator
+ terminatorFound = true;
break;
}
@@ -240,290 +247,251 @@ int DecompressorLZW::unpackLZW(Common::ReadStream *src, byte *dest, uint32 nPack
delete[] stringOffsets;
delete[] stringLengths;
- return _dwWrote == _szUnpacked ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
-}
-
-#define PAL_SIZE 1284
-#define EXTRA_MAGIC_SIZE 15
-#define VIEW_HEADER_COLORS_8BIT 0x80
-
-void DecompressorLZW::decodeRLE(byte **rledata, byte **pixeldata, byte *outbuffer, int size) {
- int pos = 0;
- byte nextbyte;
- byte *rd = *rledata;
- byte *ob = outbuffer;
- byte *pd = *pixeldata;
-
- while (pos < size) {
- nextbyte = *rd++;
- *ob++ = nextbyte;
- pos++;
- switch (nextbyte & 0xC0) {
- case 0x40:
- case 0x00:
- memcpy(ob, pd, nextbyte);
- pd += nextbyte;
- ob += nextbyte;
- pos += nextbyte;
- break;
- case 0xC0:
- default:
- break;
- case 0x80:
- nextbyte = *pd++;
- *ob++ = nextbyte;
- pos++;
- break;
- }
- }
-
- *rledata = rd;
- *pixeldata = pd;
+ // Reaching the compression terminator before writing _szUnpacked bytes is
+ // expected. For kCompLZW1View and kCompLZW1Pic, the unpacked size is not
+ // the LZW output size, it is the final size after processing LZW output.
+ return (terminatorFound || (_dwWrote == _szUnpacked)) ?
+ SCI_ERROR_NONE:
+ SCI_ERROR_DECOMPRESSION_ERROR;
}
-/**
- * Does the same this as decodeRLE, only to determine the length of the
- * compressed source data.
- */
-int DecompressorLZW::getRLEsize(byte *rledata, int dsize) {
- int pos = 0;
- int size = 0;
-
- while (pos < dsize) {
- byte nextbyte = *(rledata++);
- pos++;
- size++;
-
- switch (nextbyte & 0xC0) {
- case 0x40:
- case 0x00:
- pos += nextbyte;
- break;
- case 0xC0:
- default:
- break;
- case 0x80:
- pos++;
- break;
- }
- }
-
- return size;
-}
-
-enum {
- PIC_OPX_EMBEDDED_VIEW = 1,
- PIC_OPX_SET_PALETTE = 2,
- PIC_OP_OPX = 0xfe
-};
-
-void DecompressorLZW::reorderPic(byte *src, byte *dest, int dsize) {
- uint16 view_size, view_start, cdata_size;
- int i;
+void DecompressorLZW::unpackView(byte *src, byte *dest) {
byte *seeker = src;
byte *writer = dest;
- char viewdata[7];
- byte *cdata, *cdata_start;
- *writer++ = PIC_OP_OPX;
- *writer++ = PIC_OPX_SET_PALETTE;
-
- for (i = 0; i < 256; i++) /* Palette translation map */
- *writer++ = i;
-
- WRITE_LE_UINT32(writer, 0); /* Palette stamp */
- writer += 4;
-
- view_size = READ_LE_UINT16(seeker);
+ // read compressed header
+ byte *celLengths = src + READ_LE_UINT16(seeker) + 2;
seeker += 2;
- view_start = READ_LE_UINT16(seeker);
+ byte loopCount = *seeker++;
+ byte loopHeaderCount = *seeker++; // non-mirrored loops
+ uint16 mirrorMask = READ_LE_UINT16(seeker);
seeker += 2;
- cdata_size = READ_LE_UINT16(seeker);
+ uint16 version = READ_LE_UINT16(seeker);
+ seeker += 2;
+ uint16 paletteOffset = READ_LE_UINT16(seeker); // offset in output view
+ seeker += 2;
+ int celHeaderCount = READ_LE_UINT16(seeker); // non-mirrored loops
seeker += 2;
- memcpy(viewdata, seeker, sizeof(viewdata));
- seeker += sizeof(viewdata);
-
- memcpy(writer, seeker, 4*256); /* Palette */
- seeker += 4*256;
- writer += 4*256;
+ // read cel counts for each loop header
+ byte *celCounts = seeker;
+ seeker += loopHeaderCount;
- 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;
+ // read lengths of decoded cels
+ uint16 *celDecodedLengths = new uint16[celHeaderCount];
+ for (int i = 0; i < celHeaderCount; i++) {
+ celDecodedLengths[i] = READ_LE_UINT16(celLengths + (2 * i));
}
- if (dsize != view_start + EXTRA_MAGIC_SIZE + view_size) {
- memcpy(dest + 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;
+ // locate pixel data by seeking past each cel's RLE data
+ byte *rleData = celLengths + (2 * celHeaderCount);
+ byte *pixelData = rleData;
+ for (int i = 0; i < celHeaderCount; i++) {
+ skipRLE(&pixelData, celDecodedLengths[i]);
}
- cdata_start = cdata = (byte *)malloc(cdata_size);
- memcpy(cdata, seeker, cdata_size);
- seeker += cdata_size;
-
- writer = dest + view_start;
- *writer++ = PIC_OP_OPX;
- *writer++ = PIC_OPX_EMBEDDED_VIEW;
- *writer++ = 0;
- *writer++ = 0;
- *writer++ = 0;
- WRITE_LE_UINT16(writer, view_size + 8);
+ // write view header
+ *writer++ = loopCount;
+ *writer++ = 0x80; // flags for a VGA pic with RLE compression
+ WRITE_LE_UINT16(writer, mirrorMask);
+ writer += 2;
+ WRITE_LE_UINT16(writer, version);
+ writer += 2;
+ WRITE_LE_UINT16(writer, paletteOffset);
writer += 2;
- memcpy(writer, viewdata, sizeof(viewdata));
- writer += sizeof(viewdata);
+ // skip loop offset table, we will write it while writing loops
+ byte *loopOffsets = writer;
+ writer += 2 * loopCount;
+
+ // write loops and their cels
+ int loopTableIndex = 0;
+ int celTableIndex = 0;
+ for (int loop = 0; loop < loopCount; loop++) {
+ if (mirrorMask & (1 << loop)) {
+ // mirrored loop: write previous loop offset to table
+ memcpy(loopOffsets, loopOffsets - 2, 2);
+ } else {
+ // write loop offset to table
+ WRITE_LE_UINT16(loopOffsets, writer - dest);
+
+ // write loop header
+ byte celCount = celCounts[loopTableIndex];
+ *writer++ = celCount;
+ memset(writer, 0, 3);
+ writer += 3;
+
+ // write cel offset table
+ int celOffset = (writer - dest) + (2 * celCount);
+ for (int cel = 0; cel < celCount; cel++) {
+ WRITE_LE_UINT16(writer, celOffset);
+ writer += 2;
+ celOffset += 8 + celDecodedLengths[celTableIndex + cel];
+ }
- *writer++ = 0;
+ // write cels
+ for (int cel = 0; cel < celCount; cel++) {
+ // cel header
+ memcpy(writer, seeker, 7);
+ seeker += 7;
+ writer += 7;
+ *writer++ = 0;
+
+ // cel data
+ int celDecodedLength = celDecodedLengths[celTableIndex + cel];
+ decodeRLE(&rleData, &pixelData, writer, celDecodedLength);
+ writer += celDecodedLength;
+ }
- decodeRLE(&seeker, &cdata, writer, view_size);
+ celTableIndex += celCount;
+ loopTableIndex++;
+ }
+ loopOffsets += 2;
+ }
- free(cdata_start);
-}
+ // write palette
+ if (paletteOffset != 0) {
+ *writer++ = 'P';
+ *writer++ = 'A';
+ *writer++ = 'L';
-void DecompressorLZW::buildCelHeaders(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max) {
- for (int c = 0; c < max; c++) {
- memcpy(*writer, *seeker, 6);
- *seeker += 6;
- *writer += 6;
- int w = *((*seeker)++);
- WRITE_LE_UINT16(*writer, w); /* Zero extension */
- *writer += 2;
-
- *writer += cc_lengths[celindex];
- celindex++;
+ // palette translation map
+ for (int i = 0; i < 256; i++) {
+ *writer++ = i;
+ }
+
+ // palette time stamp and palette colors
+ // include the unrelated four bytes before the palette so that
+ // they are written to the palette time stamp. this is a bogus
+ // value but it's what sierra's decompressor did, so we do it
+ // to be consistent with it and other SCI tools. this field is
+ // ignored by the interpreter when reading a view.
+ memcpy(writer, seeker - 4, 4 + 1024);
}
+
+ delete[] celDecodedLengths;
}
-void DecompressorLZW::reorderView(byte *src, byte *dest) {
- byte *cellengths;
- int loopheaders;
- int lh_present;
- int lh_mask;
- int pal_offset;
- int cel_total;
- int unknown;
+void DecompressorLZW::unpackPic(byte *src, byte *dest, int unpackedSize) {
byte *seeker = src;
- char celcounts[100];
byte *writer = dest;
- byte *lh_ptr;
- byte *rle_ptr, *pix_ptr;
- int l, lb, c, celindex, lh_last = -1;
- int chptr;
- int w;
- int *cc_lengths;
- byte **cc_pos;
-
- /* Parse the main header */
- cellengths = src + READ_LE_UINT16(seeker) + 2;
- seeker += 2;
- loopheaders = *seeker++;
- lh_present = *seeker++;
- lh_mask = READ_LE_UINT16(seeker);
- seeker += 2;
- unknown = READ_LE_UINT16(seeker);
- seeker += 2;
- pal_offset = READ_LE_UINT16(seeker);
- seeker += 2;
- cel_total = READ_LE_UINT16(seeker);
- seeker += 2;
- cc_pos = (byte **) malloc(sizeof(byte *) * cel_total);
- cc_lengths = (int *) malloc(sizeof(int) * cel_total);
+ // begin writing set-palette instruction
+ *writer++ = 0xfe; // PIC_OP_OPX
+ *writer++ = 0x02; // PIC_OPX_VGA_SET_PALETTE
- for (c = 0; c < cel_total; c++)
- cc_lengths[c] = READ_LE_UINT16(cellengths + 2 * c);
+ // write palette translation map
+ for (int i = 0; i < 256; i++) {
+ *writer++ = i;
+ }
- *writer++ = loopheaders;
- *writer++ = VIEW_HEADER_COLORS_8BIT;
- WRITE_LE_UINT16(writer, lh_mask);
- writer += 2;
- WRITE_LE_UINT16(writer, unknown);
- writer += 2;
- WRITE_LE_UINT16(writer, pal_offset);
- writer += 2;
+ // write palette time stamp
+ memset(writer, 0, 4);
+ writer += 4;
- lh_ptr = writer;
- writer += 2 * loopheaders; /* Make room for the loop offset table */
+ // read compressed header
+ uint16 viewCelSize = READ_LE_UINT16(seeker);
+ seeker += 2;
+ uint16 viewOpPos = READ_LE_UINT16(seeker); // offset in output pic
+ seeker += 2;
+ uint16 viewPixelDataSize = READ_LE_UINT16(seeker);
+ seeker += 2;
+ byte *viewHeader = seeker;
+ seeker += 7;
+
+ // write palette colors
+ memcpy(writer, seeker, 1024);
+ seeker += 1024;
+ writer += 1024;
+
+ // write optional data before embedded-view instruction
+ if (viewOpPos != 1286) { // 1286 = set-palette instruction size
+ int preViewDataSize = viewOpPos - 1286;
+ memcpy(writer, seeker, preViewDataSize);
+ seeker += preViewDataSize;
+ writer += preViewDataSize;
+ }
- pix_ptr = writer;
+ // write optional data after embedded-view instruction (written to end)
+ int postViewDataPosition = viewOpPos + 15 + viewCelSize;
+ if (unpackedSize != postViewDataPosition) {
+ int postViewDataSize = unpackedSize - postViewDataPosition;
+ memcpy(dest + postViewDataPosition, seeker, postViewDataSize);
+ seeker += postViewDataSize;
+ }
- memcpy(celcounts, seeker, lh_present);
- seeker += lh_present;
+ // begin writing embedded-view instruction
+ *writer++ = 0xfe; // PIC_OP_OPX
+ *writer++ = 0x01; // PIC_OPX_VGA_EMBEDDED_VIEW
- lb = 1;
- celindex = 0;
+ // write coordinates (0, 0)
+ memset(writer, 0, 3);
+ writer += 3;
- rle_ptr = pix_ptr = cellengths + (2 * cel_total);
- w = 0;
+ // write cel size
+ WRITE_LE_UINT16(writer, 8 + viewCelSize);
+ writer += 2;
- for (l = 0; l < loopheaders; l++) {
- if (lh_mask & lb) { /* The loop is _not_ present */
- if (lh_last == -1) {
- warning("Error: While reordering view: Loop not present, but can't re-use last loop");
- lh_last = 0;
- }
- WRITE_LE_UINT16(lh_ptr, lh_last);
- lh_ptr += 2;
- } else {
- lh_last = writer - dest;
- WRITE_LE_UINT16(lh_ptr, lh_last);
- lh_ptr += 2;
- WRITE_LE_UINT16(writer, celcounts[w]);
- writer += 2;
- WRITE_LE_UINT16(writer, 0);
- writer += 2;
-
- /* Now, build the cel offset table */
- chptr = (writer - dest) + (2 * celcounts[w]);
-
- for (c = 0; c < celcounts[w]; c++) {
- WRITE_LE_UINT16(writer, chptr);
- writer += 2;
- cc_pos[celindex+c] = dest + chptr;
- chptr += 8 + READ_LE_UINT16(cellengths + 2 * (celindex + c));
- }
+ // write view header
+ memcpy(writer, viewHeader, 7);
+ writer += 7;
+ *writer++ = 0;
- buildCelHeaders(&seeker, &writer, celindex, cc_lengths, celcounts[w]);
+ // write view cel (stored as pixel data followed by RLE data)
+ byte *viewRleData = seeker + viewPixelDataSize;;
+ decodeRLE(&viewRleData, &seeker, writer, viewCelSize);
+}
- celindex += celcounts[w];
- w++;
- }
+/***
+ * Decodes a cel's data from two separate RLE and pixel buffers.
+ */
+void DecompressorLZW::decodeRLE(byte **rleData, byte **pixelData, byte *dest, int decodedSize) {
+ int pos = 0;
+ byte *rleSeeker = *rleData;
+ byte *pixelSeeker = *pixelData;
- lb = lb << 1;
- }
+ while (pos < decodedSize) {
+ byte currentByte = *rleSeeker++;
+ *dest++ = currentByte;
+ pos++;
- if (celindex < cel_total) {
- warning("View decompression generated too few (%d / %d) headers", celindex, cel_total);
- free(cc_pos);
- free(cc_lengths);
- return;
+ byte upperBits = (currentByte & 0xc0);
+ if (upperBits <= 0x40) { // 00, 40
+ memcpy(dest, pixelSeeker, currentByte);
+ pixelSeeker += currentByte;
+ dest += currentByte;
+ pos += currentByte;
+ } else if (upperBits == 0x80) {
+ *dest++ = *pixelSeeker++;
+ pos++;
+ }
}
- /* Figure out where the pixel data begins. */
- for (c = 0; c < cel_total; c++)
- pix_ptr += getRLEsize(pix_ptr, cc_lengths[c]);
-
- rle_ptr = cellengths + (2 * cel_total);
- for (c = 0; c < cel_total; c++)
- decodeRLE(&rle_ptr, &pix_ptr, cc_pos[c] + 8, cc_lengths[c]);
+ *rleData = rleSeeker;
+ *pixelData = pixelSeeker;
+}
- if (pal_offset) {
- *writer++ = 'P';
- *writer++ = 'A';
- *writer++ = 'L';
+/**
+ * Seeks past a cel's RLE data without decoding.
+ * Used to seek past all RLE data to locate the start of pixel data.
+ */
+void DecompressorLZW::skipRLE(byte **rleData, int decodedSize) {
+ int pos = 0;
+ byte *rleSeeker = *rleData;
- for (c = 0; c < 256; c++)
- *writer++ = c;
+ while (pos < decodedSize) {
+ byte currentByte = *(rleSeeker++);
+ pos++;
- seeker -= 4; /* The missing four. Don't ask why. */
- memcpy(writer, seeker, 4*256 + 4);
+ byte upperBits = (currentByte & 0xc0);
+ if (upperBits <= 0x40) { // 00, 40
+ pos += currentByte;
+ } else if (upperBits == 0x80) {
+ pos++;
+ }
}
- free(cc_pos);
- free(cc_lengths);
+ *rleData = rleSeeker;
}
//----------------------------------------------
diff --git a/engines/sci/resource/decompressor.h b/engines/sci/resource/decompressor.h
index 8d16b4fb88e..750d2da702c 100644
--- a/engines/sci/resource/decompressor.h
+++ b/engines/sci/resource/decompressor.h
@@ -143,7 +143,6 @@ protected:
/**
* LZW decompressor for SCI0/01/1
- * TODO: Clean-up post-processing functions
*/
class DecompressorLZW : public Decompressor {
public:
@@ -153,12 +152,11 @@ public:
protected:
int unpackLZW(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
- // functions to post-process view and pic resources
- void reorderPic(byte *src, byte *dest, int dsize);
- void reorderView(byte *src, byte *dest);
- void decodeRLE(byte **rledata, byte **pixeldata, byte *outbuffer, int size);
- int getRLEsize(byte *rledata, int dsize);
- void buildCelHeaders(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max);
+ // post-processing functions for view and pic resources
+ static void unpackView(byte *src, byte *dest);
+ static void unpackPic(byte *src, byte *dest, int unpackedSize);
+ static void decodeRLE(byte **rleData, byte **pixelData, byte *dest, int decodedSize);
+ static void skipRLE(byte **rleData, int decodedSize);
ResourceCompression _compression;
};
Commit: 79febe2586114757c7a960a4ab5e0692a10d746e
https://github.com/scummvm/scummvm/commit/79febe2586114757c7a960a4ab5e0692a10d746e
Author: sluicebox (22204938+sluicebox at users.noreply.github.com)
Date: 2026-07-15T17:38:28+03:00
Commit Message:
SCI: Cleanup decompressor code
Changed paths:
engines/sci/resource/decompressor.cpp
engines/sci/resource/decompressor.h
diff --git a/engines/sci/resource/decompressor.cpp b/engines/sci/resource/decompressor.cpp
index 45430285f87..46475ddc633 100644
--- a/engines/sci/resource/decompressor.cpp
+++ b/engines/sci/resource/decompressor.cpp
@@ -19,8 +19,6 @@
*
*/
-// Resource library
-
#include "common/compression/dcl.h"
#include "common/util.h"
#include "common/endian.h"
@@ -32,18 +30,13 @@
#include "sci/resource/resource.h"
namespace Sci {
+
int Decompressor::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
- while (nPacked && !(src->eos() || src->err())) {
- uint32 chunk = MIN<uint32>(1024, nPacked);
- src->read(dest, chunk);
- nPacked -= chunk;
- dest += chunk;
- }
- return (src->eos() || src->err()) ? 1 : 0;
+ uint32 bytesRead = src->read(dest, nPacked);
+ return (bytesRead == nPacked) ? SCI_ERROR_NONE : SCI_ERROR_IO_ERROR;
}
-void Decompressor::init(Common::ReadStream *src, byte *dest, uint32 nPacked,
- uint32 nUnpacked) {
+void Decompressor::init(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
_src = src;
_dest = dest;
_szPacked = nPacked;
@@ -100,26 +93,25 @@ byte Decompressor::getByteLSB() {
void Decompressor::putByte(byte b) {
_dest[_dwWrote++] = b;
}
+
//-------------------------------
// Huffman decompressor
//-------------------------------
-int DecompressorHuffman::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked,
- uint32 nUnpacked) {
+
+int DecompressorHuffman::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
init(src, dest, nPacked, nUnpacked);
- byte numnodes;
- int16 c;
- uint16 terminator;
- numnodes = _src->readByte();
- terminator = _src->readByte() | 0x100;
+ byte numnodes = _src->readByte();
+ uint16 terminator = _src->readByte() | 0x100;
_nodes = new byte [numnodes << 1];
_src->read(_nodes, numnodes << 1);
+ int16 c;
while ((c = getc2()) != terminator && (c >= 0) && !isFinished())
putByte(c);
delete[] _nodes;
- return _dwWrote == _szUnpacked ? 0 : 1;
+ return (_dwWrote == _szUnpacked) ? SCI_ERROR_NONE : SCI_ERROR_DECOMPRESSION_ERROR;
}
int16 DecompressorHuffman::getc2() {
@@ -498,8 +490,7 @@ void DecompressorLZW::skipRLE(byte **rleData, int decodedSize) {
// DCL decompressor for SCI1.1
//----------------------------------------------
-int DecompressorDCL::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked,
- uint32 nUnpacked) {
+int DecompressorDCL::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
return Common::decompressDCL(src, dest, nPacked, nUnpacked) ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
}
@@ -510,6 +501,7 @@ int DecompressorDCL::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked,
// Based on Andre Beck's code from
// https://web.archive.org/web/20070817214826/http://micky.ibh.de/~beck/stuff/lzs4i4l/
//----------------------------------------------
+
int DecompressorLZS::unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) {
init(src, dest, nPacked, nUnpacked);
return unpackLZS();
@@ -541,7 +533,7 @@ int DecompressorLZS::unpackLZS() {
} else // Literal byte follows
putByte(getByteMSB());
} // end of while ()
- return _dwWrote == _szUnpacked ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
+ return (_dwWrote == _szUnpacked) ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
}
uint32 DecompressorLZS::getCompLen() {
diff --git a/engines/sci/resource/decompressor.h b/engines/sci/resource/decompressor.h
index 750d2da702c..77742b9729e 100644
--- a/engines/sci/resource/decompressor.h
+++ b/engines/sci/resource/decompressor.h
@@ -33,15 +33,15 @@ namespace Sci {
enum ResourceCompression {
kCompUnknown = -1,
kCompNone = 0,
- kCompLZW,
- kCompHuffman,
- kCompLZW1, // LZW-like compression used in SCI01 and SCI1
- kCompLZW1View, // Comp3 + view Post-processing
- kCompLZW1Pic, // Comp3 + pic Post-processing
+ kCompLZW, // LZW compression used in SCI0
+ kCompHuffman, // Huffman compression used for vector pics
+ kCompLZW1, // LZW compression used in SCI01 and SCI1
+ kCompLZW1View, // LZW + view post-processing
+ kCompLZW1Pic, // LZW + pic post-processing
+ kCompDCL // SCI11
#ifdef ENABLE_SCI32
- kCompSTACpack, // ? Used in SCI32
+, kCompSTACpack // SCI32
#endif
- kCompDCL
};
/**
@@ -63,7 +63,11 @@ public:
virtual ~Decompressor() {}
-
+ /**
+ * Unpack data from source stream to destination buffer.
+ *
+ * @return SCI_ERROR_NONE on success, non-zero on error
+ */
virtual int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
protected:
@@ -73,7 +77,6 @@ protected:
* @param dest destination stream to write to
* @param nPacked size of packed data
* @param nUnpacket size of unpacked data
- * @return 0 on success, non-zero on error
*/
virtual void init(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
@@ -107,7 +110,6 @@ protected:
* Write one byte into _dest stream
* @param b byte to put
*/
-
virtual void putByte(byte b);
/**
@@ -170,17 +172,20 @@ public:
};
#ifdef ENABLE_SCI32
+
/**
* STACpack decompressor for SCI32
*/
class DecompressorLZS : public Decompressor {
public:
int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked) override;
+
protected:
int unpackLZS();
uint32 getCompLen();
void copyComp(int offs, uint32 clen);
};
+
#endif
} // End of namespace Sci
More information about the Scummvm-git-logs
mailing list