Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

Anima

zLib question

This topic is 5223 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''ve been trying to get zLib working in my own program. I''ve read the manual and have managed to use the ''compress'' and ''uncompress'' functions correctly. However, I want to use this for file compression and I think the ''deflate'' and ''inflate'' functions are more suitable for this. The problem is I''ve got no idea how to use these functions in the proper way (compressing chunks of data at a time). Can anyone give me an example of how this is done, or point me towards a tutorial for using these functions? As I said I did read the manual but found it to be difficult to follow.

Share this post


Link to post
Share on other sites
Advertisement
There isn't any real difference between the deflate and compress methods in terms of the compression ratio. deflate merely works in a piecemeal fashion whereas compress does it all in one go. To use deflate:

byte input_buffer [input_buffer_size]
int bytes_in_input_buffer = 0
byte output_buffer [output_buffer_size]
int bytes_in_output_buffer = 0

while (there are still bytes to be compressed)
{
if (bytes_in_input_buffer == 0)
{
read data into input buffer, but not exceeding input_buffer_size
bytes_in_input_buffer = bytes read or input_buffer_size
}

deflate ()

if (bytes_in_output_buffer == output_buffer_size)
{
write data from output buffer
bytes_in_output_buffer = 0
}
}

flush the compression algorithm

if (bytes_in_output_buffer == output_buffer_size)
{
write data from output buffer
}

That should give you the basic idea. You can expand on the above to use a call-back mechanism to read/write the data (the bits in the ifs).

Skizz

[edited by - Skizz on June 2, 2004 2:34:30 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Thanks. I wanted to use deflate for the cases where a really big file needed to be compressed. I didn''t want to read the whole thing into memory and so deflate seemed the better option. I will read through the pseudocode you''ve given and see if it helps.

Share this post


Link to post
Share on other sites
I've got another question. If deflate is called and the output buffer is not sufficient to hold the compressed data (I'm sure it's possible) then what happens and how should I handle it? Again, reading the manual isn't helping much. It seems to say that the deflate function won't do anything, and expects the program to call it again with a larger output buffer. Is this right?

I presumed the deflate buffer would write as much as possible to the output, inform the program that the input buffer was not completed, and give the program the opportunity to complete the deflation of the input buffer however it sees fit.

Anyway, can someone tell me how the library behaves in this situation and how I could handle it properly? If possible, code examples would be very much appreciated!

Thanks


[edited by - Anima on June 2, 2004 4:51:58 PM]

Share this post


Link to post
Share on other sites
In the psuedocode above, when deflate runs out of memory to store the compressed data, the following code (in the if block) writes the contents of the compressed data buffer and resets the count of data written to the buffer to zero. The next iteration of the loop will call deflate with an output buffer with some space in it so the function can continue to compress the input data.

Skizz

Share this post


Link to post
Share on other sites
Am having a really hard time getting this to work (at all). My main difficulties are with the meaning and purpose behind the variables in the z_stream structure, and also the processes that need to be untaken when the input buffer runs out or the output buffer becomes full.

The following is the main part of my compression function. This works fine (or seems to) when the file is compressed all at once, but it doesn''t work in the cases where the input has to be read in blocks, or where the deflate function has to be repeated (when the output buffer becomes full).

Could someone look at it and tell me where I''m going wrong? I know it''s a lot to ask, but I''ve been trying to get this working for a long while now and it''s not really getting anywhere. If I''ve missed anything you''ll need to know, then ask me and I''ll post some more information.

(Again, if anyone can recommend some internet resources relating to this I''d be very grateful.)

{
// Open the Files
std::ifstream source (strSourceFilePath);
if (!source.is_open ())
return false;

std::ofstream destination (strDestinationFilePath);
if (!destination.is_open ())
return false;

// Validate the compression level (for zlib, this must be in the range ''0 to 9'')
if (uiLevel > 9)
return false;

// Create Read and Write Buffers
char *strReadBuffer = new char [m_uiReadBufferSize];
char *strWriteBuffer = new char [m_uiWriteBufferSize];

// Inititalise the Compression Stream Object
z_stream compressor;

compressor.zalloc = Z_NULL;
compressor.zfree = Z_NULL;
compressor.opaque = Z_NULL;

compressor.next_out = (Bytef *) strWriteBuffer;
compressor.avail_out = m_uiWriteBufferSize;

if (deflateInit (&compressor, uiLevel) != Z_OK)
return false;

// Begin Compression
while (!source.eof ())
{
// Read the buffer from the source file
source.read (strReadBuffer, m_uiReadBufferSize);
int iBytesRead = source.gcount ();

// Initialise the compressor
compressor.next_in = (Bytef *) strReadBuffer;
compressor.avail_in = iBytesRead;

// Compress the read buffer
int iSyncFlush = deflate (&compressor, Z_SYNC_FLUSH);

// Check for a full output buffer
if (compressor.avail_out == 0)
{
int iFinish;

do
{
// Write the buffer to the destination file
destination.write (strWriteBuffer, m_uiWriteBufferSize);

// Reset the buffer
compressor.avail_out = m_uiWriteBufferSize;
compressor.next_out = (Bytef *) strWriteBuffer;

iFinish = deflate (&compressor, Z_FINISH);
}
while (iFinish != Z_STREAM_END);

compressor.total_out = 0;
}
}

// Write the remainder of the buffer to the destination file
if (compressor.total_out != 0)
{
destination.write (strWriteBuffer, compressor.total_out);
}

// Destroy Compression object
deflateEnd (&compressor);

// Close the Source and Destination files
destination.close ();
source.close ();

// Compression Complete
return true;
}

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!