예제 #1
0
void HuffmanDecoder::Initialize(const unsigned int *codeBits, unsigned int nCodes)
{
    // the Huffman codes are represented in 3 ways in this code:
    //
    // 1. most significant code bit (i.e. top of code tree) in the least significant bit position
    // 2. most significant code bit (i.e. top of code tree) in the most significant bit position
    // 3. most significant code bit (i.e. top of code tree) in n-th least significant bit position,
    //    where n is the maximum code length for this code tree
    //
    // (1) is the way the codes come in from the deflate stream
    // (2) is used to sort codes so they can be binary searched
    // (3) is used in this function to compute codes from code lengths
    //
    // a code in representation (2) is called "normalized" here
    // The BitReverse() function is used to convert between (1) and (2)
    // The NormalizeCode() function is used to convert from (3) to (2)

    if (nCodes == 0)
        throw Err("null code");

    m_maxCodeBits = *std::max_element(codeBits, codeBits+nCodes);

    if (m_maxCodeBits > MAX_CODE_BITS)
        throw Err("code length exceeds maximum");

    if (m_maxCodeBits == 0)
        throw Err("null code");

    // count number of codes of each length
    SecBlockWithHint<unsigned int, 15+1> blCount(m_maxCodeBits+1);
    std::fill(blCount.begin(), blCount.end(), 0);
    unsigned int i;
    for (i=0; i<nCodes; i++)
        blCount[codeBits[i]]++;

    // compute the starting code of each length
    code_t code = 0;
    SecBlockWithHint<code_t, 15+1> nextCode(m_maxCodeBits+1);
    nextCode[1] = 0;
    for (i=2; i<=m_maxCodeBits; i++)
    {
        // compute this while checking for overflow: code = (code + blCount[i-1]) << 1
        if (code > code + blCount[i-1])
            throw Err("codes oversubscribed");
        code += blCount[i-1];
        if (code > (code << 1))
            throw Err("codes oversubscribed");
        code <<= 1;
        nextCode[i] = code;
    }

    if (code > (1 << m_maxCodeBits) - blCount[m_maxCodeBits])
        throw Err("codes oversubscribed");
    else if (m_maxCodeBits != 1 && code < (1 << m_maxCodeBits) - blCount[m_maxCodeBits])
        throw Err("codes incomplete");

    // compute a vector of <code, length, value> triples sorted by code
    m_codeToValue.resize(nCodes - blCount[0]);
    unsigned int j=0;
    for (i=0; i<nCodes; i++)
    {
        unsigned int len = codeBits[i];
        if (len != 0)
        {
            code = NormalizeCode(nextCode[len]++, len);
            m_codeToValue[j].code = code;
            m_codeToValue[j].len = len;
            m_codeToValue[j].value = i;
            j++;
        }
    }
    std::sort(m_codeToValue.begin(), m_codeToValue.end());

    // initialize the decoding cache
    m_cacheBits = STDMIN(9U, m_maxCodeBits);
    m_cacheMask = (1 << m_cacheBits) - 1;
    m_normalizedCacheMask = NormalizeCode(m_cacheMask, m_cacheBits);
    assert(m_normalizedCacheMask == BitReverse(m_cacheMask));

    if (m_cache.size() != size_t(1) << m_cacheBits)
        m_cache.resize(1 << m_cacheBits);

    for (i=0; i<m_cache.size(); i++)
        m_cache[i].type = 0;
}
예제 #2
0
파일: zinflate.cpp 프로젝트: mentat/nnim
void HuffmanDecoder::Initialize(const unsigned int *codeBits, unsigned int nCodes)
{
	if (nCodes == 0)
		throw Err("null code");

	m_maxCodeBits = *std::max_element(codeBits, codeBits+nCodes);

	if (m_maxCodeBits == 0)
		throw Err("null code");

	SecBlock<unsigned int> blCount(m_maxCodeBits+1);
	std::fill(blCount.Begin(), blCount.End(), 0);
	unsigned int i;
	for (i=0; i<nCodes; i++)
		blCount[codeBits[i]]++;

	code_t code = 0;
	SecBlock<code_t> nextCode(m_maxCodeBits+1);
	nextCode[1] = 0;
	for (i=2; i<=m_maxCodeBits; i++)
	{
		// compute this while checking for overflow: code = (code + blCount[i-1]) << 1
		if (code > code + blCount[i-1])
			throw Err("codes oversubscribed");
		code += blCount[i-1];
		if (code > (code << 1))
			throw Err("codes oversubscribed");
		code <<= 1;
		nextCode[i] = code;
	}

	if (code > (1 << m_maxCodeBits) - blCount[m_maxCodeBits])
		throw Err("codes oversubscribed");
	else if (m_maxCodeBits != 1 && code < (1 << m_maxCodeBits) - blCount[m_maxCodeBits])
		throw Err("codes incomplete");

	m_codeToValue.Resize(nCodes - blCount[0]);
	unsigned int j=0;
	for (i=0; i<nCodes; i++) 
	{
		unsigned int len = codeBits[i];
		if (len != 0)
		{
			code = NormalizeCode(nextCode[len]++, len);
			m_codeToValue[j].code = code;
			m_codeToValue[j].len = len;
			m_codeToValue[j].value = i;
			j++;
		}
	}
	std::sort(m_codeToValue.Begin(), m_codeToValue.End());

	m_cacheBits = STDMIN(9U, m_maxCodeBits);
	m_cacheMask = (1 << m_cacheBits) - 1;
	code_t leftoverMask = ~NormalizeCode(m_cacheMask, m_cacheBits);
	m_cache.Resize(1 << m_cacheBits);

	for (i=0; i<m_cache.size; i++)
	{
		code_t normalizedCode = bitReverse(i);
		const CodeInfo &codeInfo = *(std::upper_bound(m_codeToValue.Begin(), m_codeToValue.End(), normalizedCode, CodeLessThan)-1);
		if (codeInfo.len <= m_cacheBits)
		{
			m_cache[i].type = 0;
			m_cache[i].value = codeInfo.value;
			m_cache[i].len = codeInfo.len;
		}
		else
		{
			m_cache[i].begin = &codeInfo;
			const CodeInfo *last = std::upper_bound(m_codeToValue.Begin(), m_codeToValue.End(), normalizedCode + leftoverMask, CodeLessThan)-1;
			if (codeInfo.len == last->len)
			{
				m_cache[i].type = 1;
				m_cache[i].len = codeInfo.len;
			}
			else
			{
				m_cache[i].type = 2;
				m_cache[i].end = last+1;
			}
		}
	}
}