Пример #1
0
void Inflator::MessageEnd(int propagation)
{
	ProcessInput(true);
	if (!(m_state == PRE_STREAM || m_state == AFTER_END))
		throw UnexpectedEndErr();
	Filter::MessageEnd(propagation);
}
Пример #2
0
size_t Inflator::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
{
    if (!blocking)
        throw BlockingInputOnly("Inflator");

    LazyPutter lp(m_inQueue, inString, length);
    ProcessInput(messageEnd != 0);

    if (messageEnd)
        if (!(m_state == PRE_STREAM || m_state == AFTER_END))
            throw UnexpectedEndErr();

    Output(0, NULL, 0, messageEnd, blocking);
    return 0;
}
Пример #3
0
void Inflator::DecodeHeader()
{
    if (!m_reader.FillBuffer(3))
        throw UnexpectedEndErr();
    m_eof = m_reader.GetBits(1) != 0;
    m_blockType = (byte)m_reader.GetBits(2);
    switch (m_blockType)
    {
    case 0:	// stored
    {
        m_reader.SkipBits(m_reader.BitsBuffered() % 8);
        if (!m_reader.FillBuffer(32))
            throw UnexpectedEndErr();
        m_storedLen = (word16)m_reader.GetBits(16);
        word16 nlen = (word16)m_reader.GetBits(16);
        if (nlen != (word16)~m_storedLen)
            throw BadBlockErr();
        break;
    }
    case 1:	// fixed codes
        m_nextDecode = LITERAL;
        break;
    case 2:	// dynamic codes
    {
        if (!m_reader.FillBuffer(5+5+4))
            throw UnexpectedEndErr();
        unsigned int hlit = m_reader.GetBits(5);
        unsigned int hdist = m_reader.GetBits(5);
        unsigned int hclen = m_reader.GetBits(4);

        FixedSizeSecBlock<unsigned int, 286+32> codeLengths;
        unsigned int i;
        static const unsigned int border[] = {    // Order of the bit length code lengths
            16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
        };
        std::fill(codeLengths.begin(), codeLengths+19, 0);
        for (i=0; i<hclen+4; i++)
            codeLengths[border[i]] = m_reader.GetBits(3);

        try
        {
            HuffmanDecoder codeLengthDecoder(codeLengths, 19);
            for (i = 0; i < hlit+257+hdist+1; )
            {
                unsigned int k, count, repeater;
                bool result = codeLengthDecoder.Decode(m_reader, k);
                if (!result)
                    throw UnexpectedEndErr();
                if (k <= 15)
                {
                    count = 1;
                    repeater = k;
                }
                else switch (k)
                    {
                    case 16:
                        if (!m_reader.FillBuffer(2))
                            throw UnexpectedEndErr();
                        count = 3 + m_reader.GetBits(2);
                        if (i == 0)
                            throw BadBlockErr();
                        repeater = codeLengths[i-1];
                        break;
                    case 17:
                        if (!m_reader.FillBuffer(3))
                            throw UnexpectedEndErr();
                        count = 3 + m_reader.GetBits(3);
                        repeater = 0;
                        break;
                    case 18:
                        if (!m_reader.FillBuffer(7))
                            throw UnexpectedEndErr();
                        count = 11 + m_reader.GetBits(7);
                        repeater = 0;
                        break;
                    }
                if (i + count > hlit+257+hdist+1)
                    throw BadBlockErr();
                std::fill(codeLengths + i, codeLengths + i + count, repeater);
                i += count;
            }
            m_dynamicLiteralDecoder.Initialize(codeLengths, hlit+257);
            if (hdist == 0 && codeLengths[hlit+257] == 0)
            {
                if (hlit != 0)	// a single zero distance code length means all literals
                    throw BadBlockErr();
            }
            else
                m_dynamicDistanceDecoder.Initialize(codeLengths+hlit+257, hdist+1);
            m_nextDecode = LITERAL;
        }
        catch (HuffmanDecoder::Err &)
        {
            throw BadBlockErr();
        }
        break;
    }
    default:
        throw BadBlockErr();	// reserved block type
    }
    m_state = DECODING_BODY;
}