checking in all the old panacean stuff
This commit is contained in:
28
puttysrc/ICONS/CICON.PL
Normal file
28
puttysrc/ICONS/CICON.PL
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Given a list of input PNGs, create a C source file containing a
|
||||
# const array of XPMs, named by a given C identifier.
|
||||
|
||||
$id = shift @ARGV;
|
||||
$k = 0;
|
||||
@xpms = ();
|
||||
foreach $f (@ARGV) {
|
||||
# XPM format is generated directly by ImageMagick, so that's easy
|
||||
# enough. We just have to adjust the declaration line so that it
|
||||
# has the right name, linkage and storage class.
|
||||
@lines = ();
|
||||
open XPM, "convert $f xpm:- |";
|
||||
push @lines, $_ while <XPM>;
|
||||
close XPM;
|
||||
die "XPM from $f in unexpected format\n" unless $lines[1] =~ /^static.*\{$/;
|
||||
$lines[1] = "static const char *const ${id}_$k"."[] = {\n";
|
||||
$k++;
|
||||
push @xpms, @lines, "\n";
|
||||
}
|
||||
|
||||
# Now output.
|
||||
foreach $line (@xpms) { print $line; }
|
||||
print "const char *const *const ${id}[] = {\n";
|
||||
for ($i = 0; $i < $k; $i++) { print " ${id}_$i,\n"; }
|
||||
print "};\n";
|
||||
print "const int n_${id} = $k;\n";
|
||||
270
puttysrc/ICONS/ICON.PL
Normal file
270
puttysrc/ICONS/ICON.PL
Normal file
@@ -0,0 +1,270 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Take a collection of input image files and convert them into a
|
||||
# multi-resolution Windows .ICO icon file.
|
||||
#
|
||||
# The input images can be treated as having four different colour
|
||||
# depths:
|
||||
#
|
||||
# - 24-bit true colour
|
||||
# - 8-bit with custom palette
|
||||
# - 4-bit using the Windows 16-colour palette (see comment below
|
||||
# for details)
|
||||
# - 1-bit using black and white only.
|
||||
#
|
||||
# The images can be supplied in any input format acceptable to
|
||||
# ImageMagick, but their actual colour usage must already be
|
||||
# appropriate for the specified mode; this script will not do any
|
||||
# substantive conversion. So if an image intended to be used in 4-
|
||||
# or 1-bit mode contains any colour not in the appropriate fixed
|
||||
# palette, that's a fatal error; if an image to be used in 8-bit
|
||||
# mode contains more than 256 distinct colours, that's also a fatal
|
||||
# error.
|
||||
#
|
||||
# Command-line syntax is:
|
||||
#
|
||||
# icon.pl -depth imagefile [imagefile...] [-depth imagefile [imagefile...]]
|
||||
#
|
||||
# where `-depth' is one of `-24', `-8', `-4' or `-1', and tells the
|
||||
# script how to treat all the image files given after that option
|
||||
# until the next depth option. For example, you might execute
|
||||
#
|
||||
# icon.pl -24 48x48x24.png 32x32x24.png -8 32x32x8.png -1 monochrome.png
|
||||
#
|
||||
# to build an icon file containing two differently sized 24-bit
|
||||
# images, one 8-bit image and one black and white image.
|
||||
#
|
||||
# Windows .ICO files support a 1-bit alpha channel on all these
|
||||
# image types. That is, any pixel can be either opaque or fully
|
||||
# transparent, but not partially transparent. The alpha channel is
|
||||
# separate from the main image data, meaning that `transparent' is
|
||||
# not required to take up a palette entry. (So an 8-bit image can
|
||||
# have 256 distinct _opaque_ colours, plus transparent pixels as
|
||||
# well.) If the input images have alpha channels, they will be used
|
||||
# to determine which pixels of the icon are transparent, by simple
|
||||
# quantisation half way up (e.g. in a PNG image with an 8-bit alpha
|
||||
# channel, alpha values of 00-7F will be mapped to transparent
|
||||
# pixels, and 80-FF will become opaque).
|
||||
|
||||
# The Windows 16-colour palette consists of:
|
||||
# - the eight corners of the colour cube (000000, 0000FF, 00FF00,
|
||||
# 00FFFF, FF0000, FF00FF, FFFF00, FFFFFF)
|
||||
# - dim versions of the seven non-black corners, at 128/255 of the
|
||||
# brightness (000080, 008000, 008080, 800000, 800080, 808000,
|
||||
# 808080)
|
||||
# - light grey at 192/255 of full brightness (C0C0C0).
|
||||
%win16pal = (
|
||||
"\x00\x00\x00\x00" => 0,
|
||||
"\x00\x00\x80\x00" => 1,
|
||||
"\x00\x80\x00\x00" => 2,
|
||||
"\x00\x80\x80\x00" => 3,
|
||||
"\x80\x00\x00\x00" => 4,
|
||||
"\x80\x00\x80\x00" => 5,
|
||||
"\x80\x80\x00\x00" => 6,
|
||||
"\xC0\xC0\xC0\x00" => 7,
|
||||
"\x80\x80\x80\x00" => 8,
|
||||
"\x00\x00\xFF\x00" => 9,
|
||||
"\x00\xFF\x00\x00" => 10,
|
||||
"\x00\xFF\xFF\x00" => 11,
|
||||
"\xFF\x00\x00\x00" => 12,
|
||||
"\xFF\x00\xFF\x00" => 13,
|
||||
"\xFF\xFF\x00\x00" => 14,
|
||||
"\xFF\xFF\xFF\x00" => 15,
|
||||
);
|
||||
@win16pal = sort { $win16pal{$a} <=> $win16pal{$b} } keys %win16pal;
|
||||
|
||||
# The black and white palette consists of black (000000) and white
|
||||
# (FFFFFF), obviously.
|
||||
%win2pal = (
|
||||
"\x00\x00\x00\x00" => 0,
|
||||
"\xFF\xFF\xFF\x00" => 1,
|
||||
);
|
||||
@win2pal = sort { $win16pal{$a} <=> $win2pal{$b} } keys %win2pal;
|
||||
|
||||
@hdr = ();
|
||||
@dat = ();
|
||||
|
||||
$depth = undef;
|
||||
foreach $_ (@ARGV) {
|
||||
if (/^-(24|8|4|1)$/) {
|
||||
$depth = $1;
|
||||
} elsif (defined $depth) {
|
||||
&readicon($_, $depth);
|
||||
} else {
|
||||
$usage = 1;
|
||||
}
|
||||
}
|
||||
if ($usage || length @hdr == 0) {
|
||||
print "usage: icon.pl ( -24 | -8 | -4 | -1 ) image [image...]\n";
|
||||
print " [ ( -24 | -8 | -4 | -1 ) image [image...] ...]\n";
|
||||
exit 0;
|
||||
}
|
||||
|
||||
# Now write out the output icon file.
|
||||
print pack "vvv", 0, 1, scalar @hdr; # file-level header
|
||||
$filepos = 6 + 16 * scalar @hdr;
|
||||
for ($i = 0; $i < scalar @hdr; $i++) {
|
||||
print $hdr[$i];
|
||||
print pack "V", $filepos;
|
||||
$filepos += length($dat[$i]);
|
||||
}
|
||||
for ($i = 0; $i < scalar @hdr; $i++) {
|
||||
print $dat[$i];
|
||||
}
|
||||
|
||||
sub readicon {
|
||||
my $filename = shift @_;
|
||||
my $depth = shift @_;
|
||||
my $pix;
|
||||
my $i;
|
||||
my %pal;
|
||||
|
||||
# Determine the icon's width and height.
|
||||
my $w = `identify -format %w $filename`;
|
||||
my $h = `identify -format %h $filename`;
|
||||
|
||||
# Read the file in as RGBA data. We flip vertically at this
|
||||
# point, to avoid having to do it ourselves (.BMP and hence
|
||||
# .ICO are bottom-up).
|
||||
my $data = [];
|
||||
open IDATA, "convert -flip -depth 8 $filename rgba:- |";
|
||||
push @$data, $rgb while (read IDATA,$rgb,4,0) == 4;
|
||||
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 $filename\n"
|
||||
unless $al == $xl;
|
||||
|
||||
# Build the alpha channel now, so we can exclude transparent
|
||||
# pixels from the palette analysis. We replace transparent
|
||||
# pixels with undef in the data array.
|
||||
#
|
||||
# We quantise the alpha channel half way up, so that alpha of
|
||||
# 0x80 or more is taken to be fully opaque and 0x7F or less is
|
||||
# fully transparent. Nasty, but the best we can do without
|
||||
# dithering (and don't even suggest we do that!).
|
||||
my $x;
|
||||
my $y;
|
||||
my $alpha = "";
|
||||
|
||||
for ($y = 0; $y < $h; $y++) {
|
||||
my $currbyte = 0, $currbits = 0;
|
||||
for ($x = 0; $x < (($w+31)|31)-31; $x++) {
|
||||
$pix = ($x < $w ? $data->[$y*$w+$x] : "\x00\x00\x00\xFF");
|
||||
my @rgba = unpack "CCCC", $pix;
|
||||
$currbyte <<= 1;
|
||||
$currbits++;
|
||||
if ($rgba[3] < 0x80) {
|
||||
if ($x < $w) {
|
||||
$data->[$y*$w+$x] = undef;
|
||||
}
|
||||
$currbyte |= 1; # MS has the alpha channel inverted :-)
|
||||
} else {
|
||||
# Might as well flip RGBA into BGR0 while we're here.
|
||||
if ($x < $w) {
|
||||
$data->[$y*$w+$x] = pack "CCCC",
|
||||
$rgba[2], $rgba[1], $rgba[0], 0;
|
||||
}
|
||||
}
|
||||
if ($currbits >= 8) {
|
||||
$alpha .= pack "C", $currbyte;
|
||||
$currbits -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# For an 8-bit image, check we have at most 256 distinct
|
||||
# colours, and build the palette.
|
||||
%pal = ();
|
||||
if ($depth == 8) {
|
||||
my $palindex = 0;
|
||||
foreach $pix (@$data) {
|
||||
next unless defined $pix;
|
||||
$pal{$pix} = $palindex++ unless defined $pal{$pix};
|
||||
}
|
||||
die "too many colours in 8-bit image $filename\n" unless $palindex <= 256;
|
||||
} elsif ($depth == 4) {
|
||||
%pal = %win16pal;
|
||||
} elsif ($depth == 1) {
|
||||
%pal = %win2pal;
|
||||
}
|
||||
|
||||
my $raster = "";
|
||||
if ($depth < 24) {
|
||||
# For a non-24-bit image, flatten the image into one palette
|
||||
# index per pixel.
|
||||
$pad = 32 / $depth; # number of pixels to pad scanline to 4-byte align
|
||||
$pmask = $pad-1;
|
||||
for ($y = 0; $y < $h; $y++) {
|
||||
my $currbyte = 0, $currbits = 0;
|
||||
for ($x = 0; $x < (($w+$pmask)|$pmask)-$pmask; $x++) {
|
||||
$currbyte <<= $depth;
|
||||
$currbits += $depth;
|
||||
if ($x < $w && defined ($pix = $data->[$y*$w+$x])) {
|
||||
if (!defined $pal{$pix}) {
|
||||
$pixhex = sprintf "%02x%02x%02x", unpack "CCC", $pix;
|
||||
die "illegal colour value $pixhex at pixel ($x,$y) in $filename\n";
|
||||
}
|
||||
$currbyte |= $pal{$pix};
|
||||
}
|
||||
if ($currbits >= 8) {
|
||||
$raster .= pack "C", $currbyte;
|
||||
$currbits -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# For a 24-bit image, reverse the order of the R,G,B values
|
||||
# and stick a padding zero on the end.
|
||||
#
|
||||
# (In this loop we don't need to bother padding the
|
||||
# scanline out to a multiple of four bytes, because every
|
||||
# pixel takes four whole bytes anyway.)
|
||||
for ($i = 0; $i < scalar @$data; $i++) {
|
||||
if (defined $data->[$i]) {
|
||||
$raster .= $data->[$i];
|
||||
} else {
|
||||
$raster .= "\x00\x00\x00\x00";
|
||||
}
|
||||
}
|
||||
$depth = 32; # and adjust this
|
||||
}
|
||||
|
||||
# Prepare the icon data. First the header...
|
||||
my $data = pack "VVVvvVVVVVV",
|
||||
40, # size of bitmap info header
|
||||
$w, # icon width
|
||||
$h*2, # icon height (x2 to indicate the subsequent alpha channel)
|
||||
1, # 1 plane (common to all MS image formats)
|
||||
$depth, # bits per pixel
|
||||
0, # no compression
|
||||
length $raster, # image size
|
||||
0, 0, 0, 0; # resolution, colours used, colours important (ignored)
|
||||
# ... then the palette ...
|
||||
if ($depth <= 8) {
|
||||
my $ncols = (1 << $depth);
|
||||
my $palette = "\x00\x00\x00\x00" x $ncols;
|
||||
foreach $i (keys %pal) {
|
||||
substr($palette, $pal{$i}*4, 4) = $i;
|
||||
}
|
||||
$data .= $palette;
|
||||
}
|
||||
# ... the raster data we already had ready ...
|
||||
$data .= $raster;
|
||||
# ... and the alpha channel we already had as well.
|
||||
$data .= $alpha;
|
||||
|
||||
# Prepare the header which will represent this image in the
|
||||
# icon file.
|
||||
my $header = pack "CCCCvvV",
|
||||
$w, $h, # width and height (this time the real height)
|
||||
1 << $depth, # number of colours, if less than 256
|
||||
0, # reserved
|
||||
1, # planes
|
||||
$depth, # bits per pixel
|
||||
length $data; # size of real icon data
|
||||
|
||||
push @hdr, $header;
|
||||
push @dat, $data;
|
||||
}
|
||||
92
puttysrc/ICONS/MAKEFILE
Normal file
92
puttysrc/ICONS/MAKEFILE
Normal file
@@ -0,0 +1,92 @@
|
||||
# Makefile for the PuTTY icon suite.
|
||||
|
||||
ICONS = putty puttycfg puttygen pscp pageant pterm ptermcfg puttyins
|
||||
SIZES = 16 32 48
|
||||
|
||||
MODE = # override to -it on command line for opaque testing
|
||||
|
||||
PNGS = $(foreach I,$(ICONS),$(foreach S,$(SIZES),$(I)-$(S).png))
|
||||
MONOPNGS = $(foreach I,$(ICONS),$(foreach S,$(SIZES),$(I)-$(S)-mono.png))
|
||||
TRUEPNGS = $(foreach I,$(ICONS),$(foreach S,$(SIZES),$(I)-$(S)-true.png))
|
||||
|
||||
ICOS = putty.ico puttygen.ico pscp.ico pageant.ico pageants.ico puttycfg.ico \
|
||||
puttyins.ico
|
||||
CICONS = xpmputty.c xpmpucfg.c xpmpterm.c xpmptcfg.c
|
||||
|
||||
base: icos cicons
|
||||
|
||||
all: pngs monopngs base # truepngs currently disabled by default
|
||||
|
||||
pngs: $(PNGS)
|
||||
monopngs: $(MONOPNGS)
|
||||
truepngs: $(TRUEPNGS)
|
||||
|
||||
icos: $(ICOS)
|
||||
cicons: $(CICONS)
|
||||
|
||||
install: icos cicons
|
||||
cp $(ICOS) ../windows
|
||||
cp $(CICONS) ../unix
|
||||
|
||||
$(PNGS): %.png: mkicon.py
|
||||
./mkicon.py $(MODE) $(join $(subst -, ,$(basename $@)),_icon) $@
|
||||
|
||||
$(MONOPNGS): %.png: mkicon.py
|
||||
./mkicon.py -2 $(MODE) $(join $(subst -, ,$(subst -mono,,$(basename $@))),_icon) $@
|
||||
|
||||
$(TRUEPNGS): %.png: mkicon.py
|
||||
./mkicon.py -T $(MODE) $(join $(subst -, ,$(subst -true,,$(basename $@))),_icon) $@
|
||||
|
||||
putty.ico: putty-16.png putty-32.png putty-48.png \
|
||||
putty-16-mono.png putty-32-mono.png putty-48-mono.png
|
||||
./icon.pl -4 $(filter-out %-mono.png, $^) -1 $(filter %-mono.png, $^) > $@
|
||||
|
||||
puttycfg.ico: puttycfg-16.png puttycfg-32.png puttycfg-48.png \
|
||||
puttycfg-16-mono.png puttycfg-32-mono.png puttycfg-48-mono.png
|
||||
./icon.pl -4 $(filter-out %-mono.png, $^) -1 $(filter %-mono.png, $^) > $@
|
||||
|
||||
puttygen.ico: puttygen-16.png puttygen-32.png puttygen-48.png \
|
||||
puttygen-16-mono.png puttygen-32-mono.png puttygen-48-mono.png
|
||||
./icon.pl -4 $(filter-out %-mono.png, $^) -1 $(filter %-mono.png, $^) > $@
|
||||
|
||||
pageant.ico: pageant-16.png pageant-32.png pageant-48.png \
|
||||
pageant-16-mono.png pageant-32-mono.png pageant-48-mono.png
|
||||
./icon.pl -4 $(filter-out %-mono.png, $^) -1 $(filter %-mono.png, $^) > $@
|
||||
|
||||
pageants.ico: pageant-16.png pageant-16-mono.png
|
||||
./icon.pl -4 $(filter-out %-mono.png, $^) -1 $(filter %-mono.png, $^) > $@
|
||||
|
||||
pscp.ico: pscp-16.png pscp-32.png pscp-48.png \
|
||||
pscp-16-mono.png pscp-32-mono.png pscp-48-mono.png
|
||||
./icon.pl -4 $(filter-out %-mono.png, $^) -1 $(filter %-mono.png, $^) > $@
|
||||
|
||||
# Because the installer icon makes heavy use of brown when drawing
|
||||
# the cardboard box, it's worth having 8-bit versions of it in
|
||||
# addition to the 4- and 1-bit ones.
|
||||
puttyins.ico: puttyins-16.png puttyins-32.png puttyins-48.png \
|
||||
puttyins-16-mono.png puttyins-32-mono.png \
|
||||
puttyins-48-mono.png \
|
||||
puttyins-16-true.png puttyins-32-true.png \
|
||||
puttyins-48-true.png
|
||||
./icon.pl -8 $(filter %-true.png, $^) \
|
||||
-4 $(filter-out %-true.png, $(filter-out %-mono.png, $^)) \
|
||||
-1 $(filter %-mono.png, $^) > $@
|
||||
|
||||
# Icon for the website. (This isn't linked into "make all".)
|
||||
website.ico: putty-16.png
|
||||
./icon.pl -4 $^ >$@
|
||||
|
||||
xpmputty.c: putty-16.png putty-32.png putty-48.png
|
||||
./cicon.pl main_icon $^ > $@
|
||||
|
||||
xpmpucfg.c: puttycfg-16.png puttycfg-32.png puttycfg-48.png
|
||||
./cicon.pl cfg_icon $^ > $@
|
||||
|
||||
xpmpterm.c: pterm-16.png pterm-32.png pterm-48.png
|
||||
./cicon.pl main_icon $^ > $@
|
||||
|
||||
xpmptcfg.c: ptermcfg-16.png ptermcfg-32.png ptermcfg-48.png
|
||||
./cicon.pl cfg_icon $^ > $@
|
||||
|
||||
clean:
|
||||
rm -f *.png *.ico *.c
|
||||
1093
puttysrc/ICONS/MKICON.PY
Normal file
1093
puttysrc/ICONS/MKICON.PY
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user