mirror of
https://gitlab.com/xonotic/xonotic
synced 2024-12-18 21:05:46 +00:00
106 lines
2.0 KiB
Perl
Executable File
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", @$_;
|
|
}
|