#file:Apache2/AMFImageRendering.pm; 
#-------------------------------- 

#
# Created by Idel Fuschini 
# Date: 01/08/10
# Site: http://www.apachemobilefilter.org
# Mail: idel.fuschini@gmail.com



package Apache2::AMFImageRendering; 
  
  use strict; 
  use warnings;
  use POSIX qw(ceil);
  use Apache2::AMFCommonLib ();
  
  use Apache2::RequestRec ();
  use Apache2::RequestUtil ();
  use Apache2::SubRequest ();
  use Apache2::Log;
  use Apache2::Filter (); 
  use APR::Table (); 
  use LWP::Simple;
  use Image::Resize;
  use Image::Scale;
  use File::Copy;
  use Imager;
  use Apache2::Const -compile => qw(OK REDIRECT DECLINED HTTP_MOVED_TEMPORARILY);
  use constant BUFF_LEN => 1024;


  #
  # Define the global environment
  # 

  use vars qw($VERSION);
  $VERSION= "4.02";
  my $CommonLib = new Apache2::AMFCommonLib ();
  my %Capability;
  my %Array_fb;
  my %Array_id;
  my %Array_fullua_id;
  my %Array_DDRcapability;

  my %XHTMLUrl;
  my %WMLUrl;
  my %CHTMLUrl;
  my %ImageType;
  my %cacheArray;
  my %cacheArray_toview;
  

  my $intelliswitch="false";
  my $mobileversionurl;
  my $fullbrowserurl;
  my $querystring="false";
  my $showdefaultvariable="false";
  my $wurflnetdownload="false";
  my $downloadwurflurl="false";
  my $resizeimagedirectory="";
  my $downloadzipfile="true";
  my $virtualdirectoryimages="false";
  my $virtualdirectory="";
  my $repasshanlder=0;
  my $globalpassvariable="";
  my $log4wurfl="";
  my $loadwebpatch="false";
  my $dirwebpatch="";
  my $patchwurflnetdownload="false"; 
  my $patchwurflurl="";
  my $redirecttranscoder="true";
  my $redirecttranscoderurl="";
  my $detectaccuracy="false";
  my $listall="false";
  my $resizeimagesmall="false";
  my $par_height='height';
  my $par_width='width';
  my $par_perc='dim';
  
  $ImageType{'image/png'}="png";
  $ImageType{'image/gif'}="gif";
  $ImageType{'image/jpg'}="jpg";
  $ImageType{'image/jpeg'}="jpeg";
  
  #
  # Check if MOBILE_HOME is setting in apache httpd.conf file for example:
  # PerlSetEnv MOBILE_HOME <apache_directory>/MobileFilter
  #
  $CommonLib->printLog("---------------------------------------------------------------------------"); 
  $CommonLib->printLog("AMFImageRendering Version $VERSION");
  if ($ENV{AMFMobileHome}) {
	  &loadConfigFile();
  } else {
	  $CommonLib->printLog("AMFMobileHome not exist.	Please set the variable AMFMobileHome into httpd.conf");
	  ModPerl::Util::exit();
  }
