source: trunk/include/derivative.inc.php @ 14143

Last change on this file since 14143 was 14143, checked in by rvelices, 12 years ago

bug 2615 php notice in calendar amd web service
multisize improve handling of cases where the original is smaller than a requested derivative, but rotation/watermarking is required

File size: 8.5 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based photo gallery                                    |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008-2012 Piwigo Team                  http://piwigo.org |
6// +-----------------------------------------------------------------------+
7// | This program is free software; you can redistribute it and/or modify  |
8// | it under the terms of the GNU General Public License as published by  |
9// | the Free Software Foundation                                          |
10// |                                                                       |
11// | This program is distributed in the hope that it will be useful, but   |
12// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
13// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
14// | General Public License for more details.                              |
15// |                                                                       |
16// | You should have received a copy of the GNU General Public License     |
17// | along with this program; if not, write to the Free Software           |
18// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
19// | USA.                                                                  |
20// +-----------------------------------------------------------------------+
21
22final class SrcImage
23{
24  const IS_ORIGINAL = 0x01;
25  const IS_MIMETYPE = 0x02;
26
27  public $id;
28  public $rel_path;
29  public $rotation = 0;
30
31  private $size=null;
32  private $flags=0;
33
34  function __construct($infos)
35  {
36    global $conf;
37
38    $this->id = $infos['id'];
39    $ext = get_extension($infos['path']);
40    if (in_array($ext, $conf['picture_ext']))
41    {
42      $this->rel_path = $infos['path'];
43      $this->flags |= self::IS_ORIGINAL;
44    }
45    elseif (!empty($infos['representative_ext']))
46    {
47      $this->rel_path = original_to_representative($infos['path'], $infos['representative_ext']);
48    }
49    else
50    {
51      $ext = strtolower($ext);
52      $this->rel_path = trigger_event('get_mimetype_location', get_themeconf('mime_icon_dir').$ext.'.png', $ext );
53      $this->flags |= self::IS_MIMETYPE;
54      $this->size = @getimagesize(PHPWG_ROOT_PATH.$this->rel_path);
55    }
56
57    if (!$this->size && isset($infos['width']) && isset($infos['height']))
58    {
59      $width = $infos['width'];
60      $height = $infos['height'];
61
62      $this->rotation = intval($infos['rotation']) % 4;
63      // 1 or 5 =>  90 clockwise
64      // 3 or 7 => 270 clockwise
65      if ($this->rotation % 2)
66      {
67        $width = $infos['height'];
68        $height = $infos['width'];
69      }
70     
71      $this->size = array($width, $height);
72    }
73  }
74
75  function is_original()
76  {
77    return $this->flags & self::IS_ORIGINAL;
78  }
79
80  function is_mimetype()
81  {
82    return $this->flags & self::IS_MIMETYPE;
83  }
84
85  function get_path()
86  {
87    return PHPWG_ROOT_PATH.$this->rel_path;
88  }
89
90  function get_url()
91  {
92    $url = get_root_url().$this->rel_path;
93    if ($this->flags & self::IS_ORIGINAL)
94    {
95      $url = trigger_event('get_src_image_url', $url, $this);
96    }
97    return embellish_url($url);
98  }
99
100  function has_size()
101  {
102    return $this->size != null;
103  }
104
105  function get_size()
106  {
107    if ($this->size == null)
108      not_implemented(); // get size from file
109    return $this->size;
110  }
111}
112
113
114
115final class DerivativeImage
116{
117  public $src_image;
118
119  private $params;
120  private $rel_path, $rel_url, $is_cached=true;
121
122  function __construct($type, $src_image)
123  {
124    $this->src_image = $src_image;
125    if (is_string($type))
126    {
127      $this->params = ImageStdParams::get_by_type($type);
128    }
129    else
130    {
131      $this->params = $type;
132    }
133
134    self::build($src_image, $this->params, $this->rel_path, $this->rel_url, $this->is_cached);
135  }
136
137  static function thumb_url($infos)
138  {
139    return self::url(IMG_THUMB, $infos);
140  }
141
142  static function url($type, $infos)
143  {
144    $src_image = is_object($infos) ? $infos : new SrcImage($infos);
145    $params = is_string($type) ? ImageStdParams::get_by_type($type) : $type;
146    self::build($src_image, $params, $rel_path, $rel_url);
147    if ($params == null)
148    {
149      return $src_image->get_url();
150    }
151    return embellish_url(
152        trigger_event('get_derivative_url',
153          get_root_url().$rel_url,
154          $params, $src_image, $rel_url
155          ) );
156  }
157
158  static function get_all($src_image)
159  {
160    $ret = array();
161    foreach (ImageStdParams::get_defined_type_map() as $type => $params)
162    {
163      $derivative = new DerivativeImage($params, $src_image);
164      $ret[$type] = $derivative;
165    }
166    foreach (ImageStdParams::get_undefined_type_map() as $type => $type2)
167    {
168      $ret[$type] = $ret[$type2];
169    }
170
171    return $ret;
172  }
173
174  private static function build($src, &$params, &$rel_path, &$rel_url, &$is_cached=null)
175  {
176    if ( $src->has_size() && $params->is_identity( $src->get_size() ) )
177    {
178      if (!$params->use_watermark && !$src->rotation)
179      {
180        $params = null;
181        $rel_path = $rel_url = $src->rel_path;
182        return;
183      }
184      $defined_types = array_keys(ImageStdParams::get_defined_type_map());
185      for ($i=0; $i<count($defined_types); $i++)
186      {
187        if ($defined_types[$i] == $params->type)
188        {
189          for ($i--; $i>=0; $i--)
190          {
191            $smaller = ImageStdParams::get_by_type($defined_types[$i]);
192            if ($smaller->sizing->max_crop==$params->sizing->max_crop && $smaller->is_identity( $src->get_size() ))
193            {
194              $params = $smaller;
195              self::build($src, $params, $rel_path, $rel_url, $is_cached);
196              return;
197            }
198          }
199          break;
200        }
201      }
202    }
203
204    $tokens=array();
205    $tokens[] = substr($params->type,0,2);
206
207    if ($params->type==IMG_CUSTOM)
208    {
209      $params->add_url_tokens($tokens);
210    }
211
212    $loc = $src->rel_path;
213    if (substr_compare($loc, './', 0, 2)==0)
214    {
215      $loc = substr($loc, 2);
216    }
217    elseif (substr_compare($loc, '../', 0, 3)==0)
218    {
219      $loc = substr($loc, 3);
220    }
221    $loc = substr_replace($loc, '-'.implode('_', $tokens), strrpos($loc, '.'), 0 );
222
223    $rel_path = PWG_DERIVATIVE_DIR.$loc;
224
225    global $conf;
226    $url_style=$conf['derivative_url_style'];
227    if (!$url_style)
228    {
229      $mtime = @filemtime(PHPWG_ROOT_PATH.$rel_path);
230      if ($mtime===false or $mtime < $params->last_mod_time)
231      {
232        $is_cached = false;
233        $url_style = 2;
234      }
235      else
236      {
237        $url_style = 1;
238      }
239    }
240
241    if ($url_style == 2)
242    {
243      $rel_url = 'i';
244      if ($conf['php_extension_in_urls']) $rel_url .= '.php';
245      if ($conf['question_mark_in_urls']) $rel_url .= '?';
246      $rel_url .= '/'.$loc;
247    }
248    else
249    {
250      $rel_url = $rel_path;
251    }
252  }
253
254  function get_path()
255  {
256    return PHPWG_ROOT_PATH.$this->rel_path;
257  }
258
259  function get_url()
260  {
261    if ($this->params == null)
262    {
263      return $this->src_image->get_url();
264    }
265    return embellish_url(
266        trigger_event('get_derivative_url',
267          get_root_url().$this->rel_url,
268          $this->params, $this->src_image, $this->rel_url
269          ) );
270  }
271
272  function same_as_source()
273  {
274    return $this->params == null;
275  }
276
277
278  function get_type()
279  {
280    if ($this->params == null)
281      return 'Original';
282    return $this->params->type;
283  }
284
285  /* returns the size of the derivative image*/
286  function get_size()
287  {
288    if ($this->params == null)
289    {
290      return $this->src_image->get_size();
291    }
292    return $this->params->compute_final_size($this->src_image->get_size());
293  }
294
295  function get_size_htm()
296  {
297    $size = $this->get_size();
298    if ($size)
299    {
300      return 'width="'.$size[0].'" height="'.$size[1].'"';
301    }
302  }
303
304  function get_size_hr()
305  {
306    $size = $this->get_size();
307    if ($size)
308    {
309      return $size[0].' x '.$size[1];
310    }
311  }
312
313  function get_scaled_size($maxw, $maxh)
314  {
315    $size = $this->get_size();
316    if ($size)
317    {
318      $ratio_w = $size[0] / $maxw;
319      $ratio_h = $size[1] / $maxh;
320      if ($ratio_w>1 || $ratio_h>1)
321      {
322        if ($ratio_w > $ratio_h)
323        {
324          $size[0] = $maxw;
325          $size[1] = floor($size[1] / $ratio_w);
326        }
327        else
328        {
329          $size[0] = floor($size[0] / $ratio_h);
330          $size[1] = $maxh;
331        }
332      }
333    }
334    return $size;
335  }
336
337  function get_scaled_size_htm($maxw=9999, $maxh=9999)
338  {
339    $size = $this->get_scaled_size($maxw, $maxh);
340    if ($size)
341    {
342      return 'width="'.$size[0].'" height="'.$size[1].'"';
343    }
344  }
345
346  function is_cached()
347  {
348    return $this->is_cached;
349  }
350}
351
352?>
Note: See TracBrowser for help on using the repository browser.