Weatimages PHP Cross Reference Image Galleries

Source: /index.php - 1420 lines - 67950 bytes - Summary - Text - Print

   1  <?php
   2  ////////////////////////////////////////////////////////////////////////////////////

   3  //

   4  // Weatimages 1.7.4, powerful easy to use albums publishing script

   5  // Copyright (c) 2003-2011 Vladimir Nazarkin

   6  // http://nazarkin.name/projects/weatimages/

   7  // weatimages@nazarkin.name

   8  //

   9  // This program is free software; you can redistribute it and/or

  10  // modify it under the terms of the GNU General Public License

  11  // as published by the Free Software Foundation; either version 2

  12  // of the License, or (at your option) any later version.

  13  //

  14  // This program is distributed in the hope that it will be useful,

  15  // but WITHOUT ANY WARRANTY; without even the implied warranty of

  16  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

  17  // GNU General Public License for more details.

  18  //

  19  // You should have received a copy of the GNU General Public License

  20  // along with this program; if not, write to the Free Software

  21  // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

  22  //

  23  // $Id: index.php,v 1.55 2011/03/07 17:29:49 Vova Exp $

  24  //

  25  ////////////////////////////////////////////////////////////////////////////////////

  26  
  27  //Do some initializations

  28  error_reporting(E_ALL ^ E_NOTICE);
  29  $limit_cpu = ini_get('max_execution_time');
  30  $limit_mem = ini_get('memory_limit');
  31  if ($limit_cpu && ($limit_cpu < 60)) { @ini_set('max_execution_time', '60'); }
  32  if ($limit_mem && (rtrim($limit_mem, 'M') < 64)) { @ini_set('memory_limit', '64M'); }
  33  
  34  //Langpack strings

  35  $langpack['albums'] = 'Albums';
  36  $langpack['nested_albums_available'] = 'Nested albums available at the first page';
  37  $langpack['additional_items'] = 'Additional items';
  38  $langpack['additional_items_available'] = 'Additional items available at the first page';
  39  $langpack['album_zip'] = 'Download entire album in single archive';
  40  $langpack['page'] = 'page';
  41  $langpack['next_image'] = 'next image';
  42  $langpack['previous_image'] = 'previous image';
  43  $langpack['return_to_album'] = 'return to album';
  44  $langpack['first_image'] = 'first image';
  45  $langpack['last_image'] = 'last image';
  46  $langpack['close_window'] = 'close window';
  47  $langpack['slideshow_start'] = 'start slideshow';
  48  $langpack['slideshow_stop'] = 'stop slideshow';
  49  $langpack['original'] = 'Original';
  50  $langpack['resized'] = 'Resized';
  51  $langpack['switch_size_toresized'] = 'Click to view resized image';
  52  $langpack['switch_size_tofullsize'] = 'Click to view full size image';
  53  $langpack['thumbnail_hint'] = 'Click to view big image';
  54  $langpack['kilobytes'] = 'Kb';
  55  $langpack['powered_by'] = 'Powered by';
  56  
  57  //kill oneself if user trying to access resource with '/../' in path

  58  if (strstr(urldecode($_SERVER['REQUEST_URI']), '/../')) { fatal_error('Suspicious query rejected'); }
  59  
  60  //$_SERVER['PATH_INFO'] and $_SERVER['PHP_SELF'] variables is very unstable with different php versions and with different web servers

  61  //so it is better to compute them manually

  62  if ( preg_match('|('.$_SERVER['SCRIPT_NAME'].'([^\?]*))\???|', urldecode($_SERVER['REQUEST_URI']), $matches) ) {
  63      //PATH_INFO is the text between SCRIPT_NAME and QUERY_STRING.

  64      //$_SERVER['REQUEST_URI'] is not urldecode'd by default on Apache (unlike IIS).

  65      $SERVER_PHP_SELF = rtrim($matches[1], '/') . '/'; //ensure that we have trailing slash

  66      $REQUEST_PATH = trim($matches[2], '/');//cut hampering slashes

  67  }
  68  else {
  69      $SERVER_PHP_SELF = $_SERVER['SCRIPT_NAME'] . '/';
  70  }
  71  if (!$REQUEST_PATH) {
  72      if ($_GET['path']) { //compatibility mode enabled and we have some path
  73          $REQUEST_PATH = $_GET['path'];
  74          $SERVER_PHP_SELF = $_SERVER['SCRIPT_NAME'] . '/' . $REQUEST_PATH . '/';
  75      }
  76      else { //we are in the root directory
  77          $REQUEST_PATH = '.';
  78      }
  79  }
  80  //$REQUEST_PATH never has starting and trailing slashes

  81  //$SERVER_PHP_SELF always has starting and trailing slashes

  82  
  83  //filter out requests to directories outside of cwd but still allow symlinks

  84  if ( preg_match('|^/|', $REQUEST_PATH) || preg_match('|\.\.|', $REQUEST_PATH) || preg_match('|://|', $REQUEST_PATH) || preg_match('|\\\\|', $REQUEST_PATH) || preg_match('|^.:|', $REQUEST_PATH) ) { fatal_error('Suspicious query rejected'); }
  85  
  86  //ini file name

  87  $ini_ini_filename = 'weatimages.ini';
  88  //read ini file if it present

  89  if (@is_readable($ini_ini_filename)) {
  90      $ini = parse_ini_file($ini_ini_filename, FALSE);
  91  }
  92  else {
  93      unset($ini);
  94  }
  95  
  96  //process nested configs

  97  if ($ini['enable_nested_ini'] && '.' != $REQUEST_PATH) {
  98      $possible_ini_places = explode('/' , $REQUEST_PATH);
  99      $current_search_path = '.';
 100      while (count($possible_ini_places)) {
 101          $current_search_path .= '/' . array_shift($possible_ini_places);
 102          $current_config = $current_search_path . '/' . $ini_ini_filename;
 103          if (@is_readable($current_config)) {
 104              $ini_override = parse_ini_file($current_config, FALSE);
 105              foreach ($ini_override as $key => $value) {
 106                  $ini[$key] = $value;
 107              }
 108              unset($ini_override);
 109          }//if (@is_readable(

 110      }//while (count($possible_ini_places

 111      unset($possible_ini_places, $current_search_path, $current_config);
 112  }//if ($ini['enable_nested_ini']

 113  
 114  //set default options if it absent in ini file of file doesn't exists

 115  if (!isset($ini['cols'])) { $ini['cols'] = 4; }
 116  if (!isset($ini['rows'])) { $ini['rows'] = 6; }
 117  if (!isset($ini['enable_albums_listing'])) { $ini['enable_albums_listing'] = 1; }
 118  if (!isset($ini['enable_albums_thumbs'])) { $ini['enable_albums_thumbs'] = 1; }
 119  if (!isset($ini['albums_thumbs_index'])) { $ini['albums_thumbs_index'] = "index"; }
 120  if (!isset($ini['enable_index_image_hide'])) { $ini['enable_index_image_hide'] = 1; }
 121  if (!isset($ini['albums_cols'])) { $ini['albums_cols'] = 2; }
 122  if (!isset($ini['enable_albums_mtime_sort'])) { $ini['enable_albums_mtime_sort'] = 0; }
 123  if (!isset($ini['enable_albums_reverse_sort'])) { $ini['enable_albums_reverse_sort'] = 0; }
 124  if (!isset($ini['enable_files_mtime_sort'])) { $ini['enable_files_mtime_sort'] = 0; }
 125  if (!isset($ini['enable_files_reverse_sort'])) { $ini['enable_files_reverse_sort'] = 0; }
 126  if (!isset($ini['albums'])) { $ini['albums'] = 50; }
 127  if (!isset($ini['enable_additional_listing'])) { $ini['enable_additional_listing'] = 1; }
 128  if (!isset($ini['additionals'])) { $ini['additionals'] = 20; }
 129  if (!isset($ini['enable_album_zip'])) { $ini['enable_album_zip'] = 0; }
 130  if (!isset($ini['enable_new_window'])) { $ini['enable_new_window'] = 0; }
 131  if (!isset($ini['enable_size_lookup'])) { $ini['enable_size_lookup'] = 1; }
 132  if (!isset($ini['enable_description'])) { $ini['enable_description'] = 1; }
 133  if (!isset($ini['enable_exif'])) { $ini['enable_exif'] = 1; }
 134  if (!isset($ini['enable_exif_date'])) { $ini['enable_exif_date'] = 0; }
 135  if (!isset($ini['enable_cell_border'])) { $ini['enable_cell_border'] = 1; }
 136  if (!isset($ini['enable_albums_edging'])) { $ini['enable_albums_edging'] = -1; }
 137  if (!isset($ini['description_filename'])) { $ini['description_filename'] = 'desc.txt'; }
 138  if (!isset($ini['description_delimiter'])) { $ini['description_delimiter'] = ' '; }
 139  if (!isset($ini['enable_omit_ext'])) { $ini['enable_omit_ext'] = 1; }
 140  if (!isset($ini['enable_filename_display'])) { $ini['enable_filename_display'] = 1; }
 141  if (!isset($ini['enable_filename_cleaning'])) { $ini['enable_filename_cleaning'] = 1; }
 142  if (!isset($ini['enable_html_container'])) { $ini['enable_html_container'] = 1; }
 143  if (!isset($ini['enable_slideshow'])) { $ini['enable_slideshow'] = 1; }
 144  if (!isset($ini['slideshow_delay'])) { $ini['slideshow_delay'] = 3; }
 145  if (!isset($ini['charset'])) { $ini['charset'] = 'windows-1251'; }
 146  if (!isset($ini['jpeg_quality'])) { $ini['jpeg_quality'] = 80; }
 147  if (!isset($ini['hidden_prefix'])) { $ini['hidden_prefix'] = '.'; }
 148  if (!isset($ini['enable_custom_container'])) { $ini['enable_custom_container'] = 0; }
 149  if (!isset($ini['cache_dir'])) { $ini['cache_dir'] = "weatimages-cache"; }
 150  if (!isset($ini['external_css'])) { $ini['external_css'] = ''; }
 151  if (!isset($ini['langpack'])) { $ini['langpack'] = ''; }
 152  if (!isset($ini['enable_compatibility_mode'])) { $ini['enable_compatibility_mode'] = 0; }
 153  
 154  if (!isset($ini['thumb_size'])) { $ini['thumb_size'] = 150; }
 155  if (!isset($ini['enable_thumbs_cache'])) { $ini['enable_thumbs_cache'] = 1; }
 156  
 157  if (!isset($ini['enable_resize'])) { $ini['enable_resize'] = 1; }
 158  if (!isset($ini['resize_size'])) { $ini['resize_size'] = 800; }
 159  if (!isset($ini['enable_smart_resize'])) { $ini['enable_smart_resize'] = 1; }
 160  if (!isset($ini['default_size_resize'])) { $ini['default_size_resize'] = 1; }
 161  if (!isset($ini['enable_resize_cache'])) { $ini['enable_resize_cache'] = 1; }
 162  
 163  //proccess options dependences

 164  // if 'enable_resize' disabled, we should to disable remaining resizing options

 165  if (!$ini['enable_resize']) {
 166      $ini['resize_size'] = 0;
 167      $ini['enable_smart_resize'] = 0;
 168      $ini['default_size_resize'] = 0;
 169      $ini['enable_resize_cache'] = 0;
 170  }
 171  //'enable_smart_resize' feature requires 'enable_size_lookup' option enabled

 172  if (!$ini['enable_size_lookup']) {
 173      $ini['enable_smart_resize'] = 0;
 174  }
 175  //'enable_omit_ext' feature is reasonable only when descriptions enabled

 176  if (!$ini['enable_description']) {
 177      $ini['enable_omit_ext'] = 0;
 178  }
 179  //turn off exif lookup if exif module not found

 180  if ($ini['enable_exif'] && !extension_loaded('exif')) {
 181      $ini['enable_exif'] = 0;
 182      $ini['enable_exif_date'] = 0;
 183  }
 184  if (!$ini['enable_html_container']) {
 185      $ini['enable_slideshow'] = 0;
 186  }
 187  
 188  //Check for GD2 lib

 189  if (!function_exists(imagecopyresampled)) {
 190      echo "Fatal error: GD2 library is not presented";
 191      exit;
 192  }
 193  
 194  //advanced options which aren't included in ini file

 195  //Assume that thumbnail creation supported for next file extensions

 196  $ini['thumbnailable_exts'] = 'jpg|jpeg|gif|png';
 197  //Always ignore files with next extensions

 198  $ini['ignore_exts'] = 'php|css|htm|html|sem';
 199  //Array containing list of filenames which should be omitted during directory loading. Wildcards aren't allowed.

 200  $ini['ignore_files'] = array('.', '..', $ini_ini_filename, $ini['description_filename'], $ini['cache_dir'], basename($_SERVER['SCRIPT_NAME']), '.htaccess', '.htpasswd', 'Thumbs.db', 'error_log', 'access_log', 'cgi-bin', '_notes');
 201  //EXIF comment strings which must be not shown.

 202  $ini['exif_comment_ignore_strings'] = array('MINOLTA DIGITAL CAMERA', 'KONICA MINOLTA DIGITAL CAMERA', 'OLYMPUS DIGITAL CAMERA', 'SAMSUNG DIGITAL CAMERA', 'DIGITAL CAMERA', 'SANYO DIGITAL CAMERA', 'Digital Camera', 'Toshiba Digital Camera');
 203  //Formatting of the timestamp taken from EXIF tags

 204  $ini['exif_date_format'] = 'd.m.Y H:i';
 205  
 206  //Load langpack file

 207  if ('' != $ini['langpack'] && 'thumb' != $_GET['action'] && 'resize' != $_GET['action']) {
 208      @include($ini['langpack']);
 209  }
 210  
 211  //begin html page

 212  function html_begin($title, $start, $header, $comment) {
 213      global $ini, $langpack;
 214      if (!$title || '.' == $title) {
 215          $title = $langpack['albums'];
 216      }
 217  ?>
 218  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 219  <html xmlns="http://www.w3.org/1999/xhtml">
 220  <head>
 221  <title><?php echo $title ?></title>
 222  <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $ini['charset'] ?>"/>
 223  <meta name="Generator" content="Weatimages"/>
 224  <?php
 225      $css_is_external = FALSE; // Flag indicating whether we use external css 

 226      $css_external_path = $ini['external_css'];
 227      if ('' != $css_external_path) {
 228          if ( preg_match('|^https?://|i', $css_external_path) || 0 == substr_compare($css_external_path, '/', 0, 1) ) { // css path is remote or absolute to the web root 
 229              $css_is_external = TRUE;
 230          }
 231          else if ( is_readable($css_external_path) ) { // css path is relative to current directory. check if it readable
 232              // convert css path to absolute path (weatimages.css -> /pics/weatimages.css)

 233              $css_external_path =  ('/' != dirname($_SERVER['SCRIPT_NAME']) ? dirname($_SERVER['SCRIPT_NAME']) : '' ) . '/' . $css_external_path;
 234              $css_is_external = TRUE;
 235          }
 236      }
 237      if ( $css_is_external ) {
 238          print('<link href="' . $css_external_path . '" rel="stylesheet" type="text/css">');
 239      }
 240      else { //output built-in css
 241  ?>
 242  <style type="text/css">
 243  <!--
 244  body {
 245      font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
 246      color: #333333;
 247      font-size: 11px;
 248      text-align: center;
 249      margin-top: 0px;
 250      padding-top: 0px;
 251      margin-bottom: 2px;
 252      margin-left: 0px;
 253      margin-right: 0px;
 254      padding: 0px;
 255      background-color: #FFFFFF;
 256  }
 257  a, a:link, a:visited {
 258      color: #002277;
 259      text-decoration: underline;
 260  }
 261  a:hover {
 262      color: #EE5500;
 263  }
 264  a:active {
 265      color: #FF0000;
 266  }
 267  .weatimages_thumbnail_cell {/* cell displayed in album view and containing image thumbnail, filename, description */
 268      font-family: Helvetica, Arial, sans-serif;
 269      padding: 4px 4px 8px 4px;
 270      border-style: solid;
 271      border-color: #DDDDDD;
 272      text-align: center;
 273      vertical-align: top;
 274  }
 275  .weatimages_thumb_border {/* border of thumbnail */
 276      padding: 0px;
 277      border-width: 1px;
 278      border-style: solid;
 279      border-color: #999999;
 280      margin: 6px 6px 2px 6px;
 281  }
 282  .weatimages_link_size {/* links to original/resized image displayed under thumbnail in album */
 283      font-size: 9px;
 284      text-decoration: underline;
 285      color: #333366;
 286      text-align: center;
 287  }
 288  .weatimages_filename {/* filename displayed under image thumbnail in album */
 289      font-size: 9px;
 290      color: #666666;
 291      font-weight: bold;
 292      text-align: center;
 293  }
 294  .weatimages_image_desc {/* description (from textfile or exif) displayed under image thumbnail in album */
 295      color: #555555;
 296      text-align: center;
 297  }
 298  .weatimages_pages_navigator {/* pager */
 299      font-size: 12px;
 300      color: #003366;
 301      text-align: center;
 302  }
 303  .weatimages_header {/* page title line - album/image name (or description) */
 304      font-size: 15px;
 305      color: #333333;
 306      margin-top: 4px;
 307      margin-bottom: 2px;
 308      margin-left: 20px;
 309      margin-right: 20px;
 310  }
 311  .weatimages_comment {/* string under page title - album/image description */
 312      font-size: 12px;
 313      color: #555555;
 314      margin-bottom: 3px;
 315      margin-left: 20px;
 316      margin-right: 20px;
 317  }
 318  .weatimages_thumb_album_name {/* album name shown on the right of album thumbnail */
 319      font-size: 14px;
 320      color: #333333;
 321  }
 322  .weatimages_thumb_album_desc {/* album decsription shown on the right of album thumbnail */
 323      font-size: 12px;
 324      color: #555555;
 325  }
 326  .weatimages_bigimage {/* style for big version of image */
 327      padding: 0px;
 328      border-width: 1px;
 329      border-style: solid;
 330      border-color: #444444;
 331      margin: 5px;
 332      text-align: center;
 333  }
 334  .weatimages_container_navig {/* links to next/previous images displayed at the page vith big version of image */
 335      font-size: 11px;
 336      text-decoration: underline;
 337  }
 338  .weatimages_toppest_navig {/* style for a div containing top navigational links - to parent albums and next/prev images */
 339      color: #555555;
 340      background-color: #FAFBFB;
 341      padding-left: 20px;
 342      padding-right: 20px;
 343      margin-bottom: 5px;
 344  }
 345  .weatimages_hotkey_tip {/* tips beside links to next/previous images */
 346      font-size: 11px;
 347      color: #BBBBBB;
 348  }
 349  -->
 350  </style>
 351  <?php
 352      }//if ( !$css_is_external ) {

 353  ?>
 354  <script language="javascript" type="text/javascript">
 355  <!--
 356  var slideshow_onload = null; //should be implemented as a function later in this document if it must be called onload

 357  var slideshow = null; //should be implemented as a function later in this document when this function is needle

 358  
 359  function go_link(link_object) {
 360      location.href = link_object.href;
 361  }
 362  function ev(e) { //process window events
 363      if (!e) var e = window.event;
 364      var key = (e.keyCode)? e.keyCode : ((e.which)?e.which:0);
 365      link_id = false;
 366      link_obj = null;
 367      if ((35 == key) && (true == e.ctrlKey)) { //ctrl + end
 368          link_id = 'page_last';
 369      }
 370      else if ((36 == key) && (true == e.ctrlKey)) { //ctrl + home
 371          link_id = 'page_first';
 372      }
 373      else if ((37 == key) && (true == e.ctrlKey)) { //ctrl + arrow left
 374          link_id = 'page_previous';
 375      }
 376      else if ((38 == key) && (true == e.ctrlKey)) { //ctrl + arrow up
 377          link_id = 'page_up';
 378      }
 379      else if ((39 == key) && (true == e.ctrlKey)) { //ctrl + arrow right
 380          link_id = 'page_next';
 381      }
 382      else if ((40 == key) && (true == e.ctrlKey)) { //ctrl + arrow down
 383          if (slideshow) {
 384              slideshow();
 385          }
 386      }
 387      if (link_id) link_obj = document.getElementById(link_id);
 388      if (link_obj) go_link(link_obj);
 389  }
 390  document.onkeydown = ev;
 391  
 392  function onload_init() {
 393      if (slideshow_onload) {
 394          slideshow_onload();
 395      }
 396  }
 397  
 398  function NextImage() {
 399      var link_to_next_image = document.getElementById("page_next");
 400      if (link_to_next_image) {
 401          window.location.href = link_to_next_image.href;
 402      }
 403  }
 404  
 405  //-->

 406  </script>
 407  </head>
 408  <body onload="onload_init();">
 409  <?php
 410      if ($ini['enable_custom_container']) {
 411          @include('weatimages_top.inc.php');
 412      }
 413      print($start);
 414      if ($header && '.' != $header) {
 415          print('<div align="center" class="weatimages_header">' . $header . '</div>');
 416      }
 417      if ($comment) {
 418          print('<div align="center" class="weatimages_comment">' . $comment . '</div>');
 419      }
 420  }//function html_begin(

 421  
 422  
 423  function html_end() {
 424      global $ini, $langpack;
 425  //You should not to remove the following software signature

 426  ?>
 427  <div align="right" style="font-size:9px; color:#909090; margin:15px;"> <?php echo $langpack['powered_by'] ?> <a href="http://nazarkin.name/projects/weatimages/">Weatimages</a></div>
 428  <?php
 429      if ($ini['enable_custom_container']) {
 430          @include('weatimages_bottom.inc.php');
 431      }
 432  ?>
 433  </body>
 434  </html>
 435  <?php
 436  }//function html_end(

 437  
 438  function fatal_error($title = 'Unknown error', $comment = '') {
 439      html_begin($title, '', $title, $comment);
 440      html_end();
 441      exit();
 442  }
 443  
 444  //calculate size of image after resizing

 445  function calc_size_after_resize($imagesize, $max_size) {
 446      //$imagesize - array containing size of source image: $imagesize[0] - width, $imagesize[1] - height

 447      //$max_size - maximal dimension of resulting image in pixels, or in percents

 448      //returns $resizedsize - size of image after resizing: $resizesize[0] - width, $resizesize[1] - height

 449      if (0 == $imagesize[0] || 0 == $imagesize[1]) { return array(0, 0); }
 450      if (preg_match('/([\.\d]+)\%$/', $max_size, $matches)) {
 451          $scale_factor = $matches[1] / 100;
 452          $resizedsize[0] = ceil( $imagesize[0] * $scale_factor );
 453          $resizedsize[1] = ceil( $imagesize[1] * $scale_factor );
 454          return $resizedsize;
 455      }
 456      if ($imagesize[0] > $imagesize[1]) { //if width > height
 457          $resizedsize[0] = $max_size; //width

 458          $resizedsize[1] = ceil( ($imagesize[1] / $imagesize[0]) * $resizedsize[0] ); //calculate height

 459      }
 460      else { //if height > width
 461          $resizedsize[1] = $max_size;
 462          $resizedsize[0] = ceil( ($imagesize[0] / $imagesize[1]) * $resizedsize[1] );
 463      }
 464      return $resizedsize;
 465  }//function calc_size_after_resize(

 466  
 467  
 468  //immediate image resizing function

 469  function resize_image ($image_input, $image_output, $max_size, $jpeg_quality) {
 470      //$image_input - path to file with original image

 471      //$image_output - path to file in which this function must to save resized image. if it empty then output image directly to browser

 472      //$max_size - maximal dimension of resulting image in pixels

 473      //$jpeg_quality - quality of resulting jpeg image

 474      $imagesize = getimagesize($image_input);
 475      if (!$imagesize) { fatal_error("Fatal error: getimagesize($image_input) failed"); }
 476      if (0 == $imagesize[0] || 0 == $imagesize[1]) { fatal_error("Fatal error: zero size happened"); }
 477      $resizedsize = calc_size_after_resize($imagesize, $max_size);
 478      //create image from source file

 479      $image_type_string = NULL; // image type = gif|jpeg|png

 480      switch ($imagesize[2]) { //find out a format of source image
 481          case 1: //gif
 482              $image = imagecreatefromgif($image_input);
 483              $image_type_string = 'gif';
 484              break;
 485          case 2: //jpg
 486              $image = imagecreatefromjpeg($image_input);
 487              $image_type_string = 'jpeg';
 488              break;
 489          case 3: //png
 490              $image = imagecreatefrompng($image_input);
 491              $image_type_string = 'png';
 492              break;
 493          default: //unknown image type
 494              fatal_error("Fatal error: unsupported file type");
 495              $image_type_string = 'unknown';
 496      }
 497      if (!$image) { fatal_error("Fatal error: cannot create image from source"); }
 498      $resized = imagecreatetruecolor($resizedsize[0], $resizedsize[1]);
 499      @imagealphablending($resized, false);
 500      @imagesavealpha($resized, true);
 501      imagecopyresampled($resized, $image, 0, 0, 0, 0, $resizedsize[0], $resizedsize[1], $imagesize[0], $imagesize[1]);
 502      if (!$image_output) { //in this case we output image directly to the browser
 503          header('Content-Type: image/'.$image_type_string);
 504      }
 505      switch ($imagesize[2]) {
 506          case 1: //gif
 507              @imagegif($resized, $image_output);
 508              break;
 509          case 2: //jpg
 510              @imagejpeg($resized, $image_output, $jpeg_quality);
 511              break;
 512          case 3: //png
 513              @imagepng($resized, $image_output);
 514              break;
 515      }
 516  }//function resize_image (

 517  
 518  
 519  //manages images resizing proccess and perform caching of resized images

 520  function resize_manager($image_input, $max_size, $cache_suffix, $is_cache_enabled) {
 521      //$image_input - path to file with original image

 522      //$max_size - maximal dimension of resulting image in pixels

 523      //$cache_suffix - suffix used to get filename of cached thumbnail from source image filename

 524      //$is_cache_enabled - indicates enabled or disabled caching of resized images

 525      global $ini;
 526      if (!@is_readable($image_input)) { fatal_error("Fatal error: requested image is not readable"); }
 527      $is_resized_sent = FALSE;
 528      if ($is_cache_enabled) {
 529          $file_cache = $ini['cache_dir'] . '/' . $image_input . $cache_suffix;
 530          if (!@is_readable($file_cache)) { //thumbnail file still don't exists
 531              $file_cache_dir = dirname($file_cache);
 532              if (!@is_dir($file_cache_dir)) {
 533                  //we need to create a copy of directories tree under cache directory

 534                  $dirs_must_exist = array($file_cache_dir);
 535                  while ('.' != $dirs_must_exist[count($dirs_must_exist)-1] && '/' != $dirs_must_exist[count($dirs_must_exist)-1]) {
 536                      array_push( $dirs_must_exist, dirname($dirs_must_exist[count($dirs_must_exist)-1]) );
 537                  }
 538                  array_pop($dirs_must_exist);
 539                  while (count($dirs_must_exist) > 0) {
 540                      $tmp_dir_new = array_pop($dirs_must_exist);
 541                      if (@is_dir($tmp_dir_new)) {
 542                          continue;
 543                      }
 544                      @mkdir($tmp_dir_new, 0777);
 545                      @chmod($tmp_dir_new, 0777);
 546                      clearstatcache();
 547                  }
 548              }
 549              if (@is_writable(dirname($file_cache))) {
 550                  $file_mutex = $ini['cache_dir'] . '/' . 'weatimages-mutex';//we allow only single image resizing proccess in a time to avoid memory issues on the server

 551                  $FP = @fopen($file_mutex, 'r');
 552                  if (FALSE === $FP) {
 553                      $FP = @fopen($file_mutex, 'w');
 554                      @chmod($file_mutex, 0666);
 555                  }
 556                  @flock($FP, LOCK_EX);
 557                  resize_image($image_input, $file_cache, $max_size, $ini['jpeg_quality']);
 558                  @chmod($file_cache, 0666);
 559                  @flock($FP, LOCK_UN);
 560                  @fclose($FP);
 561              }
 562              clearstatcache();
 563          }//if (!@is_readable($file_cache)) {

 564          if (@is_readable($file_cache)) { //check that we successfully created thumbnail file at the previous step
 565              header('Content-Type: image/jpeg');
 566              readfile($file_cache);
 567              $is_resized_sent = TRUE;
 568          }//if (@is_readable($file_cache)) {

 569       }
 570      if (!$is_resized_sent) { //we still don't have cached image. Let's resize image and output result to user's browser
 571          resize_image($image_input, NULL, $max_size, $ini['jpeg_quality']);
 572      }
 573  }//function resize_manager(

 574  
 575  
 576  //show pages-navigation-bar on thumbnails page if there are more then one page

 577  function show_pages_navigator($objects_count, $objects_on_page, $page_current, $page_query_string) {
 578      //$objects_count - total objects amount

 579      //$objects_on_page - amount of objects on a single page

 580      //$page_current - current page number

 581      //$page_query_string - string used as pagenumber variable name in http query

 582      global $ini, $langpack, $SERVER_PHP_SELF;
 583      if ($objects_count > $objects_on_page) {
 584          print('<div class="weatimages_pages_navigator"><span style="font-size:12px; color:#333333;">' . $langpack['page'] . ':&nbsp;&nbsp;</span>');
 585          //print link to previous page if current page isn't first

 586          if (1 != $page_current) {
 587              print('<a href="'
 588                  . url_compat( $SERVER_PHP_SELF . '?' . $page_query_string . '=' . ($page_current-1) )
 589                  . '" style="font-size:15px; font-weight:bold;">&lsaquo;&nbsp;&nbsp;</a>');
 590          }
 591          for ($i = 1; $objects_count > ($i-1)*$objects_on_page; $i++) {
 592              if ($i != $page_current) {
 593                  print('<a href="'
 594                      . url_compat($SERVER_PHP_SELF . '?' . $page_query_string . '=' . $i)
 595                      . '">&nbsp;' . $i . ' </a>');
 596              }
 597              else {
 598                  print('<font style="font-size: 14px; color:#555555; background-color:#F2F2F2; text-decoration:underline;">&nbsp;' . $i . '&nbsp;</font>');
 599              }
 600          }
 601          //print link to next page if current page isn't last

 602          if ( $objects_count > ($page_current*$objects_on_page) ) {
 603              print('<a href="'
 604                  . url_compat($SERVER_PHP_SELF . '?' . $page_query_string . '=' . ($page_current+1))
 605                  . '" style="font-size:15px; font-weight:bold;">&nbsp;&nbsp;&rsaquo;</a>');
 606          }
 607          print('</div>');
 608      }
 609  }//function show_pages_navigator(

 610  
 611  
 612  //load descriptions from desc file if feature enabled and file exists

 613  function load_descriptions($REQUEST_PATH) {
 614      global $ini;
 615      $descs = array();
 616      if ($ini['enable_description']) {
 617          $desc_filefullname = $REQUEST_PATH . '/' . $ini['description_filename'];
 618          if (@is_readable($desc_filefullname)) {
 619              $desc_file = file($desc_filefullname);
 620              if (is_array($desc_file)) {
 621                  foreach ($desc_file as $line) {
 622                      list($filename, $desc) = explode($ini['description_delimiter'], trim($line), 2);
 623                      $descs[$filename] = $desc;
 624                  }//foreach ($desc_file as $line) {

 625                  unset($desc_file);
 626              }//if (!is_array($desc_file) {

 627          }//if (@is_readable($desc_filefullname)) {

 628      }//if ($ini['enable_description']) {

 629      return $descs;
 630  }
 631  
 632  //read directory contents and descriptions

 633  function load_directory($REQUEST_PATH, $include_index_image) {
 634      global $ini;
 635      if ( FALSE == ($dir = opendir($REQUEST_PATH)) ) {
 636          fatal_error("Fatal error: path cannot be loaded");
 637      }
 638      $pictures = $others = $dirs = array();
 639      $pictures_mtime = $others_mtime = $dirs_mtime = array();
 640      $descs = load_descriptions($REQUEST_PATH);
 641      //read directory - get arrays with names of objects situated in that directory

 642      $pictures_count = 0;
 643      $others_count = 0;
 644      $dirs_count = 0;
 645      while (FALSE !== ($file = readdir($dir))) { //sift out directory record which are not necessary images
 646          if ('.' == $file || '..' == $file) { continue; } //sift out current directory and parental directory

 647          if (in_array($file, $ini['ignore_files'])) { continue; } //sift out descriptions file

 648          //don't include hidden objects

 649          if ( $ini['hidden_prefix'] == substr($file, 0, strlen($ini['hidden_prefix'])) ) { continue; }
 650          if (is_dir($REQUEST_PATH . '/' . $file)) { //we got an directory in directory contents listing
 651              if ($ini['enable_albums_mtime_sort']) {
 652                  $dirs_mtime[$dirs_count] = filemtime($REQUEST_PATH.'/'.$file);
 653              }
 654              $dirs[$dirs_count++] = $file;
 655              continue;
 656          }
 657          //try to find image description (for file without extension) for substituting to absent description (for file with extension)

 658          if ($ini['enable_omit_ext']) {
 659              $filename_without_ext = preg_replace('/\.[^\.]+$/', '', $file);
 660              if (!array_key_exists($file, $descs)) {
 661                  if (array_key_exists($filename_without_ext, $descs)) {
 662                      $descs[$file] = $descs[$filename_without_ext];
 663                  }
 664              }
 665              if (!array_key_exists($file.'.', $descs)) {
 666                  if (array_key_exists($filename_without_ext.'.', $descs)) {
 667                      $descs[$file.'.'] = $descs[$filename_without_ext.'.'];
 668                  }
 669              }
 670          }//if ($ini['enable_description'] && !array_key_exists($pictures[$i], $descs)) {

 671          if (preg_match('/\.(' . $ini['thumbnailable_exts'] . ')$/i', $file)) {//include files with image extensions only
 672              if ($ini['enable_files_mtime_sort']) {
 673                  $pictures_mtime[$pictures_count] = filemtime($REQUEST_PATH.'/'.$file);
 674              }
 675              if ((!$include_index_image && $ini['enable_index_image_hide']) && ($ini['albums_thumbs_index'].'.jpg' == $file || $ini['albums_thumbs_index'].'.jpeg' == $file || $ini['albums_thumbs_index'].'.png' == $file || $ini['albums_thumbs_index'].'.gif' == $file) ) {
 676                  continue;
 677              }
 678              $pictures[$pictures_count++] = $file;
 679              continue;
 680          }
 681          if (preg_match('/\.(' . $ini['ignore_exts'] . ')$/i', $file)) {//ignore files with always-dont-show extensions
 682              continue;
 683          }
 684          if ($ini['enable_files_mtime_sort']) {
 685              $others_mtime[$others_count] = filemtime($REQUEST_PATH.'/'.$file);
 686          }
 687          $others[$others_count++] = $file; //we got an non-image (not thumbnailable) and non-directory item

 688      }//while (FALSE !== ($file = readdir($dir))) {

 689      closedir($dir);
 690      //sort images and other files

 691      if ($ini['enable_files_mtime_sort']) {
 692          array_multisort($pictures_mtime, SORT_NUMERIC, (!$ini['enable_files_reverse_sort'])?SORT_ASC:SORT_DESC, $pictures, SORT_STRING, SORT_ASC);
 693          array_multisort($others_mtime, SORT_NUMERIC, (!$ini['enable_files_reverse_sort'])?SORT_ASC:SORT_DESC, $others, SORT_STRING, SORT_ASC);
 694      }
 695      else {
 696          if (!$ini['enable_files_reverse_sort']) {
 697              sort($pictures, SORT_STRING);
 698              sort($others, SORT_STRING);
 699          } else {
 700              rsort($pictures, SORT_STRING);
 701              rsort($others, SORT_STRING);
 702          }
 703      }
 704      //sort albums

 705      if ($ini['enable_albums_mtime_sort']) {
 706          array_multisort($dirs_mtime, SORT_NUMERIC, (!$ini['enable_albums_reverse_sort'])?SORT_ASC:SORT_DESC, $dirs, SORT_STRING, SORT_ASC);
 707      }
 708      else {
 709          if (!$ini['enable_albums_reverse_sort']) {
 710              sort($dirs, SORT_STRING);
 711          } else {
 712              rsort($dirs, SORT_STRING);
 713          }
 714      }
 715      return array($pictures, $others, $dirs, $descs);
 716  }//function load_directory($REQUEST_PATH) {

 717  
 718  
 719  //checks exif comment text

 720  function is_exif_text_bad(&$exif_text) {
 721      global $ini;
 722      $exif_text = preg_replace('/^[\x00\s]+/', '', $exif_text);//cut spaces at the beginning

 723      $exif_text = preg_replace('/[\x00\s]+$/', '', $exif_text);//cut trailing spaces

 724      $search_result = array_search($exif_text, $ini['exif_comment_ignore_strings']);
 725      if ( false !== $search_result && NULL !== $search_result) { $exif_text = ''; }//array_search in php<4.2 returns NULL instead of false if not found

 726      if ( preg_match('/[\.,:\-\?\S\x00]/', $exif_text) ) { return false; } else { return true; }
 727  }
 728  
 729  
 730  //get image size, size after resize, resize expediency, and EXIF data

 731  //returns array($filesize_kb, $imagesize, $resizesize, $is_resize_senseless);

 732  function get_image_sizes($image_path) {
 733      global $ini;
 734      $exif_string = '';
 735      $filesize_kb = 0;
 736      $imagesize = array();
 737      if ($ini['enable_exif'] && preg_match('/\.(jpg|jpeg|tif|tiff)$/i', $image_path)){
 738          $exif_desc = '';
 739          $exif_comment = '';
 740          $exif_data = @exif_read_data($image_path, false, true, false);
 741          //try to get description from exif. it may be contained in various exif sections

 742          if ( is_exif_text_bad($exif_desc) && isset($exif_data['IFD0']['Title']) && extension_loaded('mbstring') ) {
 743              //Title given by Windows Explorer, UNICODE

 744              $exif_desc = @mb_convert_encoding($exif_data['IFD0']['Title'], strtoupper($ini['charset']), 'UCS-2LE');
 745          }
 746          if ( is_exif_text_bad($exif_comment) && isset($exif_data['IFD0']['Comments']) && extension_loaded('mbstring') ) {
 747              //Comment given by Windows Explorer, UNICODE

 748              $exif_comment = @mb_convert_encoding($exif_data['IFD0']['Comments'], strtoupper($ini['charset']), 'UCS-2LE');
 749          }
 750          if ( is_exif_text_bad($exif_comment) && isset($exif_data['EXIF']['UserComment']) && extension_loaded('mbstring') ) {
 751              //UserComment given by ACDSee, UNICODE

 752              $comment_field = $exif_data['EXIF']['UserComment'];
 753              if (is_array($comment_field)) { $comment_field = ''; } // there was one occurence of getting array from UserComment, ignoring such data to not get php warnings for next line

 754              if (preg_match('/^([^\0]+?)\0(.+)$/', $comment_field, $matches) ) {
 755                  //now $matches[1] contains encoding of the comment (unicode most likely), $matches[2] - comment in this encoding

 756                  if ('UNICODE' == $matches[1]) { $matches[1] = 'UCS-2LE'; }
 757                  $exif_comment = @mb_convert_encoding($matches[2], strtoupper($ini['charset']), $matches[1]);
 758              }
 759          }
 760          if ( is_exif_text_bad($exif_desc) && isset($exif_data['IFD0']['ImageDescription']) ) {
 761              //ImageDescription given by ACDSee, non-UNICODE, international characters saved

 762              $exif_desc = $exif_data['IFD0']['ImageDescription'];
 763          }
 764          if ( is_exif_text_bad($exif_desc) && isset($exif_data['WINXP']['Title']) ) {
 765              //Title given by Windows Explorer, non-UNICODE

 766              $exif_desc = $exif_data['WINXP']['Title'];
 767          }
 768          if ( is_exif_text_bad($exif_comment) && isset($exif_data['WINXP']['Comments']) ) {
 769              //Comment given by Windows Explorer, non-UNICODE

 770              $exif_comment = $exif_data['WINXP']['Comments'];
 771          }
 772          if ( is_exif_text_bad($exif_comment) && isset($exif_data['COMPUTED']['UserComment']) ) {
 773              //UserComment given by ACDSee, autoconverted to ASCII probably with national characters loss

 774              $exif_comment = $exif_data['COMPUTED']['UserComment'];
 775          }
 776          
 777          if (!is_exif_text_bad($exif_desc) && !is_exif_text_bad($exif_comment)) {
 778              $exif_string = $exif_desc . '<br/>' . $exif_comment;
 779          }
 780          else if (!is_exif_text_bad($exif_desc)) { $exif_string = $exif_desc; }
 781          else if (!is_exif_text_bad($exif_comment)) { $exif_string = $exif_comment; }
 782          
 783          //try to get filesize from exif

 784          if ( isset($exif_data['FILE']['FileSize']) ) {
 785              $filesize_kb = $exif_data['FILE']['FileSize'];
 786          }
 787          //try to get image dimensions from exif

 788          if ( isset($exif_data['COMPUTED']['Width']) && isset($exif_data['COMPUTED']['Height']) ) {
 789              $imagesize[0] = $exif_data['COMPUTED']['Width'];
 790              $imagesize[1] = $exif_data['COMPUTED']['Height'];
 791          }
 792          //try to get date picture taken

 793          if ( $ini['enable_exif_date'] && isset($exif_data['EXIF']['DateTimeOriginal'])
 794              && preg_match('/^(\d\d\d\d):(\d\d):(\d\d) (\d\d):(\d\d):(\d\d)$/', $exif_data['EXIF']['DateTimeOriginal'], $matches) ) {
 795              $unixtime = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
 796              if ($unixtime > 0) {
 797                  $exif_string = (is_exif_text_bad($exif_string)?'':$exif_string.'<br/>') . date($ini['exif_date_format'], $unixtime);
 798              }
 799          }
 800      }
 801      if (!$filesize_kb) {
 802          $filesize_kb = @filesize($image_path);
 803      }
 804      $filesize_kb = ceil($filesize_kb / 1024);
 805      if (0 == $imagesize[0] || 0 == $imagesize[1]) {
 806          $imagesize = @getimagesize($image_path);
 807      }
 808      $resizesize = calc_size_after_resize($imagesize, $ini['resize_size']);
 809      $is_resize_senseless = FALSE;
 810      if (($resizesize[0] >= $imagesize[0]) && $ini['enable_smart_resize']) {
 811          $is_resize_senseless = TRUE;
 812      }
 813      return array($filesize_kb, $imagesize, $resizesize, $is_resize_senseless, $exif_string);
 814  }//function get_image_sizes(

 815  
 816  
 817  //output cell with thumbnail and image info

 818  function show_thumbnail_cell($uri_original, $uri_resize, $uri_thumb, $filesize_kb, $imagesize, $resizesize, $is_resize_senseless, $filename, $desc) {
 819      global $ini, $langpack;
 820      $thumbsize = 0;
 821      if ($ini['enable_size_lookup']) {//get thumbnail width and height
 822          $thumbsize = calc_size_after_resize($imagesize, $ini['thumb_size']);
 823      }
 824      if ($ini['enable_size_lookup'] && $ini['default_size_resize'] && $is_resize_senseless) { $uri_original .= '&amp;preferredsize=resize'; }
 825      print('<td align="center" valign="top" class="weatimages_thumbnail_cell" width="' . ($ini['thumb_size'] + 14) . '"'
 826          . ' style="border-width: ' . ($ini['enable_cell_border'] ? '1' : '0') . 'px;">'
 827          . '<a name="' . $filename . '" href="'
 828          . (($ini['default_size_resize'] && !$is_resize_senseless) ? $uri_resize : $uri_original) . '"'
 829          . ($ini['enable_new_window']?' target="blank"':'') .'>'
 830          . '<img src="' . $uri_thumb . '"'
 831          . (($ini['enable_size_lookup'])?' width="' . $thumbsize[0] . '" height="' . $thumbsize[1] . '"':'')
 832          . ' class="weatimages_thumb_border" title="' . $langpack['thumbnail_hint'] . '" alt="' . $filename . '"/>'
 833          . '</a>'
 834          . ($ini['enable_filename_display'] ? '<div class="weatimages_filename">' . wordwrap(clean_filename($filename), 30, '<br/>', 1) . '</div>' : '')
 835          . ( ($ini['enable_resize'] || $ini['enable_size_lookup']) ?
 836              '<div align="center">'
 837              . '<a href="' . $uri_original . '"'. ($ini['enable_new_window']?' target="blank"':'') .' class="weatimages_link_size">'
 838              . (($ini['enable_resize'] && !$is_resize_senseless) ? $langpack['original'] : '')
 839              . ($ini['enable_size_lookup']?' '.$imagesize[0].'x'.$imagesize[1].' ('.$filesize_kb.$langpack['kilobytes'].')':'')
 840              . '</a>'
 841              . ( (!$is_resize_senseless && $ini['enable_resize']) ?
 842                  ($ini['enable_size_lookup']?'<br/>':'<font class="weatimages_link_size" style="text-decoration:none;"> | </font>')
 843                  . '<a href="' . $uri_resize . '"'. ($ini['enable_new_window']?' target="blank"':'') .' class="weatimages_link_size">'
 844                  . $langpack['resized']. ($ini['enable_size_lookup']?' '.$resizesize[0].'x'.$resizesize[1]:'')
 845                  . '</a>' : ''
 846              )//( (!$is_resize_senseless && $ini['enable_resize']) ?
 847              . '</div>' : ''
 848          )//( ($ini['enable_resize'] || $ini['enable_size_lookup']) ?
 849          . (($ini['enable_description'] && $desc) ? '<div class="weatimages_image_desc">' . $desc . '</div>' : '')
 850          . '</td>'
 851      );//print('<td

 852  }//function show_thumbnail_cell(

 853  
 854  //calculate image urls. returns array($uri_original, $uri_resize, $uri_thumb)

 855  function get_image_urls($relative_dir, $filename, $is_need_container) {
 856      global $ini;
 857      $uri_thumb = $_SERVER['SCRIPT_NAME'] . '/' . $relative_dir . '/' . $filename . '?action=thumb';
 858      
 859      if ($is_need_container) {
 860          $uri_original = $_SERVER['SCRIPT_NAME'] . '/' . $relative_dir . '/' . $filename . '?action=big&amp;size=original';
 861          $uri_resize = $_SERVER['SCRIPT_NAME'] . '/' . $relative_dir . '/' . $filename . '?action=big&amp;size=resize';
 862      }
 863      else {
 864          $current_relative_directory = dirname($_SERVER['SCRIPT_NAME']); //current directory relative to web root

 865          if ('/' == $current_relative_directory || '\\' == $current_relative_directory) { $current_relative_directory = '/.'; }
 866          //link to original current image

 867          $uri_original = $current_relative_directory . '/' . $relative_dir . '/' . $filename;
 868          //link to resized current image

 869          $uri_resize = $_SERVER['SCRIPT_NAME'] . '/' . $relative_dir . '/' . $filename . '?action=resize';
 870          //link to the thumb of current image

 871      }
 872      if ($is_need_container) { $uri_original = url_compat($uri_original); }
 873      $uri_resize = url_compat($uri_resize);
 874      $uri_thumb = url_compat($uri_thumb);
 875      return array($uri_original, $uri_resize, $uri_thumb);
 876  }//function get_image_urls(

 877  
 878  //returns filename without extension, '_' symbols replaced by spaces

 879  function clean_filename($filename) {
 880      global $ini;
 881      if ($ini['enable_filename_cleaning']) {
 882          $filename = preg_replace('/\.('.$ini['thumbnailable_exts'].')$/i', '', $filename);
 883          $filename = preg_replace('/_/', ' ', $filename);
 884      }
 885      return $filename;
 886  }//function clean_filename(

 887  
 888  //find thumbnail image for album and return array ([0]:uri of thumbnail; [1]:array([0]:thumb width; [1]:thumb height)) or return FALSE if album hasn't thumbnails

 889  function get_album_thumb($album_dir) {
 890      global $ini;
 891      $album_thumb[0] = 0;
 892      list($nested_pictures, /*$others*/, $nested_dirs, $descs) = load_directory($album_dir, TRUE);
 893      $nested_dirs_count = count($nested_dirs);
 894      if (0 == count($nested_pictures)) {
 895          for ($i = 0; $i < $nested_dirs_count; $i++) {
 896              $album_thumb = get_album_thumb($album_dir.'/'.$nested_dirs[$i]);
 897              if ($album_thumb[0]) { break; }
 898          }
 899      } //if (0 == count($nested_pictures)) {

 900      else {
 901          if (in_array($ini['albums_thumbs_index'].'.jpg', $nested_pictures)) {
 902              $album_index_image = $ini['albums_thumbs_index'].'.jpg';
 903          }
 904          elseif (in_array($ini['albums_thumbs_index'].'.jpeg', $nested_pictures)) {
 905              $album_index_image = $ini['albums_thumbs_index'].'.jpeg';
 906          }
 907          elseif (in_array($ini['albums_thumbs_index'].'.png', $nested_pictures)) {
 908              $album_index_image = $ini['albums_thumbs_index'].'.png';
 909          }
 910          elseif (in_array($ini['albums_thumbs_index'].'.gif', $nested_pictures)) {
 911              $album_index_image = $ini['albums_thumbs_index'].'.gif';
 912          }
 913          else {
 914              $album_index_image = $nested_pictures[0];
 915          }
 916          list(/*$uri_original*/, /*$uri_resize*/, $album_thumb[0]) = get_image_urls($album_dir, $album_index_image, 0);
 917          list(/* $filesize_kb */, $album_thumb_size, /*$resizesize*/, /*$is_resize_senseless*/, /*$exif_comment*/)
 918              = get_image_sizes($album_dir.'/'.$album_index_image);
 919          $album_thumb[1] = calc_size_after_resize($album_thumb_size, $ini['thumb_size']);
 920      } //if (0 == count($nested_pictures)) { ELSE

 921      return $album_thumb;
 922  }
 923  
 924  //Converts url which use virtual path to url which don't use it

 925  //Source url must be relative to site root

 926  //Return the unchanged url if compatibility mode is disabled

 927  function url_compat($url) {
 928      global $ini;
 929      if (!$ini['enable_compatibility_mode']) {
 930          return $url;
 931      }
 932      if ( !preg_match ('|^'.$_SERVER['SCRIPT_NAME'].'([^?]*)\??([^?]*)$|', $url, $matches) ) {
 933          return $url;
 934      }
 935      $path = rawurlencode(trim($matches[1], '/'));
 936      $query_string = $matches[2];
 937      $url_compatible = $_SERVER['SCRIPT_NAME'];
 938      if ($path) { $url_compatible .= '?path=' . $path; }
 939      if ($query_string) { $url_compatible .= (($path)?'&amp;':'?') . $query_string; }
 940      return $url_compatible;
 941  }
 942  
 943  //Get url for navigational link in expanded view (links to neighbour images - previous , next, etc)

 944  //First parameter - path to image, relative to this script

 945  //Returns url to page with image

 946  function get_expanded_navig_url($path_to_image) {
 947      global $ini;
 948      if ($ini['enable_size_lookup']) {
 949          list($filesize_kb, $imagesize, $resizesize, $is_resize_senseless, /*$exif_comment*/) = get_image_sizes($path_to_image);
 950      }//if ($ini['enable_size_lookup']) {

 951      list($uri_original, $uri_resize, $uri_thumb) = get_image_urls(dirname($path_to_image), basename($path_to_image), TRUE);
 952      //if current page contains resized image, but next image cannot be resized, we'll remember that user prefers resized images and when some of next images will be resizeable, we'll show it resized

 953      if (('resize' == $_GET['size'] || 'resize' == $_GET['preferredsize']) && $is_resize_senseless) {
 954          $uri_original .= '&amp;preferredsize=resize';
 955      }
 956      if (('resize' == $_GET['size'] || 'resize' == $_GET['preferredsize']) && !$is_resize_senseless) {
 957          $result = $uri_resize;
 958      }
 959      else {
 960          $result = $uri_original;
 961      }
 962      return $result;
 963  }//function get_expanded_navig_url(

 964  
 965  //Prints link to album on expanded view

 966  function print_expanded_album_link($album_path, $album_page, $album_picture) {
 967      //$album_path - relative path to album link to which is wanted

 968      //$album_page - page of the album

 969      //$album_picture - picture which should be focused when user clicks this link

 970      global $ini, $langpack;
 971      if ($ini['enable_new_window']) { //create link for closing this window
 972  ?>
 973  <script language="javascript" type="text/javascript">
 974  <!--
 975  document.write('<a id="page_up" href="javascript:window.close();" class="weatimages_container_navig"><?php echo $langpack['close_window'] ?></a>');
 976  //-->

 977  </script><noscript><?php print('<a id="page_up" href="' . url_compat($_SERVER['SCRIPT_NAME'] . '/' . $album_path . '?page=' . $album_page . '#' . $album_picture) . '" class="weatimages_container_navig">' . $langpack['return_to_album'] . '</a>'); ?></noscript>
 978  <?php
 979      }//if ($ini['enable_new_window']) {

 980      elseif ('true' == $_GET['fromthumbnail']) { //create link for return to thumbnails page
 981  ?><script language="javascript" type="text/javascript">
 982  <!--
 983  if (history.length > 0) {
 984  document.write('<a id="page_up" href="javascript:history.back();" class="weatimages_container_navig"><?php echo $langpack['return_to_album'] ?></a>');
 985  }
 986  else {
 987  document.write('<?php print('<a id="page_up" href="' . url_compat($_SERVER['SCRIPT_NAME'] . '/' . $album_path . '?page=' . $album_page . '#' . $album_picture) . '" class="weatimages_container_navig">' . $langpack['return_to_album'] . '</a>'); ?>');
 988  }
 989  //-->

 990  </script><noscript><?php print('<a id="page_up" href="' . url_compat($_SERVER['SCRIPT_NAME'] . '/' . $album_path . '?page=' . $album_page . '#' . $album_picture) . '" class="weatimages_container_navig">' . $langpack['return_to_album'] . '</a>'); ?></noscript><?php
 991      }
 992      else {
 993          print('<a id="page_up" href="' . url_compat($_SERVER['SCRIPT_NAME'] . '/' . $album_path . '?page=' . $album_page . '#' . $album_picture) . '" class="weatimages_container_navig">' . $langpack['return_to_album'] . '</a>');
 994      }
 995  }//function print_expanded_album_link(

 996  
 997  //Prints navigation bar for expanded view

 998  function print_expanded_navigation($album_path, &$pictures, $i) {
 999      //$album_path - relative path to album

1000      //&$pictures - referencr to array containing picture filenames

1001      //$i - index of current image in array

1002      global $ini, $langpack;
1003      //show links to first and last images, and to thumbnail page

1004      print('<div align="center" class="weatimages_toppest_navig"><table border="0" cellspacing="0" cellpadding="0"><tr>');
1005      //create link to first image in album, only if current image isn't first

1006      if ($ini['enable_slideshow']) {
1007          echo '<td align="right" width="200" style="padding-right:10px;">';
1008          if (0 != $i) {//if current image is not the first image, we'll create link to first
1009              print('<script language="javascript" type="text/javascript"><!--'."\r\n".'document.write(\'<span class="weatimages_hotkey_tip">(Ctrl Home)&nbsp;</span>\');'."\r\n".'//--></script>');
1010              print('<a id="page_first" href="' . get_expanded_navig_url($album_path.'/'.$pictures[0]) . '" class="weatimages_container_navig"><strong style="font-size:12px; line-height:11px;">&lsaquo;&lsaquo;&nbsp;</strong> ' . $langpack['first_image'] . '</a> ');
1011          }//if (0 != $i) {

1012          echo '</td>';
1013          //create link to thumbnail page (exactly to page number on which located current image)

1014          echo '<td align="center">';
1015          $album_page = ceil(($i+1) / ($ini['cols']*$ini['rows'])); //number of album page which contains thumbnail of current image

1016          print_expanded_album_link($album_path, $album_page, $pictures[$i]);
1017          echo '</td>';
1018          //create link to last image in album, if current image isn't last

1019          echo '<td align="left" width="200" style="padding-left:10px;">';
1020          $i_last = count($pictures) - 1;
1021          if ($i < $i_last) {
1022              print(' <a id="page_last" href="' . get_expanded_navig_url($album_path.'/'.$pictures[$i_last]) . '" class="weatimages_container_navig">' . $langpack['last_image'] . ' <strong style="font-size:12px; line-height:11px;">&nbsp;&rsaquo;&rsaquo;</strong></a>');
1023              print('<script language="javascript" type="text/javascript"><!--'."\r\n".'document.write(\'<span class="weatimages_hotkey_tip">&nbsp;(Ctrl End)</span>\');'."\r\n".'//--></script>');
1024          }//if ($pictures[$i+1]) {

1025          echo '</td>';
1026          echo '</tr><tr>';
1027      }//if ($ini['enable_slideshow']) {

1028      //create link to previous image, if exists

1029      echo '<td align="right" width="200" style="padding-right:10px;">';
1030      if ($pictures[$i-1]) {//if previous image exists, we'll create link to it
1031          print('<script language="javascript" type="text/javascript"><!--'."\r\n".'document.write(\'<span class="weatimages_hotkey_tip">(Ctrl &larr;)&nbsp;</span>\');'."\r\n".'//--></script>');
1032          print('<a id="page_previous" href="' . get_expanded_navig_url($album_path.'/'.$pictures[$i-1]) . '" class="weatimages_container_navig"><strong style="font-size:12px; line-height:11px;">&lsaquo;&nbsp;</strong> ' . $langpack['previous_image'] . '</a> ');
1033      }//if ($pictures[$i-1]) {

1034      echo '</td>';
1035      //container for slideshow controller

1036      if ($ini['enable_slideshow']) {
1037          echo '<td id="slideshow_container" align="center">&nbsp;</td>';
1038      }
1039      else {//create link to thumbnail page 
1040          echo '<td align="center">';
1041          $album_page = ceil(($i+1) / ($ini['cols']*$ini['rows'])); //number of album page which contains thumbnail of current image

1042          print_expanded_album_link($album_path, $album_page, $pictures[$i]);
1043          echo '</td>';
1044      }
1045      //create link to next image, if it exists

1046      echo '<td align="left" width="200" style="padding-left:10px;">';
1047      if ($pictures[$i+1]) {
1048          print(' <a id="page_next" href="' . get_expanded_navig_url($album_path.'/'.$pictures[$i+1]) . '" class="weatimages_container_navig">' . $langpack['next_image'] . ' <strong style="font-size:12px; line-height:11px;">&nbsp;&rsaquo;</strong></a>');
1049          print('<script language="javascript" type="text/javascript"><!--'."\r\n".'document.write(\'<span class="weatimages_hotkey_tip">&nbsp;(Ctrl &rarr;)</span>\');'."\r\n".'//--></script>');
1050      }//if ($pictures[$i+1]) {

1051      echo '</td>';
1052      print('</tr></table></div>');
1053  }//function print_expanded_navigation(

