Exemple #1
0
uint32 BigHuffmanTree::getCode(Common::BitStream &bs) {
	byte peek = bs.peekBits(MIN<uint32>(bs.size() - bs.pos(), 8));
	uint32 *p = &_tree[_prefixtree[peek]];
	bs.skip(_prefixlength[peek]);

	while (*p & SMK_NODE) {
		if (bs.getBit())
			p += (*p) & ~SMK_NODE;
		p++;
	}

	uint32 v = *p;
	if (v != _tree[_last[0]]) {
		_tree[_last[2]] = _tree[_last[1]];
		_tree[_last[1]] = _tree[_last[0]];
		_tree[_last[0]] = v;
	}

	return v;
}
Exemple #2
0
void CodebookLibrary::rebuild(Common::BitStream &bis, size_t size, Common::BitStreamWriter &bos) {
	const uint32 id = 0x564342;
	const uint16 dimensions = bis.getBits(4);
	const uint32 entries = bis.getBits(14);

	bos.putBits(id, 24);
	bos.putBits(dimensions, 16);
	bos.putBits(entries, 24);

	const bool ordered = bis.getBit();
	bos.putBit(ordered);

	if (ordered) {
		const uint8 initialLength = bis.getBits(5);
		bos.putBits(initialLength, 5);

		uint32 currentEntry = 0;
		while (currentEntry < entries) {
			const size_t bitCount = Common::intLog2(entries - currentEntry) + 1;
			const uint32 number = bis.getBits(bitCount);
			bos.putBits(number, bitCount);

			currentEntry += number;
		}

		if (currentEntry > entries)
			throw Common::Exception("CodebookLibrary::rebuild(): Current entry out of range");

	} else {

		const uint8 codewordLengthLength = bis.getBits(3);
		const bool sparse = bis.getBit();

		if ((codewordLengthLength == 0) || (codewordLengthLength > 5))
			throw Common::Exception("CodebookLibrary::rebuild(): Nonsense codeword length");

		bos.putBit(sparse);

		for (size_t i = 0; i < entries; i++) {
			bool present = true;

			if (sparse) {
				present = bis.getBit();
				bos.putBit(present);
			}

			if (present)
				bos.putBits(bis.getBits(codewordLengthLength), 5);
		}

	}

	const uint8 lookupType = bis.getBits(1);
	bos.putBits(lookupType, 4);

	if        (lookupType == 0) {
	} else if (lookupType == 1) {

		const uint32 min = bis.getBits(32);
		const uint32 max = bis.getBits(32);

		const uint8 valueLength = bis.getBits(4) + 1;
		const bool sequenceFlag = bis.getBit();

		bos.putBits(min, 32);
		bos.putBits(max, 32);

		bos.putBits(valueLength - 1, 4);
		bos.putBit(sequenceFlag);

		const size_t quantVals = bookMapType1QuantVals(entries, dimensions);
		for (size_t i = 0; i < quantVals; i++)
			bos.putBits(bis.getBits(valueLength), valueLength);
	}

	if ((size != 0) && (((bis.pos() / 8) + 1) != size ))
		throw Common::Exception("CodebookLibrary::rebuild(): Size mismatch: %s != %s",
		                        Common::composeString((bis.pos() / 8) + 1).c_str(),
		                        Common::composeString(size).c_str());
}