<?php
// The PNG server - generates and colours PNG images on-the-fly.
// BPE - 8/2/4
//
// Parameters:
// type = tl|tr|bl|br|... the image to be generated
// rgb = a hex RGB triple being the colour of the non-transparent area
$type = isset($_GET['type']) ? $_GET['type'] : '';
$rgb = isset($_GET['rgb']) ? $_GET['rgb'] : '';
// Bail out if we don't have a proper hex RGB triple
if (!preg_match('/^[0-9a-f]{6}$/',$rgb)) {
exit;
}
// PNGs include a CRC after each chunk. Since we are changing colour
// info in the PLTE chunk we recalculate the CRC.
$plte = "504c5445ffffff".$rgb;
$crc = sprintf("%08x",crc32(pack('H*', $plte)));
$plte = '00000006'.$plte.$crc;
switch ($type) {
case 'tl': // Top-left corner
$hex = "89504e470d0a1a0a0000000d49484452"
."00000017000000170103000000dae446"
."e3{$plte}"
."0000000174524e530040e6d866"
."0000002f4944415478da63600082"
."faff3f801848ff01e20f407c00881b80"
."18285707c435405c01c505509c00c50e"
."5830140000a0520e668ebda12a000000"
."0049454e44ae426082";
break;
case 'bl': // Bottom-left corner
$hex = "89504e470d0a1a0a0000000d49484452"
."00000017000000170103000000dae446"
."e3{$plte}"
."0000000174524e530040e6d866"
."0000002e4944415478da63608002072c"
."38018a0ba0b8028a6b80b80e88eb41b8"
."01880f00f10720fe03c4ff41f80710ff"
."03009ffd10e2cc8fd973000000004945"
."4e44ae426082";
break;
case 'tr': // Top-right corner
$hex = "89504e470d0a1a0a0000000d49484452"
."00000017000000170103000000dae446"
."e3{$plte}"
."0000000174524e530040e6d866"
."000000314944415478da63600002fbff"
."ff18188198a11e88e581981d88998198"
."11881940b80e88eda0580e8af9a0980d"
."0b66026100632f0c4c80dedef6000000"
."0049454e44ae426082";
break;
case 'br': // Bottom-right corner
$hex = "89504e470d0a1a0a0000000d49484452"
."00000017000000170103000000dae446"
."e3{$plte}"
."0000000174524e530040e6d866"
."000000334944415478da6dc3c10d0010"
."1004c03d127e4aa0133aa3f33d9bb8a7"
."490640c25b3e5bec71c6ad044cb3561d"
."7a087362a93b2ffc5b0f4878b3ded600"
."00000049454e44ae426082";
break;
case 'lc': // Left tab-corner
$hex = "89504e470d0a1a0a0000000d49484452"
."00000006000000060103000000da027d"
."0b{$plte}"
."0000000174524e530040e6d866"
."000000134944415478da63f8c1f080e1"
."004303103200001bd40399841f22d700"
."00000049454e44ae426082";
break;
case 'rc': // Right tab-corner
$hex = "89504e470d0a1a0a0000000d49484452"
."00000006000000060103000000da027d"
."0b{$plte}"
."0000000174524e530040e6d866"
."000000124944415478da63a8619061e0"
."61600142060006d000adf2bc83440000"
."000049454e44ae426082";
break;
case 'ra': // Right-arrow
$hex = "89504e470d0a1a0a0000000d49484452"
."0000000c0000000b010300000071befe"
."1c{$plte}"
."0000000174524e530040e6d866"
."00000004674946670000000a7c59ed53"
."000000214944415478da636062606006"
."a20686ff0718fe3f60f8ff014c1e0089"
."00c5991800a8dc0a3c61ad8e7d000000"
."0049454e44ae426082";
break;
case 'l': // Left line-end
$hex = "89504e470d0a1a0a0000000d49484452"
."000000130000002501030000009abd40"
."3f{$plte}"
."0000000174524e530040e6d866"
."000000404944415478da7dce310e0020"
."0803c03e9da7f9149ee0c860acc560c2"
."e4700b81169000435c4c006c59a23166"
."f1321afbe87beff66545e5674ff6dd5e"
."af3f88030c2325c9ac7a62fd00000000"
."49454e44ae426082";
break;
case 'r': // Right line-end
$hex = "89504e470d0a1a0a0000000d49484452"
."000000130000002501030000009abd40"
."3f{$plte}"
."0000000174524e530040e6d866"
."0000003d4944415478da6390ffff8081"
."19881940d81e88e581981f88d9819819"
."8819a19801861390b0021e8cac0eaa17"
."661633d47c7ea87df610fb41ee00ba07"
."00f6501f51345d757a0000000049454e"
."44ae426082";
break;
default:
exit;
}
$content_length = strlen($hex)/2;
$expires = date('r', time()+24*3600);
header("Content-Type: image/png");
header("Content-Length: $content_length");
header("Cache-Control: public");
header("Expires: $expires");
header("Last-Modified: Fri, 6 Feb 2004 12:00:00 GMT");
print pack('H*', $hex);
?>