#! /usr/bin/perl

##[[[[[[[[[[[[[[[[[[[[[[[
#Blur.cgi
#takes a jpeg and, applies a cosine transformation, shows the transform,
# filters the transformation, and then displays the filtered image.
#
#by Ian Smith-Heisters ian@0x09.com
#March 8th, 2004
##]]]]]]]]]]]]]]]]]]]]]]]

use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
use GD;
use strict;
use warnings;

#initialize global variable hash
my %g = (filename => 'test.jpg',
	);

#Load any global variables from the URL
for my $key (keys %g){
  $g{$key} = param($key) if defined param($key);
}

#create an image from filename
my $image = GD::Image -> new($g{filename}, 1) || die;

#get the width and height of the image
#  getBounds returns a two member list (width,height)
my @bounds = $image -> getBounds();
my $width  = shift @bounds;
my $height = pop   @bounds;

#returns a hash containing three arrays, each containing R, G, or B information
# for each pixel in the image
sub getColors {
  my $img = shift;
  my %temp;
  for (my $x = 0;$x<$width;$x++){ #start with by looping over the columns
    for (my $y = 0;$y<$height;$y++){ #then loop over each row
      my @index = $img -> getPixel($x,$y);
      my $red = shift @index;
      my $green = shift @index;
      my $blue = shift @index;
      $temp{r}[$x][$y] = $red;
      $temp{g}[$x][$y] = $green;
      $temp{b}[$x][$y] = $blue;
    }
  }
  return %temp;
}

#return an image given an rgb hash
sub getImage {
  my %rgb = shift;
  my $img = GD::Image -> new($rgb{r}, $rgb{r}[0], 1)||die; # create a new image
  for (my $x=0; $x<$width; $x++) { # cycle through x pixels
    for (my $y=0; $y<$height; $y++){	# cycle through y pixels
      my @rgbList = ($rgb{r}[$x][$y], $rgb{g}[$x][$y], $rgb{b}[$x][$y]);
      $img -> setPixel($x, $y, $img->colorClosest(@rgbList));
    }
  }
  return $img;
}

my %hash = getColors($image);
my $newImage = getImage(%hash);

print 'Content-type: image/jpg\n\n';
print $newImage -> jpeg;