sub loadConfigFile {
		 my $null="";
		 my $null2="";
		 my $null3="";
         my $val;
	     my $capability;
	     my $r_id;
	     my $dummy;
	      	#The filter
	      	$CommonLib->printLog("ResizeImageDirectory: Start read configuration from httpd.conf");
	      	 if ($ENV{ResizeImageDirectory}) {
				$resizeimagedirectory=$ENV{ResizeImageDirectory};
				$CommonLib->printLog("ResizeImageDirectory is: $resizeimagedirectory");
			 } else {
			    $CommonLib->printLog("ERROR: ResizeImageDirectory parameter must be setted");
			    ModPerl::Util::exit();
		}
		if ($ENV{ResizeSmallImage}) {
			$resizeimagesmall=$ENV{ResizeSmallImage};
			$CommonLib->printLog("ResizeSmallImage is: $resizeimagesmall. The image smallest of device screensize is also resized (low quality)");
		}
	      	if ($ENV{ImageParamWidth}) {
				$par_width=$ENV{ImageParamWidth};
				$CommonLib->printLog("ImageParamWidth is: $par_width. To force the width of image the url must be <url image>?$par_width=<width>");
		} 
	      	if ($ENV{ImageParamHeight}) {
				$par_height=$ENV{ImageParamHeight};
				$CommonLib->printLog("ImageParamHeight is: $par_height. To force the height of image the url must be <url image>?$par_width=<height>");
		} 
	      	if ($ENV{ImageParamPerc}) {
				$par_perc=$ENV{ImageParamPerc};
				$CommonLib->printLog("ImageParamPerc is: $par_perc. To force the percentage of image the url must be <url image>?$par_perc=<percentage>");
		} 

	    $CommonLib->printLog("Finish loading  parameter");
}
sub handler    {
      my $f = shift;
      my $capability2;
      my $s = $f->r->server;
      my $query_string=$f->r->args;
      my $uri = $f->r->uri();
      $uri =~ s/\//_/g;
      my $content_type=$f->r->content_type();
      my @fileArray = split(/\//, $uri);
      my $file=$fileArray[-1];
      my $docroot = $f->r->document_root();
      $docroot =~ s/\//_/g;
      my $servername=$f->r->get_server_name();
      my $id="";
      my $method="";     
      my $location;
      my $width_toSearch;
      my $type_redirect="internal";
      my $return_value=Apache2::Const::DECLINED;
	  my $dummy="";
	  my $variabile2="";
	  my %ArrayCapFound;
	  my $controlCookie;
	  my $query_img="";
      my %ArrayQuery;
      my $var;
      my $cookie = $f->r->headers_in->{Cookie} || '';
      my $width=1000;
      my $height=1000;
      my $image2="";
      my $device_claims_web_support='null';
      my $is_wireless_device='null';
      my $isMobile='true';

      $content_type=lc($content_type);
      if ($f->r->pnotes('max_image_width')) {      
      	$width=$f->r->pnotes('max_image_width')
      }
      if ($f->r->pnotes('max_image_height')) {
         $height=$f->r->pnotes('max_image_height');
      }
      if ($f->r->pnotes('amf_device_ismobile')) {
        $isMobile=$f->r->pnotes('amf_device_ismobile');
      }
      
      $repasshanlder=$repasshanlder + 1;
 	  #
 	  # Reading value of query string 
 	  #
      if ($query_string) {
		  my @vars = split(/&/, $query_string); 	  
		  foreach $var (sort @vars){
				   if ($var) {
						my ($v,$i) = split(/=/, $var);
						$v =~ tr/+/ /;
						$v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
						$i =~ tr/+/ /;
						$i =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
						$i =~ s/<!--(.|\n)*-->//g;
						$ArrayQuery{$v}=$i;
					}
		  }
 	  }      
	  if ($ImageType{$content_type}) {
	          my $imageToConvert;
	          my $imagefile="";
				  if ($ArrayQuery{par_height}) {
				       if ( $ArrayQuery{$par_height} =~ /^-?\d/) {
				       		$height=$ArrayQuery{par_height};
				       }
				  }
				  $imageToConvert=$f->r->filename();
				  if ($isMobile eq 'false') {
					my $image = Image::Resize->new("$imageToConvert");
					$width=$image->width();					
				  }
				  if ($ArrayQuery{$par_width}) {
				       if ( $ArrayQuery{$par_width} =~ /^-?\d/) {
				       		$width=$ArrayQuery{$par_width};
				       }
				  }

				  if ($ArrayQuery{$par_perc}) {
				       if ( $ArrayQuery{$par_perc} =~ /^-?\d/) {
				       		$width=$ArrayQuery{$par_perc} * $width / 100;
				       }
				  }
				  $imagefile="$resizeimagedirectory/$docroot-$uri.$width";
				  #
				  # control if image exist
				  #
				  $return_value=Apache2::Const::DECLINED;
				  
				  if ( -e "$imageToConvert") {
						  
					  my $filesize; 
					  if ( -e "$imagefile") {
					  } else { 
						  my $image = Image::Resize->new("$imageToConvert");
						  if ($image->width() < $width && $resizeimagesmall eq 'false') {
							copy($imageToConvert, $imagefile);
     					          } else {
							if ($content_type eq "image/gif") {
							      my @in = Imager->read_multi(file => $imageToConvert) or die "Cannot read image file: ", Imager->errstr, "\n";
							      $in[0]->tags(name => 'i_format') eq 'gif' or die "File $imageToConvert is not a GIF image";
							      my $src_screen_width = $in[0]->tags(name => 'gif_screen_width');
							      my $src_screen_height = $in[0]->tags(name => 'gif_screen_height');
							      my $factor=$width/$src_screen_width;
							      my $out_screen_width = ceil($src_screen_width * $factor);
							      my $out_screen_height = ceil($src_screen_height * $factor);
							      my @out;
							      for my $in (@in) {
							      my $scaled = $in->scale(scalefactor => $factor, qtype=>'mixing');
							      
							      # roughly preserve the relative position
							      $scaled->settag(name => 'gif_left', 
									      value => $factor * $in->tags(name => 'gif_left'));
							      $scaled->settag(name => 'gif_top', 
									      value => $factor * $in->tags(name => 'gif_top'));
							    
							      $scaled->settag(name => 'gif_screen_width', value => $out_screen_width);
							      $scaled->settag(name => 'gif_screen_height', value => $out_screen_height);
							    
							      # set some other tags from the source
							      for my $tag (qw/gif_delay gif_user_input gif_loop gif_disposal/) {
								$scaled->settag(name => $tag, value => $in->tags(name => $tag));
							      }
							      if ($in->tags(name => 'gif_local_map')) {
								$scaled->settag(name => 'gif_local_map', value => 1);
							      }
							    
							      push @out, $scaled;
							      }
							      my $dummy=$imagefile.".gif";
							      Imager->write_multi({ file => $dummy }, @out) or die "Cannot save $imagefile: ", Imager->errstr, "\n";
							      rename($dummy, $imagefile);
							} 
							if ($content_type eq "image/png") {
							       my $img = Image::Scale->new("$imageToConvert") ;
							       $img->resize_gd( { width => $width } );
							       $img->save_png("$imagefile");
							}
							if ($content_type eq "image/jpeg") {
							       my $img = Image::Scale->new("$imageToConvert") ;
							       $img->resize_gd( { width => $width } );
							       $img->save_jpeg("$imagefile");
							}
						 }

					  }
					     unless( $f->ctx ) { 
					       $f->r->headers_out->unset('Content-Length'); 
					       $f->ctx(1); 
					    }
					  $filesize = -s "$imagefile";
		   			  $f->r->headers_out->set("Content-Length"=>$filesize);
					  $f->r->content_type($content_type);
					  open (FH,"$imagefile") or die ("couldn't open $imagefile\n");
 							read (FH,$image2,$filesize) ;
 					  close FH;

					  $f->print($image2);				  
					  $return_value=Apache2::Const::OK;
				  }
	  }
      return $return_value;
      
} 

1;


=head1 NAME

Apache2::AMFImageRendering - Used to resize images (jpg, png, gif gifanimated) on the fly to adapt to the screen size of the mobile device

=head1 DESCRIPTION

This module have the scope to manage with AMF51DegreesFilter, AMFDetectRightFilter and AMFWURFLFilter module the images for mobile devices. 

For more details: http://wiki.apachemobilefilter.org

=head1 AMF PROJECT SITE

http://www.apachemobilefilter.org

=head1 DOCUMENTATION

http://wiki.apachemobilefilter.org

Perl Module Documentation: http://wiki.apachemobilefilter.org/index.php/AMFImageRendering

=head1 AUTHOR

Idel Fuschini (idel.fuschini [at] gmail [dot] com)

=head1 COPYRIGHT

You may distribute under the terms of either the GNU General Public
License or the Artistic License, as specified in the Perl README file.

=cut
