zLib inflate has empty result in some cases

2.7k views Asked by At

My program processes PDF files and reads some streams out of them. There are also FlateEncoded streams in there. I use the "inflate()" method of zlib to decompress them.

This usually works really well with the following code:

static string FlateDecode(string s){

    int factor = 50;
    z_stream stream;
    while(true){
        char * out = new char[s.length()*factor];           

        stream.zalloc = Z_NULL;
        stream.zfree = Z_NULL;
        stream.opaque = Z_NULL;
        stream.avail_in = s.length();
        stream.next_in = (Bytef*)s.c_str();
        stream.avail_out = s.length()*factor;
        stream.next_out = (Bytef*)out;
        inflateInit(&stream);
        inflate(&stream, Z_FINISH);
        inflateEnd(&stream);


        if(stream.total_out >= factor*s.length()){
            delete[] out;
            factor *= 2;
            continue;

        }
        string result;
        for(unsigned long i = 0; i < stream.total_out; i++){
            result += out[i];
        }

        delete[] out;
        return result;
    }
}

But inflate has an empty result for some streams. It´s not often, but it happens. Has someone an idea why?

The streams must be ok because all PDF readers read the PDF files correctly.

Thanks for your help!

UPDATE

I've uploaded the PDF and the stream so you can check it by your own.

PDF -> The stream starts at byte 43296

Stream

UPDATE 2

I compared the streams that can´t be decompressed with the streams that can be decompressed. I've noticed an interesting thing: The working streams all begin with the 2 bytes H%. The problematic streams begin with ö>. Does anyone now what this means?

Thanks for any help!

2

There are 2 answers

1
Van Coding On BEST ANSWER

zlib simply seems to not support all deflated streams found in PDF files.

9
sharptooth On

You shouldn't reinitialize the stream on each iteration. Initialize it before the loop and call inflate() inside the loop until it returns either Z_OK or Z_STREAM_END.