##########################################################
#                #                                       #
#	 ManyPage    #    See habille.pl / Voir habille.pl   #
#                #                                       #
##########################################################
#
# Cette fonction calcule la taille des images a afficher,
# Ca ne marche qu'avec les fichier gif (prononcer guif) et jpeg
#
# Cette fonction ne viens pas de moi, mais de
# Patrick Atoon (patricka\@cs.kun.nl),
# Que lui meme a copie de 
# Marcus E. Hennecke <marcush@leland.stanford.edu>
#
# Comique, non?
#
############################
#
# Cette petite fonction (image_size) ,
# Parcontre, est a moi
#
# Cette fonction va chercher la taille de images pour l'inserer
# Dans le tag <IMG> (WIDTH et HEIGHT)
# Si WIDTH ou HEIGHT existent deja, on laisse tomber.
#
###############
#
#  Copyright (C) 2000 Pierre Cordani - Pascal Vuylsteker
#
# 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.
#
# Ce programme est un logiciel libre ; vous pouvez le redistribuer et/ou le modifier conformŽment
# aux dispositions de la Licence Publique GŽnŽrale GNU, telle que publiŽe par la Free Software
# Foundation ; version 2 de la licence, ou encore (ˆ votre choix) toute version ultŽrieure.
#
###################

sub image_size
{
 local ($info_image,$source_image) = @_;

# print " toto $source_image\n";

      while($info_image =~ /.*(<\s*iMG(.*?)>).*/s)
	  {
#	   print "1 $1 - $2\n";
	   $le_tout = $1;
	   $le_reste = $2;
	   $info_image =~ s/\Q$le_tout\E/<IMG$le_reste>/g;
	  }

# print " 2 toto $source_image\n";

      while($info_image =~ /.*(<\s*iMg(.*?)>).*/s)
	  {
#	   print "2 $1 - $2\n";
	   $le_tout = $1;
	   $le_reste = $2;
	   $info_image =~ s/\Q$le_tout\E/<IMG$le_reste>/g;
	  }

# print " 3 toto $source_image\n";

      while($info_image =~ /.*(<\s*imG(.*?)>).*/s)
	  {
#	   print "3 $1 - $2\n";
	   $le_tout = $1;
	   $le_reste = $2;
	   $info_image =~ s/\Q$le_tout\E/<IMG$le_reste>/g;
	  }
# print " 3 toto $source_image\n";
      while($info_image =~ /^.*?(<\s*img(.*?)>).*$/s)
	  {
#	   print "4 $1 - $2\n";
	   $le_tout = $1;
	   $le_reste = $2;
#	   print "$1 - $2\n";
	   $info_image =~ s/\Q$le_tout\E/<IMG$le_reste>/g;
	  }
# print " 3 toto $source_image\n";
      while($info_image =~ /.*(<\s*ImG(.*?)>).*/s)
	  {
#	   print "5 $1 - $2\n";
	   $le_tout = $1;
	   $le_reste = $2;
	   $info_image =~ s/\Q$le_tout\E/<IMG$le_reste>/g;
	  }
# print " 3 toto $source_image\n";
      while($info_image =~ /.*(<\s*Img(.*?)>).*/s)
	  {
#	   print "6 $1 - $2\n";
	   $le_tout = $1;
	   $le_reste = $2;
	   $info_image =~ s/\Q$le_tout\E/<IMG$le_reste>/g;
	  }
# print " 3 toto $source_image\n";
      while($info_image =~ /.*(<\s*IMg(.*?)>).*/s)
	  {
#	   print "7 $1 - $2\n";
	   $le_tout = $1;
	   $le_reste = $2;
	   $info_image =~ s/\Q$le_tout\E/<IMG$le_reste>/g;
	  }
	  
#	  print "$source_image\n";

 local $rest1 =  substr($info_image, 0, (length($info_image)/2));
 local $rest2 =  substr($info_image, (length($info_image)/2), length($info_image));
 
 if($rest2 =~ /^([^<]*)<(.*)$/is)
  {
#   print "==>$1<==\n";
#   print "==>$2<==\n";
   local ($test1, $test2) = ($1, $2);
   if($test2 =~ /.*>.*/s)
    {
	 $rest2 = "<$test2";
	 $rest1 .= $test1;
	}
 }
 ($info_image, $rest2) = do_image_size($info_image, $rest1, $rest2,$source_image);
 ($info_image, $rest2) = do_image_size($info_image, $rest2, "",$source_image);

 $info_image =~ s/$SAPI_LT/</g;
 $info_image =~ s/$SAPI_GT/>/g;
 return $info_image;
}

