'; /* this script needs to have three contexts: 1) display image list with thumbnails 2) display image frame 2) display an image user preferences should be: 1) maximum image width. This way: - small images won't be scaled down - sideways images will be safe - large images will retain their ratio This tool depends on ImageMagick being installed. The tool "convert" in particular. ;) To set this tool up so that caching will work, you need to do: mkdir -p /tmp/imgcache/DATA chown nobody.nobody /tmp/imgcache/DATA And then change the $CACHE_SUFFIX to identify YOUR stuff.... Thanks to following for ideas and improvements - Jason Ernst - Tony Brummett */ $CONVERT_PATH="/usr/bin/convert"; $CACHE_SUFFIX="kees"; $CACHE_LOC="/tmp/imgcache/DATA"; $CACHE_PREFIX="$CACHE_LOC/$CACHE_SUFFIX"; # This should be $_SERVER['PHP_SELF'] unless it's named "index.php" # in which case, it can stay blank, making the URL shorter. $SCRIPT_NAME=""; # set up the reported timezone putenv ("TZ=PST8PDT"); # US Pacific #putenv ("TZ=CST6CDT"); # US Central # Add style sheets, etc here $HEADERS=''; #$HEADERS=''; # Image resolutions you want to offer viewers $RESLIST=array("1600","1024","640","320","160"); $RESDEFAULT="640"; $THUMBRES="80"; # Show prev/next thumbnails? $NAVTHUMBS=1; $THUMB_COLS=1; # Columns of thumbnails (not implemented yet) # Can't this be controlled with style sheets? $THUMB_BORDER="0"; $IMAGE_BORDER="0"; # What the date on the images means (taken, posted, etc) $DATETITLE=""; # Blank to me says "this is when it was taken" # Show EXIF data in HTML comments? $EXIF=0; # What to put at the end of the page $FOOTER="Display Code Copyright © 1999-2005 Kees Cook"; /* FUNCTIONS */ function human_filesize($filename) { $filesize = filesize($filename); # If you have a Gb image (or Tb) you need to be slapped if ($filesize>=1024*1024*1024) { $filesize/=(1024*1024*1024); $str=sprintf("%0.1fG",$filesize); } else if ($filesize>=1024*1024) { $filesize/=(1024*1024); $str=sprintf("%0.1fM",$filesize); } else if ($filesize>=1024) { $filesize/=(1024); $str=sprintf("%dK",$filesize); } else { $str=sprintf("%0.1fB",$filesize); } return $str; } function NiceName($path) { $dirs=explode("/",$path); $name=array_pop($dirs); if ($name==".") $name="Previous Directory"; return $name; } function NiceDir($path) { return implode(" :: ",explode("/",$path)); } /* this takes an img's x/y size and a user's maxx, and spit out newx, newy, and html tag for that in an array */ function CorrectImageSize ($imgx, $imgy, $maxx) { $newx=$imgx; $newy=$imgy; $measure=$imgx; if ($imgx<$imgy) { $measure=$imgy; } if ($measure > $maxx) { if ($imgx<$imgy) { $newy=$maxx; $newx=floor($imgx * ($newy / $imgy)); } else { $newx=$maxx; $newy=floor($imgy * ($newx / $imgx)); } } $html="width=\"$newx\" height=\"$newy\""; return array($newx,$newy,$html); } function GetImageHTML ($dir, $pick, $max) { global $SCRIPT_NAME; global $RESDEFAULT; $url="$SCRIPT_NAME?l=$dir&p=$pick"; if ($max != $RESDEFAULT) { $url.="&m=$max"; } return ""; } function GetThumbHTML ($dir,$file_path) { global $THUMBRES; global $THUMB_BORDER; $thumb_res = GetImageSize($file_path); $thumb_adj=CorrectImageSize($thumb_res[0],$thumb_res[1],$THUMBRES); $thumb_htmlsize=$thumb_adj[2]; return ""; } /* gets a list of viewable images */ // perhaps I can replace this with DB calls in the future? function GetImageList ($dir) { /* for our directory searcher */ $pattern="/\.(jpe?g|gif|png)$/i"; $other="/\.mpg$/i"; $filelist=array(); $namelist=array(); $dirlist=array(); $otherlist=array(); $captionlist=array(); $dir="/$dir/"; $dir=preg_replace("/\/\.\.\//","",$dir); $dir=preg_replace("/^\/*/","",$dir); $dir=preg_replace("/\/*$/","",$dir); # load caption list $captions=@file("$dir/captions.txt"); if ($captions!=FALSE) foreach ($captions as $line) { list($name,$caption)=explode("\t",$line); $captionlist[$name]=trim($caption); } $handle=opendir($dir); /* add each image to our list */ while ($file = readdir($handle)) { if ($dir!=".") $filename="$dir/$file"; else $filename=$file; if (preg_match($pattern,$file)) { array_push($filelist,$filename); } else { if (is_file($filename) && preg_match($other,$file)) array_push($otherlist,$filename); if (is_dir($filename) && !preg_match("/^\.{1,2}$/",$file) && is_readable($filename) && is_readable("$filename/.")) array_push($dirlist,$filename); } } sort($filelist); for ($count=0;$count&1 |".EscapeShellCmd("/usr/bin/tee $file.tmp")." 2>&1;".EscapeShellCmd("mv $file.tmp $file")." 2>&1",$exitcode); if ($exitcode != 0) { echo "passthru failed with $exitcode\n"; } return; } } else { $file=$dump; } $hash = md5($file); $headers = getallheaders(); if (isset($headers['If-None-Match']) && ereg($hash,$headers['If-None-Match'])) { header('HTTP/1.1 304 Not Modified'); } else { header("ETag: \"{$hash}\""); header("Last-Modified: ".gmdate("D, d M Y H:i:s", filemtime($file)) . " GMT"); header("Content-type: $mimetype"); header("Content-Length: ".filesize($file)); $fp = @fopen($file,"rb"); fpassthru($fp); fclose($fp); } } // grab GET variables $max=$_REQUEST["m"]; // M)ax resolution $pick=$_REQUEST["p"]; // P)icture $dump=$_REQUEST["d"]; // D)ump $dir=$_REQUEST["l"]; // L)ocation /* set our default user inputs */ if ($max==0) $max=$RESDEFAULT; /* with the DB, we'll have more context for getting the image list */ if (!isset($dir)) $dir="."; list($filelist,$namelist,$dirlist,$otherlist,$captionlist)=GetImageList($dir); //$filelist=$something[0]; //$namelist=$something[1]; //$dirlist=$something[2]; //$otherlist=$something[3]; /* for the future design, the "pick" number could be things like the index into a list of DB IDs, and then we can later map IDs onto file name paths for actually display the image contents. But since we want things in the DB to be contextual, all the other info should come from the ID, allowing for differing titles, etc in the frame */ /* maybe for choosing the context this script is in, I could use yet another HTTP-passed variable? Or maybe this will go away somehow when I start using session IDs? */ if (isset($pick) && !isset($dump)) { $dump=$filelist[$pick]; } else { /* kill requests for images that aren't listed */ // maybe this should be a function of sorts if (isset($dump)) { if (!isset($namelist[$dump]) || !is_file($dump)) unset($dump); } } /* get info we need for either operation */ if (isset($dump)) { $filesize = filesize($dump); $res = GetImageSize($dump); $imgres= "$res[0]x$res[1]"; $adj=CorrectImageSize($res[0],$res[1],$max); $adjres= "$adj[0]x$adj[1]"; $htmlsize=$adj[2]; } // sign it header('X-Powered-By: http://outflux.net/software/pkgs/keesmage/ $Id: keesmage.php,v 1.47 2006/01/02 00:45:36 nemesis Exp $'); header("X-License: this program is licensed under the GPL: http://www.gnu.org/copyleft/gpl.html"); /* this section dumps the image instead of making the surroundings */ if (!isset($pick) && isset($dump)) { DumpImage($dump,$imgres,$adjres); exit(0); } /* force total expiration. This can change once we figure out a way to uniquly ID our pictures. Perhaps name and res? */ // Date in the past header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); //always modified header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // HTTP/1.1 header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.0 header("Pragma: no-cache"); echo "\n"; echo "\n"; echo "$GPL\n"; echo "$HEADERS\n"; /* show list entry */ if (isset($pick)) { $name=NiceName($dump); $loc=$captionlist["title"]; if (!isset($loc)) { $loc=NiceDir($dir); } if (isset($captionlist[$name])) $name=$captionlist[$name]; echo "$name\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; $prev=$pick-1; $prevf=$filelist[$prev]; $next=$pick+1; $nextf=$filelist[$next]; echo "
\n"; echo "$loc
\n"; echo "\n"; echo "
\n"; echo "
$name
\n$DATETITLE"; echo "(".date("F jS, Y, g:ia T",filemtime($dump)).")
\n"; echo "

