--- qdig.php.orig	Sun Sep 18 14:55:32 2005
+++ qdig-20051005cnj.php	Wed Oct  5 18:04:03 2005
@@ -16,6 +16,10 @@
 | for customizing your galleries.  The script runs stand-alone, or a
 | gallery may be included within another page.  Enjoy!
 +----------------------------------------------------------------------+
+| Portions Copyright 2005 Matthew Wronka <qdig@nonce.matt.wronka.org>
+| *   Any support questions with this script should be sent to Matt!   *
+| * Please do not ask Hagan or use the forums for the original script. *
+| Original script by Hagan Fox <http://qdig.sourceforge.net/>
 | Copyright 2002, 2003, 2004, 2005 Hagan Fox
 | This program is distributed under the terms of the
 | GNU General Public License, Version 2
@@ -33,9 +37,9 @@
 | Version 2 along with this program; if not, visit GNU's Home Page
 | http://www.gnu.org/
 +----------------------------------------------------------------------+
-CVS: $Id: qdig.php.virgin,v 1.1 2005/06/13 06:20:42 matt Exp $#
+CVS: $Id: qdig.php,v 1.19 2005/10/05 22:02:00 matt Exp $#
 */#
-$qdig_version = '20050509';
+$qdig_version = '20051005cnj [based on 20050509]';
 $mtime = microtime();
 $mtime = explode(' ', $mtime);
 $start_time = $mtime[1] + $mtime[0];
@@ -111,7 +115,7 @@
 $dir_nav['cntr_ena']  = TRUE;  // Display the counter.
 $dir_nav['path_delim'] = '&gt;'; // Delimiter between path elements
 $dir_nav['align_dirs'] = 'center'; // Subdirs-only alignment (left/center/right).
-$dir_nav['dir_is_new'] = 0 * 24 * 60 * 60; // New if less than this many seconds
+$dir_nav['dir_is_new'] = 30 * 24 * 60 * 60; // New if less than this many seconds
 $dir_nav_lang_new      = 'New';#
 $dir_nav['new_flag']   = "&nbsp;
       <small style='font-size:8pt; vertical-align:top; padding-bottom:1px; text-decoration:none;
@@ -123,7 +127,7 @@
 $dir_nav['icon']      = FALSE;  // Display a camera icon in directory links.
 $dir_nav['updir_ena'] = TRUE;   // Display an up-one-level link.
 $dir_nav['row_width'] = '100%'; // Width of the Directory Navigation row
-$dir_nav['start_thm'] = FALSE;  // Start in a dir with thumbs-only display (if
+$dir_nav['start_thm'] = TRUE;  // Start in a dir with thumbs-only display (if
                                 // enabled), else jump to the first image.
 
 /**
@@ -153,12 +157,14 @@
                              // own request so pages load more quickly.
 // Wrapping -- Don't wrap only one or two thumbnails.
 $thmb_row['maxwidth'] = 680; // Approx. max. width of thumbnails row
-$thmb_row['softwrap'] = 85;  // A percentage, 51 to 99
+$thmb_row['softwrap'] = 60;  // A percentage, 51 to 99
 // NEW! Thumbs-only View of Gallery Directories
 $thumbs['thm_only'] = TRUE;  // Folder is thumbs-only if more than...
-$thumbs['t_o_imgs'] = 999;   // ...this many images, or...
+$thumbs['t_o_imgs'] = 1;   // ...this many images, or...
 $thumbs['t_o_rows'] = 2;     // ...this many rows, whichever is smaller.
 $thumbs['t_o_h2w']  = 0.75;  // Height-to-width ratio of an average image.
+$thumbs['row_view']  = TRUE;  // Use rows of images/captions instead of just thumbs for thumbs-only view
+$thumbs['row_cols']  = 3;  // number of columns per row in row_view
 // NEW!  Vicinity Thumbs -- Show only a single row of thumbnail links.
 $thumbs['vicinity'] = TRUE;  // Show only thumbs for "nearby" images.
 $thumbs['shift_by'] = 0;     // Adjust the number of vicinity lead-in images. // TODO shift to right is limited.
@@ -185,8 +191,9 @@
 * If nothing on the row is enabled, the navigation row is omitted.
 */
 $upr_nav['enable']    = TRUE;
-$upr_nav['tmp_size']  = FALSE; // Show resizing links.  Overrides 'full_link'.
+$upr_nav['tmp_size']  = TRUE; // Show resizing links.  Overrides 'full_link'.
 $upr_nav['full_link'] = FALSE; // Show `Full Size' link if image is resized.
+$upr_nav['nav_hook'] = FALSE; // Execute external function, overridden by above.
 $upr_nav['prv_next']  = TRUE;  // Show `Previous' / `Next' links.
 $upr_nav['wrap']      = FALSE; // Wrap Next / Prev. at the last / first image.
 $upr_nav['frst_last'] = TRUE;  // Show ` |<< ' and ` >>| ' links.
@@ -199,11 +206,51 @@
 /**
 * Image Display
 */ // TODO External captions
-$caption['min_width'] = 300;   // Minimum width for an image caption
+$caption['min_width'] = 250;   // Minimum width for an image caption
 $caption['padding']   = '3px'; // Padding around caption text
 $caption['nl2br']     = FALSE; // Automatically insert <br /> tags in captions.
 $caption['left_just'] = FALSE; // Left-justify caption (otherwise centered).
 $caption['above']     = FALSE; // Place caption above the image, not below it.
+// Exif information -- Verbose information or just the camera line
+$exif_camera['enable'] = TRUE;	// Show a line mentioning camera and settings.
+$exif_camera['min_width'] = 300;
+$exif_camera['padding'] = '3px';
+$exif_camera['above'] = TRUE;	// Place camera line above the image, not below.
+$exif_verbose['enable'] = TRUE;	// Show verbose EXtendedInFormation on the side
+$exif_verbose['min_width'] = 300;	/// XXX these need to change
+$exif_verbose['padding'] = '3px';
+$exif_verbose['above'] = FALSE;	// Plase verbose above image, not below
+$exif_verbose_ignore[] = 'EXIF.MakerNote';	// Ignore these fields
+$exif_verbose_ignore[] = 'THUMBNAIL'; 	// or an entire section
+$exif_verbose_ignore[] = 'COMPUTED'; 	
+$exif_verbose_ignore[] = 'FILE'; 		
+$exif_verbose_ignore[] = 'EXIF.ComponentsConfiguration';
+$exif_verbose_ignore[] = 'IFD0'; 		// We're ignoring everything.
+$exif_verbose_ignore[] = 'EXIF'; 		// We're ignoring everything.
+$exif_verbose_show[]	= 'EXIF.ISOSpeedRatings';	// Allow these back in
+$exif_verbose_show[]	= 'EXIF.FNumber';	
+//$exif_verbose_show[]	= 'COMPUTED.ApertureFNumber';	
+$exif_verbose_show[]	= 'EXIF.ExposureBiasValue';	
+$exif_verbose_show[]	= 'EXIF.CompressedBitsPerPixel';
+$exif_verbose_show[]	= 'EXIF.ExposureTime';
+$exif_verbose_show[]	= 'EXIF.MaxApertureValue';
+$exif_verbose_show[]	= 'EXIF.Flash';
+$exif_verbose_show[]	= 'EXIF.FocalLength';
+$exif_verbose_show[]	= 'EXIF.FocalLengthIn35mmFilm';
+$exif_verbose_show[]	= 'EXIF.SubjectDistanceRange';
+$exif_verbose_show[]	= 'IFD0.Make';
+$exif_verbose_show[]	= 'IFD0.Model';
+$exif_verbose_show[]	= 'IFD0.XResolution';
+$exif_verbose_show[]	= 'IFD0.YResolution';
+$exif_verbose_show[]	= 'IFD0.ResolutionUnit';
+$exif_verbose_show[]	= 'IFD0.Software';
+$exif_verbose_show[]	= 'IFD0.DateTime';
+$exif_verbose_show[]	= 'FILE.FileSize';
+$exif_verbose_show[]	= 'FILE.MimeType';
+$exif_verbose_show[]	= 'COMPUTED.Height';
+$exif_verbose_show[]	= 'COMPUTED.Width';
+
+
 // Settings for making the displayed image an active link
 $img_link['next']    = TRUE;  // Link to the next image from the one displayed.
 $img_link['wrap']    = FALSE; // Link back to first image from the last one.
@@ -211,9 +258,9 @@
 $img_link['th_page'] = FALSE; // NEW! Link to all-thumbs view if available... // TODO Rename?
 $img_link['t_p_few'] = FALSE; // NEW! ...even in directories with few images. // TODO better description
 // Other scripts have the following, so some people must like it.
-$img_link['full']  = FALSE; // If the image is a resized version, link to the
+$img_link['full']  = TRUE; // If the image is a resized version, link to the
                             // full sized version.  Disables 'next' and 'wrap'.
-$img_link['file']  = FALSE; // Full size link goes directly to the image file.
+$img_link['file']  = TRUE; // Full size link goes directly to the image file.
 
 /**
 * Lower Gallery Navigation Row below the image and caption
@@ -222,7 +269,8 @@
 */
 $lwr_nav['enable']    = TRUE;
 $lwr_nav['tmp_size']  = FALSE; // Show resizing links.  Overrides 'full_link'.
-$lwr_nav['full_link'] = TRUE;  // Show `Full Size' link if image is resized.
+$lwr_nav['full_link'] = FALSE;  // Show `Full Size' link if image is resized.
+$lwr_nav['nav_hook'] = TRUE; // Execute external function, overridden by above.
 $lwr_nav['prv_next']  = TRUE;  // Show `previous' / `next' links.
 $lwr_nav['wrap']      = FALSE; // Wrap Next / Prev. at the last / first image.
 $lwr_nav['frst_last'] = TRUE;  // Show ` |<< ' and ` >>| ' links.
@@ -290,11 +338,11 @@
 * daemon, but the script needs write permissions to write empty caption .txt
 * files and converted-image files (thumbnail and alternate-sized images).
 */
-$qdig_files = 'qdig-files/'; // The root of the writable tree.  Setup is easy: (lang)#
+//$qdig_files = 'qdig-files/'; // The root of the writable tree.  Setup is easy: (lang)#
                              // Create the directory.  Give it 2777 permissions
                              // (`chmod 2777').  Visit the gallery once.  Then
                              // change the permissions to something sane (0755).
-//$cnvrtd_dir = 'qdig-converted';  // Name of the resampled images subdirectory.
+$cnvrtd_dir = 'qdig-converted';  // Name of the resampled images subdirectory.
                                    // Uncomment this and comment out $qdig_files
                                    // for the behavior of previous releases.
 $convrtd_subdir = 'converted-images/';  // Subdir for resampled images   (lang)#
@@ -308,7 +356,7 @@
 * To use the one that isn't the default, set the default one to FALSE.
 */
 $convert_magick = TRUE;  // Use Image Magick, if available, to convert images.
-$convert_cmd    = '/usr/bin/convert';  // Full pathname to `convert'.
+$convert_cmd    = '/usr/local/bin/convert';  // Full pathname to `convert'.
 // Example $convert_cmd for Win32 users:
 //$convert_cmd    = '"C:\\Program Files\\ImageMagick-5.5.3-Q16\\convert.exe"';
 $convert_GD     = TRUE;  // Use PHP GD, if available, to convert images.
@@ -321,11 +369,11 @@
 * Old Defaults: FALSE,TRUE,TRUE,TRUE,TRUE,FALSE
 * Basic: FALSE,FALSE,TRUE,FALSE,FALSE,TRUE
 */
-$disp_size[0] = FALSE; // 'XS' | These cause resizing
-$disp_size[1] = FALSE; // 'S'  | links in the Control
+$disp_size[0] = TRUE; // 'XS' | These cause resizing
+$disp_size[1] = TRUE; // 'S'  | links in the Control
 $disp_size[2] = TRUE;  // 'M'  | Bar and Navigation
-$disp_size[3] = FALSE; // 'L'  | Bar to disappear
-$disp_size[4] = FALSE; // 'XL' | if set to FALSE and
+$disp_size[3] = TRUE; // 'L'  | Bar to disappear
+$disp_size[4] = TRUE; // 'XL' | if set to FALSE and
 $disp_size[5] = TRUE;  // 'FS' | appear if set to TRUE.
 // If no size is specified, default to the following size.
 $default_img_size = '2';  // '2' is Medium.  Must be an enabled size.
@@ -349,6 +397,11 @@
   "thm{$cnvrt_thmb['size']}_";  // The default includes the thumb file size.  #
 //$cnvrt_thmb['prefix'] = 'thm_'; // Uncomment for 'thm_' (w/o file size).    #
 
+$cnvrt_thmb_rv=$cnvrt_thmb;
+$cnvrt_thmb_rv['size'] = 150;	// Thunbnail image height in pixels, 
+				// for images in row view.
+$cnvrt_thmb_rv['prefix']  =        // Filename prefix for thumbnail row images.      #
+  "thm{$cnvrt_thmb_rv['size']}_";  // The default includes the thumb file size.  #
 /**
 * Alternate-sized Image Conversion Settings
 *
@@ -392,12 +445,25 @@
 // actual
 $cnvrt_size[5]['prefix']  = '../';
 
+/**
+* Sound settings.  
+* Audio caption settings.
+*/
+$snd_suffixes[] = 'wav';
+$snd_suffixes[] = 'WAV';
+$snd_suffixes[] = 'aiff';
+$snd_suffixes[] = 'au';
+$snd_suffixes[] = 'ogg';
+$snd_suffixes[] = 'flac';
+$snd_suffixes[] = 'shn';
+$snd_suffixes[] = 'mp3';
+
 // Language Settings --------------------------------------------------+
 // Text that appears in the output may be configured here.
 
 //  htmlHeader()   #
 $header['lang_code'] = 'en';#
-$header['charset']   = 'iso-8859-1';#
+$header['charset']   = 'utf-8';#
 $header['keywords']  = ''; // e.g. 'foo,bar'   #
 // dirNav()   #
 $dir_nav['summary_txt']     = 'Directory Navigation';#
@@ -491,6 +557,7 @@
 $admin['after_link']  = ')';#
 // qdigHomelink()   #
 $qdig_homelink['div_title'] = 'Gallery by Qdig';#
+$qdig_homelink['div_hacked'] = 'Hacked by Matthew Wronka';#
 // Misc.   #
 $lang['Diag Messages'] = 'Diagnostic Messages';#
 $lang['Image Gallery'] = 'Image Gallery';#
@@ -511,16 +578,16 @@
 /**
 * Paranoia Settings
 */
-$safe_captions    = TRUE;  // Disable HTML in Captions.  Convert special
+$safe_captions    = FALSE;  // Disable HTML in Captions.  Convert special
                            // characters (<>&"') to `HTML entities'
 $check_security   = TRUE;  // Perform a security check for world-writability.
 $ignore_dir_links = TRUE;  // Ignore gallery directories if they're symlinks.
 $ignore_img_links = TRUE;  // Ignore image files if they're symlinks.
-$pathname_maxlen  = 100;   // Max. number of characters in a pathname.
-$imgname_maxlen   = 100;   // Max. number of characters in an image filename.
-$extra_paranoia   = FALSE; // Do extra-strict checking for '..'.
-$ignore_dotfiles  = FALSE; // Ignore files that start with '.'.
-$ignore_dotdirs   = FALSE; // Ignore directories that start with '.'.
+$pathname_maxlen  = 255;   // Max. number of characters in a pathname.
+$imgname_maxlen   = 255;   // Max. number of characters in an image filename.
+$extra_paranoia   = TRUE; // Do extra-strict checking for '..'.
+$ignore_dotfiles  = TRUE; // Ignore files that start with '.'.
+$ignore_dotdirs   = TRUE; // Ignore directories that start with '.'.
 // HTML Header settings are only effective for stand-alone Qdig.
 $header['zap_frames']    = FALSE; // Break out of a frameset.
 $header['ie_imgbar_off'] = TRUE;  // Suppress IE6's image toolbar.
@@ -533,7 +600,7 @@
 // Disable use of certain PHP functions for compatibility with some servers.
 $is_readable_disa = FALSE; // Set to TRUE if is_readable() causes trouble.
 $file_exists_disa = FALSE; // Set to TRUE if file_exists() causes trouble.
-$max_exec_time    = 30;    // Max. execution time in seconds
+$max_exec_time    = 300;    // Max. execution time in seconds
 $compat_quote     = TRUE;  // Add and extra "s to exec() command on Win32.
                            // For Win98 this should be set to FALSE.
 $exclude_gif      = FALSE; // Exclude GIF images.
@@ -548,7 +615,7 @@
 $qdig_url = ''; // Self-referring URL path.  Examples: '/photos/' or
                 // '/photos/qdig.php' or '/~someuser/qdig/index.php'
 // The next two are the same location; as a URL and as a filesystem path.
-$url_base_path = ''; // Base URL path to the images (not the script)
+$url_base_path = '/pictures/'; // Base URL path to the images (not the script)
                      // Examples: '/photos/qdig/' or '/~someuser/qdig/'
 $fs_base_path  = ''; // Filesystem path to the root dir of the gallery.
                      // Ex.: '/home/someuser/public_html/qdig/' or '../qdig'
@@ -558,7 +625,8 @@
 */
 $excl_dirs[] = 'Private';        // | Ignore a directory with its name
 $excl_dirs[] = 'qdig-converted'; // | included here.  Do not  end these
-$excl_dirs[] = '';               // | name(s) with '/'.
+$excl_dirs[] = 'CVS';               // | name(s) with '/'.
+$excl_dirs[] = '';               // 
 $excl_imgs[] = 'qdig-bg.jpg'; // | Ignore any image with its name
 $excl_imgs[] = 'favicon.png'; // | included here.  Add as many of
 $excl_imgs[] = '';            // | these as you wish.
@@ -729,7 +797,7 @@
 	if ($convert_GD == TRUE) {
 		$img_exts = '\.jpg$|\.jpeg$|\.jpe$|\.png$';
 	} else {
-		$img_exts = '\.jpg$|\.jpeg$|\.jpe$|\.png$|\.bmp$';
+		$img_exts = '\.jpg$|\.jpeg$|\.jpe$|\.png$|\.tiff$|\.tif$|\.bmp$';
 	}
 	if ($exclude_gif == FALSE) {
 		$img_exts .= '|\.gif$';
@@ -745,7 +813,7 @@
 				securityExit('Updir ("..") is not allowed in a filename.');
 			}
 			if (strlen($file) > $imgname_maxlen) {
-				securityExit('Filename length exceed.  Increase $imgname_maxlen?');
+				securityExit('Filename ('.$file.') length exceed.  Increase $imgname_maxlen?');
 			}
 		}
 		if ($ignore_dotfiles == TRUE && $file[0] == '.') { continue; }
@@ -821,7 +889,7 @@
 			continue;
 		}
 		if ($ignore_dotfiles == TRUE && $file[0] == '.') { continue; }
-		if (eregi('\.jpg$|\.jpeg$|\.jpe$|\.png$|\.gif$|\.bmp$', $file)) {
+		if (eregi('\.jpg$|\.jpeg$|\.jpe$|\.png$|\.gif$|\.tiff$|\.tif$|\.bmp$', $file)) {
 			$has_img = TRUE;
 			closedir($pwd_handle);
 			return $has_img;
@@ -1062,7 +1130,7 @@
 			}
 		}
 		$orig_img   = $pwd.'/'.$img_file;
-		$cnvrtd_img = $cnvrt_path.'/'.$cnvrt_thmb['prefix'].$img_file;
+		$cnvrtd_img = $cnvrt_path.'/'.$cnvrt_thmb['prefix'].$img_file.'.jpeg';
 		if (($file_exists_disa == TRUE && ! is_file($cnvrtd_img))
 			|| ! file_exists($cnvrtd_img))
 		{
@@ -1070,6 +1138,8 @@
 			$height = $img_size[1];
 			$th_maxdim = $height;
 			$cnvt_percent = round(($cnvrt_thmb['size'] / $th_maxdim) * 100, 2);
+			$cnvrtd_img.='[0]'; // TODO: Do we always want the 0th scene?
+
 			// convert it
 			if ($convert_magick == TRUE) {
 				// Image Magick image conversion
@@ -1110,19 +1180,7 @@
 						$dest_width, $dest_height, $src_width, $src_height);
 				}
 				imagedestroy($src_img);
-				if (eregi('\.jpg$|\.jpeg$', $img_file) == TRUE
-					&& (imageTypes() & IMG_JPG) == TRUE)
-				{
-					imageJpeg($dst_img, $cnvrtd_img, $cnvrt_thmb['qual']);
-				} elseif (eregi('\.png$', $img_file) == TRUE
-					&& (imageTypes() & IMG_PNG) == TRUE)
-				{
-					imagePng($dst_img, $cnvrtd_img);
-				} elseif (eregi('\.gif$', $img_file) == TRUE
-					&& (imageTypes() & IMG_GIF) == TRUE)
-				{
-					imageGif($dst_img, $cnvrtd_img);
-				}
+				imageJpeg($dst_img, $cnvrtd_img, $cnvrt_thmb['qual']);
 				imagedestroy($dst_img);
 				$using = $cnvrt_mesgs['using GD'].$gd_version;
 			}
@@ -1174,7 +1232,7 @@
 	foreach ($imgs as $img_file) {
 		if ($cnvrt_alt['indiv'] == TRUE && $img_file != $reqd_image['file']) { continue; }
 		$orig_img   = $reqd_image['pwd'].'/'.$img_file;
-		$cnvrtd_img = $cnvrt_path.'/'.$cnvrt_arry['prefix'].$img_file;
+		$cnvrtd_img = $cnvrt_path.'/'.$cnvrt_arry['prefix'].$img_file.'.jpeg';
 		if (! is_file($cnvrtd_img)) {
 			$img_size = GetImageSize($orig_img);
 			$height   = $img_size[1];
@@ -1200,6 +1258,8 @@
 				}
 				// convert it
 				if ($convert_magick == TRUE) {
+					$cnvrtd_img.='[0]'; // TODO: Do we always want the 0th scene?
+
 					// Image Magick image conversion
 					if ($platform == 'Win32'
 						&& $compat_quote == TRUE)
@@ -1245,19 +1305,7 @@
 							$dest_width, $dest_height, $src_width, $src_height);
 					}
 					imageDestroy($src_img);
-					if (eregi('\.jpg$|\.jpeg$', $img_file) == TRUE
-						&& (imageTypes() & IMG_JPG) == TRUE)
-					{
-						imageJpeg($dst_img, $cnvrtd_img, $cnvrt_arry['qual']);
-					} elseif (eregi('\.png$', $img_file) == TRUE
-						&& (imageTypes() & IMG_PNG) == TRUE)
-					{
-						imagePng($dst_img, $cnvrtd_img);
-					} elseif (eregi('\.gif$', $img_file) == TRUE
-						&& (imageTypes() & IMG_GIF) == TRUE)
-					{
-						imageGif($dst_img, $cnvrtd_img);
-					}
+					imageJpeg($dst_img, $cnvrtd_img, $cnvrt_arry['qual']);
 					imageDestroy($dst_img);
 					$using = $cnvrt_mesgs['using GD'].$gd_version;
 				}
@@ -1587,7 +1635,7 @@
 function subdirLinks($dir_nav)
 {
 	global $imgs, $qdig_url, $extra_param, $anchor, $reqd_image, $subdirs,
-		$thumbs, $rootdir;
+		$thumbs, $rootdir, $caption_path;
 	if (isset($imgs)) {
 		if ($dir_nav['icon'] == 1) {
 			$icon = '<img src="'.$qdig_url.'?image=cam-icon" alt="camera icon" />&nbsp;';
@@ -1624,6 +1672,7 @@
 			$dirurl = rawurlencode($dir);
 			$dirtxt = str_replace(' ', '&nbsp;', $dir);  // replace spaces
 			$dirtxt = str_replace("'", '&#39;', $dir);   // replace apostrophes
+			$dircapt= file_exists("$caption_path/$dir.txt")?file_get_contents("$caption_path/$dir.txt"):"";
 			if ($age_idx < ($dir_nav['dir_is_new'] * 1000)) {
 				$newdir = $dir_nav['new_flag'];
 			} else {
@@ -1632,7 +1681,7 @@
 			$str .= <<<EOT
     <span style='white-space:nowrap;'>$tag1$bkt1
      <a  href="$qdig_url?{$extra_param}Qwd={$reqd_image['pwd_url']}/$dirurl{$qif}&amp;Qiv={$reqd_image['view']}&amp;Qis={$reqd_image['size']}$anchor"
-      class="qdig-subdirlink" title="{$dir_nav['go_to_txt']} $dir">$icon$dirtxt$newdir</a>
+      class="qdig-subdirlink" title="{$dir_nav['go_to_txt']} $dir">$icon$dirtxt$newdir $dircapt</a>
     $bkt2</span>\n
 EOT;
 		}
@@ -1750,6 +1799,103 @@
 } //End imageTextLinks()
 
 /**
+* Build a list of Thumbnail Image Links to the images in the current directory, 
+* in rows with captions.
+*/
+function imageThumbRowLinks($thmb_row) 
+{
+	global $get_vars, $pwd, $imgs, $qdig_url, $extra_param, $anchor,
+		$reqd_image, $cnvrt_path, $cnvrt_thmb_rv, $nav_lnk, $thumbs_msg,
+		$thumbs, $file_exists_disa, $cnvrt_mesgs, $url_base_path,
+		$diag_messages, $safe_mode, $header;
+	$cnvrt_thmb=$cnvrt_thmb_rv;
+	// set a default maxwidth (if necessary)
+	if (empty($thmb_row['maxwidth'])) { $thmb_row['maxwidth'] = 500; }
+	// set a default softwrap (if necessary)
+	if (empty($thmb_row['softwrap'])
+		|| $thmb_row['softwrap'] < 50
+		|| $thmb_row['softwrap'] > 99)
+	{
+		$thmb_row['softwrap'] = 75;
+	}
+	$num_imgs = count($imgs);
+	if (isset($imgs) && $num_imgs > 1) {
+		$str = " <!-- thumbnail-image links -->\n";
+		$str .= " <div align=\"center\" style=\"padding-top:2px; white-space:nowrap\">\n";
+		$str .= "  <table><tr>\n";
+		// prepare wrap data
+		$thumbs_width = 0;
+		$thumbs_wrap  = 0;
+		$thumbs_wide  = 0;
+		$width_so_far = 0;
+		$num     = 0;
+		$wrapped = FALSE;
+		$thumb_cnt=-1;	// we start the first row anyway
+		foreach ($imgs as $image) {
+			$num++;
+			if ($thumbs['vicinity']== TRUE
+				&& ($num < ($reqd_image['num'] - @$wid_num + 0.45 - $thumbs['shift_by'])))
+			{ continue; }
+			if ($thumbs['vicinity'] == TRUE && $wid_px < 0) { continue; }
+			$thmbs[$image]['num']    = $num;
+			$thmbs[$image]['image']  = $image;
+			$thmb_file = $cnvrt_path.'/'.$cnvrt_thmb['prefix'].$image.'.jpeg';
+			$thmbs[$image]['thumb']  = $thmb_file;
+			$thmb      = $cnvrt_thmb['prefix'].rawurlencode($image.'.jpeg');
+			$thmbs[$image]['cnvurl'] = $url_base_path.urlPath($cnvrt_path)."/$thmb";
+			$imgurl    = rawurlencode($image);
+			$thmbs[$image]['imgurl'] = $imgurl;
+			if (($file_exists_disa == TRUE && is_file($thmb_file))
+				|| file_exists($thmb_file))
+			{
+				$exists = TRUE;
+				$thmbs[$image]['exists'] = TRUE;
+			} else {
+				$exists = FALSE;
+				$thmbs[$image]['exists'] = FALSE;
+			}
+		}
+		foreach ($thmbs as $thm) {
+			$thumb_id = '';
+			if (!  @$get_vars['Qtmp'] == 'thumbs' // TODO
+				&& $reqd_image['num'] == $thm['num'] - 1)
+			{
+				$thumb_id = 'id="qdig-thumb-current"';
+			}
+			if ( ++$thumb_cnt >= $thumbs['row_cols'] )
+			{
+				$str .= " </tr><!-- wrap thubms row -->\n"
+					." <tr>\n";
+				$thumb_cnt = 0;
+			}
+			if ($thumbs['onfly'] == FALSE
+				&& ! (($file_exists_disa == TRUE && is_file($thm['thumb']))
+					|| file_exists($thm['thumb'])))
+			{
+				$thm['cnvurl'] = "$qdig_url?image=clear-dot";
+			}
+			$str .= "   <td align='center' valign='top'>";
+			if ($caption['above'] == TRUE) {
+				$str .= captionBlock($thm['image'], $img_size[0]);
+			}
+			$str .= <<<EOT
+  <a href="$qdig_url?{$extra_param}Qwd={$reqd_image['pwd_url']}&amp;Qif={$thm['imgurl']}&amp;Qiv={$reqd_image['view']}&amp;Qis={$reqd_image['size']}$anchor"
+   title="{$nav_lnk['Image']} {$thm['num']} - {$thm['image']}"><img class="$thumb_class" $thumb_id src="{$thm['cnvurl']}"
+   alt="{$thm['image']}" {$thm['img_size'][3]} /></a>\n
+EOT;
+			if ($caption['above'] != TRUE) {
+				$str .= captionBlock($thm['image'], $img_size[0]);
+			}
+			$str .= "   </td>\n";
+		}
+		$str .= "  </tr></table>\n";
+		$str .= " </div>\n";
+		return $str;
+	}
+
+} // End imageThumbRowsLinks
+
+/**
 * Build a list of Thumbnail Image Links to the images in the current directory.
 */
 function imageThumbsLinks($thmb_row)
@@ -1797,9 +1943,9 @@
 			if ($thumbs['vicinity'] == TRUE && $wid_px < 0) { continue; }
 			$thmbs[$image]['num']    = $num;
 			$thmbs[$image]['image']  = $image;
-			$thmb_file = $cnvrt_path.'/'.$cnvrt_thmb['prefix'].$image;
+			$thmb_file = $cnvrt_path.'/'.$cnvrt_thmb['prefix'].$image.'.jpeg';
 			$thmbs[$image]['thumb']  = $thmb_file;
-			$thmb      = $cnvrt_thmb['prefix'].rawurlencode($image);
+			$thmb      = $cnvrt_thmb['prefix'].rawurlencode($image.'.jpeg');
 			$thmbs[$image]['cnvurl'] = $url_base_path.urlPath($cnvrt_path)."/$thmb";
 			$imgurl    = rawurlencode($image);
 			$thmbs[$image]['imgurl'] = $imgurl;
@@ -1882,9 +2028,9 @@
 				if ($thumbs['vicinity'] == TRUE && $wid_px < 0) { continue; }
 				$thmbs[$image]['num']    = $num_imgs - $num + 1;
 				$thmbs[$image]['image']  = $image;
-				$thmb_file = $cnvrt_path.'/'.$cnvrt_thmb['prefix'].$image;
+				$thmb_file = $cnvrt_path.'/'.$cnvrt_thmb['prefix'].$image.'.jpeg';
 				$thmbs[$image]['thumb']  = $thmb_file;
-				$thmb      = $cnvrt_thmb['prefix'].rawurlencode($image);
+				$thmb      = $cnvrt_thmb['prefix'].rawurlencode($image.'.jpeg');
 				$thmbs[$image]['cnvurl'] = $url_base_path.urlPath($cnvrt_path)."/$thmb";
 				$imgurl    = rawurlencode($image);
 				$thmbs[$image]['imgurl'] = $imgurl;
@@ -2057,9 +2203,10 @@
 	global $get_vars, $imgs, $qdig_url, $rootdir, $extra_param, $anchor,
 		$cnvrt_path, $reqd_img_size_tmp, $nav_lnk, $cnvrt_size, $subdirs,
 		$is_readable_disa, $img_link, $caption, $url_base_path, $safe_mode,
-		$omit_image, $dir_nav, $lang;
+		$omit_image, $dir_nav, $lang, $exif_verbose, $exif_camera;
 	if (empty($imgs) || @$omit_image == TRUE) { return ''; }
 	$str = '';
+	$suffix_string   = '';
 	foreach ($cnvrt_size as $size_info) {
 		if ($reqd_img_size_tmp == $size_info['label']
 			|| (! isset($size_string) && $reqd_image['size'] == $size_info['label']))
@@ -2067,17 +2214,20 @@
 			$cnvrt_url    = urlPath($cnvrt_path);
 			$size_string  = $cnvrt_path.'/'.$size_info['prefix'];
 			$size_str_url = $cnvrt_url.'/'.$size_info['prefix'];
-			if (! is_file($size_string.$reqd_image['file'])
-				|| ! ($is_readable_disa == TRUE || is_readable($size_string.$reqd_image['file'])))
+			$suffix_string   = '.jpeg';
+			if (! is_file($size_string.$reqd_image['file'].'.jpeg')
+				|| ! ($is_readable_disa == TRUE || is_readable($size_string.$reqd_image['file'].'.jpeg')))
 			{
 				$size_string  = $reqd_image['pwd'].'/';
 				$size_str_url = $reqd_image['pwd_url'].'/';
+				$suffix_string   = '';
 			}
 		}
 	}
 	if (! isset($size_string)) {
 		$size_string  = $reqd_image['pwd'].'/';
 		$size_str_url = $reqd_image['pwd_url'].'/';
+		$suffix_string   = '';
 	}
 	$str = "\n <!-- requested image -->\n";
 	if (@$get_vars['Qtmp'] == 'popup') {
@@ -2085,7 +2235,6 @@
 	} else {
 		$pad = 'padding-top:2px;';
 	}
-	$str .= " <div align=\"center\" style=\"$pad\">\n";
 	if (! is_file($reqd_image['pwd'].'/'.$reqd_image['file'])) {
 		$img_file = $imgs[0];
 		$img_num = 1;
@@ -2095,20 +2244,33 @@
 	}
 	$num_imgs = count($imgs);
 	if ($safe_mode == FALSE) {
-		$img_size = GetImageSize($size_string.$img_file);
+		$img_size = GetImageSize($size_string.$img_file.$suffix_string);
+		$img_orig = GetImageSize($reqd_image['pwd'].'/'.$img_file);
+		if ( ($img_orig[2]==2 || $img_orig[2]==7 || $img_orig[2]==8) &&
+			($exif_verbose['enable'] || $exif_camera['enable'])) {
+			$exif_data = exif_read_data($reqd_image['pwd'].'/'.
+							$img_file, 0, true);
+		}
 	} else {
 		$img_size[0] = '';
 		$img_size[3] = '';
 	}
+	$str .= " <div align=\"center\" style=\"$pad\">\n";
+	if ($exif_verbose['enable'] == TRUE && $exif_verbose['above'] == TRUE) {
+		$str .= exifVerboseBlock($exif_data, $exif_camera);
+	}
 	if ($caption['above'] == TRUE) {
 		$str .= captionBlock($img_file, $img_size[0]);
 	}
+	if ($exif_camera['enable'] == TRUE && $exif_camera['above'] == TRUE) {
+		$str .= exifCameraBlock($exif_data, $exif_camera);
+	}
 	if ($img_link['wrap_up'] == TRUE
 		&& $reqd_image['pwd'] == $rootdir)
 	{
 		$img_link['wrap_up'] = FALSE;	
 	}
-	$img_url = $size_str_url.rawurlencode($img_file);
+	$img_url = $size_str_url.rawurlencode($img_file.$suffix_string);
 	if (@$get_vars['Qtmp'] == 'popup') {
 		$str .= <<<EOT
   <a href="javascript:window.close();" title='{$lang['Close Window']}'
@@ -2221,13 +2383,102 @@
 		$str .= '  <img class="qdig-image" src="'.$url_base_path.$img_url
 			.'" alt="'.$img_file.'" '.$img_size[3].' />'."\n";
 	}
+	if ($exif_camera['enable'] == TRUE && $exif_camera['above'] != TRUE) {
+		$str .= exifCameraBlock($exif_data, $exif_camera);
+	}
 	if ($caption['above'] != TRUE) {
 		$str .= captionBlock($img_file, $img_size[0]);
 	}
+	if ($exif_verbose['enable'] == TRUE && $exif_verbose['above'] != TRUE) {
+		$str .= exifVerboseBlock($exif_data, $exif_camera);
+	}
 	$str .= " </div>\n";
 	return $str;
 } // End displayImage()
 
+
+/**
+* Produce a line stating camera model, aperature, ISO setting and shutter speed.
+*
+* The block is as wide as the image or else $exif_camera['min_width'] pixels.
+*/
+function exifCameraBlock($exif_data, $exif_camera)
+{
+	if($exif_data==FALSE) return "";
+	$str = " <div title='{$caption['lang_ExifCamera']}'"
+		." class='qdig-exifcamera'"
+		." style='width:{$exif_camera['min_width']}px;"
+		." padding:{$exif_camera['padding']};"
+		." text-align:{$exif_camera['txt_align']};'>\n";
+	$str.= "<p>" ;
+	$str.=exifCameraBlockData($exif_data, $exif_camera);
+	$str.= "</p>\n";
+	$str.= "</div>";
+	return $str;
+} // End exifCameraBlock()
+
+/*
+ * The actual data for the exifCameraBlock
+ */
+function exifCameraBlockData($exif_data, $exif_camera)
+{
+	$str = '';
+	if(''!=$exif_data['IFD0']['Model']) {
+		if(FALSE===strstr($exif_data['IFD0']['Model'], ' ')){
+			$str.= "{$exif_data['IFD0']['Make']} ";
+		}
+		$str.= "{$exif_data['IFD0']['Model']} @ ";
+	}
+	if(''!=$exif_data['EXIF']['ISOSpeedRatings']) 
+		$str.= "ISO-{$exif_data['EXIF']['ISOSpeedRatings']}, " ;
+	if(''!=$exif_data['COMPUTED']['ApertureFNumber']) 
+		$str.=	$exif_data['COMPUTED']['ApertureFNumber'] . ',' ;
+	if(''!=$exif_data['EXIF']['ExposureTime']) 
+		$str.=	$exif_data['EXIF']['ExposureTime'] . ',' ;
+	if(''!=$exif_data['EXIF']['FocalLengthIn35mmFilm']) 
+		$str.=	"{$exif_data['EXIF']['FocalLengthIn35mmFilm']}mm equiv. ";
+	if(''!=$exif_data['IFD0']['DateTime']) 
+		$str.= "[{$exif_data['IFD0']['DateTime']}]";
+	return $str;
+} // End exifCameraBlock()
+
+/**
+* Display all(?) EXtended InFormation (in TIFFs and JPEGs)
+*
+* The block is as wide as the image or else $exif_verbose['min_width'] pixels.
+*/
+function exifVerboseBlock($exif_data, $exif_verbose)
+{
+	global $exif_verbose_ignore, $exif_verbose_show;
+	if($exif_data==FALSE) return "";
+	$str = " <div title='{$caption['lang ExifVerbose']}'"
+		." class='qdig-exifverbose'"
+		." style='width:{$exif_verbose['min_width']}px;"
+		." padding:{$exif_verbose['padding']};"
+		." text-align:{$exif_verbose['txt_align']};'>\n";
+	$str.="\t<table width='100%'>\n";
+	foreach($exif_data as $key => $section) {
+		foreach($section as $name => $val) {
+			if(stristr($key.'.'.$name, 'undefined')!==FALSE) {
+				continue;
+			}
+			if(//!isset($exif_verbose_ignore) ||
+			   in_array($key.'.'.$name, $exif_verbose_show) 
+				|| ! (	in_array(
+						$key.'.'.$name, 
+						$exif_verbose_ignore)  ||
+				 	in_array(
+						$key,
+						$exif_verbose_ignore) ) ) {
+				$str .= "\t\t<tr><td>$name</td><td>$val</td></tr>\n";
+			} 
+		}
+	}
+	$str.= "\t</table>\n";
+	$str.= "</div>";
+	return $str;
+} // End exifVerboseBlock()
+
 /**
 * Produce an Image Caption table.
 *
@@ -2236,8 +2487,26 @@
 function captionBlock($img_file, $img_width)
 {
 	global $pwd, $caption, $safe_captions, $caption_path, $touch_captions,
-		$is_readable_disa, $file_exists_disa, $safe_mode, $diag_messages;
+		$is_readable_disa, $file_exists_disa, $safe_mode, $diag_messages,
+		$url_base_path, $snd_suffixes;
 	$caption_file = $caption_path.'/'.$img_file.'.txt';
+	// check for audio caption
+	$audio_caption= array();
+	$audio_suffix= array();
+	if (  $file_exists_disa != TRUE ) {
+		foreach ($snd_suffixes as $suf) {
+			$t = $img_file.'.'.$suf;
+			if ( file_exists($caption_path.'/'.$t) ) {
+				$audio_caption[] = $t;
+				$audio_suffix[] = $suf;
+			}
+			$t = substr($img_file, 0, strrpos($img_file, '.')+1).$suf;
+			if ( file_exists($caption_path.'/'.$t) ) {
+				$audio_caption[] = $t;
+				$audio_suffix[] = $suf;
+			}
+		}
+	}
 	if ($touch_captions == TRUE) {
 		if ((($file_exists_disa == TRUE && ! is_file($caption_file))
 				|| ! file_exists($caption_file))
@@ -2264,10 +2533,6 @@
 			} else {
 				$txt_align = 'center';
 			}
-			// display caption
-			$str = " <div title='{$caption['lang Caption']}'"
-				." class='qdig-caption' style='width:{$caption_width}px;"
-				." padding:{$caption['padding']}; text-align:$txt_align;'>\n";
 			$txt = '';
 			if ($diag_messages == TRUE) {
 				$fd = fopen ($caption_file, 'r');
@@ -2288,14 +2553,23 @@
 			} else {
 				return;
 			}
-			if ($safe_captions == TRUE && $caption['nl2br'] == TRUE) {
-				$str .= nl2br($txt);
-			} else {
-				$str .= $txt;
+		} 
+		// display caption
+		$str = " <div title='{$caption['lang Caption']}'"
+			." class='qdig-caption' style='width:{$caption_width}px;"
+			." padding:{$caption['padding']}; text-align:$txt_align;'>\n";
+		if ($safe_captions == TRUE && $caption['nl2br'] == TRUE) {
+			$str .= nl2br($txt);
+		} else {
+			$str .= $txt;
+		}
+		if ( sizeof($audio_suffix)>0 ) {
+			for($i=0; $i < sizeof($audio_suffix); ++$i) {
+				$str .= "<a href='$url_base_path$caption_path/$audio_caption[$i]'>[$audio_suffix[$i]]</a>";
 			}
-			$str .= " </div>";
-			return $str;
 		}
+		$str .= " </div>";
+		return $str;
 	}
 } // End captionBlock()
 
@@ -2435,6 +2709,9 @@
 	}
 	if ($nav['tmp_size'] == TRUE) { // Sizer overrides Full Size link.
 		$nav['full_link'] = FALSE;
+		$nav['nav_hook'] = FALSE;
+	} else if ($nav['full_link'] == TRUE) { // overrides nav_hook link.
+		$nav['nav_hook'] = FALSE;
 	}
 	$nav_full =  navFull($nav['sml_txt'], $img_sz_labels['nav']);
 	if ($nav_full['show_full_link'] == FALSE) { $nav['full_link'] = FALSE; }
@@ -2500,10 +2777,15 @@
 			}
 		}
 		if (($nav['cntr'] == TRUE && $num_imgs > 1)
-			&& ($nav['tmp_size'] == TRUE || $nav['full_link'] == TRUE ))
+			&& ($nav['tmp_size'] == TRUE 
+				|| $nav['full_link'] == TRUE 
+				|| $nav['nav_hook'] == TRUE ))
 		{
 			$str .= "    <td width=\"20%\" style='white-space:nowrap; text-align:center;'> &nbsp;";
-		} elseif ($nav['tmp_size'] == TRUE || $nav['full_link'] == TRUE ) {
+		} elseif ($nav['tmp_size'] == TRUE 
+				|| $nav['full_link'] == TRUE 
+				|| $nav['nav_hook'] == TRUE )
+		{
 			$str .= "    <td width=\"30%\" style='white-space:nowrap; text-align:center;'>\n";
 		}
 		if ($nav['tmp_size'] == TRUE) {
@@ -2514,6 +2796,12 @@
 		{
 			$str .= $nav_full['str']."    </td>\n";
 		}
+		if ($nav['tmp_size'] == FALSE
+			&& $nav['full_link'] == FALSE
+			&& $nav['nav_hook'] == TRUE)
+		{
+			$str .= navHook()."    </td>\n";
+		}
 		if ($num_imgs > 1) {
 			if ($nav['prv_next'] == TRUE) {
 				$str .= "    <td width=\"14%\" style='white-space:nowrap; text-align:center;'>$tag_bfr_lnk\n"
@@ -2530,6 +2818,29 @@
 } // End navRow()
 
 /**
+* Calls external functions to hook into the nav row.
+*
+* Enable by setting either $upr_nav['nav_hook']=TRUE; or
+* $lwr_nav['nav_hook']=TRUE for it to show up in the respective
+* nav bar.  
+*
+* Returns a string containing the concatenated output of all 
+* functions in $nav_hook[].
+*/
+function navHook()
+{
+	global $nav_hook;
+	if(!is_array($nav_hook)) return "";
+	$str="";
+	foreach($nav_hook as $f) {
+		if(function_exists($f)) {
+			$str .= ' ' . call_user_func($f);
+		}
+	}
+	return $str;
+} // End navHook()
+
+/**
 * Produce a Gallery Footer Row table.
 *
 * Includes Site Link, Copyright, and Quig Home link.
@@ -2607,9 +2918,14 @@
 */
 function displayImageLinks($thmb_row, $nmrl_row)
 {
-	global $thmbs_ena, $convert_readable;
+	global $thmbs_ena, $convert_readable, $thumbs, $omit_image ;
+
 	if ($thmbs_ena == TRUE && $convert_readable == TRUE) {
-		$str = imageThumbsLinks($thmb_row);
+		if($thumbs['row_view'] == TRUE && $omit_image == TRUE) {
+			$str = imageThumbRowLinks($thmb_row);
+		} else {
+			$str = imageThumbsLinks($thmb_row);
+		}
 	} else {
 		$str = imageTextLinks($nmrl_row);
 	}
@@ -2793,8 +3109,8 @@
 			$qtmp_txt = '&amp;Qtmp='.$size;
 		}
 		$title = $labels['See the'].$cnvrt_size[$i]['txt'].$labels['version of'];
-		$file  = $cnvrt_path.'/'.$cnvrt_size[$i]['prefix'].$reqd_image['file'];
-		$file2 = $cnvrt_path.'/'.@$cnvrt_size[$z]['prefix'].$reqd_image['file'];
+		$file  = $cnvrt_path.'/'.$cnvrt_size[$i]['prefix'].$reqd_image['file'].'.jpeg';
+		$file2 = $cnvrt_path.'/'.@$cnvrt_size[$z]['prefix'].$reqd_image['file'].'.jpeg';
 		$z=$i;
 		if ($size == $reqd_image['size'] && is_file($file2)) { $foo = TRUE; }
 		if ($size == $size_displayed && is_file($file)) { $bar = TRUE; }
@@ -2989,6 +3305,12 @@
       <a href="http://qdig.sourceforge.net/"
        title="Qdig Gallery Script Home Page" style="color:{$qdig_homelink['color']};
        font-weight:normal;">Qdig</a>\n     </div>\n
+     <div title="{$qdig_homelink['div_hacked']}"
+      style="color:{$qdig_homelink['color']}; font-size:{$qdig_homelink['fnt_size']}; text-align:$txt_align;">
+      Hacked by
+      <a href="http://matt.wronka.org/stuff/projects/qdig/"
+       title="Qdig Patches and Addons" style="color:{$qdig_homelink['color']};
+       font-weight:normal;">cnj</a>\n     </div>\n
 EOT;
 		return $str;
 	}
@@ -3437,15 +3759,11 @@
 
 	// Get the file attriubutes for the header
 	$img_size = GetImageSize($name);
-	$content_types[1] = 'image/gif';
-	$content_types[2] = 'image/jpg';
-	$content_types[3] = 'image/png';
-	$content_types[6] = 'image/bmp';
-	$content_type = $content_types[$img_size[2]];
+	$content_type = image_type_to_mime_type($img_size[2]);
 	$content_length = filesize($name);
 
 	// Send the right headers
-	header("Pragma: no-cache"); // TODO: Useful?
+	//header("Pragma: no-cache"); // TODO: Useful?
 	header("Content-Length: $content_length");
 	header("Content-Type: $content_type");
 
@@ -3486,6 +3804,7 @@
 */
 if ($thumbs['onfly'] == FALSE) {
 	$thumbs_msg = createThumbs($cnvrt_thmb);
+	$thumbs_msg = createThumbs($cnvrt_thmb_rv);
 }
 
 /**
@@ -3638,6 +3957,7 @@
 +----------+
 */
 
+if(!(isset($GLOBALS['no_qdig_body']) &&  $GLOBALS['no_qdig_body'])) {
 /**
 * Echo an HTML header if the script is running stand-alone.
 */
@@ -3771,6 +4091,9 @@
 	echo displayImageLinks($thmb_row, $nmrl_row);
 }
 
+$dirhead= file_exists("$caption_path/header")?file_get_contents("$caption_path/header"):"";
+$dirfoot= file_exists("$caption_path/footer")?file_get_contents("$caption_path/footer"):"";
+echo "<div class='qdig-dirheader'>$dirhead</div>\n";
 // Show an Upper Navigation Row, above the displayed image.
 echo navRow($upr_nav);
 
@@ -3788,6 +4111,7 @@
 {
 	echo displayImageLinks($thmb_row, $nmrl_row);
 }
+echo "<div class='qdig-dirfooter'>$dirfoot</div>\n";
 
 // Gallery Footer Row (site link / copyright / qdig home link)
 echo footerRow();
@@ -3848,5 +4172,6 @@
 // Leave the working dir and error reporting the way we found them.
 if (isset($orig_wd)) { chdir($orig_wd); }
 error_reporting($orig_err_rep_level);
+}
 
 /* vim: set noexpandtab tabstop=4 shiftwidth=4: */
