#!/usr/bin/perl
# web interface cgi script to gif2png
# Copyright (C) 2003-2004 Richard Stanway
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# http://www.gnu.org/licenses/gpl.txt
#
# Live demo: http://www.r1ch.net/stuff/gif2png/webinterface/
#required modules
use CGI;
use HTTP::Date;
use Digest::SHA1;
use Fcntl ':flock';
#barf totally at 250kB uploads
$CGI::POST_MAX = 1024 * 250;
#binaries and directories needed - note, tempdir and stats
#must be writable by whoever the cgi runs as!
$tempdir = '/home/r1ch/gif2png/temp';
$statsfile = '/home/r1ch/gif2png/stats';
$gif2png_location = '/home/r1ch/gif2png/gif2png';
$pngcrush_location = '/home/r1ch/gif2png/pngcrush';
#load an already converted image
if ($ENV{'REQUEST_URI'} =~ /loadimg\/(.+)\//) {
$match = $1;
#illegal request
if ($match !~ /^[a-fA-F0-9]{40}$/) {
print "Status: 403 Unauthorized\nContent-type: text/plain\n\nIllegal request.";
exit (1);
}
#tell browser to use cached version
if ($ENV{'HTTP_IF_MODIFIED_SINCE'} ne '' || $ENV{'HTTP_IF_MATCH'} ne '') {
print "Status: 304 Not Modified\n\n";
exit(0);
}
#open existing temp image
$fname = "$tempdir/gif2pngcgitemp" . $match;
$last_modified = (stat($fname))[9];
open (GIF2PNG, "$fname.png") or perror();
if (read(GIF2PNG, $buffer, 1024)) {
#file exists, dump it to browser
print "Content-type: image/png\n";
print "Last-Modified: " . time2str($last_modified) . "\n\n";
print $buffer;
while (read(GIF2PNG, $buffer, 1024)) {
print $buffer;
}
exit(0);
} else {
#file is missing, probably pruned
perror();
}
}
$query = new CGI;
$file_handle = $query->upload('file');
print <gif2png web interface
EOF
#read stats
open (STATS, "<$statsfile");
@stats =
For 99.9% of browsers, the output PNG file will display exactly the same as the .gif file, including transparency. PNG files work on Internet Explorer 4.0+, Netscape 4.0+, Mozilla, and many more browsers.
EOF } else { #image uploaded, process it srand(time()); $fh = $query->upload('file'); binmode ($fh); #get unique temp filename $fcode = Digest::SHA1::sha1_hex($ENV{REMOTE_ADDR}.time().$$.$query->param ('file')); $fname = "$tempdir/gif2pngcgitemp" . $fcode; #write upload to temp file open (GIF2PNG, ">$fname.gif") or error(); binmode (GIF2PNG); $bytestotal = 0; if ($bytesread = read($fh, $buffer, 1024)) { print 'Converting file, please wait...'; $donemsg = 1; print GIF2PNG $buffer; $bytestotal += $bytesread; while ($bytesread = read($fh, $buffer, 1024)) { $bytestotal += $bytesread; print GIF2PNG $buffer; } close (GIF2PNG); if ($bytestotal == 0) { $errdetails = "upload failure."; error(); } #run gif2png $undef = `$gif2png_location -a $fname.gif 2>&1`; $beforec = (stat("$fname.png"))[7]; if ($beforec > 0) { #run pngcrush on the resultant png (assuming one is made) @undef = `ulimit -v 16384 ; ulimit -m 16384 ; ulimit -l 16384 ; $pngcrush_location -rem alla -brute -l 8 $fname.png $fname-crushed.png`; $afterc = (stat("$fname-crushed.png"))[7]; if ($afterc < $beforec) { unlink ("$fname.png"); rename ("$fname-crushed.png", "$fname.png"); } else { unlink ("$fname-crushed.png"); } } else { #gif2png failed for some reason, find out why if ($undef =~ /is animated/) { $errdetails = "upload was an animated .gif (png does not support animation)"; } elsif ($undef =~ /not a GIF file/) { $errdetails = "upload was not a valid .gif file"; } else { $errdetails = "gif2png failure."; } unlink ("$fname.gif"); error(); } #conversion/crushing finished ok $fsize = (stat("$fname.png"))[7]; print "\n\n"; $donemsg = 0; if ($fsize == 0) { $errdetails = "pngcrush failure."; error(); } $userfname = $query->param ('file'); if ($userfname =~ /(.*(\\|\/))*(.+)$/) { $userfname = $3; } if ($userfname eq '') { $userfname = "tempupload.gif"; } $pngname = $userfname; $pngname =~ s/\.gif$/\.png/i; $pcc = int(100 - (($fsize / $bytestotal) * 100)); print <Optimized .png image ($pngname): $fsize bytes ($pcc% smaller):
Please save the above .png file to your hard disk if you wish to keep it. It will be deleted from this server in one hour. Right-click here and choose 'save link target' or 'save target as' to save this .png