Index: /trunk/admin/cat_modify.php
===================================================================
--- /trunk/admin/cat_modify.php	(revision 12953)
+++ /trunk/admin/cat_modify.php	(revision 12954)
@@ -29,4 +29,74 @@
 include_once(PHPWG_ROOT_PATH.'include/functions_mail.inc.php');
 
+
+// get_complete_dir returns the concatenation of get_site_url and
+// get_local_dir
+// Example : "pets > rex > 1_year_old" is on the the same site as the
+// Piwigo files and this category has 22 for identifier
+// get_complete_dir(22) returns "./galleries/pets/rex/1_year_old/"
+function get_complete_dir( $category_id )
+{
+  return get_site_url($category_id).get_local_dir($category_id);
+}
+
+// get_local_dir returns an array with complete path without the site url
+// Example : "pets > rex > 1_year_old" is on the the same site as the
+// Piwigo files and this category has 22 for identifier
+// get_local_dir(22) returns "pets/rex/1_year_old/"
+function get_local_dir( $category_id )
+{
+  global $page;
+
+  $uppercats = '';
+  $local_dir = '';
+
+  if ( isset( $page['plain_structure'][$category_id]['uppercats'] ) )
+  {
+    $uppercats = $page['plain_structure'][$category_id]['uppercats'];
+  }
+  else
+  {
+    $query = 'SELECT uppercats';
+    $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id = '.$category_id;
+    $query.= ';';
+    $row = pwg_db_fetch_assoc( pwg_query( $query ) );
+    $uppercats = $row['uppercats'];
+  }
+
+  $upper_array = explode( ',', $uppercats );
+
+  $database_dirs = array();
+  $query = 'SELECT id,dir';
+  $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id IN ('.$uppercats.')';
+  $query.= ';';
+  $result = pwg_query( $query );
+  while( $row = pwg_db_fetch_assoc( $result ) )
+  {
+    $database_dirs[$row['id']] = $row['dir'];
+  }
+  foreach ($upper_array as $id)
+  {
+    $local_dir.= $database_dirs[$id].'/';
+  }
+
+  return $local_dir;
+}
+
+// retrieving the site url : "http://domain.com/gallery/" or
+// simply "./galleries/"
+function get_site_url($category_id)
+{
+  global $page;
+
+  $query = '
+SELECT galleries_url
+  FROM '.SITES_TABLE.' AS s,'.CATEGORIES_TABLE.' AS c
+  WHERE s.id = c.site_id
+    AND c.id = '.$category_id.'
+;';
+  $row = pwg_db_fetch_assoc(pwg_query($query));
+  return $row['galleries_url'];
+}
+
 // +-----------------------------------------------------------------------+
 // | Check Access and exit when user status is not ok                      |
Index: /trunk/include/derivative.inc.php
===================================================================
--- /trunk/include/derivative.inc.php	(revision 12953)
+++ /trunk/include/derivative.inc.php	(revision 12954)
@@ -25,4 +25,5 @@
   const IS_MIMETYPE = 0x02;
 
+  public $id;
   public $rel_path;
 
@@ -34,5 +35,6 @@
   {
     global $conf;
-
+    
+    $this->id = $infos['id'];
     $ext = get_extension($infos['path']);
     if (in_array($ext, $conf['picture_ext']))
@@ -77,5 +79,5 @@
   function get_url()
   {
-    return get_root_url().$this->rel_path;
+    return embellish_url(get_root_url().$this->rel_path);
   }
 
@@ -97,9 +99,6 @@
 final class DerivativeImage
 {
-  const SAME_AS_SRC = 0x10;
-
   public $src_image;
 
-  private $flags = 0;
   private $params;
   private $rel_path, $rel_url;
@@ -117,5 +116,5 @@
     }
 
-    self::build($src_image, $this->params, $this->rel_path, $this->rel_url, $this->flags);
+    self::build($src_image, $this->params, $this->rel_path, $this->rel_url);
   }
 