1054  
1055  //Output slideshow javascript code to the browser

1056  function print_slideshow() {
1057      global $ini, $langpack;
1058      if ($ini['enable_slideshow']) {
1059  ?>
1060  <script language="javascript" type="text/javascript">
1061  <!--
1062  var LANGPACK_SLIDESHOW_START = "<?php echo $langpack['slideshow_start'] ?>";
1063  var LANGPACK_SLIDESHOW_STOP = "<?php echo $langpack['slideshow_stop'] ?>";
1064  var SLIDESHOW_INTERVAL = 1000 * <?php echo $ini['slideshow_delay'] ?>;
1065  var strUrlMarker = 'slideshow=true';
1066  var iTimerId = 0;
1067  var bSlideshowRunning = ((location.href.length-strUrlMarker.length) == location.href.lastIndexOf(strUrlMarker)) ? true : false;
1068  var next_obj = null;
1069  var first_obj = null;
1070  
1071  function slideshow_init() {
1072      next_obj = document.getElementById('page_next');
1073      first_obj = document.getElementById('page_first');
1074      if (next_obj || first_obj) {
1075          document.getElementById('slideshow_container').innerHTML = '<a id="slideshow_control" onclick="javascript:slideshow();" style="cursor:pointer">' + ( (bSlideshowRunning && next_obj) ? LANGPACK_SLIDESHOW_STOP : LANGPACK_SLIDESHOW_START ) + '</a>';
1076      }
1077      if (bSlideshowRunning && !next_obj) {
1078          bSlideshowRunning = false;
1079      }
1080  }
1081  
1082  function slideshow_go() {
1083      location.href = ( (next_obj) ? next_obj.href : first_obj.href ) + '&amp;' + strUrlMarker;
1084  }
1085  function slideshow_start() {
1086      iTimerId = setTimeout('slideshow_go();', SLIDESHOW_INTERVAL);
1087      bSlideshowRunning = true;
1088      document.getElementById('slideshow_control').innerHTML = LANGPACK_SLIDESHOW_STOP;
1089  }
1090  function slideshow_stop() {
1091      clearTimeout(iTimerId);
1092      bSlideshowRunning = false;
1093      document.getElementById('slideshow_control').innerHTML = LANGPACK_SLIDESHOW_START;
1094  }
1095  function slideshow() {
1096      if (!bSlideshowRunning) slideshow_start();
1097      else slideshow_stop();
1098  }
1099  function slideshow_onload() {
1100      if (bSlideshowRunning && next_obj) {
1101          slideshow_start();
1102      }
1103  }
1104  
1105  slideshow_init();
1106  //-->

1107  </script>
1108  <?php
1109      }
1110  }//function print_slideshow(

