summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/src/icons/square.pl
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2017-04-29 18:21:56 -0400
committerFranklin Wei <git@fwei.tk>2017-04-29 18:24:42 -0400
commit881746789a489fad85aae8317555f73dbe261556 (patch)
treecec2946362c4698c8db3c10f3242ef546c2c22dd /apps/plugins/puzzles/src/icons/square.pl
parent03dd4b92be7dcd5c8ab06da3810887060e06abd5 (diff)
downloadrockbox-881746789a489fad85aae8317555f73dbe261556.tar.gz
rockbox-881746789a489fad85aae8317555f73dbe261556.zip
puzzles: refactor and resync with upstream
This brings puzzles up-to-date with upstream revision 2d333750272c3967cfd5cd3677572cddeaad5932, though certain changes made by me, including cursor-only Untangle and some compilation fixes remain. Upstream code has been moved to its separate subdirectory and future syncs can be done by simply copying over the new sources. Change-Id: Ia6506ca5f78c3627165ea6791d38db414ace0804
Diffstat (limited to 'apps/plugins/puzzles/src/icons/square.pl')
-rwxr-xr-xapps/plugins/puzzles/src/icons/square.pl95
1 files changed, 95 insertions, 0 deletions
diff --git a/apps/plugins/puzzles/src/icons/square.pl b/apps/plugins/puzzles/src/icons/square.pl
new file mode 100755
index 0000000000..815b94b532
--- /dev/null
+++ b/apps/plugins/puzzles/src/icons/square.pl
@@ -0,0 +1,95 @@
1#!/usr/bin/perl
2
3# Read an input image, crop its border to a standard width, and
4# convert it into a square output image. Parameters are:
5#
6# - the required total image size
7# - the output border thickness
8# - the input image file name
9# - the output image file name.
10
11($osize, $oborder, $infile, $outfile) = @ARGV;
12
13# Determine the input image's size.
14$ident = `identify -format "%w %h" $infile`;
15$ident =~ /(\d+) (\d+)/ or die "unable to get size for $infile\n";
16($w, $h) = ($1, $2);
17
18# Read the input image data.
19$data = [];
20open IDATA, "convert -depth 8 $infile rgb:- |";
21push @$data, $rgb while (read IDATA,$rgb,3,0) == 3;
22close IDATA;
23# Check we have the right amount of data.
24$xl = $w * $h;
25$al = scalar @$data;
26die "wrong amount of image data ($al, expected $xl) from $infile\n"
27 unless $al == $xl;
28
29# Find the background colour, by looking around the entire border
30# and finding the most popular pixel colour.
31for ($i = 0; $i < $w; $i++) {
32 $pcount{$data->[$i]}++; # top row
33 $pcount{$data->[($h-1)*$w+$i]}++; # bottom row
34}
35for ($i = 1; $i < $h-1; $i++) {
36 $pcount{$data->[$i*$w]}++; # left column
37 $pcount{$data->[$i*$w+$w-1]}++; # right column
38}
39@plist = sort { $pcount{$b} <=> $pcount{$a} } keys %pcount;
40$back = $plist[0];
41
42# Crop rows and columns off the image to find the central rectangle
43# of non-background stuff.
44$ystart = 0;
45$ystart++ while $ystart < $h and scalar(grep { $_ ne $back } map { $data->[$ystart*$w+$_] } 0 .. ($w-1)) == 0;
46$yend = $h-1;
47$yend-- while $yend >= $ystart and scalar(grep { $_ ne $back } map { $data->[$yend*$w+$_] } 0 .. ($w-1)) == 0;
48$xstart = 0;
49$xstart++ while $xstart < $w and scalar(grep { $_ ne $back } map { $data->[$_*$w+$xstart] } 0 .. ($h-1)) == 0;
50$xend = $w-1;
51$xend-- while $xend >= $xstart and scalar(grep { $_ ne $back } map { $data->[$_*$w+$xend] } 0 .. ($h-1)) == 0;
52
53# Decide how much border we're going to put back on to make the
54# image perfectly square.
55$hexpand = ($yend-$ystart) - ($xend-$xstart);
56if ($hexpand > 0) {
57 $left = int($hexpand / 2);
58 $xstart -= $left;
59 $xend += $hexpand - $left;
60} elsif ($hexpand < 0) {
61 $vexpand = -$hexpand;
62 $top = int($vexpand / 2);
63 $ystart -= $top;
64 $yend += $vexpand - $top;
65}
66$ow = $xend - $xstart + 1;
67$oh = $yend - $ystart + 1;
68die "internal computation problem" if $ow != $oh; # should be square
69
70# And decide how much _more_ border goes on to add the bit around
71# the edge.
72$realow = int($ow * ($osize / ($osize - 2*$oborder)));
73$extra = $realow - $ow;
74$left = int($extra / 2);
75$xstart -= $left;
76$xend += $extra - $left;
77$top = int($extra / 2);
78$ystart -= $top;
79$yend += $extra - $top;
80$ow = $xend - $xstart + 1;
81$oh = $yend - $ystart + 1;
82die "internal computation problem" if $ow != $oh; # should be square
83
84# Now write out the resulting image, and resize it appropriately.
85open IDATA, "| convert -size ${ow}x${oh} -depth 8 -resize ${osize}x${osize}! rgb:- $outfile";
86for ($y = $ystart; $y <= $yend; $y++) {
87 for ($x = $xstart; $x <= $xend; $x++) {
88 if ($x >= 0 && $x < $w && $y >= 0 && $y < $h) {
89 print IDATA $data->[$y*$w+$x];
90 } else {
91 print IDATA $back;
92 }
93 }
94}
95close IDATA;