COMPRESS::RAW::ZLIB(3perl)

๐Ÿ’– Compress::Raw::Zlib ๐Ÿ’–

okay bestie, buckle UP, because this is Compress::Raw::Zlib from the Perl Programmers Reference Guide (that's the 3perl manual section, iykyk) and she is long. This is part 1 of 4, so don't go anywhere, we're just getting started. ๐ŸŽ€


โœจ NAME โœจ

Compress::Raw::Zlib โ€” the low-key, low-level interface to the zlib or zlib-ng compression library. no cap, this is the raw sauce. ๐Ÿ”ฅ


โœจ 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();

like, look at all those methods. she's giving utility. ๐Ÿ’…


โœจ DESCRIPTION โœจ

So Compress::Raw::Zlib is the Perl interface to the zlib or zlib-ng compression libraries. (If you wanna know where to actually get zlib or zlib-ng, the "SEE ALSO" section has you covered, bestie. ๐Ÿซถ)

heads up: everywhere below where we say "zlib", it also means zlib-ng, unless we specifically say otherwise. no exceptions, fr fr.

๐ŸŒˆ Compress::Raw::Zlib::Deflate ๐ŸŒˆ

This section defines an interface that lets you do in-memory compression using the deflate interface that zlib provides. yes, in memory, no file nonsense, we're fancy like that. โœจ

Here's the definition of the interface you get:


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

Initialises a deflation object. iconic behaviour, honestly. ๐Ÿ‘‘

If you already know the zlib library, this one combines the features of the zlib functions deflateInit, deflateInit2 and deflateSetDictionary. three-for-one deal, we love to see it.

If it works, it returns the freshly initialised deflation object $d, plus a $status of Z_OK โ€” but only in list context. In scalar context it just hands you the deflation object $d, that's it, that's the whole vibe.

If it does not work, the returned deflation object $d will be undef and $status will hold a zlib error code. (crying, but at least you know why ๐Ÿ˜ญ)

The function optionally takes a bunch of named options given as "Name => value" pairs. That way you can tweak individual options without having to spell out every single one in the parameter list. so convenient, honestly.

For backward compatibility, it's also possible to pass the parameters as a reference to a hash containing the name=>value pairs. retro, but valid. ๐Ÿ’œ

Below is the list of valid options:

  • -Level โ€” defines the compression level. The 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 present (and also the default) is Z_DEFLATED.
  • -WindowBits โ€” okay so this one is doing a lot, pay attention:
    • 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 (that's gzip, bestie), set WindowBits to WANT_GZIP.
    • For a definition of the meaning and valid values for WindowBits, go read the zlib documentation for deflateInit2. that's where the lore lives.
    • Defaults to MAX_WBITS.
  • -MemLevel โ€” for a definition of the meaning and valid values for MemLevel, refer to the zlib documentation for deflateInit2. Defaults to MAX_MEM_LEVEL.
  • -Strategy โ€” defines the strategy used to tune the compression. The valid values are Z_DEFAULT_STRATEGY, Z_FILTERED, Z_RLE, Z_FIXED and Z_HUFFMAN_ONLY. The default is Z_DEFAULT_STRATEGY. pick your fighter. ๐Ÿ’…
  • -Dictionary โ€” when a dictionary is specified, Compress::Raw::Zlib will automatically call deflateSetDictionary directly after calling deflateInit. You can grab the Adler32 value for the dictionary by calling the method $d->dict_adler(). The default is no dictionary.
  • -Bufsize โ€” sets the initial size for the output buffer used by the $d->deflate and $d->flush methods. If the buffer has to be reallocated to increase the size, it'll grow in increments of Bufsize. The default buffer size is 4096.
  • -AppendOutput โ€” this option controls how data is written to the output buffer by the $d->deflate and $d->flush methods.
    • If AppendOutput is set to false, the output buffers in the $d->deflate and $d->flush methods will be truncated before uncompressed data is written to them.
    • If the option is set to true, uncompressed data will be appended to the output buffer in the $d->deflate and $d->flush methods.
    • This option defaults to false.
  • -CRC32 โ€” if set to true, a crc32 checksum of the uncompressed data will be calculated. Use the $d->crc32 method to retrieve this value. This option defaults to false.
  • -ADLER32 โ€” if set to true, an adler32 checksum of the uncompressed data will be calculated. Use the $d->adler32 method to retrieve this value. This option defaults to false.

Here's an example of using the Compress::Raw::Zlib::Deflate optional parameter list to override the default buffer size and compression level. Every other option just takes its default value. so easy. ๐Ÿฆ‹

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

๐Ÿ’– $status = $d->deflate($input, $output)

Deflates the contents of $input and writes the compressed data to $output. ๐Ÿ’ซ

The $input and $output parameters can be either scalars or scalar references.

When it's finished, $input will be completely processed (assuming nothing errored out). If the deflation was successful, it writes the deflated data to $output and returns a status value of Z_OK.

On error, it returns a zlib error code. rude, but okay.

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

โš ๏ธ Note: this method will not necessarily write compressed data to $output every time it's called. So do NOT assume there's been an error just because the contents of $output is empty when you return from this method. As long as the return code from the method is Z_OK, the deflate has succeeded. periodt. โœ‹

๐Ÿ’– $status = $d->flush($output [, $flush_type])

Typically used to finish the deflation. Any pending output will be written to $output. ๐Ÿงš

Returns Z_OK if successful.

โš ๏ธ note that flushing can seriously degrade the compression ratio, so it should only be used to terminate a decompression (using Z_FINISH) or when you actually want to create a full flush point (using Z_FULL_FLUSH). don't just flush for fun, bestie, that's how you tank your ratio. ๐Ÿ’€

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 details. like, fr, read the docs first.

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


๐Ÿ’– $status = $d->deflateReset()

This method will reset the deflation object $d. Use it when you're compressing multiple data streams and you want to reuse the same object to compress each one. ๐ŸŒธ

It should only be used 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 successful.


๐Ÿ’– $status = $d->deflateParams([OPT])

Change settings for the deflate object $d. glow-up time. โœจ

Here's the list of valid options โ€” anything you don't specify just stays exactly as it was:

  • -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: shorter list than up top, don't @ me, that's just what it says.)
  • -BufSize โ€” sets the initial size for the output buffer used by the $d->deflate and $d->flush methods. If the buffer has to be reallocated to increase the size, it'll grow in increments of Bufsize.

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

Tune the internal settings for the deflate object $d. ๐ŸŽ›๏ธ

This option is only available if you are running zlib 1.2.2.3 or better.

Refer to the documentation in zlib.h for instructions on how to fly deflateTune. (yes, "fly". iconic wording, we keep it.)


๐Ÿ’– $d->dict_adler()

Returns the adler32 value for the dictionary. that's it. simple. ๐Ÿ’œ


๐Ÿ’– $d->crc32()

Returns the crc32 value for the uncompressed data to date.

If the CRC32 option isn't 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. the receipts, basically. ๐Ÿงพ


๐Ÿ’– $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 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 example of using deflate. It simply reads standard input, deflates it and writes it to standard output. baby's first deflate, adorable. ๐ŸŽ€

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 ;

and that's where part 1 leaves us, bestie โ€” plenty more where that came from. ๐Ÿฆ‹

Compress::Raw::Zlib::Inflate ๐Ÿ’–

Okay so this whole part is about squishing compressed data back into its original form, in memory โ€” that's what "inflation" means here, bestie, it's literally the un-zip of the zlib world ๐Ÿฆ‹. It uses the inflate interface that zlib hands us.

Here's the interface definition, no cap:

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

This spins up a fresh inflation object, slay โœจ.

In list context it gives you back the inflation object, $i, and the zlib status code, $status. In scalar context you only get the inflation object.

If it worked, $i holds the inflation object and $status is "Z_OK" ๐Ÿ’….

If it didn't work, $i is undef and $status holds the zlib error code ๐Ÿ˜ญ.

It optionally takes a bunch of named options given as -Name => value pairs. That way you can tweak individual options without having to spell out every single one in the parameter list.

For backward compatibility, you can also pass the parameters as a reference to a hash holding the name=>value pairs.

Here's the full list of valid options โ€” read them all, fr fr:

  • -WindowBits โ€” to 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, iykyk), set WindowBits to WANT_GZIP. To auto-detect and uncompress 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 documentation for inflateInit2. Defaults to MAX_WBITS.
  • -Bufsize โ€” sets the initial size for the output buffer that the $i->inflate method uses. If that output buffer has to be reallocated to get bigger, it grows in increments of Bufsize. Default is 4096.
  • -Dictionary โ€” the default is no dictionary.
  • -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 inside $i->inflate gets truncated before any uncompressed data is written to it. If it's set to true, the uncompressed data gets appended to the output buffer by $i->inflate. This option defaults to false.
  • -CRC32 โ€” if set to true, a crc32 checksum of the uncompressed data gets calculated. Use the $i->crc32 method to grab that value. This option defaults to false.
  • -ADLER32 โ€” if set to true, an adler32 checksum of the uncompressed data gets calculated. Use the $i->adler32 method to grab that value. This option 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 makes progress. Super useful when you're processing compressed data that's embedded inside some other file/buffer โ€” because in that case, whatever data sits immediately after the compressed stream just stays there in the input buffer ๐Ÿซถ. This option defaults to true.
  • -LimitOutput โ€” the LimitOutput 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 used 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 honestly tricky, so don't rely on getting an exact output buffer size ๐Ÿ‘‘. When LimitOutout is not specified, $i->inflate will use as much memory as it takes to write out all the uncompressed data it creates by uncompressing the input buffer. If LimitOutput is enabled, the ConsumeInput option will also be enabled. This option defaults to false. See "The LimitOutput option" for a whole discussion on why LimitOutput is needed and how to use it.

