コード例 #1
0
ファイル: HuffmanCodec.cpp プロジェクト: corelon/paco
int HuffmanCodec::decode( int* raw,
                          int rawCapacity,
                          BitDecoder* source )
{
	/** read header
	  */
	int rawFill = source ->readUIntVlc();
	int rawMin = source->readIntVlc();
	int rawMax = source->readIntVlc();
	int encodingFlag = source->readBit();

	if (rawFill > rawCapacity)
		FTL_THROW(StreamSemanticException, "Decoding buffer of insufficient size provided.");

	/** optional fallback to raw data transmission
	  */
	if (encodingFlag == 0)
	{
		const int bits = ilog2(rawMax - rawMin + 1);
		for (int i = 0; i < rawFill; ++i)
			raw[i] = int(source->readUIntVlc(bits)) + rawMin;
		return rawFill;
	}
	
	/** read frequency table
	  */
	reset();
	int diversity = source ->readUIntVlc();
	for (int i = 0; i < diversity; ++i)
	{
		int value = source->readUIntVlc();
		int count = source->readUIntVlc();
		addSymbol(value, count);
	}

	/** generate code table
	  */
	generateCodeTable();
	
	/** decode symbols
	  */
	for (int i = 0; i < rawFill; ++i)
	{
		SymbolNode* sym = codeTableRoot_;
		while (sym->leftChild)
			sym = (source->readBit()) ?  sym->rightChild : sym->leftChild;
		raw[i] = sym->value + rawMin;
	}

	return rawFill;
}
コード例 #2
0
ファイル: mktables.c プロジェクト: AlexSnet/libz80
void generateCode (void)
{
	FILE* spec, *opcodes, *code, *table;
	
	/* ----- Read the specification ----- */
	printf("Reading specification...");

	spec = openOrDie(OPCODES_SPEC, "rb");
	if (!readSpec(spec))
		fatal("Error reading the specification");	
	fclose(spec);
	printf("done\n");

	opcodes = openOrDie(OPCODES_LIST, "rb");
	code = openOrDie(OPCODES_IMPL, "wb");
		
	generateCodeTable(opcodes, code);
	
	fclose(opcodes);
	fclose(code);
}
コード例 #3
0
ファイル: HuffmanCodec.cpp プロジェクト: corelon/paco
void HuffmanCodec::encode(BitEncoder* sink, int* raw, int rawFill, bool* userFallback)
{
	/** determine dynamic range (min, max)
	  */
	int rawMin = raw[0];
	int rawMax = raw[0];
	{
		for (int i = 1; i < rawFill; ++i)
		{
			int x = raw[i];
			if (x < rawMin) rawMin = x;
			else if (x > rawMax) rawMax = x;
		}
	}

	/** optional fallback to raw data transmission
	  */
	if (rawMax - rawMin + 1 > rawDynamicRange_)
	{
#ifdef FTL_HUFFMANCODEC_PROFILING
		print(
			"Fallback to unencoded transmission, because out of dynamic range.\n"
			"    (rawMax - rawMin + 1, rawDynamicRange_) = (%%, %%)\n",
			(rawMax - rawMin + 1), rawDynamicRange_
		);
#endif // FTL_HUFFMANCODEC_PROFILING
		if (!userFallback)
			writeRawFrame(sink, raw, rawFill, rawMin, rawMax);
		else
			*userFallback = true;
		return;
	}
	
	/** determine symbol frequencies
	  */
	reset();
	for (int i = 0; (i < rawFill) && (codeTableFill_ < rawDiversity_); ++i)
	{
		int x = raw[i] - rawMin;
		if (!codeMap_[x].symbol)
			addSymbol(x, 0);
		++codeMap_[x].symbol->count;
	}

	/** optional fallback to raw data transmission
	  */
	if (codeTableFill_ == rawDiversity_)
	{
		if (!userFallback)
			writeRawFrame(sink, raw, rawFill, rawMin, rawMax);
		else
			*userFallback = true;
		return;
	}

	/** generate code table
	  */
	int diversity = codeTableFill_;
	generateCodeTable();

#ifdef FTL_HUFFMANCODEC_DEBUG_STATISTICS
	for (int i = 0; i < diversity; ++i)
	{
		FTL_DEBUG << i << ": H(" << codeTable_[i].value << ") = " << codeTable_[i].count << endl;
	}
#endif

	/** determine output size
	  */
	int tableSize = 0;
	int outSize = 1;    // encoding flag
	outSize += BitEncoder::bitsPerUIntVlc(rawFill);
	outSize += BitEncoder::bitsPerUIntVlc(rawMin);
	tableSize += BitEncoder::bitsPerUIntVlc(diversity);
	for (int i = 0; i < diversity; ++i)
	{
		tableSize += BitEncoder::bitsPerUIntVlc(codeTable_[i].value);
		tableSize += BitEncoder::bitsPerUIntVlc(codeTable_[i].count);
		SymbolNode* sym = codeTable_ + i;
		int len = 0;
		while ((sym = sym->parent) != 0) ++len;
		outSize += len * codeTable_[i].count;
	}
	
	outSize += tableSize;
	int outSizeBytes = outSize / 8 + (outSize % 8 != 0);

#ifdef FTL_HUFFMANCODEC_PROFILING
	print(
		"diversity, outSize, table weight = %%, %%, %%\n",
		diversity, outSize/8, double(tableSize) / outSize
	);
#endif // FTL_HUFFMANCODEC_PROFILING

	/** optional fallback to raw data transmission
	  */
	if (outSizeBytes > encodedCapacity(rawFill, rawMax-rawMin+1))
	{
#ifdef FTL_HUFFMANCODEC_PROFILING
		print("fallback to unencoded transmission\n");
#endif // FTL_HUFFMANCODEC_PROFILING
		if (!userFallback)
			writeRawFrame(sink, raw, rawFill, rawMin, rawMax);
		else
			*userFallback = true;
		return;
	}

	if (userFallback)
		*userFallback = false;
	
	/** write header
	  */
	sink->writeUIntVlc(rawFill);
	sink->writeIntVlc(rawMin);
	sink->writeIntVlc(rawMax);
	sink->writeBit(1);    // encoding flag
	
	/** write frequency table
	  */
	sink->writeUIntVlc(diversity);
	for (int i = 0; i < diversity; ++i)
	{
		sink->writeUIntVlc(codeTable_[i].value);
		sink->writeUIntVlc(codeTable_[i].count);
	}

	/** encode symbols
	  */
	for (int i = 0; i < rawFill; ++i)
	{

		int x = raw[i] - rawMin;
		
		SymbolNode* sym = codeMap_[x].symbol;
		bitStack_.clear();
		while (sym->parent)
		{
			SymbolNode* parent = sym->parent;
			bitStack_.push(parent->rightChild == sym);
			sym = parent;
		}
		while (bitStack_.fill() > 0)
			sink->writeBit(bitStack_.pop());
	}
}