1111  
1112  //Output html container with big image

1113  function page_big() {
1114      global $ini, $langpack, $REQUEST_PATH;
1115      list($pictures, $others, $dirs, $descs) = load_directory(dirname($REQUEST_PATH), FALSE);
1116      $i = array_search(basename($REQUEST_PATH), $pictures);
1117      list(/* $filesize_kb_current */, $imagesize_current, $resizesize_current, $is_resize_senseless_current, $exif_comment_current) = get_image_sizes($REQUEST_PATH);
1118      if (!$descs[$pictures[$i]]) {
1119          $descs[$pictures[$i]] = $exif_comment_current;
1120      }
1121      //show page header depending on prefences

1122      if ($ini['enable_filename_display']) {
1123          html_begin(clean_filename($pictures[$i]), '', '', '');
1124      }
1125      else {
1126          html_begin(($descs[$pictures[$i]])?strip_tags($descs[$pictures[$i]]):clean_filename($pictures[$i]), '', '', '');
1127      }
1128      //print navigational panel    

1129      print_expanded_navigation(dirname($REQUEST_PATH), $pictures, $i);
1130      print_slideshow(); //all navigational links just created, now we can initialize slideshow 

1131      //show title and description

1132      if ($ini['enable_filename_display']) {
1133          print('<div align="center" class="weatimages_header">' . clean_filename($pictures[$i]) . '</div>');
1134          print('<div align="center" class="weatimages_comment">' . $descs[$pictures[$i]] . '</div>');
1135      }
1136      else {
1137          print('<div align="center" class="weatimages_header">' . $descs[$pictures[$i]] . '</div>');
1138      }
1139      //show big image

1140      if (!$ini['enable_resize']) { $is_resize_senseless_current = TRUE; }//resize really senseless when resize completely disabled

1141      list($uri_original, $uri_resize, /* $uri_thumb */) = get_image_urls(dirname($REQUEST_PATH), basename($REQUEST_PATH), FALSE);
1142      list($uri_original_contained, $uri_resize_contained, /* $uri_thumb */) = get_image_urls(dirname($REQUEST_PATH), basename($REQUEST_PATH), TRUE);
1143      print('<div align="center"' . ( ($pictures[$i+1])? ' onclick="javascript:NextImage();" style="cursor:pointer;"' :'') . '>');
1144      if ('original' == $_GET['size']) {
1145          print('<img src="' . $uri_original . '" class="weatimages_bigimage"' . ' alt="' . $pictures[$i] . '" width="'.$imagesize_current[0].'" height="'.$imagesize_current[1].'"/>');
1146      }
1147      else {
1148          print('<img src="' . $uri_resize . '" class="weatimages_bigimage"' . ' alt="' . $pictures[$i] . '" width="'.$resizesize_current[0].'" height="'.$resizesize_current[1].'"/>');
1149      }
1150      print('</div>');
1151      if (!$is_resize_senseless_current) {
1152          print('<div style="font-size:9px; color:#999999;">');
1153          if ('original' == $_GET['size']) {
1154              print('<a href="' . $uri_resize_contained . '">' . $langpack['switch_size_toresized'] . '</a>');
1155          }
1156          else {
1157              print('<a href="' . $uri_original_contained . '">' . $langpack['switch_size_tofullsize'] . '</a>');
1158          }
1159          print('</div>');
1160      }
1161      //Show last description

1162      if ($descs[$pictures[$i].'.']) {
1163          print('<div align="center" class="weatimages_comment">' . $descs[$pictures[$i].'.'] . '</div>');
1164      }
1165      html_end();
1166  }//function page_big(