@@ -130,5 +129,13 @@
     $params = is_string($type) ? ImageStdParams::get_by_type($type) : $type;
     self::build($src_image, $params, $rel_path, $rel_url);
-    return get_root_url().$rel_url;
+    if ($params == null)
+    {
+      return $src_image->get_url();
+    }
+    return embellish_url(
+        trigger_event('get_derivative_url',
+          get_root_url().$rel_url,
+          $params, $src_image, $rel_url
+          ) );
   }
 
@@ -149,10 +156,9 @@
   }
 
-  private static function build($src, &$params, &$rel_path, &$rel_url, &$flags = null)
+  private static function build($src, &$params, &$rel_path, &$rel_url)
   {
     if ( $src->has_size() && $params->is_identity( $src->get_size() ) )
     {
       // todo - what if we have a watermark maybe return a smaller size?
-      $flags |= self::SAME_AS_SRC;
       $params = null;
       $rel_path = $rel_url = $src->rel_path;
@@ -221,10 +227,18 @@
   function get_url()
   {
-    return get_root_url().$this->rel_url;
+    if ($this->params == null)
+    {
+      return $this->src_image->get_url();
+    }
+    return embellish_url(
+        trigger_event('get_derivative_url',
+          get_root_url().$this->rel_url,
+          $this->params, $this->src_image, $this->rel_url
+          ) );
   }
 
   function same_as_source()
   {
-    return $this->flags & self::SAME_AS_SRC;
+    return $this->params == null;
   }
 
@@ -232,5 +246,5 @@
   function get_type()
   {
-    if ($this->flags & self::SAME_AS_SRC)
+    if ($this->params == null)
       return 'original';
     return $this->params->type;
@@ -240,5 +254,5 @@
   function get_size()
   {
-    if ($this->flags & self::SAME_AS_SRC)
+    if ($this->params == null)
     {
       return $this->src_image->get_size();
Index: /trunk/include/functions.inc.php
===================================================================
--- /trunk/include/functions.inc.php	(revision 12953)
+++ /trunk/include/functions.inc.php	(revision 12954)
@@ -779,12 +779,5 @@
 function get_thumbnail_url($element_info)
 {
-  $loc = $url = get_thumbnail_location($element_info);
-  if ( !url_is_remote($loc) )
-  {
-    $url = (get_root_url().$loc);
-  }
-  // plugins want another url ?
-  $url = trigger_event('get_thumbnail_url', $url, $element_info, $loc);
-  return embellish_url($url);
+  return DerivativeImage::thumb_url($element_info);
 }
 
Index: /trunk/include/functions_category.inc.php
===================================================================
--- /trunk/include/functions_category.inc.php	(revision 12953)
+++ /trunk/include/functions_category.inc.php	(revision 12954)
@@ -214,72 +214,5 @@
 }
 
-// get_complete_dir returns the concatenation of get_site_url and
-// get_local_dir
-// Example : "pets > rex > 1_year_old" is on the the same site as the
-// Piwigo files and this category has 22 for identifier
-// get_complete_dir(22) returns "./galleries/pets/rex/1_year_old/"
-function get_complete_dir( $category_id )
-{
-  return get_site_url($category_id).get_local_dir($category_id);
-}
-
-// get_local_dir returns an array with complete path without the site url
-// Example : "pets > rex > 1_year_old" is on the the same site as the
-// Piwigo files and this category has 22 for identifier
-// get_local_dir(22) returns "pets/rex/1_year_old/"
-function get_local_dir( $category_id )
-{
-  global $page;
-
-  $uppercats = '';
-  $local_dir = '';
-
-  if ( isset( $page['plain_structure'][$category_id]['uppercats'] ) )
-  {
-    $uppercats = $page['plain_structure'][$category_id]['uppercats'];
-  }
-  else
-  {
-    $query = 'SELECT uppercats';
-    $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id = '.$category_id;
-    $query.= ';';
-    $row = pwg_db_fetch_assoc( pwg_query( $query ) );
-    $uppercats = $row['uppercats'];
-  }
-
-  $upper_array = explode( ',', $uppercats );
-
-  $database_dirs = array();
-  $query = 'SELECT id,dir';
-  $query.= ' FROM '.CATEGORIES_TABLE.' WHERE id IN ('.$uppercats.')';
-  $query.= ';';
-  $result = pwg_query( $query );
-  while( $row = pwg_db_fetch_assoc( $result ) )
-  {
-    $database_dirs[$row['id']] = $row['dir'];
-  }
-  foreach ($upper_array as $id)
-  {
-    $local_dir.= $database_dirs[$id].'/';
-  }
-
-  return $local_dir;
-}
-
-// retrieving the site url : "http://domain.com/gallery/" or
-// simply "./galleries/"
-function get_site_url($category_id)
-{
-  global $page;
-
-  $query = '
-SELECT galleries_url
-  FROM '.SITES_TABLE.' AS s,'.CATEGORIES_TABLE.' AS c
-  WHERE s.id = c.site_id
-    AND c.id = '.$category_id.'
-;';
-  $row = pwg_db_fetch_assoc(pwg_query($query));
-  return $row['galleries_url'];
-}
+
 
 // returns an array of image orders available for users/visitors
Index: /trunk/include/template.class.php
===================================================================
--- /trunk/include/template.class.php	(revision 12953)
+++ /trunk/include/template.class.php	(revision 12954)
@@ -115,4 +115,5 @@
     $this->smarty->register_function('get_combined_scripts', array(&$this, 'func_get_combined_scripts') );
     $this->smarty->register_function('combine_css', array(&$this, 'func_combine_css') );
+    $this->smarty->register_function('define_derivative', array(&$this, 'func_define_derivative') );
     $this->smarty->register_compiler_function('get_combined_css', array(&$this, 'func_get_combined_css') );
     $this->smarty->register_block('footer_script', array(&$this, 'block_footer_script') );
@@ -545,4 +546,43 @@
       $this->html_style .= $content;
     }
+  }
+
+  function func_define_derivative($params, &$smarty)
+  {
+    !empty($params['name']) or fatal_error('define_derviative missing name');
+    if (isset($params['type']))
+    {
+      $derivative = ImageStdParams::get_by_type($params['type']);
+      $smarty->assign( $params['name'], $derivative);
+      return;
+    }
+    !empty($params['width']) or fatal_error('define_derviative missing width');
+    !empty($params['height']) or fatal_error('define_derviative missing height');
+
+    $derivative = new DerivativeParams( SizingParams::classic( intval($params['width']), intval($params['height'])) );
+    if (isset($params['crop']))
+    {
+      if (is_bool($params['crop']))
+      {
+        $derivative->sizing->max_crop = $params['crop'] ? 1:0;
+      }
+      else
+      {
+        $derivative->sizing->max_crop = round($params['crop']/100, 2);
+      }
+
+      if ($derivative->sizing->max_crop)
+      {
+        $minw = empty($params['min_width']) ? $derivative->max_width() : intval($params['min_width']);
+        $minw <= $derivative->max_width() or fatal_error('define_derviative invalid min_width');
+        $minh = empty($params['min_height']) ? $derivative->max_height() : intval($params['min_height']);
+        $minh <= $derivative->max_height() or fatal_error('define_derviative invalid min_height');
+
+        $derivative->sizing->min_size = array($minw, $minh);
+      }
+    }
+
+    ImageStdParams::apply_global($derivative);
+    $smarty->assign( $params['name'], $derivative);
   }
 
Index: /trunk/themes/default/template/thumbnails.tpl
===================================================================
--- /trunk/themes/default/template/thumbnails.tpl	(revision 12953)
+++ /trunk/themes/default/template/thumbnails.tpl	(revision 12954)
@@ -1,3 +1,4 @@
 {if !empty($thumbnails)}{strip}
+{*define_derivative name='derivative_params' width=160 height=90 crop=true*}
 {html_style}
 {*Set some sizes according to maximum thumbnail width and height*}
