Compres...aw::Lzma(3)

πŸ’– Compres...aw::Lzma πŸ’– β€” the Compress::Raw::Lzma page, bestie edition πŸŽ€

(Perl's own User Contributed Perl Documentation, no cap β€” this is the Compres...aw::Lzma(3) manpage and yes we're doing the whole thing)


✨ NAME ✨

Compress::Raw::Lzma β€” the low-level Perl interface to the lzma compression library πŸ¦‹


✨ SYNOPSIS ✨

okay so here's the whole vibe up front, no gatekeeping:

use Compress::Raw::Lzma ;

# Encoders
my ($lz, $status) = new Compress::Raw::Lzma::EasyEncoder [OPTS]
    or die "Cannot create lzma object: $status\n";

my ($lz, $status) = new Compress::Raw::Lzma::AloneEncoder [OPTS]
    or die "Cannot create lzma object: $status\n";

my ($lz, $status) = new Compress::Raw::Lzma::StreamEncoder [OPTS]
    or die "Cannot create lzma object: $status\n";

my ($lz, $status) = new Compress::Raw::Lzma::RawEncoder [OPTS]
    or die "Cannot create lzma object: $status\n";

$status = $lz->code($input, $output);
$status = $lz->flush($output);

# Decoders
my ($lz, $status) = new Compress::Raw::Lzma::AloneDecoder [OPTS]
    or die "Cannot create lzma object: $status\n";

my ($lz, $status) = new Compress::Raw::Lzma::AutoDecoder [OPTS]
    or die "Cannot create lzma object: $status\n";

my ($lz, $status) = new Compress::Raw::Lzma::StreamDecoder [OPTS]
    or die "Cannot create lzma object: $status\n";

my ($lz, $status) = new Compress::Raw::Lzma::RawDecoder [OPTS]
    or die "Cannot create lzma object: $status\n";

$status = $lz->code($input, $output);

my $version = Compress::Raw::Lzma::lzma_version_number();
my $version = Compress::Raw::Lzma::lzma_version_string();

four encoders, four decoders, two version functions, and two little workhorse methods that do all the actual labour. iconic honestly.


✨ DESCRIPTION ✨

so Compress::Raw::Lzma is your in-memory compression / uncompression hookup straight to the lzma compression library πŸ’…

like, yes, the main reason this module exists is so that IO::Compress::Lzma, IO::Uncompress::UnLzma, IO::Compress::Xz and IO::Uncompress::UnXz have something to stand on β€” but bestie, it works perfectly fine on its own for simple compression / uncompression tasks too 🫢

There are two functions that show up in every single compression and uncompression interface in this module, and they're called code and flush. By default, both of these overwrite whatever data was already sitting in the output buffer parameter πŸ™ˆ so if your dream is to compress/uncompress into one single buffer and have code and flush just keep appending to it, you gotta turn on the AppendOutput option when you create the compression/decompression object. periodt.


🌈 Compression 🌈

There are four compression interfaces hanging out in this module:

  • Compress::Raw::Lzma::EasyEncoder
  • Compress::Raw::Lzma::AloneEncoder
  • Compress::Raw::Lzma::StreamEncoder
  • Compress::Raw::Lzma::RawEncoder

πŸŽ€ ($z, $status) = new Compress::Raw::Lzma::EasyEncoder [OPTS];

Makes you a brand new xz compression object ✨

If it goes well, it returns the freshly initialised compression object $z and a $status of LZMA_OK β€” that's in list context. In scalar context you just get the deflation object $z, and nothing else, so know which one you're in, bestie.

If it does not go well, the returned compression object $z will be undef and $status will hold an lzma error code. sad but informative.