1167  
1168  function zip_directory($path) {
1169      global $ini;
1170      if ('.' != $path) {
1171          $zip_filename = preg_replace('|/|', '-', $path) . '.zip';
1172      }
1173      else {
1174          $zip_filename = 'Album.zip';
1175      }
1176      $zip_fullpath = dirname(__FILE__) . '/' . $ini['cache_dir'] . '/' . $zip_filename;
1177      $zip_url = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER["HTTP_HOST"] . dirname($_SERVER['SCRIPT_NAME']) . '/' . $ini['cache_dir'] . '/' . $zip_filename;
1178      if (!is_file($zip_fullpath)) {
1179          if (is_writable($ini['cache_dir'])) {
1180              exec('zip -1Dj "' . $zip_fullpath . '" "' . dirname(__FILE__) . '/' . $path . '/"* -x \*.php \*.css \*.ini \*.db');
1181          }
1182          else {
1183              fatal_error('Cannot create archive within cache directory.');
1184          }
1185      }
1186      header('Location: ' . $zip_url);
1187  }//function zip_directory($path) {

1188  
1189  
1190  if ('thumb' == $_GET['action']) {
1191      //expected that in $REQUEST_PATH variable relative path to source image stored

1192      resize_manager($REQUEST_PATH, $ini['thumb_size'], '.thumb_' . $ini['thumb_size'] . '_' . $ini['jpeg_quality'] . '.cache', $ini['enable_thumbs_cache']);
1193  }//if ('thumb' == $_GET['action']) {

