summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/icons/square.pl
diff options
context:
space:
mode:
authorFranklin Wei <frankhwei536@gmail.com>2016-11-20 15:16:41 -0500
committerFranklin Wei <frankhwei536@gmail.com>2016-11-24 16:23:09 -0500
commit56c9984511f016eab7e1278ba9e40d88bb59a162 (patch)
tree1bfa6d3aeb3bf2a6ffec71387ac073cd0b8b2a51 /apps/plugins/puzzles/icons/square.pl
parent29648f817677b84c03c2bcfe89eb8cf53653e7db (diff)
downloadrockbox-puzzles.zip
rockbox-puzzles.tar.gz
rockbox-puzzles.tar.bz2
rockbox-puzzles.tar.xz
[WIP] Port of Simon Tatham's Puzzle Collectionpuzzles
Original revision: 5123b1bf68777ffa86e651f178046b26a87cf2d9 MIT Licensed. Some games still crash and others are unplayable due to issues with controls. Still need a "real" polygon filling algorithm. The following games are at least partially broken for various reasons: Cube: crash with certain settings Galaxies: crash Inertia: crash Keen: input issues Loopy: weird stuff happens Map: crash on input Mines: weird stuff happens on target Palisade: input issues Signpost: crash on input Solo: input issues Towers: input and drawing issues Train Tracks: drawing issues Twiddle: weird animation on target Undead: input and drawing issues Unequal: input and drawing issues Untangle: input issues All in all, about 40% of the games are at least partially broken. Change-Id: I7c69b6860ab115f973c8d76799502e9bb3d52368
Diffstat (limited to 'apps/plugins/puzzles/icons/square.pl')
-rwxr-xr-xapps/plugins/puzzles/icons/square.pl95
1 files changed, 95 insertions, 0 deletions
diff --git a/apps/plugins/puzzles/icons/square.pl b/apps/plugins/puzzles/icons/square.pl
new file mode 100755
index 0000000..815b94b
--- /dev/null
+++ b/apps/plugins/puzzles/icons/square.pl
@@ -0,0 +1,95 @@
+#!/usr/bin/perl
+
+# Read an input image, crop its border to a standard width, and
+# convert it into a square output image. Parameters are:
+#
+# - the required total image size
+# - the output border thickness
+# - the input image file name
+# - the output image file name.
+
+($osize, $oborder, $infile, $outfile) = @ARGV;
+
+# Determine the input image's size.
+$ident = `identify -format "%w %h" $infile`;
+$ident =~ /(\d+) (\d+)/ or die "unable to get size for $infile\n";
+($w, $h) = ($1, $2);
+
+# Read the input image data.
+$data = [];
+open IDATA, "convert -depth 8 $infile rgb:- |";
+push @$data, $rgb while (read IDATA,$rgb,3,0) == 3;
+close IDATA;
+# Check we have the right amount of data.
+$xl = $w * $h;
+$al = scalar @$data;
+die "wrong amount of image data ($al, expected $xl) from $infile\n"
+ unless $al == $xl;
+
+# Find the background colour, by looking around the entire border
+# and finding the most popular pixel colour.
+for ($i = 0; $i < $w; $i++) {
+ $pcount{$data->[$i]}++; # top row
+ $pcount{$data->[($h-1)*$w+$i]}++; # bottom row
+}
+for ($i = 1; $i < $h-1; $i++) {
+ $pcount{$data->[$i*$w]}++; # left column
+ $pcount{$data->[$i*$w+$w-1]}++; # right column
+}
+@plist = sort { $pcount{$b} <=> $pcount{$a} } keys %pcount;
+$back = $plist[0];
+
+# Crop rows and columns off the image to find the central rectangle
+# of non-background stuff.
+$ystart = 0;
+$ystart++ while $ystart < $h and scalar(grep { $_ ne $back } map { $data->[$ystart*$w+$_] } 0 .. ($w-1)) == 0;
+$yend = $h-1;
+$yend-- while $yend >= $ystart and scalar(grep { $_ ne $back } map { $data->[$yend*$w+$_] } 0 .. ($w-1)) == 0;
+$xstart = 0;
+$xstart++ while $xstart < $w and scalar(grep { $_ ne $back } map { $data->[$_*$w+$xstart] } 0 .. ($h-1)) == 0;
+$xend = $w-1;
+$xend-- while $xend >= $xstart and scalar(grep { $_ ne $back } map { $data->[$_*$w+$xend] } 0 .. ($h-1)) == 0;
+
+# Decide how much border we're going to put back on to make the
+# image perfectly square.
+$hexpand = ($yend-$ystart) - ($xend-$xstart);
+if ($hexpand > 0) {
+ $left = int($hexpand / 2);
+ $xstart -= $left;
+ $xend += $hexpand - $left;
+} elsif ($hexpand < 0) {
+ $vexpand = -$hexpand;
+ $top = int($vexpand / 2);
+ $ystart -= $top;
+ $yend += $vexpand - $top;
+}
+$ow = $xend - $xstart + 1;
+$oh = $yend - $ystart + 1;
+die "internal computation problem" if $ow != $oh; # should be square
+
+# And decide how much _more_ border goes on to add the bit around
+# the edge.
+$realow = int($ow * ($osize / ($osize - 2*$oborder)));
+$extra = $realow - $ow;
+$left = int($extra / 2);
+$xstart -= $left;
+$xend += $extra - $left;
+$top = int($extra / 2);
+$ystart -= $top;
+$yend += $extra - $top;
+$ow = $xend - $xstart + 1;
+$oh = $yend - $ystart + 1;
+die "internal computation problem" if $ow != $oh; # should be square
+
+# Now write out the resulting image, and resize it appropriately.
+open IDATA, "| convert -size ${ow}x${oh} -depth 8 -resize ${osize}x${osize}! rgb:- $outfile";
+for ($y = $ystart; $y <= $yend; $y++) {
+ for ($x = $xstart; $x <= $xend; $x++) {
+ if ($x >= 0 && $x < $w && $y >= 0 && $y < $h) {
+ print IDATA $data->[$y*$w+$x];
+ } else {
+ print IDATA $back;
+ }
+ }
+}
+close IDATA;