sub do_image_size
 {

  local ($info_image, $info_buffer, $other_buf,$source_image) = @_;
  
#  print "\n\n\n$info_buffer\n\n\n";
  
  
  while($info_buffer =~ /.*(<\s*IMG(.*?))>.*/s)
  {
   local($le_tout,$entre) = ($1,$2);
#   if($le_tout =~ /^<.*<.*/)
#    {
#	 error("le fichier est errone ($le_tout)");
#	 return $info_image, $other_buf;;
#	}
   if($le_tout =~ /^<.*<(.*)/)
    {
	 local ($maudit_tag) = $1;
#print "\n\n\n$info_buffer\n\n\n";
	 print "==>$maudit_tag<==\n";
	 print "==>$le_tout<==\n";
     $info_image =~ s/\Q<$maudit_tag>(.*?)<\/$maudit_tag>\E/$SAPI_LT$maudit_tag$SAPI_GT$1$SAPI_LT\/$maudit_tag$SAPI_GT/sg;
     $info_buffer =~ s/\Q<$maudit_tag>(.*?)<\/$maudit_tag>\E/$SAPI_LT$maudit_tag$SAPI_GT$1$SAPI_LT\/$maudit_tag$SAPI_GT/sg;
     $other_buf =~ s/\Q<$maudit_tag>(.*?)<\/$maudit_tag>\E/$SAPI_LT$maudit_tag$SAPI_GT$1$SAPI_LT\/$maudit_tag$SAPI_GT/sg;

#
# Au cas ou ce serai un tag isole (sans fermeture)
#

     $info_image =~ s/\Q<$maudit_tag>\E/$SAPI_LT$maudit_tag$SAPI_GT/sg;
     $info_buffer =~ s/\Q<$maudit_tag>\E/$SAPI_LT$maudit_tag$SAPI_GT/sg;
     $other_buf =~ s/\Q<$maudit_tag>\E/$SAPI_LT$maudit_tag$SAPI_GT/sg;
	}
   else
    {
#	 print "ok\n";	
     if($entre =~ /.*SRC\s*=\s*"(.*?)".*/is)
      {
	   $image_name = $1;
	   local $n = split (/$SAPI_LT/,$image_name);
#Nombre d'images en trop pour le calcul de WIDTH et HEIGHT
	   local ($total) = ($n - 3) / 2; 
	   local ($i) = 0;
#	   print "$image_name\n";
	   while($n[$i]){print "$n[$i]\n";$i++;}
	   while($total > 0)
	    {
	     $image_name =~ s/$SAPI_LT.*?$SAPI_GT.*?$SAPI_LT\/.*?$SAPI_GT//;
		 $total--;
		}
	   $image_name =~ s/$SAPI_LT.*?$SAPI_GT//g;
#	   print "$total : $image_name\n";
	  }
     else
      {
       $le_tout =~ s/</&lt/g;
       $le_tout =~ s/>/&gt/g;
	   print "Attention, le tag IMG est erron&eacute; : $le_tout<BR>\n";
	  }

     if(!($le_tout =~ /.*(WIDTH|HEIGHT).*/is))
      {
       if($image_name =~ /^\/.*/s)
 	    {$image_name = $Dest.$image_name}
 	   else
 	    {
		 $source_image =~ s/(.*\/).*$/$1/s;
	     $image_name = "$source_image/$image_name"
	    }

	   if($image_name =~ /.*\.gif$/is)
        {
	     local ($res) = &GIF_size($image_name);
	     $info_image =~ s/\Q$le_tout\E>/$le_tout $res>/gs
	    }
       if($image_name =~ /.*\.(jpg|jpeg)$/is)
        {
	     local ($res) = &JPEG_size($image_name);
	     $info_image =~ s/\Q$le_tout\E>/$le_tout $res>/gs
	    }
      }
     $info_buffer =~ s/\Q$le_tout\E>//gs;
     $other_buf =~ s/\Q$le_tout\E>//gs;

    }
  } 
  
 return $info_image, $other_buf;
 }


#########################################################################
#
# Subroutines
#

# This is a little hack to determine the width and height in pixels of
# a JPEG image. It is a hack because it assumes that some markers
# exist which in fact don't. This should really cause no problems,
# however.
# Original written by Marcus E. Hennecke <marcush@leland.stanford.edu>