1194  
1195  if ('resize' == $_GET['action']) {
1196      //expected that in $REQUEST_PATH variable relative path to source image stored

1197      if (!$ini['enable_resize']) { fatal_error("Fatal error: operation not permitted"); }
1198      resize_manager($REQUEST_PATH, $ini['resize_size'], '.resize_' . $ini['resize_size'] . '_' . $ini['jpeg_quality'] . '.cache', $ini['enable_resize_cache']);
1199  }//if ('resize' == $_GET['action']) {

1200  
1201  if ('noimage' == $_GET['action']) {
1202      $image = imagecreatetruecolor($ini['thumb_size'], floor(0.75*$ini['thumb_size']));
1203      $color_bg = imagecolorallocate($image, 255, 255, 255);
1204      imagefill($image, 0, 0, $color_bg);
1205      header("Content-Type: image/png");
1206      imagepng($image);
1207      imagedestroy($image);
1208  }//if ('noimage' == $_GET['action']) {

1209  
1210  //show big image inside html page

1211  if ('big' == $_GET['action']) {
1212      page_big();
1213  }//if ('big' == $_GET['action']) {

1214  
1215  if ('zip' == $_GET['action']) {
1216      if ($ini['enable_album_zip'] && is_dir($REQUEST_PATH)) {
1217          zip_directory($REQUEST_PATH);
1218      }
1219      else {
1220          fatal_error('Operation not permitted');
1221      }
1222  }//if ('zip' == $_GET['action']) {

