1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
/* gzio.c - decompression support for gzip */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 1999,2005,2006,2007,2009 Free Software Foundation, Inc.
*
* GRUB 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 3 of the License, or
* (at your option) any later version.
*
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Most of this file was originally the source file "inflate.c", written
* by Mark Adler. It has been very heavily modified. In particular, the
* original would run through the whole file at once, and this version can
* be stopped and restarted on any boundary during the decompression process.
*
* The license and header comments that file are included here.
*/
/* inflate.c -- Not copyrighted 1992 by Mark Adler
version c10p1, 10 January 1993 */
/* You can do whatever you like with this source file, though I would
prefer that if you modify it and redistribute it that you include
comments to that effect with your name and the date. Thank you.
*/
#include "common/scummsys.h"
#include "common/stream.h"
#include "common/ptr.h"
namespace Common {
/* The state stored in filesystem-specific data. */
class GzioReadStream : public Common::SeekableReadStream
{
public:
static GzioReadStream* openClickteam(Common::SeekableReadStream *parent, uint64 uncompressed_size, DisposeAfterUse::Flag disposeParent = DisposeAfterUse::NO);
static GzioReadStream* openDeflate(Common::SeekableReadStream *parent, uint64 uncompressed_size, DisposeAfterUse::Flag disposeParent = DisposeAfterUse::NO);
static GzioReadStream* openZlib(Common::SeekableReadStream *parent, uint64 uncompressed_size, DisposeAfterUse::Flag disposeParent = DisposeAfterUse::NO);
static int32 clickteamDecompress (byte *outbuf, uint32 outsize, byte *inbuf, uint32 insize, int64 off = 0);
static int32 deflateDecompress (byte *outbuf, uint32 outsize, byte *inbuf, uint32 insize, int64 off = 0);
static int32 zlibDecompress (byte *outbuf, uint32 outsize, byte *inbuf, uint32 insize, int64 off = 0);
int32 readAtOffset(int64 offset, byte *buf, uint32 len);
uint32 read(void *dataPtr, uint32 dataSize) override;
bool eos() const override { return _eos; }
bool err() const override { return _err; }
void clearErr() override { _eos = false; _err = false; }
int64 pos() const override { return _streamPos; }
int64 size() const override { return _uncompressedSize; }
bool seek(int64 offs, int whence = SEEK_SET) override;
private:
/*
* Window Size
*
* This must be a power of two, and at least 32K for zip's deflate method
*/
static const int WSIZE = 0x8000;
static const int INBUFSIZ = 0x2000;
/* If input is in memory following fields are used instead of file. */
Common::DisposablePtr<Common::SeekableReadStream> _input;
/* The offset at which the data starts in the underlying file. */
int64 _dataOffset;
/* The type of current block. */
int _blockType;
/* The length of current block. */
int _blockLen;
/* The flag of the last block. */
int _lastBlock;
/* The flag of codes. */
int _codeState;
/* The length of a copy. */
unsigned _inflateN;
/* The index of a copy. */
unsigned _inflateD;
/* The bit buffer. */
unsigned long _bb;
/* The bits in the bit buffer. */
unsigned _bk;
/* The sliding window in uncompressed data. */
uint8 _slide[WSIZE];
/* Current position in the slide. */
unsigned _wp;
/* The literal/length code table. */
struct huft *_tl;
/* The distance code table. */
struct huft *_td;
/* The lookup bits for the literal/length code table. */
int _bl;
/* The lookup bits for the distance code table. */
int _bd;
/* The original offset value. */
int64 _savedOffset;
bool _err;
/* The input buffer. */
byte _inbuf[INBUFSIZ];
int _inbufD;
int _inbufSize;
uint64 _uncompressedSize;
uint64 _streamPos;
bool _eos;
enum class Mode { ZLIB, CLICKTEAM } _mode;
GzioReadStream(Common::SeekableReadStream *parent, DisposeAfterUse::Flag disposeParent, uint64 uncompressedSize, Mode mode) :
_dataOffset(0), _blockType(0), _blockLen(0),
_lastBlock(0), _codeState (0), _inflateN(0),
_inflateD(0), _bb(0), _bk(0), _wp(0), _tl(nullptr),
_td(nullptr), _bl(0),
_bd(0), _savedOffset(0), _err(false), _mode(mode), _input(parent, disposeParent),
_inbufD(0), _inbufSize(0), _uncompressedSize(uncompressedSize), _streamPos(0), _eos(false) {}
void inflate_window();
void initialize_tables();
bool test_zlib_header();
void get_new_block();
byte parentGetByte();
void parentSeek(int64 off);
void init_fixed_block();
int inflate_codes_in_window();
void init_dynamic_block ();
void init_stored_block ();
};
}
|