COMPRESS::RAW::ZLIB(3pm)

✨ NAME ✨

Compress::Raw::Zlib β€” the low-level interface to the zlib or zlib-ng compression library πŸ’… (yes bestie, both, we'll get into it)

πŸ¦‹ SYNOPSIS πŸ¦‹

use Compress::Raw::Zlib ;

($d, $status) = new Compress::Raw::Zlib::Deflate( [OPT] ) ;
$status = $d->deflate($input, $output) ;
$status = $d->flush($output [, $flush_type]) ;
$d->deflateReset() ;
$d->deflateParams(OPTS) ;
$d->deflateTune(OPTS) ;
$d->dict_adler() ;
$d->crc32() ;
$d->adler32() ;
$d->total_in() ;
$d->total_out() ;
$d->msg() ;
$d->get_Strategy();
$d->get_Level();
$d->get_Bufsize();

($i, $status) = new Compress::Raw::Zlib::Inflate( [OPT] ) ;
$status = $i->inflate($input, $output [, $eof]) ;
$status = $i->inflateSync($input) ;
$i->inflateReset() ;
$i->dict_adler() ;
$d->crc32() ;
$d->adler32() ;
$i->total_in() ;
$i->total_out() ;
$i->msg() ;
$d->get_Bufsize();

$crc = adler32($buffer [,$crc]) ;
$crc = crc32($buffer [,$crc]) ;

$crc = crc32_combine($crc1, $crc2, $len2);
$adler = adler32_combine($adler1, $adler2, $len2);

my $version = Compress::Raw::Zlib::zlib_version();
my $flags = Compress::Raw::Zlib::zlibCompileFlags();

is_zlib_native();
is_zlibng_native();
is_zlibng_compat();
is_zlibng();

🌸 DESCRIPTION 🌸

Okay so Compress::Raw::Zlib gives you a Perl interface to the zlib or zlib-ng compression libraries β€” if you wanna know where to actually get zlib or zlib-ng, peep the "SEE ALSO" section, iykyk 🫢

And literally, every single time we say "zlib" down below, it also applies to zlib-ng too, unless we say otherwise. No cap. ✨


πŸŽ€ Compress::Raw::Zlib::Deflate πŸŽ€

This section is all about the interface that lets you do in-memory compression using the deflate interface that zlib hands you. It's giving ✨compression era✨.

Here's the whole interface, bestie:

πŸ’– ($d, $status) = new Compress::Raw::Zlib::Deflate( [OPT] )

This initialises a deflation object. Iconic.

If you already know the zlib library, think of this as zlib's deflateInit, deflateInit2 and deflateSetDictionary all rolled into one β€” it combines the features of all three πŸ”₯

If it works, you get the initialised deflation object $d and a $status of Z_OK back β€” in list context that is. In scalar context it just hands you the deflation object $d only.

If it doesn't work, the returned deflation object $d will be undef and $status will hold a zlib error code. Sad girl hours 😭

The function optionally takes a bunch of named options passed as Name => value pairs. This is so you can tweak individual options without having to spell out every single one of them in the parameter list πŸŽ€

And for backward compatibility, you can also pass the parameters as a reference to a hash containing the name=>value pairs. (Legacy behaviour, but she's still slaying.)

Below is the list of valid options:

  • -Level β€” defines the compression level. Valid values are 0 through 9, Z_NO_COMPRESSION, Z_BEST_SPEED, Z_BEST_COMPRESSION, and Z_DEFAULT_COMPRESSION. The default is Z_DEFAULT_COMPRESSION.
  • -Method β€” defines the compression method. The only valid value at the present moment (and also the default, periodt) is Z_DEFLATED.
  • -WindowBits β€” okay so:
    • To compress an RFC 1950 data stream, set WindowBits to a positive number between 8 and 15.
    • To compress an RFC 1951 data stream, set WindowBits to -MAX_WBITS.
    • To compress an RFC 1952 data stream (i.e. gzip), set WindowBits to WANT_GZIP.
    • For the actual definition of what WindowBits means and which values are valid, go check the zlib documentation for deflateInit2.
    • Defaults to MAX_WBITS.
  • -MemLevel β€” for the meaning and the valid values of MemLevel, refer to the zlib documentation for deflateInit2. Defaults to MAX_MEM_LEVEL.
  • -Strategy β€” defines the strategy used to tune the compression. Valid values are Z_DEFAULT_STRATEGY, Z_FILTERED, Z_RLE, Z_FIXED and Z_HUFFMAN_ONLY. The default is Z_DEFAULT_STRATEGY.
  • -Dictionary β€” when you specify a dictionary, Compress::Raw::Zlib will automatically call deflateSetDictionary directly after calling deflateInit. You can get the Adler32 value for the dictionary by calling the method $d->dict_adler(). The default is no dictionary.
  • -Bufsize β€” sets the initial size of the output buffer used by the $d->deflate and $d->flush methods. If the buffer has to be reallocated to make it bigger, it grows in increments of Bufsize. The default buffer size is 4096.
  • -AppendOutput β€” this one controls how data gets written to the output buffer by the $d->deflate and $d->flush methods:
    • If AppendOutput is set to false, the output buffers in $d->deflate and $d->flush will be truncated before uncompressed data is written to them.
    • If it's set to true, uncompressed data gets appended to the output buffer in $d->deflate and $d->flush.
    • This option defaults to false.
  • -CRC32 β€” if you set this to true, a crc32 checksum of the uncompressed data will be calculated. Use the $d->crc32 method to grab that value. Defaults to false.
  • -ADLER32 β€” if you set this to true, an adler32 checksum of the uncompressed data will be calculated. Use the $d->adler32 method to grab that value. Defaults to false.

Here's a little example of using the Compress::Raw::Zlib::Deflate optional parameter list to override the default buffer size and the compression level β€” everything else just takes its default values, nbd:

my $d = new Compress::Raw::Zlib::Deflate ( -Bufsize => 300,
                                           -Level   => Z_BEST_SPEED ) ;

πŸ¦‹ $status = $d->deflate($input, $output)

Deflates whatever's inside $input and writes the compressed data out to $output πŸ’«

Both $input and $output can be either scalars or scalar references β€” flexible queen.

When it's done, $input will be completely processed (assuming nothing errored out, obviously). If the deflation worked, it writes the deflated data to $output and returns a status value of Z_OK. On error, it returns a zlib error code.

If the AppendOutput option was set to true in the constructor for the $d object, the compressed data gets appended to $output. If it's false, $output gets truncated before any compressed data is written to it.

⚠️ Note bestie: this method will not necessarily write compressed data to $output every single time you call it. So do not assume there's been an error just because $output is empty when this method returns. As long as the return code from the method is Z_OK, the deflate has succeeded. Trust the process πŸ’…

🌈 $status = $d->flush($output [, $flush_type])

Typically used to finish the deflation. Any pending output gets written to $output. Returns Z_OK if it's successful.

πŸ’€ Heads up: flushing can seriously degrade the compression ratio, so only use it to terminate a decompression (with Z_FINISH) or when you actually want to create a full flush point (with Z_FULL_FLUSH). Like, fr fr, be careful.

By default the flush_type used is Z_FINISH. Other valid values for flush_type are Z_NO_FLUSH, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH and Z_FULL_FLUSH. It is strongly recommended that you only set the flush_type parameter if you fully understand the implications of what it does. See the zlib documentation for the details, k? πŸ”₯

If the AppendOutput option is set to true in the constructor for the $d object, the compressed data gets appended to $output. If it's false, $output gets truncated before any compressed data is written to it.


🧚 $status = $d->deflateReset()

This method resets the deflation object $d. It's the one you want when you're compressing multiple data streams and wanna reuse the same object to compress each of them. Just only use it once the previous data stream has been flushed successfully β€” meaning a call to $d->flush(Z_FINISH) has returned Z_OK. Returns Z_OK if it's successful ✨


πŸ“ $status = $d->deflateParams([OPT])

Changes the settings for the deflate object $d.

The list of valid options is right below. Any option you don't specify just stays the way it was, no cap.

  • -Level β€” defines the compression level. Valid values are 0 through 9, Z_NO_COMPRESSION, Z_BEST_SPEED, Z_BEST_COMPRESSION, and Z_DEFAULT_COMPRESSION.
  • -Strategy β€” defines the strategy used to tune the compression. The valid values are Z_DEFAULT_STRATEGY, Z_FILTERED and Z_HUFFMAN_ONLY. (Note: this list is shorter than the constructor's, bestie β€” read it carefully πŸ‘€)
  • -BufSize β€” sets the initial size of the output buffer used by the $d->deflate and $d->flush methods. If the buffer has to be reallocated to make it bigger, it grows in increments of Bufsize.

πŸ’œ $status = $d->deflateTune($good_length, $max_lazy, $nice_length, $max_chain)

Tunes the internal settings for the deflate object $d. This one is only available if you're running zlib 1.2.2.3 or better β€” so do a vibe check on your version first.

Refer to the documentation in zlib.h for the instructions on how to fly deflateTune πŸ•ŠοΈ


πŸŽ€ $d->dict_adler()

Returns the adler32 value for the dictionary.

🌟 $d->crc32()

Returns the crc32 value for the uncompressed data to date.

If the CRC32 option is not enabled in the constructor for this object, this method will always return 0;

🌟 $d->adler32()

Returns the adler32 value for the uncompressed data to date.

🌸 $d->msg()

Returns the last error message generated by zlib.

🌸 $d->total_in()

Returns the total number of bytes uncompressed bytes input to deflate.

🌸 $d->total_out()

Returns the total number of compressed bytes output from deflate.

πŸ‘‘ $d->get_Strategy()

Returns the deflation strategy currently being used. Valid values are Z_DEFAULT_STRATEGY, Z_FILTERED and Z_HUFFMAN_ONLY.

πŸ‘‘ $d->get_Level()

Returns the compression level being used.

πŸ‘‘ $d->get_Bufsize()

Returns the buffer size used to carry out the compression.


πŸ’« Example πŸ’«

Here's a trivial little example of using deflate. It literally just reads standard input, deflates it, and writes it to standard output. Baby's first compression 🍼✨

use strict ;
use warnings ;

use Compress::Raw::Zlib ;

binmode STDIN;
binmode STDOUT;
my $x = new Compress::Raw::Zlib::Deflate
   or die "Cannot create a deflation stream\n" ;

my ($output, $status) ;
while (<>)
{
    $status = $x->deflate($_, $output) ;

    $status == Z_OK
        or die "deflation failed\n" ;

    print $output ;
}

$status = $x->flush($output) ;

$status == Z_OK
    or die "deflation failed\n" ;

print $output ;

πŸ¦‹ Compress::Raw::Zlib::Inflate πŸ¦‹

Okay bestie, this section is literally the whole interface for doing in-memory *un*compression with the inflate side of zlib. Here's the definition, laid out for you πŸ’…


πŸŽ€ ($i, $status) = new Compress::Raw::Zlib::Inflate( [OPT] )

This constructor initialises an inflation object. Iconic.

In list context it hands you back the inflation object, $i, plus the zlib status code, $status. In scalar context you only get the inflation object. That's it, that's the vibe.

If it works, $i holds the inflation object and $status will be Z_OK. Slay ✨

If it doesn't work, $i will be undef and $status will hold the zlib error code. Sad but informative 😭

The function optionally takes a bunch of named options, passed as -Name => value pairs. That's so you can tweak individual options without having to spell out every single one in the parameter list β€” very main character of it.

And for backward compatibility (iykyk), you can also pass the parameters as a reference to a hash containing the name=>value pairs. Old school, but valid 🫢

Here's the list of valid options, no cap:

  • -WindowBits β€” If you wanna uncompress an RFC 1950 data stream, set WindowBits to a positive number between 8 and 15. To uncompress an RFC 1951 data stream, set WindowBits to -MAX_WBITS. To uncompress an RFC 1952 data stream (that's gzip, bestie), set WindowBits to WANT_GZIP. And to auto-detect and uncompress either an RFC 1950 or RFC 1952 data stream (gzip again), set WindowBits to WANT_GZIP_OR_ZLIB. For the full definition of what WindowBits means and which values are valid, go check the zlib docs for inflateInit2. Defaults to MAX_WBITS. ✨
  • -Bufsize β€” Sets the initial size of the output buffer that the $i->inflate method uses. If that output buffer has to be reallocated to grow, it'll grow in increments of Bufsize. Default is 4096.
  • -Dictionary β€” The default is no dictionary. That's the whole tea πŸ“
  • -AppendOutput β€” This one controls how data gets written to the output buffer by the $i->inflate method. If it's set to false, the output buffer in $i->inflate gets truncated before uncompressed data is written to it. If it's set to true, the uncompressed data gets appended to the output buffer by $i->inflate instead. Defaults to false.
  • -CRC32 β€” If you set it to true, a crc32 checksum of the uncompressed data gets calculated. Then use the $i->crc32 method to grab that value. Defaults to false.
  • -ADLER32 β€” If you set it to true, an adler32 checksum of the uncompressed data gets calculated. Use the $i->adler32 method to retrieve it. Defaults to false.
  • -ConsumeInput β€” If set to true, this option removes compressed data from the input buffer of the $i->inflate method as the inflate progresses. Super useful when you're processing compressed data that's embedded in another file or buffer β€” in that case, whatever immediately follows the compressed stream just stays chilling in the input buffer. Defaults to true.
  • -LimitOutput β€” This option changes the behavior of the $i->inflate method so the amount of memory the output buffer uses can be limited. When LimitOutput is on, the size of the output buffer will be either the value of the Bufsize option or the amount of memory already allocated to $output, whichever is larger. Predicting the available output size is tricky, so don't go relying on getting an exact output buffer size, fr fr. When LimitOutout is not specified, $i->inflate will use as much memory as it takes to write all the uncompressed data it creates by uncompressing the input buffer. And heads up: if LimitOutput is enabled, the ConsumeInput option gets enabled too. Defaults to false. See "The LimitOutput option" for a whole discussion on why LimitOutput is needed and how to actually use it πŸ‘‘

Here's an example of using an optional parameter to override the default buffer size β€” look at it go:

my ($i, $status) = new Compress::Raw::Zlib::Inflate( -Bufsize => 300 ) ;

πŸ’œ $status = $i->inflate($input, $output [,$eof])

This inflates the complete contents of $input and writes the uncompressed data to $output. Both the $input and $output parameters can be either scalars or scalar references β€” flexible, we love to see it.

It returns Z_OK if it worked, and Z_STREAM_END if the end of the compressed data has been successfully reached. If it didn't work, $status holds the zlib error code.

Now, if the ConsumeInput option was set to true when the Compress::Raw::Zlib::Inflate object was created, then $input gets modified by inflate. On completion it'll contain whatever's left of the input buffer after inflation. In practice that means: when the return status is Z_OK, $input will contain an empty string; and when the return status is Z_STREAM_END, $input will contain whatever (if anything) was stored in the input buffer after the deflated data stream. So good for file formats that wrap a compressed stream (gzip, zip, etc.) and then have useful data right after the deflation stream. Total lifesaver 🫢

If the AppendOutput option is set to true in this object's constructor, the uncompressed data gets appended to $output. If it's false, $output gets truncated before any uncompressed data is written to it.

🌸 okay so about the $eof parameter

The $eof parameter needs a lil bit of explaining, bestie.

Before version 1.2.0, zlib assumed there was at least one trailing byte immediately after the compressed data stream while it was doing decompression. Normally that's not a problem, because most zlib applications guarantee there'll be data right after the compressed data stream. Like, gzip (RFC 1950) and zip both define trailing data that follows the compressed data stream. So it's usually fine ✨

You only need to use the $eof parameter if all of these conditions apply:

  1. You're either using a copy of zlib older than version 1.2.0, or you want your application code to be able to run with as many different versions of zlib as possible.
  2. You've set the WindowBits parameter to -MAX_WBITS in the constructor for this object β€” i.e. you're uncompressing a raw deflated data stream (RFC 1951).
  3. There is no data immediately after the compressed data stream.

If all of those are true, then you need to set the $eof parameter to true on the final call (and only the final call) to $i->inflate.

If you built this module with zlib >= 1.2.0, the $eof parameter is ignored. You can still set it if you want, but it won't be used behind the scenes. It's giving decorative πŸ’€


⭐ $status = $i->inflateSync($input)

This method attempts to recover good data from a compressed data stream that's partially corrupt. It scans $input until it reaches either a full flush point or the end of the buffer.

If a full flush point is found, Z_OK is returned and $input will have all data up to the flush point removed. That data can then be passed to the $i->inflate method to be uncompressed. Iconic recovery arc 🌈

Any other return code means a flush point wasn't found. If more data is available, you can call inflateSync repeatedly with more compressed data until the flush point turns up.

Note: full flush points are not present by default in compressed data streams. They have to be added explicitly when the data stream was created, by calling Compress::Deflate::flush with Z_FULL_FLUSH.

🧚 $status = $i->inflateReset()

This resets the inflation object $i. Use it when you're uncompressing multiple data streams and you wanna reuse the same object for each one β€” efficiency queen πŸ‘‘

Returns Z_OK if successful.


πŸ“ $i->dict_adler()

Returns the adler32 value for the dictionary.

πŸ”₯ $i->crc32()

Returns the crc32 value for the uncompressed data to date.

If the CRC32 option isn't enabled in this object's constructor, this method will always return 0.

πŸ’– $i->adler32()

Returns the adler32 value for the uncompressed data to date.

If the ADLER32 option isn't enabled in this object's constructor, this method will always return 0.

πŸŽ€ $i->msg()

Returns the last error message generated by zlib.

πŸ‘‘ $i->total_in()

Returns the total number of bytes compressed bytes input to inflate.

πŸ¦‹ $i->total_out()

Returns the total number of uncompressed bytes output from inflate.

πŸ’… $d->get_Bufsize()

Returns the buffer size used to carry out the decompression.


✨ Examples ✨

Here's an example of using inflate:

use strict ;
use warnings ;

use Compress::Raw::Zlib;

my $x = new Compress::Raw::Zlib::Inflate()
   or die "Cannot create a inflation stream\n" ;

my $input = '' ;
binmode STDIN;
binmode STDOUT;

my ($output, $status) ;
while (read(STDIN, $input, 4096))
{
    $status = $x->inflate($input, $output) ;

    print $output ;

    last if $status != Z_OK ;
}

die "inflation failed\n"
    unless $status == Z_STREAM_END ;

And the next example shows how to use the LimitOutput option. Notice the two nested loops in this case πŸ”₯ The outer loop reads the data from the input source β€” STDIN β€” and the inner loop repeatedly calls inflate until $input is exhausted, we hit an error, or the end of the stream is reached. One thing worth remembering: by using the LimitOutput option you also get ConsumeInput set as well β€” which makes the code below so much simpler.

use strict ;
use warnings ;

use Compress::Raw::Zlib;

my $x = new Compress::Raw::Zlib::Inflate(LimitOutput => 1)
   or die "Cannot create a inflation stream\n" ;

my $input = '' ;
binmode STDIN;
binmode STDOUT;

my ($output, $status) ;

OUTER:
while (read(STDIN, $input, 4096))
{
    do
    {
        $status = $x->inflate($input, $output) ;

        print $output ;

        last OUTER
            unless $status == Z_OK || $status == Z_BUF_ERROR ;
    }
    while length $input;
}

die "inflation failed\n"
    unless $status == Z_STREAM_END ;

πŸ’– CHECKSUM FUNCTIONS πŸ’–

okay so zlib ships two checksum functions and bestie, the Perl interface flips the parameter order on BOTH of them β€” not a typo, that's on purpose. Why? Because the flip means you can do a running checksum and a one-off calculation with the same function, which is honestly kind of iconic.

    $crc = adler32($buffer [,$crc]) ;
    $crc = crc32($buffer [,$crc]) ;

The $buffer param can be a plain scalar or a scalar reference β€” either one works, slay.

If the $crc param is undef, the crc value gets reset. periodt.

And if you built this module against zlib 1.2.3 or better, you get two bonus CRC-related functions:

    $crc = crc32_combine($crc1, $crc2, $len2);
    $adler = adler32_combine($adler1, $adler2, $len2);

These ones let you merge checksums together 🌸 β€” head over to the zlib documentation for the full deets.


✨ Misc ✨

πŸŽ€ my $version = Compress::Raw::Zlib::zlib_version();

Returns the version of the zlib library β€” but only if this module was built with the zlib library. Notes, because there are always notes:

  • If this module was built with zlib-ng in native mode, this function returns an empty string.
  • If this module was built with zlib-ng in compat mode, this function returns the Izlib> API version that zlib-ng is supporting.

πŸ¦‹ my $version = Compress::Raw::Zlib::zlibng_version();

Returns the version of the zlib-ng library if this module was built with zlib-ng. And plot twist: if this module was built with zlib, this function returns an empty string. It's giving mutual exclusivity πŸ’…

⭐ my $flags = Compress::Raw::Zlib::zlibCompileFlags();

Returns the flags that indicate which compile-time options were used to build the zlib or zlib-ng library. Wanna know what the flags mean? That's a zlib documentation moment β€” go check the description of the flags returned by zlibCompileFlags.

Heads up πŸ’€ when the zlib sources are built along with this module, the sprintf flags (bits 24, 25 and 26) should be ignored.
Also: if you're on zlib 1.2.0 or older, zlibCompileFlags will return 0. Yes, really.

🌈 the is_zlib_native() / is_zlibng_native() / is_zlibng_compat() / is_zlibng() squad

These functions are how you check whether Compress::Raw::Zlib was built with zlib or zlib-ng. Here's the whole vibe check:

  • is_zlib_native returns true if Compress::Raw::Zlib was built with zlib. πŸ‘‘
  • is_zlibng returns true if Compress::Raw::Zlib was built with zlib-ng.
  • The zlib-ng library has an option to build with a zlib-compatible API. The is_zlibng_compat function returns true if zlib-ng has been built with this API.
  • Finally, is_zlibng_native returns true if zlib-ng was built with its native API.

So basically: four little booleans and you always know exactly what you're working with 🫢


πŸŒ€ The LimitOutput option πŸŒ€

okay so by default, $i->inflate($input, $output) uncompresses all the data in $input and writes all of the uncompressed data it generated to $output. Which makes the inflate interface super simple β€” if the method uncompressed $input successfully, then all the compressed data in $input has been dealt with, done, no crumbs left behind ✨

So if you're reading from an input source and uncompressing as you go, the code looks something like this:

    use strict ;
    use warnings ;

    use Compress::Raw::Zlib;

    my $x = new Compress::Raw::Zlib::Inflate()
       or die "Cannot create a inflation stream\n" ;

    my $input = '' ;

    my ($output, $status) ;
    while (read(STDIN, $input, 4096))
    {
        $status = $x->inflate($input, $output) ;

        print $output ;

        last if $status != Z_OK ;
    }

    die "inflation failed\n"
        unless $status == Z_STREAM_END ;

Points to note, bestie πŸ“Œ

  • The main processing loop in the code handles reading of compressed data from STDIN.
  • The status code returned from inflate will only trigger termination of the main processing loop if it isn't Z_OK. When LimitOutput has not been used, the Z_OK status means that the end of the compressed data stream has been reached or there has been an error in uncompression.
  • After the call to inflate, all of the uncompressed data in $input will have been processed. Which means the subsequent call to read can overwrite its contents without any problem at all. πŸ’…

For most use-cases the behavior described above is totally acceptable (this module and its predecessor, Compress::Zlib, have used it for over 10 years without an issue), but in a few very specific use-cases the amount of memory required for $output can be prohibitively large. Like imagine this: if the compressed data stream contains the same pattern repeated thousands of times, a relatively small compressed data stream can uncompress into hundreds of megabytes 😭 Remember, inflate will keep allocating memory until all the uncompressed data has been written to the output buffer β€” the size of $output is unbounded. nothing about that is lowkey.

The LimitOutput option exists specifically to help with this use-case 🫢

The main difference in your code when using LimitOutput is that you have to deal with cases where the $input parameter still contains some uncompressed data that inflate hasn't processed yet. The status code returned from inflate will be Z_OK if uncompression took place and Z_BUF_ERROR if the output buffer is full.

Below is typical code showing how to use LimitOutput:

    use strict ;
    use warnings ;

    use Compress::Raw::Zlib;

    my $x = new Compress::Raw::Zlib::Inflate(LimitOutput => 1)
       or die "Cannot create a inflation stream\n" ;

    my $input = '' ;
    binmode STDIN;
    binmode STDOUT;

    my ($output, $status) ;

  OUTER:
    while (read(STDIN, $input, 4096))
    {
        do
        {
            $status = $x->inflate($input, $output) ;

            print $output ;

            last OUTER
                unless $status == Z_OK || $status == Z_BUF_ERROR ;
        }
        while length $input;
    }

    die "inflation failed\n"
        unless $status == Z_STREAM_END ;

Points to note this time πŸ‘‘

  • There are now two nested loops in the code: the outer loop for reading the compressed data from STDIN, same as before; and the inner loop that carries out the uncompression.
  • There are two exit points from the inner uncompression loop.
    • Firstly, when inflate has returned a status other than Z_OK or Z_BUF_ERROR. That means either the end of the compressed data stream has been reached (Z_STREAM_END) or there's an error in the compressed data. Either way there's no point continuing to read the compressed data, so both loops get terminated.
    • The second exit point tests if there's any data left in the input buffer, $input β€” and remember, the ConsumeInput option is automatically enabled when LimitOutput is used. When the input buffer has been exhausted, the outer loop can run again and overwrite a now-empty $input. πŸ¦‹

πŸ—‚οΈ ACCESSING ZIP FILES πŸ—‚οΈ

So technically, with some effort on your part, it is possible to use this module to access .zip files. But bestie, there are other perl modules out there that will do all the hard work for you, and honestly? Let them. Go check out Archive::Zip, Archive::Zip::SimpleZip, IO::Compress::Zip and IO::Uncompress::Unzip πŸ’…


❓ FAQ ❓

😭 Compatibility with Unix compress/uncompress.

Real talk: this module is not compatible with Unix compress. Not a vibe, just a fact.

If you have the uncompress program available, you can use it to read compressed files:

    open F, "uncompress -c $filename |";
    while (<F>)
    {
        ...

Alternatively, if you have the gunzip program available, you can use that to read compressed files:

    open F, "gunzip -c $filename |";
    while (<F>)
    {
        ...

And this is how you write compress files, if you have the compress program available:

    open F, "| compress -c $filename ";
    print F "data";
    ...
    close F ;

πŸ“¦ Accessing .tar.Z files

See the previous FAQ item πŸ‘† (the compress incompatibility one).

If the Archive::Tar module is installed and either the uncompress or gunzip programs are available, you can use one of these workarounds to read .tar.Z files.

First, with uncompress:

    use strict;
    use warnings;
    use Archive::Tar;

    open F, "uncompress -c $filename |";
    my $tar = Archive::Tar->new(*F);
    ...

And this one with gunzip:

    use strict;
    use warnings;
    use Archive::Tar;

    open F, "gunzip -c $filename |";
    my $tar = Archive::Tar->new(*F);
    ...

Similarly, if the compress program is available, you can use it to write a .tar.Z file:

    use strict;
    use warnings;
    use Archive::Tar;
    use IO::File;

    my $fh = new IO::File "| compress -c >$filename";
    my $tar = Archive::Tar->new();
    ...
    $tar->write($fh);
    $fh->close ;

🧚 Zlib Library Version Support

By default, Compress::Raw::Zlib builds with a private copy of version 1.2.5 of the zlib library. (Peep the README file for details on how to override this behaviour β€” yes, there's a whole procedure for it.)

If you decide to use a different version of the zlib library, you need to be aware of the following issues πŸ”₯

  • First off, you must have zlib 1.0.5 or better.
  • You need to have zlib 1.2.1 or better if you want to use the -Merge option with IO::Compress::Gzip, IO::Compress::Deflate and IO::Compress::RawDeflate.

🌟 CONSTANTS 🌟

All the zlib constants are automatically imported when you make use of Compress::Raw::Zlib. No imports to write, no modules to beg β€” they just show up. iconic behaviour honestly πŸ’œ


🫢 SUPPORT 🫢

Got general feedback, questions, or bug reports? Send them to <https://github.com/pmqs/Compress-Raw-Zlib/issues> (preferred πŸ’–) or <https://rt.cpan.org/Public/Dist/Display.html?Name=Compress-Raw-Zlib>.


πŸ‘€ SEE ALSO πŸ‘€

The whole extended friend group, in one place:

Compress::Zlib, IO::Compress::Gzip, IO::Uncompress::Gunzip, IO::Compress::Deflate, IO::Uncompress::Inflate, IO::Compress::RawDeflate, IO::Uncompress::RawInflate, IO::Compress::Bzip2, IO::Uncompress::Bunzip2, IO::Compress::Lzma, IO::Uncompress::UnLzma, IO::Compress::Xz, IO::Uncompress::UnXz, IO::Compress::Lzip, IO::Uncompress::UnLzip, IO::Compress::Lzop, IO::Uncompress::UnLzop, IO::Compress::Lzf, IO::Uncompress::UnLzf, IO::Compress::Zstd, IO::Uncompress::UnZstd, IO::Uncompress::AnyInflate, IO::Uncompress::AnyUncompress

IO::Compress::FAQ

File::GlobMapper, Archive::Zip, Archive::Tar, IO::Zlib

For RFC 1950, 1951 and 1952 see <https://datatracker.ietf.org/doc/html/rfc1950>, <https://datatracker.ietf.org/doc/html/rfc1951> and <https://datatracker.ietf.org/doc/html/rfc1952>

The zlib compression library was written by Jean-loup Gailly gzip@prep.ai.mit.edu and Mark Adler madler@alumni.caltech.edu. legends, honestly 🌈

The primary site for the zlib compression library is <http://www.zlib.org>.

The primary site for the zlib-ng compression library is <https://github.com/zlib-ng/zlib-ng>.

The primary site for gzip is <http://www.gzip.org>.


πŸ’œ AUTHOR πŸ’œ

This module was written by Paul Marquess, pmqs@cpan.org. πŸ‘‘

πŸ“œ MODIFICATION HISTORY ✨

Okay so if you wanna know what changed and when, the vibe is: go read the Changes file. That's it, that's the whole section β€” the receipts live over there, bestie. 🧾


Copyright (c) 2005-2026 Paul Marquess. All rights reserved.

Yes, all of them. Every last right. Reserved. πŸ’…

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

So like β€” free software, do your thing, remix it, share it, just keep the same terms as Perl itself and we're golden. 🫢 No cap, it's that simple.


And that's a wrap on Compress::Raw::Zlib! πŸ¦‹ Bestie, you made it to the very bottom of the whole page and honestly? Iconic behavior. 🌈

This lil masterpiece came from perl v5.42.3, dated 2026-11-03 β€” and yeah, the page header truncates the name to something like Compres...aw::Zlib(3pm) because man pages have zero chill about column width. 😭

Now go compress something. Slay. πŸ’–βœ¨

πŸ“¦ where this page comes from