Here's the full list of valid options, no skips:

  • Preset => $preset β€” used to choose the compression preset. valid values are 0-9 and LZMA_PRESET_DEFAULT. 0 is the fastest compression with the lowest memory usage and the lowest compression. 9 is the slowest compression with the highest memory usage, but it gives you the best compression. defaults to LZMA_PRESET_DEFAULT. πŸ’«
  • Extreme => 0|1 β€” makes the compression a lot slower, but you get a small compression gain out of it. defaults to 0.
  • Check => $check β€” used to specify the integrity check used in the xz data stream. valid values are LZMA_CHECK_NONE, LZMA_CHECK_CRC32, LZMA_CHECK_CRC64, LZMA_CHECK_SHA256. defaults to LZMA_CHECK_CRC32. πŸ”
  • AppendOutput => 0|1 β€” controls whether the compressed data gets appended to the output buffer in the code and flush methods. defaults to 0. (heads up: in versions of this module prior to 2.072 the default value was incorrectly documented as 1 β€” so if you read an old doc, that's why you're confused, it wasn't you 🫠)
  • BufSize => $number β€” sets the initial size for the output buffer used by the $d->code method. if the buffer has to be reallocated to grow bigger, it grows in increments of Bufsize. defaults to 16k.

πŸŽ€ ($z, $status) = new Compress::Raw::Lzma::AloneEncoder [OPTS];

Creates you a legacy lzma compression object. this format is also known as lzma_alone. it's giving vintage, respectfully. πŸ•°οΈ

If it works, you get the initialised compression object $z and a $status of LZMA_OK in list context. In scalar context you get the deflation object $z only.

If it doesn't work, $z is undef and $status holds an lzma error code.

Valid options, the whole list:

  • Filter => $filter β€” the $filter option must be an object of type Lzma::Filter::Lzma1. See Lzma::Filter::Lzma in Compress::Raw::Lzma for a definition of Lzma::Filter::Lzma1. if this option isn't present, an Lzma::Filter::Lzma1 object with default values gets used instead.
  • AppendOutput => 0|1 β€” controls whether the compressed data gets appended to the output buffer in the code and flush methods. defaults to 0. (again: in versions of this module prior to 2.072 the default value was incorrectly documented as 1)
  • BufSize => $number β€” sets the initial size for the output buffer used by the $d->code method. if the buffer has to be reallocated to increase the size, it grows in increments of Bufsize. defaults to 16k.

πŸŽ€ ($z, $status) = new Compress::Raw::Lzma::StreamEncoder [OPTS];

Creates you an xz compression object ✨

Success = you get the initialised compression object $z and a $status of LZMA_OK in list context. Scalar context = you get the deflation object $z only.

No success = $z is undef, $status holds an lzma error code. πŸ’€

The valid options, all of them:

  • Filter => $filter
  • Filter => [$filter1, $filter2,...] β€” this option is used to change the behaviour of the StreamEncoder by applying between one and LZMA_FILTERS_MAX filters to the data stream during compression. See "Filters" for more details on the available filters. if this option is present it must either contain a single Lzma::Filter::Lzma filter object, or an array reference containing between one and LZMA_FILTERS_MAX filter objects. if this option is not present, an Lzma::Filter::Lzma2 object with default values is used. 🧚
  • Check => $check β€” used to specify the integrity check used in the xz data stream. valid values are LZMA_CHECK_NONE, LZMA_CHECK_CRC32, LZMA_CHECK_CRC64, LZMA_CHECK_SHA256. defaults to LZMA_CHECK_CRC32.
  • AppendOutput => 0|1 β€” controls whether the compressed data is appended to the output buffer in the code and flush methods. defaults to 0. (and once more for the people in the back: in versions of this module prior to 2.072 the default value was incorrectly documented as 1)
  • BufSize => $number β€” sets the initial size for the output buffer used by the $d->code method. if the buffer has to be reallocated to increase the size, it will grow in increments of Bufsize. defaults to 16k.

πŸŽ€ ($z, $status) = new Compress::Raw::Lzma::RawEncoder [OPTS];

Low level access to lzma. this is the no-frills, down-to-the-metal one, iykyk. πŸ”₯

If successful, it returns the initialised compression object $z and a $status of LZMA_OK in list context. In scalar context, the deflation object $z only.

If not successful, $z will be undef and $status will hold an lzma error code.

The valid options, all four:

  • Filter => $filter
  • Filter => [$filter1, $filter2,...] β€” this option changes the behaviour of the RawEncoder by applying between one and LZMA_FILTERS_MAX filters to the data stream during compression. See "Filters" for more details on the available filters. if present it must either contain a single Lzma::Filter::Lzma filter object, or an array reference containing between one and LZMA_FILTERS_MAX filter objects. if it's not present, an Lzma::Filter::Lzma2 object with default values gets used.
  • AppendOutput => 0|1 β€” controls whether the compressed data is appended to the output buffer in the code and flush methods. defaults to 0. (yes, and in versions of this module prior to 2.072 the default value was incorrectly documented as 1 β€” same saga, different encoder πŸ™ˆ)
  • BufSize => $number β€” sets the initial size for the output buffer used by the $d->code method. if the buffer has to be reallocated to increase the size, it will grow in increments of Bufsize. defaults to 16k.
  • ForZip => 1/0 β€” this boolean option enables prefixing the compressed data stream with an encoded copy of the filter properties. defaults to 0. 🎁

πŸ’… $status = $lz->code($input, $output)

Reads what's in $input, compresses it, and writes the compressed data into $output.

Returns LZMA_OK on success, and an lzma error code on failure. ✨

If appendOutput is enabled in the constructor for the lzma object, the compressed data gets appended to $output. If it's not enabled, $output gets truncated before the compressed data is written into it. so watch out for that, bestie.


πŸ’… $status = $lz->flush($output, LZMA_FINISH);

Flushes any pending compressed data out to $output. by default, it terminates the compressed data stream β€” so like, that's the end of the road, no more data after that.

Returns LZMA_STREAM_END on success, and an lzma error code on failure. πŸ¦‹


okay that's part 1 wrapped, and there's more coming so don't go anywhere πŸ’–

πŸ’– Compression examples πŸ’–

Okay bestie, time for the fun part β€” actual code. Grab a snack. πŸ“


✨ Simple compression with EasyEncoder ✨

The gateway drug. Preset 6, no extreme mode, in and out. πŸŽ€

use strict;
use warnings;

use Compress::Raw::Lzma;

my ($lz, $status) = Compress::Raw::Lzma::EasyEncoder->new(
    Preset => 6,
    Extreme => 0,
);
die "Cannot create encoder: $status\n" unless $lz;

my $input = "This is the data to compress " x 100;
my $compressed = '';

$status = $lz->code($input, $compressed);
die "Compression failed: $status\n" unless $status == LZMA_OK;

$status = $lz->flush($compressed);
die "Flush failed: $status\n" unless $status == LZMA_STREAM_END;

print "Original size: ", length($input), "\n";
print "Compressed size: ", length($compressed), "\n";

πŸ¦‹ Streaming compression with AppendOutput πŸ¦‹

When your data comes in little pieces like a group chat and you don't wanna hold it all in memory. Set AppendOutput => 1 and keep feeding it. πŸ’…

use strict;
use warnings;

use Compress::Raw::Lzma;

my ($lz, $status) = Compress::Raw::Lzma::EasyEncoder->new(
    AppendOutput => 1,
    Preset => LZMA_PRESET_DEFAULT,
);
die "Cannot create encoder: $status\n" unless $lz;

my $compressed = '';

# Compress data in chunks
for my $chunk ("Hello ", "world", "!") {
    $status = $lz->code($chunk, $compressed);
    die "Compression failed\n" unless $status == LZMA_OK;
}

# Finish compression
$status = $lz->flush($compressed);
die "Flush failed\n" unless $status == LZMA_STREAM_END;

print "Compressed: ", length($compressed), " bytes\n";

🌸 Using custom filters with StreamEncoder 🌸

Now we're in our main character era β€” hand-crafting a custom LZMA2 filter, every knob exactly where you want it. πŸ‘‘

use strict;
use warnings;

use Compress::Raw::Lzma;

# Create a custom LZMA2 filter
my $filter = Lzma::Filter::Lzma2(
    DictSize => 1024 * 1024 * 8,  # 8MB dictionary
    Lc => 3,
    Lp => 0,
    Pb => 2,
    Mode => LZMA_MODE_NORMAL,
    Nice => 128,
    Mf => LZMA_MF_BT4,
    Depth => 512,
);

my ($lz, $status) = Compress::Raw::Lzma::StreamEncoder->new(
    Filter => $filter,
    Check => LZMA_CHECK_SHA256,
);
die "Cannot create encoder: $status\n" unless $lz;

my $input = "Custom filter example data";
my $compressed = '';

$status = $lz->code($input, $compressed);
$status = $lz->flush(compressed);

πŸ”₯ Using multiple filters (BCJ + LZMA2) πŸ”₯

Stacking filters like it's an outfit. BCJ for x86 binaries, LZMA2 for the actual squishing. Iconic behavior, no cap. ✨

use strict;
use warnings;

use Compress::Raw::Lzma;

# Combine BCJ filter for x86 binaries with LZMA2 compression
my @filters = (
    Lzma::Filter::X86(),      # BCJ filter for x86 code
    Lzma::Filter::Lzma2(),    # LZMA2 compression
);

my ($lz, $status) = Compress::Raw::Lzma::StreamEncoder->new(
    Filter => \@filters,
    Check => LZMA_CHECK_CRC64,
);
die "Cannot create encoder: $status\n" unless $lz;

# ... compress binary data ...

🌈 Uncompression 🌈

Now the other direction, bestie. Going backwards. 🫢 There are four uncompression interfaces chilling in this module:

  • Compress::Raw::Lzma::AutoDecoder
  • Compress::Raw::Lzma::AloneDecoder
  • Compress::Raw::Lzma::StreamDecoder
  • Compress::Raw::Lzma::RawDecoder

πŸ’œ ($z, $status) = new Compress::Raw::Lzma::AutoDecoder [OPTS] ;

This one's the social butterfly β€” it can uncompress any of the compressed data streams that this module is capable of creating. Versatile queen. πŸ’…

If it works, you get the freshly initialised uncompression object, $z, plus a $status of "LZMA_OK" β€” but only in list context. In scalar context it just hands you the deflation object, $z, and nothing else. Periodt.

If it doesn't work? $z comes back undef and $status holds an lzma error code. Sad but informative. 😭

Here's the full rundown of valid options:

  • -MemLimit β€” the number of bytes to use when uncompressing. Default is unlimited β€” go wild, no limits, main character energy. πŸ‘‘
  • -Bufsize β€” sets the initial size for the output buffer used by the $i->code method. If that output buffer has to be reallocated to grow bigger, it grows in increments of Bufsize. Default is 16k.
  • -AppendOutput β€” controls how data gets written to the output buffer by the $i->code method. Set it to false and the output buffer gets truncated before uncompressed data is written into it. Set it to true and the uncompressed data gets appended to the output buffer by $i->code. Defaults to false.
  • -ConsumeInput β€” if set to true, this strips compressed data out of the input buffer of the $i->code method as uncompression rolls along. Super handy when you're processing compressed data that's embedded inside another file or buffer β€” that way whatever immediately follows the compressed stream stays sitting in the input buffer. Defaults to true.
  • -LimitOutput β€” this one changes how $i->code behaves so the memory used by the output buffer can actually be capped. When LimitOutput is on, the output buffer size will be either the value of the Bufsize option or however much memory is already allocated to $output β€” whichever is bigger. Predicting the available output size is genuinely tricky, so don't expect an exact output buffer size, fr fr. When LimitOutout is not specified, $i->code 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.

πŸ’œ ($z, $status) = new Compress::Raw::Lzma::AloneDecoder [OPTS] ;

This one un-compresses an lzma_alone data stream. It's a specialist. πŸŽ€

If it works, you get the initialised uncompression object, $z, plus $status of "LZMA_OK" in list context. In scalar context it gives you just the deflation object, $z.

If it doesn't work, $z is undef and $status holds an lzma error code.

Valid options, coming right up:

  • -MemLimit β€” the number of bytes to use when uncompressing. Default is unlimited.
  • -Bufsize β€” sets the initial size for the output buffer used by the $i->code method. If the output buffer in this method has to be reallocated to grow, it grows in increments of Bufsize. Default is 16k.
  • -AppendOutput β€” controls how data is written to the output buffer by the $i->code method. Set to false, and the output buffer gets truncated before uncompressed data is written to it. Set to true, and uncompressed data gets appended to the output buffer by $i->code. Defaults to false.
  • -ConsumeInput β€” if set to true, it removes compressed data from the input buffer of the $i->code method as uncompression progresses. Useful when the compressed data is embedded in another file or buffer, because then the data immediately following the compressed stream stays in the input buffer. Defaults to true.
  • -LimitOutput β€” changes the behavior of $i->code so the amount of memory the output buffer uses can be limited. When LimitOutput is used, the size of the output buffer will be either the value of Bufsize or the memory already allocated to $output, whichever is larger. Predicting the output size is tricky, so don't count on an exact output buffer size, bestie. When LimitOutout isn't specified, $i->code uses as much memory as it needs to write all the uncompressed data it creates by uncompressing the input buffer. And if LimitOutput is enabled, ConsumeInput gets enabled too. Defaults to false.

✨ $status = $z->code($input, $output); ✨

The workhorse. It uncompresses $input and writes the uncompressed data to $output. πŸ’–

Returns "LZMA_OK" if the uncompression worked but we haven't hit the end of the compressed data stream yet. Returns "LZMA_STREAM_END" on a successful uncompression where the end of the compression stream has been reached. That's the finish line, slay. 🏁

If consumeInput is enabled in the constructor for the lzma object, $input will have all its compressed data removed after uncompression. On an "LZMA_OK" return, that means $input will be an empty string. When it's "LZMA_STREAM_END", $input will either be an empty string or will contain whatever data immediately followed the compressed data stream.

If appendOutput is enabled in the constructor for the lzma object, the uncompressed data gets appended to $output. If it's not enabled, $output gets truncated before the uncompressed data is written to it. πŸ¦‹

✨ Uncompression examples ✨

bestie, these are the decoder examples. read them, love them, run them. πŸ’–

🌈 Simple uncompression with AutoDecoder

use strict;
use warnings;

use Compress::Raw::Lzma;

# $compressed contains xz/lzma compressed data
my $compressed = ...;

my ($lz, $status) = Compress::Raw::Lzma::AutoDecoder->new(
    AppendOutput => 1,
    ConsumeInput => 1,
);
die "Cannot create decoder: $status\n" unless $lz;

my $uncompressed = '';
$status = $lz->code($compressed, $uncompressed);
die "Decompression failed: $status\n"
    unless $status == LZMA_STREAM_END;

print "Uncompressed size: ", length($uncompressed), "\n";

🌸 Streaming uncompression with LimitOutput

use strict;
use warnings;

use Compress::Raw::Lzma;

my ($lz, $status) = Compress::Raw::Lzma::AutoDecoder->new(
    LimitOutput => 1,
    ConsumeInput => 1,
    Bufsize => 4096,
);
die "Cannot create decoder: $status\n" unless $lz;

# Process compressed data in chunks
my $compressed = ...;  # your compressed data
my $uncompressed = '';

while (length($compressed) > 0) {
    my $output = '';
    $status = $lz->code($compressed, $output);

    $uncompressed .= $output;

    last if $status == LZMA_STREAM_END;
    die "Decompression error: $status\n" unless $status == LZMA_OK;
}

print "Total uncompressed: ", length($uncompressed), " bytes\n";

πŸ¦‹ Uncompressing specific format with AloneDecoder

use strict;
use warnings;

use Compress::Raw::Lzma;

# For legacy .lzma format (lzma_alone)
my ($lz, $status) = Compress::Raw::Lzma::AloneDecoder->new(
    MemLimit => 128 * 1024 * 1024,  # 128 MB limit
    AppendOutput => 0,
);
die "Cannot create decoder: $status\n" unless $lz;

my $compressed = ...;  # .lzma format data
my $output = '';

$status = $lz->code($compressed, $output);
die "Decompression failed: $status\n"
    unless $status == LZMA_STREAM_END;

πŸ‘‘ Filters πŸ‘‘

okay so here's the tea: some of the Lzma compression interfaces β€” literally Compress::Raw::Lzma::StreamEncoder & Compress::Raw::Lzma::AloneEncoder β€” plus the raw lzma uncompression interface all use filters. filters are the little knobs that change the behaviour of compression (and raw uncompression). πŸŽ›οΈβœ¨

and every single Lzma Filter is sub-classed from the Lzma::Filter base-class. no cap. πŸ’…

πŸ’œ Lzma::Filter::Lzma

the Lzma::Filter::Lzma class is the primary compression filter for LZMA algorithms. it gives you fine-grained control over compression parameters. like, extremely fine-grained. 🧚

there are two subclasses of Lzma::Filter::Lzma, namely Lzma::Filter::Lzma1 and Lzma::Filter::Lzma2.

  • the former is typically used with Compress::Raw::Lzma::AloneEncoder.
  • the latter with Compress::Raw::Lzma::StreamEncoder.
⚠️ when you're using Lzma filters, an Lzma::Filter::Lzma must be included, and it must be the last filter in the chain. also there can only be one Lzma::Filter::Lzma filter in any filter chain. one. single. periodt. πŸ’€

the Lzma::Filter::Lzma construction takes these options:

  • DictSize => $value β€” dictionary size in bytes. this controls how many bytes of the recently processed uncompressed data is kept in memory. the size of the dictionary must be at least LZMA_DICT_SIZE_MIN. defaults to LZMA_DICT_SIZE_DEFAULT. 🧠
  • PresetDict => $dict β€” provide an initial dictionary. this value is used to initialize the LZ77 history window. this feature only works correctly with raw encoding and decoding, so you may not be able to decode other formats that have been encoded with a preset dictionary. $dict should contain typical strings that occur in the files being compressed, with the most probable strings near the end of the preset dictionary. if $dict is larger than DictSize, only the last DictSize bytes are processed. πŸ“
  • Lc => $value β€” number of literal context bits. how many of the highest bits of the previous uncompressed eight-bit byte (also known as a literal) are taken into account when predicting the bits of the next literal. $value must be a number between LZMA_LCLP_MIN and LZMA_LCLP_MAX. heads up: the sum of the Lc and Lp options cannot exceed 4. defaults to LZMA_LC_DEFAULT.
  • Lp => $value β€” number of literal position bits. how many of the lowest bits of the current position (number of bytes from the beginning of the uncompressed data) in the uncompressed data is taken into account when predicting the bits of the next literal (a single eight-bit byte). defaults to LZMA_LP_DEFAULT.
  • Pb => $value β€” number of position bits. how many of the lowest bits of the current position in the uncompressed data is taken into account when estimating probabilities of matches. a match is a sequence of bytes for which a matching sequence is found from the dictionary and thus can be stored as a distance-length pair. $value must be a number between LZMA_PB_MIN and LZMA_PB_MAX. defaults to LZMA_PB_DEFAULT.
  • Mode => $value β€” the Compression Mode. valid values are LZMA_MODE_FAST and LZMA_MODE_NORMAL. defaults to LZMA_MODE_NORMAL. πŸ”₯
  • Nice => $value β€” nice length of a match. defaults to 64.
  • Mf => $value β€” defines which Match Finder to use. valid values are LZMA_MF_HC3, LZMA_MF_HC4, LZMA_MF_BT2, LZMA_MF_BT3 and LZMA_MF_BT4. defaults to LZMA_MF_BT4.
  • Depth => $value β€” maximum search depth in the match finder. defaults to 0.

🌈 Lzma::Filter::BCJ

the sub-classes of Lzma::Filter::BCJ are the Branch/Call/Jump conversion filters. these filters are used to rewrite executable binary code for a number of processor architectures. and the best part? none of these classes take any options. zero. zilch. iconic behaviour honestly. ✨

  • Lzma::Filter::X86 β€” filter for x86 binaries.
  • Lzma::Filter::PowerPC β€” filter for Big endian PowerPC binaries.
  • Lzma::Filter::IA64 β€” filter for IA64 (Itanium) binaries.
  • Lzma::Filter::ARM β€” filter for ARM binaries.
  • Lzma::Filter::ARMThumb β€” filter for ARMThumb binaries.
  • Lzma::Filter::Sparc β€” filter for Sparc binaries.

πŸŽ€ Lzma::Filter::Delta

usage is

Lzma::Filter::Delta [OPTS]
  • Type => $type β€” defines the type of Delta calculation. the only available type (and therefore the default) is LZMA_DELTA_TYPE_BYTE.
  • Distance => $value β€” defines the Delta Distance. $value must be a number between LZMA_DELTA_DIST_MIN and LZMA_DELTA_DIST_MAX. default is LZMA_DELTA_DIST_MIN. πŸ’…

Filter examples 🌸

okay bestie, this is the fun part β€” real code you can copy-paste into your little .pl file and go absolutely feral with. every example below is verbatim, so don't @ me if you change one character and it explodes πŸ’€

Using LZMA2 filter with custom dictionary size πŸŽ€

big dictionary = better compression, and that's just the vibe. watch:

use strict;
use warnings;

use Compress::Raw::Lzma;

# Create LZMA2 filter with large dictionary for better compression
my $filter = Lzma::Filter::Lzma2(
    DictSize => 16 * 1024 * 1024,  # 16 MB dictionary
    Lc => 3,
    Lp => 0,
    Pb => 2,
);

my ($lz, $status) = Compress::Raw::Lzma::StreamEncoder->new(
    Filter => $filter,
    Check => LZMA_CHECK_CRC64,
);
die "Cannot create encoder: $status\n" unless $lz;

my $input = "Data to compress...";
my $output = '';

$lz->code($input, $output);
$lz->flush($output);

Using LZMA1 filter for legacy .lzma format πŸ¦‹

the old-school format, the vintage one, the one your grandma's tar archive uses. respect the elders πŸ’œ

use strict;
use warnings;

use Compress::Raw::Lzma;

# LZMA1 is used for the legacy .lzma format
my $filter = Lzma::Filter::Lzma1(
    DictSize => 8 * 1024 * 1024,
    Mode => LZMA_MODE_NORMAL,
    Mf => LZMA_MF_BT4,
    Nice => 273,
);

my ($lz, $status) = Compress::Raw::Lzma::AloneEncoder->new(
    Filter => $filter,
);
die "Cannot create encoder: $status\n" unless $lz;

Using preset-based LZMA2 filter ✨

why hand-tune forty parameters when a preset can do it for you? lazy girlies stay winning:

use strict;
use warnings;

use Compress::Raw::Lzma;

# Use preset instead of manually configuring parameters
# Preset 9 = maximum compression
my $filter = Lzma::Filter::Lzma2::Preset(9 | LZMA_PRESET_EXTREME);

my ($lz, $status) = Compress::Raw::Lzma::StreamEncoder->new(
    Filter => $filter,
);
die "Cannot create encoder: $status\n" unless $lz;

Combining Delta filter with LZMA2 🌈

delta filter is so underrated. it's giving "data with tiny byte-to-byte changes" energy β€” think raw images, audio samples. chef's kiss:

use strict;
use warnings;

use Compress::Raw::Lzma;

# Delta filter is useful for data with small changes between bytes
# (e.g., uncompressed images, audio samples)
my @filters = (
    Lzma::Filter::Delta(
        Type => LZMA_DELTA_TYPE_BYTE,
        Distance => 1,
    ),
    Lzma::Filter::Lzma2(
        DictSize => 8 * 1024 * 1024,
    ),
);

my ($lz, $status) = Compress::Raw::Lzma::StreamEncoder->new(
    Filter => \@filters,
    Check => LZMA_CHECK_CRC32,
);
die "Cannot create encoder: $status\n" unless $lz;

# Compress image or audio data
my $raw_data = ...;
my $compressed = '';

$lz->code($raw_data, $compressed);
$lz->flush($compressed);

Using BCJ filter for x86 executable compression πŸ‘‘

BCJ = Branch/Call/Jump, and no, it does not stand for "bestie coded java" 😭 it makes x86 binaries compress way nicer. periodt:

use strict;
use warnings;

use Compress::Raw::Lzma;

# BCJ (Branch/Call/Jump) filter optimizes compression of x86 binaries
my @filters = (
    Lzma::Filter::X86(Offset => 0),
    Lzma::Filter::Lzma2(),
);

my ($lz, $status) = Compress::Raw::Lzma::StreamEncoder->new(
    Filter => \@filters,
    Check => LZMA_CHECK_SHA256,
);
die "Cannot create encoder: $status\n" unless $lz;

# Read and compress x86 binary
open my $fh, '<', 'program.exe' or die $!;
binmode $fh;
my $binary = do { local $/; <$fh> };
close $fh;

my $compressed = '';
$lz->code($binary, $compressed);
$lz->flush($compressed);

print "Original: ", length($binary), " bytes\n";
print "Compressed: ", length($compressed), " bytes\n";

Using ARM filter for ARM binaries 🧚

same energy, different architecture. ARM girlies rise:

use strict;
use warnings;

use Compress::Raw::Lzma;

# For ARM executables
my @filters = (
    Lzma::Filter::ARM(),
    Lzma::Filter::Lzma2(
        DictSize => 4 * 1024 * 1024,
    ),
);

my ($lz, $status) = Compress::Raw::Lzma::StreamEncoder->new(
    Filter => \@filters,
);
die "Cannot create encoder: $status\n" unless $lz;

Maximum compression with multiple filters πŸ”₯

stacking filters like stacking accessories. 64 MB dictionary, LZMA_MODE_NORMAL, Nice => 273, Depth => 1024 β€” she's going through it and I love her for it:

use strict;
use warnings;

use Compress::Raw::Lzma;

# Combine filters for maximum compression
my @filters = (
    Lzma::Filter::Delta(Distance => 1),
    Lzma::Filter::Lzma2(
        DictSize => 64 * 1024 * 1024,  # 64 MB
        Lc => 4,
        Lp => 0,
        Pb => 2,
        Mode => LZMA_MODE_NORMAL,
        Nice => 273,
        Mf => LZMA_MF_BT4,
        Depth => 1024,
    ),
);

my ($lz, $status) = Compress::Raw::Lzma::StreamEncoder->new(
    Filter => \@filters,
    Check => LZMA_CHECK_SHA256,
);
die "Cannot create encoder: $status\n" unless $lz;

Misc πŸ’…

just a couple of little version-checkers, cute and useful, no notes:

  • my $version = Compress::Raw::Lzma::lzma_version_number(); β€” hands you the version of the underlying lzma library this module is using at run-time, as a number.
  • my $version = Compress::Raw::Lzma::lzma_version_string(); β€” same thing but as a string, run-time flavor.
  • my $version = Compress::Raw::Lzma::LZMA_VERSION(); β€” the version of the underlying lzma library this module was using at compile-time, as a number. (yes, compile-time. she's different.)
  • my $version = Compress::Raw::Lzma::LZMA_VERSION_STRING(); β€” compile-time version, but as a string. slay.

Constants ✨

bestie these are all exported by this module. no cap, they're just there for you. πŸ’–

Return/Status Codes πŸŽ€

  • LZMA_OK β€” operation completed successfully. the good ending.
  • LZMA_STREAM_END β€” end of stream reached, meaning the whole compressed thing has been decoded/encoded. done and dusted.
  • LZMA_NO_CHECK β€” the input stream has no integrity check. she's raw, she's unfiltered.
  • LZMA_UNSUPPORTED_CHECK β€” the integrity check can't be calculated because this build doesn't support it. not her fault.
  • LZMA_GET_CHECK β€” the integrity check type is now available. mystery solved.
  • LZMA_MEM_ERROR β€” cannot allocate memory. πŸ’€
  • LZMA_MEMLIMIT_ERROR β€” memory usage limit was reached. she hit the ceiling.
  • LZMA_FORMAT_ERROR β€” file format not recognized. who is she.
  • LZMA_OPTIONS_ERROR β€” invalid or unsupported options. respectfully, no.
  • LZMA_DATA_ERROR β€” data is corrupt. πŸ™ˆ
  • LZMA_BUF_ERROR β€” no progress is possible because the stream is truncated or corrupt. stuck in traffic fr.
  • LZMA_PROG_ERROR β€” programming error, and per the docs this should never happen in correct usage. so if you see it… bestie what did you do 😭

Flush Modes 🌊

  • LZMA_RUN β€” keep coding. this is the normal-operation one.
  • LZMA_SYNC_FLUSH β€” makes all the input available at output. not commonly used with LZMA.
  • LZMA_FULL_FLUSH β€” finishes encoding of the current Block. also not commonly used.
  • LZMA_FINISH β€” finishes the coding operation, and all input must have been given to the encoder first. no takebacks.

Integrity Check Types πŸ›‘οΈ

  • LZMA_CHECK_NONE β€” no Check is calculated. chaotic.
  • LZMA_CHECK_CRC32 β€” CRC32 using the polynomial from IEEE-802.3.
  • LZMA_CHECK_CRC64 β€” CRC64 using the polynomial from ECMA-182.
  • LZMA_CHECK_SHA256 β€” SHA-256 checksum. the strong one.
  • LZMA_CHECK_ID_MAX β€” maximum valid Check ID.
  • LZMA_CHECK_SIZE_MAX β€” maximum size of any Check algorithm.

Preset and Compression Level ⭐

  • LZMA_PRESET_DEFAULT β€” the default compression preset, which is currently 6.
  • LZMA_PRESET_LEVEL_MASK β€” mask for the preset level, 0-9.
  • LZMA_PRESET_EXTREME β€” the extreme compression preset flag. can be combined with a preset level using bitwise OR, like 6 | LZMA_PRESET_EXTREME. go big or go home.

Stream Flags 🚩

  • LZMA_TELL_NO_CHECK β€” accept streams with no integrity check.
  • LZMA_TELL_UNSUPPORTED_CHECK β€” accept streams with an unsupported integrity check.
  • LZMA_TELL_ANY_CHECK β€” accept any type of integrity check. she's not picky.
  • LZMA_CONCATENATED β€” enable support for concatenated streams.

Match Finder Types πŸ”

  • LZMA_MF_HC3 β€” Hash Chain with 3 byte hashing.
  • LZMA_MF_HC4 β€” Hash Chain with 4 byte hashing.
  • LZMA_MF_BT2 β€” Binary Tree with 2 byte hashing.
  • LZMA_MF_BT3 β€” Binary Tree with 3 byte hashing.
  • LZMA_MF_BT4 β€” Binary Tree with 4 byte hashing, and it's the default and recommended one. main character energy fr.

Compression Mode ⚑

  • LZMA_MODE_FAST β€” fast compression mode.
  • LZMA_MODE_NORMAL β€” normal compression mode, and it's the default.

Dictionary and Parameter Limits πŸ“

  • LZMA_DICT_SIZE_MIN β€” minimum dictionary size, 4 KiB.
  • LZMA_DICT_SIZE_DEFAULT β€” default dictionary size.
  • LZMA_LCLP_MIN β€” minimum for lc and lp, which is 0.
  • LZMA_LCLP_MAX β€” maximum for lc and lp, which is 4.
  • LZMA_LC_DEFAULT β€” default number of literal context bits, which is 3.
  • LZMA_LP_DEFAULT β€” default number of literal position bits, which is 0.
  • LZMA_PB_MIN β€” minimum number of position bits, which is 0.
  • LZMA_PB_MAX β€” maximum number of position bits, which is 4.
  • LZMA_PB_DEFAULT β€” default number of position bits, which is 2.

BCJ (Branch/Call/Jump) Filters πŸ—οΈ

architecture-specific filters for executable code. iykyk:

  • LZMA_FILTER_X86 β€” filter for x86 (32-bit and 64-bit) binaries.
  • LZMA_FILTER_POWERPC β€” filter for Big endian PowerPC binaries.
  • LZMA_FILTER_IA64 β€” filter for IA-64 (Itanium) binaries.
  • LZMA_FILTER_ARM β€” filter for ARM binaries.
  • LZMA_FILTER_ARMTHUMB β€” filter for ARM-Thumb binaries.
  • LZMA_FILTER_SPARC β€” filter for SPARC binaries.

Delta Filter 🌊

  • LZMA_FILTER_DELTA β€” the delta filter ID.
  • LZMA_DELTA_TYPE_BYTE β€” byte-wise delta calculation.
  • LZMA_DELTA_DIST_MIN β€” minimum delta distance, which is 1.
  • LZMA_DELTA_DIST_MAX β€” maximum delta distance, which is 256.

LZMA Filters πŸ’œ

  • LZMA_FILTER_LZMA2 β€” the LZMA2 filter, used in the .xz format.
  • LZMA_FILTERS_MAX β€” maximum number of filters in a chain, which is 4.

Stream Header and Block πŸ“¦

  • LZMA_STREAM_HEADER_SIZE β€” size of the Stream Header, 12 bytes.
  • LZMA_BLOCK_HEADER_SIZE_MIN β€” minimum size of the Block Header.
  • LZMA_BLOCK_HEADER_SIZE_MAX β€” maximum size of the Block Header.
  • LZMA_BACKWARD_SIZE_MIN β€” minimum Backward Size.

Version Information 🏷️

  • LZMA_VERSION β€” encoded version number of liblzma.
  • LZMA_VERSION_MAJOR β€” major version number.
  • LZMA_VERSION_MINOR β€” minor version number.
  • LZMA_VERSION_PATCH β€” patch version number.
  • LZMA_VERSION_STABILITY β€” stability indicator.
  • LZMA_VERSION_STABILITY_STRING β€” stability as a string, e.g. "alpha", "beta", "stable".
  • LZMA_VERSION_STRING β€” the full version string.

SUPPORT 🫢

got feedback? questions? bugs? general feelings? send them here:

πŸ‘€ SEE ALSO πŸ‘€

okay bestie, here's the whole friend group πŸ’– β€” every single one of these is doing a similar job and they all wanna be in your use statements:

  • 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

and then the little bonus crew ✨:

  • IO::Compress::FAQ
  • File::GlobMapper
  • Archive::Zip
  • Archive::Tar
  • IO::Zlib

like, so many icons in one lineup, it's giving compression cinematic universe 🌈


πŸ’œ AUTHOR πŸ’œ

this module was written by Paul Marquess, "pmqs@cpan.org". absolute legend behavior, no cap πŸ‘‘


πŸ¦‹ MODIFICATION HISTORY πŸ¦‹

See the Changes file. that's where all the lore lives, bestie πŸ“œ


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. slay, go forth, remix responsibly πŸ’…


and that's a wrap on the whole page, bestie 🫢 this one was rendered by perl v5.42.0 and dated 2026-03-08, from the page titled Compres...aw::Lzma(3) β€” thanks for reading all five parts, you're literally the main character 🌸✨

πŸ“¦ where this page comes from