Question

How can I re-pack bits into a bitstream after modifying them in Perl?

I'm currently using the following to unpack:

my $bits = 5;
my $code = '';

foreach my $i (reverse 0..$bits-1) {
    $code <<= 1;
    $code  |= vec($data,$i,1);
}

For example, the output might be 16.

EDIT:

This question relates to the data block of a GIF image.

What I'm trying to do is to pad the LZW codes to match the length required by PDF's LZWDecode method.

LZWDecode expects 8-bit images in which the <Clear> code is 256 and the <End> code is 257 (PDF Reference, page 44.)

For 5-bit images, codes 0-31 map to colors in the image's global color table, <Clear> is 32 and <End> is 33.

So I need to re-pack the bitstream so that codes 0-31 remain the same, but 32+ are offset by 256-32.

I'm using ActiveState Perl for Windows.

Was it helpful?

Solution

# Unpack from 8 bit fields.
my @vals = unpack('C*', $bytes);

... transform @vals into 5 bit values here ...

# Pack to 5 bit fields.
my $bits = join '', map substr(pack('B*', $val), -5), @vals;
$bits .= '0' x (-length($bits) % 8);  # Pad with zeros to byte boundary
$bytes = pack('B*', $bits);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top