\n"; # EXIF info if ($EXIF) { $exif = exif_read_data($dump, 0, true); foreach ($exif as $key => $section) { foreach ($section as $name => $val) { echo "\n"; } } } echo "
\n"; echo ""; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
"; if (is_file($prevf)) { $filesize = filesize($prevf); $name=NiceName($prevf); if (isset($captionlist[$name])) $name=$captionlist[$name]; $prev_url=GetImageHTML($dir,$prev,$max); echo "[${prev_url}PREV: $name]"; echo "\n"; } echo ""; echo " [List] "; echo ""; if (is_file($nextf)) { $filesize = filesize($nextf); $name=NiceName($nextf); if (isset($captionlist[$name])) $name=$captionlist[$name]; $next_url=GetImageHTML($dir,$next,$max); echo "[${next_url}NEXT: $name]"; echo "\n"; } echo "
\n"; if (is_file($prevf)) { if ($NAVTHUMBS) { $thumb_html = GetThumbHTML($dir,$prevf); echo "${prev_url}$thumb_html\n"; } } echo "\n"; if (is_file($nextf)) { if ($NAVTHUMBS) { $thumb_html = GetThumbHTML($dir,$nextf); echo "${next_url}$thumb_html\n"; } } echo "
\n"; echo "
\n"; } /* show WHOLE list */ else { if ($captionlist["title"]) { $title=$captionlist["title"]; } else { $title = "Top"; if ($dir != ".") $title=implode(" :: ",explode("/",$dir)); } echo "$title\n"; echo "\n"; echo "\n"; echo "\n"; echo "
\n"; echo "

