Skip to content

Instantly share code, notes, and snippets.

@vi
Last active October 21, 2015 10:17
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save vi/9297cd5bf80f0b34e8a2 to your computer and use it in GitHub Desktop.
Alpha channel remover from old BPG pictures
#!/usr/bin/perl
# Removes alpha channel from BPG v0.9.3- image, so it can be decoded with libbpg v0.9.4+.
# Implemented by Vitaly "_Vi" Shukela in 2015
# License: MIT
read STDIN,$_,4;
my $magic=unpack("N", $_);
printf STDERR "magic: %08X\n", $magic;
print STDOUT pack("N", $magic);
read STDIN,$_,1;
my $q = unpack("C",$_);
my $pf = $q >> 5;
my $al = ($q >> 4) & 1;
my $bd = $q & 0xF;
printf STDERR "PixelFormat: %d alpha: %d bitdepth: %d\n", $pf, $al, $bd+8;
my $q_ = ($pf << 5) | $bd;
print STDOUT pack("C", $q_);
read STDIN,$_,1;
my $q2 = unpack("C",$_);
my $cs = $q2 >> 4;
my $extp = ($q2 & 0x08);
my $alpha2 = ($q2 & 0x04);
my $lrf = ($q2 & 0x02);
my $reserz = ($q2 & 0x01);
printf STDERR "ColorSpace: %d ExtPresent: %d Alpha2: %d LimitedRange: %d ReservedZero: %d\n", $cs, $extp, $alpha2, $lrf, $reserz;
my $q2_ = ($cs << 4) | $extp | $lrf | $reserz;
print STDOUT pack("C", $q2_);
sub read_ue7($) {
my $maxbytes = shift;
my $x = 0;
for(my $i=0;$i<$maxbytes;++$i) {
read STDIN,$_,1;
my $q = unpack("C",$_);
$x *= 128;
if ($q & 0x80) {
$x += $q & 0x7F;
} else {
$x += $q;
return $x;
}
}
return $x;
}
sub write_ue7($) {
my $x = shift;
my $last = 0x00;
my $s = "";
while ($x > 127) {
$s = pack("C", ($x & 0x7F) | $last) . $s;
$x = $x >> 7;
$last = 0x80;
}
$s = pack("C", ($x & 0x7F) | $last) . $s;
print STDOUT $s;
}
my ($w, $h) = (read_ue7(4), read_ue7(4));
printf STDERR "Width: %d Height: %d\n", $w, $h;
write_ue7($w); write_ue7($h);
my $pdl = read_ue7(4);
printf STDERR "Picture data length: %d\n", $pdl;
write_ue7($pdl);
my $edl;
if ($extp) {
$edl = read_ue7(4);
printf STDERR "Extension data length: %d\n", $edl;
write_ue7($edl);
}
my $adl;
if ($al or $alpha2) {
$adl = read_ue7(4);
printf STDERR "Alpha data length: %d\n", $adl;
}
if ($extp) {
read STDIN, $_, $edl;
print STDOUT $_;
}
read STDIN, $_, $pdl;
print STDOUT $_;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment