コード例 #1
0
ファイル: decompressor.cpp プロジェクト: St0rmcrow/scummvm
int DecompressorLZW::unpackLZW(Common::ReadStream *src, byte *dest, uint32 nPacked,
                                uint32 nUnpacked) {
	init(src, dest, nPacked, nUnpacked);

	uint16 token; // The last received value

	uint16 tokenlist[4096]; // pointers to dest[]
	uint16 tokenlengthlist[4096]; // char length of each token
	uint16 tokenlastlength = 0;

	while (!isFinished()) {
		token = getBitsLSB(_numbits);

		if (token == 0x101)
			return 0; // terminator
		if (token == 0x100) { // reset command
			_numbits = 9;
			_endtoken = 0x1FF;
			_curtoken = 0x0102;
		} else {
			if (token > 0xff) {
				if (token >= _curtoken) {
					warning("unpackLZW: Bad token %x", token);
					return SCI_ERROR_DECOMPRESSION_ERROR;
				}
				tokenlastlength = tokenlengthlist[token] + 1;
				if (_dwWrote + tokenlastlength > _szUnpacked) {
					// For me this seems a normal situation, It's necessary to handle it
					warning("unpackLZW: Trying to write beyond the end of array(len=%d, destctr=%d, tok_len=%d)",
					        _szUnpacked, _dwWrote, tokenlastlength);
					for (int i = 0; _dwWrote < _szUnpacked; i++)
						putByte(dest[tokenlist[token] + i]);
				} else
					for (int i = 0; i < tokenlastlength; i++)
						putByte(dest[tokenlist[token] + i]);
			} else {
				tokenlastlength = 1;
				if (_dwWrote >= _szUnpacked)
					warning("unpackLZW: Try to write single byte beyond end of array");
				else
					putByte(token);
			}
			if (_curtoken > _endtoken && _numbits < 12) {
				_numbits++;
				_endtoken = (_endtoken << 1) + 1;
			}
			if (_curtoken <= _endtoken) {
				tokenlist[_curtoken] = _dwWrote - tokenlastlength;
				tokenlengthlist[_curtoken] = tokenlastlength;
				_curtoken++;
			}

		}
	}

	return _dwWrote == _szUnpacked ? 0 : SCI_ERROR_DECOMPRESSION_ERROR;
}
コード例 #2
0
ファイル: decompressor.cpp プロジェクト: pdpdds/sglt
byte Decompressor::getByteLSB() {
	return getBitsLSB(8);
}