$title

\n"; echo "
\n"; # print "

    \n"; print " \n"; for ($count=0;$count\n \n \n"; } } for ($count=0;$count\n"; echo " \n"; echo " \n"; echo " \n"; } for ($count=0;$count\n"; echo " \n"; echo " \n"; echo " \n"; } if (isset($dir) && $dir!=".") { $dirs=explode("/",$dir); array_pop($dirs); $prevdir=implode("/",$dirs); if ($prevdir=="") $prevdir="."; echo " \n"; echo " \n"; } #print " \n\n"; print "
    "; $url=GetImageHTML($dir,$count,$max); echo $url; $thumb_html = GetThumbHTML($dir,$file_path); $name=NiceName($filename); if (isset($captionlist[$name])) $name=$captionlist[$name]; echo "$thumb_html"; echo "$url$name
    "; echo date("F jS, Y, g:ia T",filemtime($file_path)); echo "
    \n"; echo "
    Movie\n"; echo "$name
    "; echo date("F jS, Y, g:ia T",filemtime($filename)); echo " ($filesize)
    \n"; echo "
    DIR\n"; echo " $name
    \n"; echo "
    DIR\n"; echo "Previous Directory
    \n"; echo "
    \n\n"; } echo "
    \n"; if (isset($pick)) echo "\n"; if (isset($dir)) echo "\n"; ?>