mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-22 09:49:11 +00:00
200 lines
5.2 KiB
C++
200 lines
5.2 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#ifndef SCI_DECOMPRESSOR_H
|
|
#define SCI_DECOMPRESSOR_H
|
|
|
|
#include "common/scummsys.h"
|
|
|
|
namespace Common {
|
|
class ReadStream;
|
|
}
|
|
|
|
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
|
|
#ifdef ENABLE_SCI32
|
|
kCompSTACpack, // ? Used in SCI32
|
|
#endif
|
|
kCompDCL
|
|
};
|
|
|
|
/**
|
|
* Base class for decompressors.
|
|
* Simply copies nPacked bytes from src to dest.
|
|
*/
|
|
class Decompressor {
|
|
public:
|
|
Decompressor() {}
|
|
virtual ~Decompressor() {}
|
|
|
|
|
|
virtual int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
|
|
|
|
protected:
|
|
/**
|
|
* Initialize decompressor.
|
|
* @param src source stream to read from
|
|
* @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);
|
|
|
|
/**
|
|
* Get a number of bits from _src stream, starting with the most
|
|
* significant unread bit of the current four byte block.
|
|
* @param n number of bits to get
|
|
* @return n-bits number
|
|
*/
|
|
uint32 getBitsMSB(int n);
|
|
|
|
/**
|
|
* Get a number of bits from _src stream, starting with the least
|
|
* significant unread bit of the current four byte block.
|
|
* @param n number of bits to get
|
|
* @return n-bits number
|
|
*/
|
|
uint32 getBitsLSB(int n);
|
|
|
|
/**
|
|
* Get one byte from _src stream.
|
|
* @return byte
|
|
*/
|
|
byte getByteMSB();
|
|
byte getByteLSB();
|
|
|
|
void fetchBitsMSB();
|
|
void fetchBitsLSB();
|
|
|
|
/**
|
|
* Write one byte into _dest stream
|
|
* @param b byte to put
|
|
*/
|
|
|
|
virtual void putByte(byte b);
|
|
|
|
/**
|
|
* Returns true if all expected data has been unpacked to _dest
|
|
* and there is no more data in _src.
|
|
*/
|
|
bool isFinished() {
|
|
return (_dwWrote == _szUnpacked) && (_dwRead >= _szPacked);
|
|
}
|
|
|
|
uint32 _dwBits; ///< bits buffer
|
|
byte _nBits; ///< number of unread bits in _dwBits
|
|
uint32 _szPacked; ///< size of the compressed data
|
|
uint32 _szUnpacked; ///< size of the decompressed data
|
|
uint32 _dwRead; ///< number of bytes read from _src
|
|
uint32 _dwWrote; ///< number of bytes written to _dest
|
|
Common::ReadStream *_src;
|
|
byte *_dest;
|
|
};
|
|
|
|
/**
|
|
* Huffman decompressor
|
|
*/
|
|
class DecompressorHuffman : public Decompressor {
|
|
public:
|
|
int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
|
|
|
|
protected:
|
|
int16 getc2();
|
|
|
|
byte *_nodes;
|
|
};
|
|
|
|
/**
|
|
* LZW-like decompressor for SCI01/SCI1.
|
|
* TODO: Needs clean-up of post-processing fncs
|
|
*/
|
|
class DecompressorLZW : public Decompressor {
|
|
public:
|
|
DecompressorLZW(int nCompression) {
|
|
_compression = nCompression;
|
|
}
|
|
void init(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
|
|
int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
|
|
|
|
protected:
|
|
enum {
|
|
PIC_OPX_EMBEDDED_VIEW = 1,
|
|
PIC_OPX_SET_PALETTE = 2,
|
|
PIC_OP_OPX = 0xfe
|
|
};
|
|
// unpacking procedures
|
|
// TODO: unpackLZW and unpackLZW1 are similar and should be merged
|
|
int unpackLZW1(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
|
|
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);
|
|
|
|
// decompressor data
|
|
struct Tokenlist {
|
|
byte data;
|
|
uint16 next;
|
|
};
|
|
uint16 _numbits;
|
|
uint16 _curtoken, _endtoken;
|
|
int _compression;
|
|
};
|
|
|
|
/**
|
|
* DCL decompressor for SCI1.1
|
|
*/
|
|
class DecompressorDCL : public Decompressor {
|
|
public:
|
|
int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
|
|
};
|
|
|
|
#ifdef ENABLE_SCI32
|
|
/**
|
|
* STACpack decompressor for SCI32
|
|
*/
|
|
class DecompressorLZS : public Decompressor {
|
|
public:
|
|
int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked);
|
|
protected:
|
|
int unpackLZS();
|
|
uint32 getCompLen();
|
|
void copyComp(int offs, uint32 clen);
|
|
};
|
|
#endif
|
|
|
|
} // End of namespace Sci
|
|
|
|
#endif // SCI_SCICORE_DECOMPRESSOR_H
|