xonotic/misc/tools/fiximage.pl
2010-03-18 14:22:15 +01:00

106 lines
2.0 KiB
Perl
Executable File

#!/usr/bin/perl
use strict;
use warnings;
# Usage:
# convert image.tga -depth 8 RGBA:- | perl fiximage.pl 72 | convert -depth 8 -size 72x56 RGBA:- output.tga
my ($width) = @ARGV;
my @pixels = ();
for(;;)
{
read STDIN, my $data, 4
or last;
my ($r, $g, $b, $a) = unpack "CCCC", $data;
push @pixels, [$r, $g, $b, $a];
}
my $height = @pixels / $width;
my @fixlater;
for my $y(0..($height-1))
{
for my $x(0..($width-1))
{
next
if $pixels[$x + $y * $width][3] != 0;
# alpha is zero? Replace by weighted average.
my ($r, $g, $b, $a) = (0, 0, 0);
for my $dy(-1..1)
{
next if $y + $dy < 0;
next if $y + $dy >= $height;
for my $dx(-1..1)
{
next if $x + $dx < 0;
next if $x + $dx >= $width;
my $pix = $pixels[($x + $dx) + ($y + $dy) * $width];
$r += $pix->[0] * $pix->[3];
$g += $pix->[1] * $pix->[3];
$b += $pix->[2] * $pix->[3];
$a += $pix->[3];
}
}
if($a == 0)
{
push @fixlater, [$x, $y];
$pixels[$x + $y * $width] = [0, 0, 0, 0, undef];
next;
}
$r = int ($r / $a);
$g = int ($g / $a);
$b = int ($b / $a);
print STDERR "Fixing ($x, $y -> $r, $g, $b, $a)\n";
$pixels[$x + $y * $width] = [$r, $g, $b, 0];
}
}
while(@fixlater)
{
print STDERR "Pixels left: ", scalar(@fixlater), "\n";
# These pixels have no neighbors with a non-zero alpha.
my @fixels = @fixlater;
@fixlater = ();
my @pixelsorig = @pixels;
for(@fixels)
{
my ($x, $y) = @$_;
my ($r, $g, $b, $a) = (0, 0, 0, 0);
for my $dy(-1..1)
{
next if $y + $dy < 0;
next if $y + $dy >= $height;
for my $dx(-1..1)
{
next if $x + $dx < 0;
next if $x + $dx >= $width;
my $pix = $pixelsorig[($x + $dx) + ($y + $dy) * $width];
next
if @$pix == 5;
$r += $pix->[0];
$g += $pix->[1];
$b += $pix->[2];
$a += 1;
}
}
if($a == 0)
{
push @fixlater, [$x, $y];
next;
}
$r = int ($r / $a);
$g = int ($g / $a);
$b = int ($b / $a);
#print STDERR "Fixing later ($x, $y -> $r, $g, $b, $a)\n";
$pixels[$x + $y * $width] = [$r, $g, $b, 0];
}
}
for(@pixels)
{
print pack "CCCC", @$_;
}