Here's an example of using an optional parameter to override that default buffer size:

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

$status = $i->inflate($input, $output [,$eof])

Inflates the entire contents of $input and writes the uncompressed data to $output. The $input and $output parameters can be scalars or scalar references, dealer's choice ๐Ÿ’.

Returns Z_OK if it worked, and Z_STREAM_END if the end of the compressed data was successfully reached ๐Ÿ”ฅ.

If it didn't work, $status will hold the zlib error code.

If the ConsumeInput option was set to true when the Compress::Raw::Zlib::Inflate object got created, the $input parameter gets modified by inflate. When it's done, it'll contain whatever's left of the input buffer after inflation. In practice that means: when the return status is Z_OK, the $input parameter will contain an empty string, and when the return status is Z_STREAM_END, the $input parameter will contain whatever (if anything) was stored in the input buffer after the deflated data stream.

This feature is genuinely so handy when you're processing a file format that wraps a compressed data stream (like gzip, zip) and there's useful data sitting right after the deflation stream.

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

Now 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 the vast majority of zlib applications guarantee there'll be data directly after the compressed data stream. Like, both gzip (RFC 1950) and zip define trailing data that follows the compressed data stream.

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

  1. You're either using a copy of zlib that's 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 the case, 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.

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

This method can be used to attempt to recover good data out of a compressed data stream that's partially corrupt. It scans $input until it hits 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 the data up to the flush point removed. That data can then be passed to the $i->inflate method to be uncompressed ๐Ÿ™Œ.

