mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 22:28:10 +00:00
Some clean-up of DecompressorComp3 class
svn-id: r39323
This commit is contained in:
parent
e2d33d81ab
commit
738160d17a
@ -35,18 +35,20 @@ namespace Sci {
|
|||||||
|
|
||||||
int Decompressor::unpack(Common::ReadStream *src, Common::WriteStream *dest, uint32 nPacked,
|
int Decompressor::unpack(Common::ReadStream *src, Common::WriteStream *dest, uint32 nPacked,
|
||||||
uint32 nUnpacked) {
|
uint32 nUnpacked) {
|
||||||
init(src, dest, nPacked, nUnpacked);
|
return copyBytes(src, dest, nPacked);
|
||||||
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;
|
|
||||||
}
|
|
||||||
return _src->ioFailed() || _dest->ioFailed() ? 1 : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Decompressor::copyBytes(Common::ReadStream *src, Common::WriteStream *dest, uint32 nSize) {
|
||||||
|
byte buff[1024];
|
||||||
|
uint32 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;
|
||||||
|
}
|
||||||
void Decompressor::init(Common::ReadStream *src, Common::WriteStream *dest, uint32 nPacked,
|
void Decompressor::init(Common::ReadStream *src, Common::WriteStream *dest, uint32 nPacked,
|
||||||
uint32 nUnpacked) {
|
uint32 nUnpacked) {
|
||||||
_src = src;
|
_src = src;
|
||||||
@ -147,6 +149,7 @@ int DecompressorComp3::unpack(Common::ReadStream *src, Common::WriteStream *dest
|
|||||||
byte *buffer = NULL;
|
byte *buffer = NULL;
|
||||||
byte *buffer2 = NULL;
|
byte *buffer2 = NULL;
|
||||||
Common::MemoryWriteStream *pBuff = NULL;
|
Common::MemoryWriteStream *pBuff = NULL;
|
||||||
|
Common::MemoryReadStream *pBuffIn = NULL;
|
||||||
|
|
||||||
switch (_compression) {
|
switch (_compression) {
|
||||||
case kComp3: // Comp3 compression
|
case kComp3: // Comp3 compression
|
||||||
@ -155,16 +158,21 @@ int DecompressorComp3::unpack(Common::ReadStream *src, Common::WriteStream *dest
|
|||||||
case kComp3View:
|
case kComp3View:
|
||||||
case kComp3Pic:
|
case kComp3Pic:
|
||||||
buffer = new byte[nUnpacked];
|
buffer = new byte[nUnpacked];
|
||||||
buffer2 = new byte[nUnpacked];
|
|
||||||
pBuff = new Common::MemoryWriteStream(buffer, nUnpacked);
|
pBuff = new Common::MemoryWriteStream(buffer, nUnpacked);
|
||||||
doUnpack(src, pBuff, nPacked, nUnpacked);
|
doUnpack(src, pBuff, nPacked, nUnpacked);
|
||||||
if (_compression == kComp3View)
|
if (_compression == kComp3View) {
|
||||||
|
buffer2 = new byte[nUnpacked];
|
||||||
view_reorder(buffer, buffer2);
|
view_reorder(buffer, buffer2);
|
||||||
else
|
dest->write(buffer2, nUnpacked);
|
||||||
pic_reorder(buffer, buffer2, nUnpacked);
|
}
|
||||||
dest->write(buffer2, nUnpacked);
|
else {
|
||||||
|
pBuffIn = new Common::MemoryReadStream(buffer, nUnpacked);
|
||||||
|
reorderPic(pBuffIn, dest, nUnpacked);
|
||||||
|
}
|
||||||
delete[] buffer2;
|
delete[] buffer2;
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
delete pBuff;
|
||||||
|
delete pBuffIn;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -243,36 +251,32 @@ int DecompressorComp3::doUnpack(Common::ReadStream *src, Common::WriteStream *de
|
|||||||
return _dwWrote ? 0 : 1;
|
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 PAL_SIZE 1284
|
||||||
#define CEL_HEADER_SIZE 7
|
|
||||||
#define EXTRA_MAGIC_SIZE 15
|
#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) {
|
void DecompressorComp3::decode_rle(byte **rledata, byte **pixeldata, byte *outbuffer, int size) {
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
@ -339,80 +343,53 @@ int DecompressorComp3::rle_size(byte *rledata, int dsize) {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecompressorComp3::pic_reorder(byte *inbuffer, byte *outbuffer, int dsize) {
|
void DecompressorComp3::reorderPic(Common::ReadStream *src, Common::WriteStream *dest, int dsize) {
|
||||||
int view_size;
|
int view_size, view_start, cdata_size;
|
||||||
int view_start;
|
byte viewdata[7];
|
||||||
int cdata_size;
|
byte *cdata = NULL;
|
||||||
int i;
|
byte *extra = NULL;
|
||||||
byte *seeker = inbuffer;
|
|
||||||
byte *writer;
|
|
||||||
char viewdata[CEL_HEADER_SIZE];
|
|
||||||
byte *cdata, *cdata_start;
|
|
||||||
|
|
||||||
writer = outbuffer;
|
// Setting palette
|
||||||
|
dest->writeByte(PIC_OP_OPX);
|
||||||
|
dest->writeByte(PIC_OPX_SET_PALETTE);
|
||||||
|
|
||||||
*writer++ = PIC_OP_OPX;
|
for (int i = 0; i < 256; i++) // Palette translation map
|
||||||
*writer++ = PIC_OPX_SET_PALETTE;
|
dest->writeByte(i);
|
||||||
|
dest->writeUint32LE(0); //Palette timestamp
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) /* Palette translation map */
|
view_size = src->readUint16LE();
|
||||||
*writer++ = i;
|
view_start = src->readUint16LE();
|
||||||
|
cdata_size = src->readUint16LE();
|
||||||
WRITE_LE_UINT16(writer, 0); /* Palette stamp */
|
src->read(viewdata, sizeof(viewdata));
|
||||||
writer += 2;
|
// Copy palette colors
|
||||||
WRITE_LE_UINT16(writer, 0);
|
copyBytes(src, dest, 1024);
|
||||||
writer += 2;
|
// copy drawing opcodes
|
||||||
|
if (view_start != PAL_SIZE + 2)
|
||||||
view_size = READ_LE_UINT16(seeker);
|
copyBytes(src, dest, view_start - PAL_SIZE - 2);
|
||||||
seeker += 2;
|
// storing extra opcodes to be pasted after the cel
|
||||||
view_start = READ_LE_UINT16(seeker);
|
if (dsize != view_start + EXTRA_MAGIC_SIZE + view_size) {
|
||||||
seeker += 2;
|
extra = new byte[dsize - view_size - view_start - EXTRA_MAGIC_SIZE];
|
||||||
cdata_size = READ_LE_UINT16(seeker);
|
src->read(extra, dsize - view_size - view_start - EXTRA_MAGIC_SIZE);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
// Writing picture cel opcode and header
|
||||||
if (dsize != view_start+EXTRA_MAGIC_SIZE+view_size) {
|
dest->writeByte(PIC_OP_OPX);
|
||||||
memcpy(outbuffer+view_size+view_start+EXTRA_MAGIC_SIZE, seeker,
|
dest->writeByte(PIC_OPX_EMBEDDED_VIEW);
|
||||||
dsize-view_size-view_start-EXTRA_MAGIC_SIZE);
|
dest->writeByte(0);
|
||||||
seeker += dsize-view_size-view_start-EXTRA_MAGIC_SIZE;
|
dest->writeUint16LE(0);
|
||||||
}
|
dest->writeUint16LE(view_size + 8);
|
||||||
|
dest->write(viewdata, sizeof(viewdata));
|
||||||
cdata_start = cdata = (byte *)malloc(cdata_size);
|
dest->writeByte(0);
|
||||||
memcpy(cdata, seeker, cdata_size);
|
// Unpacking RLE cel data
|
||||||
seeker += cdata_size;
|
cdata = new byte[cdata_size];
|
||||||
|
src->read(cdata, cdata_size);
|
||||||
writer = outbuffer + view_start;
|
decodeRLE(src, dest, cdata, view_size);
|
||||||
*writer++ = PIC_OP_OPX;
|
// writing stored extra opcodes
|
||||||
*writer++ = PIC_OPX_EMBEDDED_VIEW;
|
if (extra)
|
||||||
*writer++ = 0;
|
dest->write(extra, dsize - view_size - view_start - EXTRA_MAGIC_SIZE);
|
||||||
*writer++ = 0;
|
delete[] extra;
|
||||||
*writer++ = 0;
|
delete[] cdata;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VIEW_HEADER_COLORS_8BIT 0x80
|
|
||||||
|
|
||||||
void DecompressorComp3::build_cel_headers(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max) {
|
void DecompressorComp3::build_cel_headers(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max) {
|
||||||
for (int c = 0; c < max; c++) {
|
for (int c = 0; c < max; c++) {
|
||||||
memcpy(*writer, *seeker, 6);
|
memcpy(*writer, *seeker, 6);
|
||||||
|
@ -79,6 +79,7 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual void putByte(byte b);
|
virtual void putByte(byte b);
|
||||||
virtual void fetchBits();
|
virtual void fetchBits();
|
||||||
|
int copyBytes(Common::ReadStream *src, Common::WriteStream *dest, uint32 nSize);
|
||||||
|
|
||||||
uint32 _dwBits;
|
uint32 _dwBits;
|
||||||
byte _nBits;
|
byte _nBits;
|
||||||
@ -120,20 +121,27 @@ public:
|
|||||||
uint32 nUnpacked);
|
uint32 nUnpacked);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
enum {
|
||||||
|
PIC_OPX_EMBEDDED_VIEW = 1,
|
||||||
|
PIC_OPX_SET_PALETTE = 2,
|
||||||
|
PIC_OP_OPX = 0xfe,
|
||||||
|
};
|
||||||
// actual unpacking procedure
|
// actual unpacking procedure
|
||||||
int doUnpack(Common::ReadStream *src, Common::WriteStream *dest, uint32 nPacked,
|
int doUnpack(Common::ReadStream *src, Common::WriteStream *dest, uint32 nPacked,
|
||||||
uint32 nUnpacked);
|
uint32 nUnpacked);
|
||||||
// functions to post-process view and pic resources
|
// 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);
|
void decode_rle(byte **rledata, byte **pixeldata, byte *outbuffer, int size);
|
||||||
int rle_size(byte *rledata, int dsize);
|
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 build_cel_headers(byte **seeker, byte **writer, int celindex, int *cc_lengths, int max);
|
||||||
void view_reorder(byte *inbuffer, byte *outbuffer);
|
void view_reorder(byte *inbuffer, byte *outbuffer);
|
||||||
|
// decompressor data
|
||||||
struct tokenlist {
|
struct tokenlist {
|
||||||
byte data;
|
byte data;
|
||||||
uint16 next;
|
uint16 next;
|
||||||
} _tokens[0x1004];
|
} _tokens[0x1004];
|
||||||
byte _stak[0x1014];
|
byte _stak[0x1014];
|
||||||
byte _lastchar;
|
byte _lastchar;
|
||||||
uint16 _stakptr;
|
uint16 _stakptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user