sub JPEG_size
{
	# Define marker types
	local($M_SOF0) = 0xC0;
	local($M_SOF15) = 0xCF;
	local($M_SOI) = 0xD8;
	local($M_EOI) = 0xD9;
	local($M_SOS) = 0xDA;
	local($M_COM) = 0xFE;
	local($l,$d,$h,$w);

	local($fn) = @_;

	if (!open(IMAGE, $fn))
	{
		print "Could not open file \"$fn\"!\n";
		return "";
	}

	# Check the first few bytes to see if this is a JPEG file. From the docs:
	#
	# o you can identify a JFIF file by looking for the following sequence:
	#   X'FF', SOI, X'FF', APP0, <2 bytes to be skipped>, "JFIF", X'00'.

	local($c1) = &read_1_byte;
	local($c2) = &read_1_byte;

	if ($c1 != 0xFF || $c2 != $M_SOI)
	{
		print("\"$fn\" is not a JPEG file!\n");
		close(IMAGE);
		return "";
	}

	# Go through the markers in the header. Stop when height and width are
	# determined or when end of header is reached

	while (1)
	{
		# Get the next marker
		local($db) = 0;
		$c1 = &read_1_byte;

		while ($c1 != 0xFF)
		{
			$db++;
			$c1 = &read_1_byte;
		}

		while ($c1 == 0xFF)
		{
			$c1 = &read_1_byte;
		}

		if ($db)
		{
			 print("Warning: garbage data found in JPEG file \"$fn\"\n");
		}

		# What type marker are we looking at?
		# Note that this first if statement is actually not quite correct.
		# It assumes that the markers SOF0 to SOF15 all exist and are in
		# order. In reality, they are in order, but SOF4, SOF8, and SOF12
		# do not exist. Nevertheless, these markers should not normally
		# appear in a JPEG file and so this if statement works.

		if ($c1 >= $M_SOF0 && $c1 <= $M_SOF15)
		{
			# Do we have width and height?
			($l,$d,$h,$w) = unpack("nCnn", &read_n_bytes(7));

			$l = &ushort($l);
			$h = &ushort($h);
			$w = &ushort($w);
			close(IMAGE);
			return "WIDTH=${w} HEIGHT=${h}";
		}
		elsif ($c1 == $M_SOS || $c1 == $M_EOI)
		{
			# Did we reach header end?
			close(IMAGE);
			return "";
		}
		else
		{
			# Otherwise, skip this variable
			$l = &ushort(unpack("n", &read_n_bytes(2))) - 2;

			if ($l < 0)
			{
				print("Erroneous JPEG marker length in file \"$fn\"!\n");
				close(IMAGE);
				return "";
			}

			&read_n_bytes($l);
		}
	}
}

#
# Determine the size of a GIF file
#
sub GIF_size
{
	local($fn) = @_;

	if (!open(IMAGE, $fn))
	{
		print "Could not open file \"$fn\"!\n";
		return "";
	}

	$read = &read_n_bytes(6);

	if ($read ne "GIF87a" && $read ne "GIF89a")
	{
		print "\"$fn\" is not a GIF file!\n";
		close(IMAGE);
		return "";
	}

	# Examine the Logical Screen Descriptor
	local($lsw, $lsh, $pf, $bg, $par) = unpack("vvCCC", &read_n_bytes(7));

	# Is it followed by a Global Color table?
	if ($pf & 0x80)
	{
		# Skip the Global Color Table
		local($GCTsize) = $pf & 0x07;
		&read_n_bytes(3 * (2 << $GCTsize));
	}

	# Go through the markers in the header. Stop when height and width are
	# determined or when end of header is reached

	while (1)
	{
		# Get the next marker
		$c = &read_1_byte;

		if ($c == 0x21)
		{
			#
			# This is an Extension.
			#

			# Read the label.
			$c = &read_1_byte;

			# Read the remainder of this Extension Block and while we're at it,
			# read all possible Data Sub-blocks as well.
			while ($blksize = &read_1_byte)
			{
				&read_n_bytes($blksize);
			}
		}
		elsif ($c == 0x2c)
		{
			#
			# This is the most holy of all... The Image Descriptor.
			#
			local($lp,$tp,$w,$h,$pf) = unpack("vvvvC", &read_n_bytes(9));
			$w = &ushort($w);
			$h = &ushort($h);
			close(IMAGE);
			return "WIDTH=${w} HEIGHT=${h}";
		}
		else
		{
			close(IMAGE);
			return "";
		}
	}
}

#Fonction de fin de page
sub fin_page
{
 local ($S) = @_;
 print $S "</BODY>\n";
 print $S "</HTML>\n";
 
}

# Reads one byte. If EOF is reached, terminates with an error message.
sub read_1_byte
{
	return ord(getc(IMAGE));
}

# Reads N bytes. If EOF is reached, terminates with an error message.
sub read_n_bytes
{
	local($n) = @_;
	local($ch) = "";
	read(IMAGE, $ch, $n) == $n || print("Premature EOF in GIF file \"$fn\"!\n");
	return $ch;
}

# Make a signed short unsigned.
sub ushort
{
	local($n) = @_;

	if ($n < 0)
	{
		$n += 65536;
	}

	return $n;
}

return 1;