Any other return code means a flush point wasn't found. If there's more data available, inflateSync can be called over and over 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 have been added explicitly when the data stream was created, by calling Compress::Deflate::flush with Z_FULL_FLUSH.

$status = $i->inflateReset()

This method resets the inflation object $i. It's useful when you're uncompressing multiple data streams and want to reuse the same object for each of them ๐ŸŒˆ.

Returns Z_OK if it worked.

$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 the constructor for this object, 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 the constructor for this object, this method will always return 0;

$i->msg()

Returns the last error message generated by zlib.

$i->total_in()

Returns the total number of 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, bestie:

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 ;

The next example shows how to use the LimitOutput option. Notice the two nested loops in this one, okay? ๐Ÿ‘€ The outer loop reads the data from the input source โ€” STDIN โ€” and the inner loop calls inflate over and over until $input is exhausted, we hit an error, or we reach the end of the stream. One thing worth remembering: by using the LimitOutput option you also get ConsumeInput set as well โ€” and that 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 hands us two functions for calculating checksums. plot twist though: in the Perl interface, the order of the two parameters in both functions has been reversed ๐Ÿ”„ โ€” which is actually a slay, because it lets you do running checksums and one-off calculations with the same functions. iconic design tbh.

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

The $buffer parameters can be either a plain scalar or a scalar reference. either one, she's flexible ๐Ÿ’…

If the $crc parameter is undef, the crc value gets reset. clean slate energy โœจ

And if you built this module with zlib 1.2.3 or better, you get two more CRC-related functions, no cap:

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

These ones let you merge checksums ๐Ÿซถ. For the full tea, go check the zlib documentation.


๐ŸŒˆ Misc ๐ŸŒˆ

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

Returns the version of the zlib library โ€” if this module was built with the zlib library. But heads up bestie, it's complicated:

  • 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 zlib 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 the zlib-ng library. If this module was built with zlib instead? Empty string. ๐Ÿ’€

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

