/* 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. * * $URL$ * $Id$ * */ #ifndef SCI_SCICORE_DECOMPRESSOR_H #define SCI_SCICORE_DECOMPRESSOR_H #include "common/file.h" 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 kCompDCL, kCompSTACpack // ? Used in SCI32 }; //---------------------------------------------- // 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 (int) 0 on success, non-zero on error */ virtual void init(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked); //! get one bit from _src stream /** @return (bool) bit; */ bool getBitMSB(); bool getBitLSB(); //! get a number of bits from _src stream /** @param n - number of bits to get @return (uint32) n-bits number */ uint32 getBitsMSB(int n); uint32 getBitsLSB(int n); //! get one byte from _src stream /** @return (byte) byte */ byte getByteMSB(); byte getByteLSB(); void fetchBitsMSB(); void fetchBitsLSB(); //! put byte to _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; // # of bits in buffer uint32 _szPacked; uint32 _szUnpacked; uint32 _dwRead; // # of bytes read from _src uint32 _dwWrote; 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); protected: int unpackDCL(byte *dest); int huffman_lookup(int *tree); }; //---------------------------------------------- // STACpack decompressor for SCI32 //---------------------------------------------- class DecompressorLZS : public Decompressor { public: int unpack(Common::ReadStream *src, byte *dest, uint32 nPacked, uint32 nUnpacked); protected: int unpackLZS(); uint16 getCompLen(); void copyComp(int offs, int clen); }; } // End of namespace Sci #endif // SCI_SCICORE_DECOMPRESSOR_H