1223  
1224  //show page with thumbnails if correct path requested

1225  if ('' == $_GET['action']) {
1226      //do some simple checks

1227      if (!is_dir($REQUEST_PATH)) {
1228          fatal_error('Album not found', $ini['enable_albums_listing'] ? 'Try to start browsing from the <a href="' . $_SERVER['SCRIPT_NAME'] . '">root album</a>.' : 'Check the album name and then try again.');
1229      }
1230  
1231      //read directory contents and descriptions

1232      list($pictures, $others, $dirs, $descs) = load_directory($REQUEST_PATH, FALSE);
1233      $pictures_count = count($pictures);
1234      $others_count = count($others);
1235      $dirs_count = count($dirs);
1236      if ('.' != $REQUEST_PATH && !$descs['.'] && !$descs['..']) {//try to get album description from descs-file in parental directory
1237          $parent_descs = load_descriptions(dirname($REQUEST_PATH));
1238          $descs['.'] = $parent_descs[basename($REQUEST_PATH)];
1239      }
1240      
1241      //show navigational links to all parental directories

1242      if ($ini['enable_albums_listing'] && '.' != $REQUEST_PATH) {
1243          $link = ' &nbsp;/&nbsp; ' . clean_filename(basename($REQUEST_PATH));
1244          for ($path = dirname($REQUEST_PATH); '.' != $path; $path = dirname($path)) {
1245              $link = ' &nbsp;/&nbsp; <a href="' . url_compat($_SERVER['SCRIPT_NAME'] . '/' . $path) . '">' . clean_filename(basename($path)) . '</a> ' . $link;
1246          }
1247          $link = ' <a href="' . $_SERVER['SCRIPT_NAME'] . '">' . $langpack['albums'] . '</a> ' . $link;
1248          $link = '<div align="center" class="weatimages_toppest_navig" style="text-decoration:underline;">' . $link;
1249          $link .= '</div>';
1250      }//if ('.' != $REQUEST_PATH)

1251      
1252      html_begin($descs['.'] ? $descs['.'] : basename($REQUEST_PATH), $link, ($descs['.'] || $ini['enable_albums_listing']) ? $descs['.'] : basename($REQUEST_PATH), $descs['..']);
1253      
1254       //show nested albums

1255      if ($ini['enable_albums_listing'] && $dirs_count > 0) {
1256          if ($_GET['page'] < 2 && $_GET['addspage'] < 2) {//show other items only if it is first thumbnails page
1257              $albumspage = ($_GET['albumspage'] > 0) ? $_GET['albumspage'] : 1;
1258              show_pages_navigator($dirs_count, $ini['albums'], $albumspage, 'albumspage');
1259              $bound_low = $ini['albums'] * ($albumspage - 1); //lowest index of $pictures[] which should be shown on current page

1260              $bound_high = ($ini['albums'] * $albumspage) - 1; //highest index of $pictures[] which should be shown on current page

1261              print('<table border="0" cellspacing="0" cellpadding="0" align="center" width="100%" style="margin-top:5px; margin-bottom:5px;">');
1262              print('<tr><td colspan="' . $ini['cols'] . '" align="center" valign="top">'
1263                  . '<table border="0" cellspacing="0" cellpadding="0" align="center" width="'. $ini['cols']*$ini['thumb_size'] .'">'
1264                  . '<tr><td align="left" style="font-size:12px; padding-left:5px;">' . $langpack['albums'] .'<a name="weatimagesdirsblock" style="visibility:hidden;">&nbsp;</a></td></tr>'
1265                  . '<tr><td align="center" valign="top" style="padding-left:5px;'
1266                  . ($ini['enable_albums_edging'] ? ' border-color:#AAAAAA; border-top-width:1px; border-top-style:dashed;' : '') . '">'
1267              );//print('

1268              print('<table border="0" cellspacing="0" cellpadding="0" align="center" style="font-size:13px;'
1269                  . ((1 == $ini['enable_albums_edging']) ? ' border-color:#AAAAAA; border-left-width:1px; border-left-style:dashed;' : '')
1270                  . '">');
1271              for ($i = 0; $i < $dirs_count; $i++) {
1272                  if ($i < $bound_low) { continue; } //we still don't reached file which must be first on current page

1273                  if ($i > $bound_high) { break; } //last file on current page was shown on previous iteration

1274                  $uri_target = url_compat($SERVER_PHP_SELF . $dirs[$i]);
1275                  
1276                  if (0 == $i%$ini['albums_cols']) { print('<tr>'); }
1277                  
1278                  if ($ini['enable_albums_thumbs']) {
1279                       $nested_uri_thumb = get_album_thumb('./'.$REQUEST_PATH.'/'.$dirs[$i]);
1280                       if (!$nested_uri_thumb[0]) {
1281                           $nested_uri_thumb[0] = $SERVER_PHP_SELF . '?action=noimage';
1282                           $nested_uri_thumb[1][0] = $ini['thumb_size'];
1283                           $nested_uri_thumb[1][1] = ceil(0.75*$ini['thumb_size']);
1284                       }
1285                       print('<td align="right" valign="top" style="padding-left:10px; padding-right:0px; padding-top:10px;">'
1286                           . '<a href="'.$uri_target.'"><img src="' . $nested_uri_thumb[0]
1287                           . '" style="border-color:#CCCCCC; border-width:1px; border-style:solid;"'
1288                           . 'width="'.$nested_uri_thumb[1][0].'" height="'.$nested_uri_thumb[1][1].'" alt="'.$dirs[$i].'"/></a>'
1289                           . '</td><td align="left" valign="top" style="padding-left:10px; padding-right:30px; padding-top:20px;"><span class="weatimages_thumb_album_name">'.clean_filename($dirs[$i]).'</span><br/><span class="weatimages_thumb_album_desc">'.$descs[$dirs[$i]].'</span></td>'
1290                           );//print(

1291                  } //if (!$ini['enable_albums_thumbs']) {

1292                  else {    
1293                  print('<td align="left" style="padding-left:5px; padding-top:2px; padding-right:10px;">'
1294                      . '<table border="0" cellspacing="0" cellpadding="0"><tr>'
1295                      . '<td align="right" valign="top"><strong>&raquo;</strong>&nbsp;<a href="' . $uri_target . '">' . clean_filename($dirs[$i]) . '</a></td>'
1296                      . ( $descs[$dirs[$i]] ? '<td align="left" valign="top">&nbsp;<strong>:</strong>&nbsp;</td><td align="left" valign="top">'
1297                      . $descs[$dirs[$i]] . '</td>' : '')
1298                      . '</tr></table>'
1299                      . '</td>'
1300                  );//print(

1301                  } //if (!$ini['enable_albums_thumbs']) { ELSE

1302                  
1303                  if ((0 == ($i+1)%$ini['albums_cols']) || ($i == $dirs_count-1)) { print('</tr>'); }
1304              }//for ($i = 0; $i < $others_count; $i++) {

1305              print('</table>'
1306                  . '</td></tr></table>'
1307                  . '</td></tr>'
1308              );//print(

1309              print('</table>');
1310              show_pages_navigator($dirs_count, $ini['albums'], $albumspage, 'albumspage');
1311              print('<br/>');
1312          }//if ($_GET['page'] < 2)

1313          else {//it is not first thumbnails page, so we only mention about other items existence
1314              print('<table border="0" cellspacing="0" cellpadding="0" align="center" width="100%" style="margin-top:5px; margin-bottom:5px;">');
1315              print('<tr><td colspan="' . $ini['cols'] . '" align="center" valign="top" style="color:#777777;">'
1316                  . '<a href="' . url_compat($SERVER_PHP_SELF . '?' . (($_GET['page'] > 1)?'page':'addspage') . '=1#weatimagesdirsblock') . '">' . $langpack['nested_albums_available'] . '</a>'
1317                  . '</td></tr>'
1318              );//print(

1319              print('</table>');
1320          }//if ($_GET['page'] < 2) else

1321      }//if ($ini['enable_albums_listing'] && $dirs_count > 0) {

1322      
1323      //show thumbnails

1324      if ($pictures_count > 0) {
1325          $page = ($_GET['page'] > 0) ? $_GET['page'] : 1;
1326          $images_on_page = $ini['cols']*$ini['rows'];
1327          show_pages_navigator($pictures_count, $images_on_page, $page, 'page');
1328          
1329          print('<table align="center" cellspacing="10" border="0">');
1330          $bound_low = $images_on_page * ($page - 1); //lowest index of $pictures[] which should be shown on current page

1331          $bound_high = ($images_on_page * $page) - 1; //highest index of $pictures[] which should be shown on current page

1332          $new_row_indicator = 0; //counter for decision when new row must be started

1333          for ($i = 0; $i < $pictures_count; $i++) {
1334              if ($i < $bound_low) { continue; } //we still don't reached file which must be first on current page

1335              if ($i > $bound_high) { break; } //last file on current page was shown on previous iteration

1336              if (0 == $new_row_indicator++) {//we need to begin new table row
1337                  print('<tr>');
1338              }
1339              
1340              //get image sizes if size indication enabled

1341              if ($ini['enable_size_lookup']) {
1342                  list($filesize_kb, $imagesize, $resizesize, $is_resize_senseless, $exif_comment) = get_image_sizes($REQUEST_PATH . '/' . $pictures[$i]);
1343              }//if ($ini['enable_size_lookup']) {

1344              
1345              if (!$descs[$pictures[$i]] && $exif_comment) {
1346                  $descs[$pictures[$i]] = $exif_comment;
1347              }
1348              
1349              list($uri_original, $uri_resize, $uri_thumb) = get_image_urls($REQUEST_PATH, $pictures[$i], $ini['enable_html_container']);
1350              if ($ini['enable_html_container']) {//tell html container that it can return to thumbnails page simply using history.back() javascript call
1351                  $uri_original .= '&amp;fromthumbnail=true';
1352                  $uri_resize .= '&amp;fromthumbnail=true';
1353              }
1354              show_thumbnail_cell($uri_original, $uri_resize, $uri_thumb, $filesize_kb, $imagesize, $resizesize, $is_resize_senseless, $pictures[$i], $descs[$pictures[$i]]);
1355  
1356              if ($new_row_indicator == $ini['cols'] || $i == $pictures_count - 1) { //we need to close row if number of columns reached or it was last image
1357                  print('</tr>');
1358                  $new_row_indicator = 0;
1359              }
1360          }//for ($i = 0; $i < $pictures_count; $i++) {

1361          print('</table>');
1362          show_pages_navigator($pictures_count, $images_on_page, $page, 'page');
1363      }//if ($pictures_count > 0) {

1364      
1365      if ($ini['enable_album_zip'] && ($pictures_count > 0 || ($ini['enable_additional_listing'] && $others_count > 0))) {
1366          print ('<div align="center" style="width:100%;"><a href="'
1367              . url_compat($SERVER_PHP_SELF . '?action=zip')
1368              . '">' . $langpack['album_zip'] . '</a></div>'
1369          );
1370      }
1371      
1372      //show links to non-thumbnailable items

1373      if ($ini['enable_additional_listing'] && $others_count > 0) {
1374          print('<table border="0" cellspacing="0" cellpadding="0" align="center" width="100%" style="margin-top:5px; margin-bottom:5px;">');
1375          if ($_GET['page'] < 2 && $_GET['albumspage'] < 2) {//show other items only if it is first thumbnails page
1376              $addspage = ($_GET['addspage'] > 0) ? $_GET['addspage'] : 1;
1377              $bound_low = $ini['additionals'] * ($addspage - 1); //lowest index of $pictures[] which should be shown on current page

1378              $bound_high = ($ini['additionals'] * $addspage) - 1; //highest index of $pictures[] which should be shown on current page

1379              print('<tr><td colspan="' . $ini['cols'] . '" align="center" valign="top">'
1380                  . '<table border="0" cellspacing="0" cellpadding="0" align="center" width="'. $ini['cols']*$ini['thumb_size'] .'">'
1381                  . '<tr><td align="left" style="font-size:12px; padding-left:5px;">' . $langpack['additional_items'] . '<a name="weatimagesothersblock" style="visibility:hidden;">&nbsp;</a></td></tr>'
1382                  . '<tr><td align="center" valign="top" style="padding-left:5px;'
1383                  . ($ini['enable_albums_edging'] ? ' border-color:#AAAAAA; border-top-width:1px; border-top-style:dashed;' : '') . '">'
1384              );//print('

1385              print('<table border="0" cellspacing="0" cellpadding="0" align="center" style="'
1386                  . ((1 == $ini['enable_albums_edging']) ? ' border-color:#AAAAAA; border-left-width:1px; border-left-style:dashed;' : '')
1387                  . '">');
1388              for ($i = 0; $i < $others_count; $i++) {
1389                  if ($i < $bound_low) { continue; } //we still don't reached file which must be first on current page

1390                  if ($i > $bound_high) { break; } //last file on current page was shown on previous iteration

1391                  list($uri_original, /* $uri_resize */, /* $uri_thumb */) = get_image_urls($REQUEST_PATH, $others[$i], FALSE);
1392                  $filesize_kb = ceil(filesize($REQUEST_PATH . '/' . $others[$i]) / 1024);
1393                  print('<tr><td align="left" style="padding-left:5px;">'
1394                      . '<table border="0" cellspacing="0" cellpadding="0"><tr>'
1395                      . '<td align="right" valign="top"><strong>&raquo;</strong>&nbsp;<a href="' . $uri_original . '">' . $others[$i] . '&nbsp;(' . $filesize_kb . $langpack['kilobytes'] . ')' . '</a></td>'
1396                      . ( $descs[$others[$i]] ? '<td align="left" valign="top">&nbsp;<strong>:</strong>&nbsp;</td><td align="left" valign="top">'
1397                      . $descs[$others[$i]] . '</td>' : '')
1398                      . '</tr></table>'
1399                      . '</td></tr>'
1400                  );//print(

1401              }//for ($i = 0; $i < $others_count; $i++) {

1402              print('</table>'
1403                  . '</td></tr></table>'
1404                  . '</td></tr>'
1405              );//print(

1406          }//if ($_GET['page'] < 2 && $_GET['albumspage'] < 2) {

1407          else {//it is not first thumbnails page, so we only mention about other items existence
1408              print('<tr><td colspan="' . $ini['cols'] . '" align="center" valign="top" style="color:#777777;">'
1409                  . '<a href="' . url_compat($SERVER_PHP_SELF . '?' . (($_GET['page'] > 1)?'page':'albumspage') . '=1#weatimagesothersblock') . '">' . $langpack['additional_items_available'] . '</a>'
1410                  . '</td></tr>'
1411              );//print(

1412          }//if (2 > $_GET['page']) else

1413          print('</table>');
1414          if ($_GET['page'] < 2 && $_GET['albumspage'] < 2) { show_pages_navigator($others_count, $ini['additionals'], $addspage, 'addspage'); }
1415      }//if ($ini['enable_additional_listing'] && $others_count > 0) {

1416      
1417      html_end();
1418  }//if ('' == $_GET['action']) {

1419  ?>
1420  

title

Description

title

Description

title

Description

title

title

Body