Returns the flags indicating compile-time options that were used to build the zlib or zlib-ng library. Wanna know what those flags actually mean? The zlib documentation has the description of the flags returned by zlibCompileFlags. iykyk ๐Ÿ“š

โš ๏ธ Note: when the zlib sources are built along with this module, the sprintf flags (bits 24, 25 and 26) should be ignored. just pretend they're not there, they're not the moment.

And if you're on zlib 1.2.0 or older, zlibCompileFlags will just return 0. nothing to see here ๐Ÿ™ˆ

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

fr the original text for these looks like this, so here it is verbatim, pod-formatting leakage and all ๐Ÿ’€:

is_zlib_native(); =head2 is_zlibng_native(); =head2 is_zlibng_compat();
=head2 is_zlibng();

These functions can be used to check whether Compress::Raw::Zlib was built with zlib or zlib-ng ๐Ÿ”

  • 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. ๐Ÿงฉ

And finally, is_zlibng_native returns true if zlib-ng was built with its native API. periodt ๐Ÿ’…


๐Ÿšฆ The LimitOutput option. ๐Ÿšฆ

Bestie, this one matters so much, sit down for it. ๐Ÿช‘

By default, $i->inflate($input, $output) will uncompress all the data in $input and write all of the uncompressed data it has generated to $output. This makes the interface to inflate much simpler โ€” if the method has uncompressed $input successfully, all compressed data in $input will have been dealt with. So if you're reading from an input source and uncompressing as you go, the code will look 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 ;

The points to note are ๐Ÿ‘€

  • 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. This means the subsequent call to read can overwrite its contents without any problem.

For most use-cases the behavior described above is perfectly acceptable (this module and its predecessor, Compress::Zlib, have used it for over 10 years without an issue, so she's got history ๐Ÿ‘‘). But in a few very specific use-cases, the amount of memory required for $output can be prohibitively large. ๐Ÿ’€

For example: 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. ๐Ÿ˜ญ

The LimitOutput option is designed to help with this use-case. queen behavior, honestly.

The main difference in your code when using LimitOutput is having 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 that shows 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, as before; and the inner loop to carry 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. This means that either the end of the compressed data stream has been reached (Z_STREAM_END) or there is an error in the compressed data. In either of these cases there is no point in continuing with reading the compressed data, so both loops are terminated.
    • The second exit point tests if there is any data left in the input buffer, $input โ€” remember that 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 ๐Ÿ—‚๏ธ

ngl, although it is possible (with some effort on your part ๐Ÿ’…) to use this module to access .zip files, there are other perl modules out there that will do all the hard work for you. So like... let them? Check out Archive::Zip, Archive::Zip::SimpleZip, IO::Compress::Zip and IO::Uncompress::Unzip. ๐Ÿซถ


โ“ FAQ โ“

๐ŸŒ€ Compatibility with Unix compress/uncompress.

This module is not compatible with Unix compress. ๐Ÿšซ

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

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

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

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

and this to 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 previous FAQ item. โฌ†๏ธ

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.

Firstly with uncompress:

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

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

and this 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 this 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 will build with a private copy of version 1.2.5 of the zlib library. (See the README file for details of how to override this behaviour โ€” she has options.)

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 use gymnastics required, she just shows up ready to go โœจ


๐Ÿซถ SUPPORT ๐Ÿซถ

General feedback/questions/bug reports should be sent 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 ๐Ÿ‘€

  • 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 โœจ

ok so if you wanna know absolutely everything that's ever changed, bestie, it lives in the Changes file. that's the whole section. go read it, it's giving receipts ๐Ÿ’…


Copyright (c) 2005-2026 Paul Marquess. All rights reserved. ๐Ÿซถ

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. no cap, that's the actual license situation, and honestly? iconic. ๐ŸŒˆ


and that's a wrap on this whole entire manpage, besties!! ๐ŸŽ€ the source is perl, version v5.44.0, dated 2026-10-17, and the footer that got cut off is just Compre...w::Zlib(3perl) doing its little truncated-name thing because page headers have a character limit and honestly, same. ๐Ÿ˜ญ

go compress something. slay. ๐Ÿ’œโœจ

๐Ÿ“ฆ where this page comes from
  • arch rolling: perl 5.44.0-1 ยท Artistic-1.0-Perl AND GPL-1.0-or-later
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms