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.
# 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);