[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / ecrire / inc / filtres_images_lib_mini.php
index 468d619..98af284 100644 (file)
@@ -3,7 +3,7 @@
 /* *************************************************************************\
  *  SPIP, Systeme de publication pour l'internet                           *
  *                                                                         *
- *  Copyright (c) 2001-2016                                                *
+ *  Copyright (c) 2001-2017                                                *
  *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
  *                                                                         *
  *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
  * Ce fichier contient les fonctions utilisées
  * par les fonctions-filtres de traitement d'image.
  *
- * @package SPIP\image
+ * @package SPIP\Core\Filtres\Images
  */
 
 
-if (!defined('_ECRIRE_INC_VERSION')) return;
+if (!defined('_ECRIRE_INC_VERSION')) {
+       return;
+}
 include_spip('inc/filtres'); // par precaution
 include_spip('inc/filtres_images_mini'); // par precaution
 
@@ -26,23 +28,29 @@ include_spip('inc/filtres_images_mini'); // par precaution
  * Transforme une couleur vectorielle R,G,B en hexa (par exemple pour usage css)
  *
  * @param int $red
- *             Valeur du rouge de 0 à 255.
+ *     Valeur du rouge de 0 à 255.
  * @param int $green
- *             Valeur du vert de 0 à 255.
+ *     Valeur du vert de 0 à 255.
  * @param int $blue
- *             Valeur du bleu de 0 à 255.
+ *     Valeur du bleu de 0 à 255.
  * @return string
- *             le code de la couleur en hexadécimal.
+ *     Le code de la couleur en hexadécimal.
  */
 function _couleur_dec_to_hex($red, $green, $blue) {
        $red = dechex($red);
        $green = dechex($green);
        $blue = dechex($blue);
-       
-       if (strlen($red) == 1) $red = "0".$red;
-       if (strlen($green) == 1) $green = "0".$green;
-       if (strlen($blue) == 1) $blue = "0".$blue;
-       
+
+       if (strlen($red) == 1) {
+               $red = "0" . $red;
+       }
+       if (strlen($green) == 1) {
+               $green = "0" . $green;
+       }
+       if (strlen($blue) == 1) {
+               $blue = "0" . $blue;
+       }
+
        return "$red$green$blue";
 }
 
@@ -50,17 +58,17 @@ function _couleur_dec_to_hex($red, $green, $blue) {
  * Transforme une couleur hexa en vectorielle R,G,B
  *
  * @param string $couleur
- *             Code couleur en hexa (#000000 à #FFFFFF).
+ *     Code couleur en hexa (#000000 à #FFFFFF).
  * @return array
- *             Un tableau des 3 éléments : rouge, vert, bleu.
+ *     Un tableau des 3 éléments : rouge, vert, bleu.
  */
 function _couleur_hex_to_dec($couleur) {
        $couleur = couleur_html_to_hex($couleur);
-       $couleur = preg_replace(",^#,","",$couleur);
+       $couleur = preg_replace(",^#,", "", $couleur);
        $retour["red"] = hexdec(substr($couleur, 0, 2));
        $retour["green"] = hexdec(substr($couleur, 2, 2));
        $retour["blue"] = hexdec(substr($couleur, 4, 2));
-       
+
        return $retour;
 }
 
@@ -68,65 +76,79 @@ function _couleur_hex_to_dec($couleur) {
 /**
  * Donne un statut au fichier-image intermédiaire servant au traitement d'image
  * selon qu'il doit être gravé (fichier .src) ou pas.
- * Un appel php direct aux fonctions de filtre d'image produira ainsi une image
+ *
+ * Un appel PHP direct aux fonctions de filtre d'image produira ainsi une image
  * permanente (gravée) ; un appel généré par le compilateur via
- * filtrer('image_xx, ...) effacera automatiquement le fichier-image temporaire.
+ * `filtrer('image_xx, ...)` effacera automatiquement le fichier-image temporaire.
  *
  * @param bool|string $stat
- *             true, false ou le statut déjà défini si traitements enchaînés.
+ *     true, false ou le statut déjà défini si traitements enchaînés.
  * @return bool
- *             true si il faut supprimer le fichier temporaire ; false sinon.
+ *     true si il faut supprimer le fichier temporaire ; false sinon.
  */
-function statut_effacer_images_temporaires($stat){
+function statut_effacer_images_temporaires($stat) {
        static $statut = false; // par defaut on grave toute les images
-       if ($stat==='get') return $statut;
-       $statut = $stat?true:false;
+       if ($stat === 'get') {
+               return $statut;
+       }
+       $statut = $stat ? true : false;
 }
 
 
 /**
  * Fonctions de traitement d'image
+ *
  * Uniquement pour GD2.
  *
+ * @pipeline_appel image_preparer_filtre
+ * @uses extraire_attribut()
+ * @uses inserer_attribut()
+ * @uses tester_url_absolue()
+ * @uses copie_locale() Si l'image est distante
+ * @uses taille_image()
+ * @uses _image_ratio()
+ * @uses reconstruire_image_intermediaire()
+ *
  * @param string $img
- *             Un tag html <img src=... />.
+ *     Chemin de l'image ou balise html `<img src=... />`.
  * @param string $effet
- *             Les nom et paramètres de l'effet à apporter sur l'image
- *             (par exemple : reduire-300-200).
+ *     Les nom et paramètres de l'effet à apporter sur l'image
+ *     (par exemple : reduire-300-200).
  * @param bool|string $forcer_format
- *             Un nom d'extension spécifique demandé (par exemple : jpg, png, txt...
- *             par défaut false : GD se débrouille seule).
+ *     Un nom d'extension spécifique demandé (par exemple : jpg, png, txt...).
+ *     Par défaut false : GD se débrouille seule).
  * @param array $fonction_creation
- *             Un tableau à 2 éléments. Le premier (string) indique le nom du
- *             filtre de traitement demandé (par exemple : image_reduire) ; le
- *             second (array) est lui-même un tableau reprenant la valeur de $img
- *             et chacun des paramètres passés au filtre.
+ *     Un tableau à 2 éléments :
+ *     1) string : indique le nom du filtre de traitement demandé (par exemple : `image_reduire`) ;
+ *     2) array : tableau reprenant la valeur de `$img` et chacun des arguments passés au filtre utilisé.
  * @param bool $find_in_path
- *             false (par défaut) indique que l'on travaille sur un fichier
- *             temporaire (.src) ; true, sur un fichier définitif déjà existant.
+ *     false (par défaut) indique que l'on travaille sur un fichier
+ *     temporaire (.src) ; true, sur un fichier définitif déjà existant.
  * @return bool|string|array
- *             false si pas de tag <img,
- *                 si l'extension n'existe pas,
- *                 si le fichier source n'existe pas,
- *                 si les dimensions de la source ne sont pas accessibles,
- *                 si le fichier temporaire n'existe pas,
- *                 si la fonction _imagecreatefrom{extension} n'existe pas ;
- *             "" (chaîne vide) si le fichier source est distant et n'a pas
- *                 réussi à être copié sur le serveur ;
- *             l'appel à la fonction pipeline image_preparer_filtre.
+ *
+ *     - false si pas de tag `<img`,
+ *       -   si l'extension n'existe pas,
+ *       -   si le fichier source n'existe pas,
+ *       -   si les dimensions de la source ne sont pas accessibles,
+ *       -   si le fichier temporaire n'existe pas,
+ *       -   si la fonction `_imagecreatefrom{extension}` n'existe pas ;
+ *     - "" (chaîne vide) si le fichier source est distant et n'a pas
+ *       réussi à être copié sur le serveur ;
+ *     - array : tableau décrivant de l'image
  */
-function _image_valeurs_trans($img, $effet, $forcer_format = false, $fonction_creation = NULL, $find_in_path = false) {
+function _image_valeurs_trans($img, $effet, $forcer_format = false, $fonction_creation = null, $find_in_path = false) {
        static $images_recalcul = array();
-       if (strlen($img)==0) return false;
+       if (strlen($img) == 0) {
+               return false;
+       }
 
        $source = trim(extraire_attribut($img, 'src'));
-       if (strlen($source) < 1){
+       if (strlen($source) < 1) {
                $source = $img;
                $img = "<img src='$source' />";
-       }
-       # gerer img src="data:....base64"
-       else if (preg_match('@^data:image/(jpe?g|png|gif);base64,(.*)$@isS', $source, $regs)) {
-               $local = sous_repertoire(_DIR_VAR,'image-data').md5($regs[2]).'.'.str_replace('jpeg', 'jpg', $regs[1]);
+       } # gerer img src="data:....base64"
+       elseif (preg_match('@^data:image/(jpe?g|png|gif);base64,(.*)$@isS', $source, $regs)) {
+               $local = sous_repertoire(_DIR_VAR, 'image-data') . md5($regs[2]) . '.' . str_replace('jpeg', 'jpg', $regs[1]);
                if (!file_exists($local)) {
                        ecrire_fichier($local, base64_decode($regs[2]));
                }
@@ -138,83 +160,106 @@ function _image_valeurs_trans($img, $effet, $forcer_format = false, $fonction_cr
        }
 
        // les protocoles web prennent au moins 3 lettres
-       if (preg_match(';^(\w{3,7}://);', $source)){
+       if (tester_url_absolue($source)) {
                include_spip('inc/distant');
                $fichier = _DIR_RACINE . copie_locale($source);
-               if (!$fichier) return "";
-       }       else {
+               if (!$fichier) {
+                       return "";
+               }
+       } else {
                // enlever le timestamp eventuel
-               $source=preg_replace(',[?][0-9]+$,','',$source);
-               if (strpos($source,"?")!==false
-                       AND strncmp($source,_DIR_IMG,strlen(_DIR_IMG))==0
-                       AND file_exists($f=preg_replace(',[?].*$,','',$source))){
+               if (strpos($source, "?") !== false) {
+                       $source = preg_replace(',[?][0-9]+$,', '', $source);
+               }
+               if (strpos($source, "?") !== false
+                       and strncmp($source, _DIR_IMG, strlen(_DIR_IMG)) == 0
+                       and file_exists($f = preg_replace(',[?].*$,', '', $source))
+               ) {
                        $source = $f;
                }
                $fichier = $source;
        }
 
-       $terminaison_dest = "";
+       $terminaison = $terminaison_dest = "";
        if (preg_match(",\.(gif|jpe?g|png)($|[?]),i", $fichier, $regs)) {
                $terminaison = strtolower($regs[1]);
                $terminaison_dest = $terminaison;
-               
-               if ($terminaison == "gif") $terminaison_dest = "png";
+
+               if ($terminaison == "gif") {
+                       $terminaison_dest = "png";
+               }
+       }
+       if ($forcer_format !== false) {
+               $terminaison_dest = $forcer_format;
        }
-       if ($forcer_format!==false) $terminaison_dest = $forcer_format;
 
-       if (!$terminaison_dest) return false;
+       if (!$terminaison_dest) {
+               return false;
+       }
 
        $term_fonction = $terminaison;
-       if ($term_fonction == "jpg") $term_fonction = "jpeg";
+       if ($term_fonction == "jpg") {
+               $term_fonction = "jpeg";
+       }
 
        $nom_fichier = substr($fichier, 0, strlen($fichier) - (strlen($terminaison) + 1));
        $fichier_dest = $nom_fichier;
-       if (($find_in_path AND $f=find_in_path($fichier) AND $fichier=$f)
-               OR @file_exists($f = $fichier)){
+       if (($find_in_path and $f = find_in_path($fichier) and $fichier = $f)
+               or @file_exists($f = $fichier)
+       ) {
                // on passe la balise img a taille image qui exraira les attributs si possible
                // au lieu de faire un acces disque sur le fichier
-               list ($ret["hauteur"],$ret["largeur"]) = taille_image($find_in_path?$f:$img);
+               list($ret["hauteur"], $ret["largeur"]) = taille_image($find_in_path ? $f : $img);
                $date_src = @filemtime($f);
-       }
-       elseif (@file_exists($f = "$fichier.src")
-               AND lire_fichier($f,$valeurs)
-               AND $valeurs=unserialize($valeurs)
-               AND isset($valeurs["hauteur_dest"])
-               AND isset($valeurs["largeur_dest"])) {
+       } elseif (@file_exists($f = "$fichier.src")
+               and lire_fichier($f, $valeurs)
+               and $valeurs = unserialize($valeurs)
+               and isset($valeurs["hauteur_dest"])
+               and isset($valeurs["largeur_dest"])
+       ) {
                $ret["hauteur"] = $valeurs["hauteur_dest"];
                $ret["largeur"] = $valeurs["largeur_dest"];
                $date_src = $valeurs["date"];
-       }
-       // pas de fichier source par la
-       else
+       } // pas de fichier source par la
+       else {
                return false;
+       }
 
        // pas de taille mesurable
-       if (!($ret["hauteur"] OR $ret["largeur"]))
+       if (!($ret["hauteur"] or $ret["largeur"])) {
                return false;
-               
+       }
+
+       // les images calculees dependent du chemin du fichier source
+       // pour une meme image source et un meme filtre on aboutira a 2 fichiers selon si l'appel est dans le public ou dans le prive
+       // ce n'est pas totalement optimal en terme de stockage, mais chaque image est associee a un fichier .src
+       // qui contient la methode de reconstrucion (le filtre + les arguments d'appel) et les arguments different entre prive et public
+       // la mise en commun du fichier image cree donc un bug et des problemes qui necessiteraient beaucoup de complexite de code
+       // alors que ca concerne peu de site au final
+       // la release de r23632+r23633+r23634 a provoque peu de remontee de bug attestant du peu de sites impactes
+       $identifiant = $fichier;
 
        // cas general :
        // on a un dossier cache commun et un nom de fichier qui varie avec l'effet
        // cas particulier de reduire :
        // un cache par dimension, et le nom de fichier est conserve, suffixe par la dimension aussi
        $cache = "cache-gd2";
-       if (substr($effet,0,7)=='reduire') {
-               list(,$maxWidth,$maxHeight) = explode('-',$effet);
-               list ($destWidth,$destHeight) = _image_ratio($ret['largeur'], $ret['hauteur'], $maxWidth, $maxHeight);
+       if (substr($effet, 0, 7) == 'reduire') {
+               list(, $maxWidth, $maxHeight) = explode('-', $effet);
+               list($destWidth, $destHeight) = _image_ratio($ret['largeur'], $ret['hauteur'], $maxWidth, $maxHeight);
                $ret['largeur_dest'] = $destWidth;
                $ret['hauteur_dest'] = $destHeight;
                $effet = "L{$destWidth}xH$destHeight";
                $cache = "cache-vignettes";
                $fichier_dest = basename($fichier_dest);
-               if (($ret['largeur']<=$maxWidth)&&($ret['hauteur']<=$maxHeight)){
+               if (($ret['largeur'] <= $maxWidth) && ($ret['hauteur'] <= $maxHeight)) {
                        // on garde la terminaison initiale car image simplement copiee
                        // et on postfixe son nom avec un md5 du path
                        $terminaison_dest = $terminaison;
-                       $fichier_dest .= '-'.substr(md5("$fichier"),0,5);
+                       $fichier_dest .= '-' . substr(md5("$identifiant"), 0, 5);
+               } else {
+                       $fichier_dest .= '-' . substr(md5("$identifiant-$effet"), 0, 5);
                }
-               else
-                       $fichier_dest .= '-'.substr(md5("$fichier-$effet"),0,5);
                $cache = sous_repertoire(_DIR_VAR, $cache);
                $cache = sous_repertoire($cache, $effet);
                # cherche un cache existant
@@ -222,36 +267,41 @@ function _image_valeurs_trans($img, $effet, $forcer_format = false, $fonction_cr
                        if (@file_exists($cache . $fichier_dest . '.' . $fmt)) {
                                $terminaison_dest = $fmt;
                        }*/
-       }
-       else    {
-               $fichier_dest = md5("$fichier-$effet");
+       } else {
+               $fichier_dest = md5("$identifiant-$effet");
                $cache = sous_repertoire(_DIR_VAR, $cache);
+               $cache = sous_repertoire($cache, substr($fichier_dest, 0, 2));
+               $fichier_dest = substr($fichier_dest, 2);
        }
-       
-       $fichier_dest = $cache . $fichier_dest . "." .$terminaison_dest;
-       
-       $GLOBALS["images_calculees"][] =  $fichier_dest;
+
+       $fichier_dest = $cache . $fichier_dest . "." . $terminaison_dest;
+
+       $GLOBALS["images_calculees"][] = $fichier_dest;
 
        $creer = true;
        // si recalcul des images demande, recalculer chaque image une fois
-       if (defined('_VAR_IMAGES') AND _VAR_IMAGES AND !isset($images_recalcul[$fichier_dest])){
+       if (defined('_VAR_IMAGES') and _VAR_IMAGES and !isset($images_recalcul[$fichier_dest])) {
                $images_recalcul[$fichier_dest] = true;
-       }
-       else {
-               if (@file_exists($f = $fichier_dest)){
-                       if (filemtime($f)>=$date_src)
+       } else {
+               if (@file_exists($f = $fichier_dest)) {
+                       if (filemtime($f) >= $date_src) {
                                $creer = false;
-               }
-               else if (@file_exists($f = "$fichier_dest.src")
-                 AND lire_fichier($f,$valeurs)
-                 AND $valeurs=unserialize($valeurs)
-                       AND $valeurs["date"]>=$date_src)
+                       }
+               } else {
+                       if (@file_exists($f = "$fichier_dest.src")
+                               and lire_fichier($f, $valeurs)
+                               and $valeurs = unserialize($valeurs)
+                               and $valeurs["date"] >= $date_src
+                       ) {
                                $creer = false;
+                       }
+               }
        }
        if ($creer) {
                if (!@file_exists($fichier)) {
                        if (!@file_exists("$fichier.src")) {
                                spip_log("Image absente : $fichier");
+
                                return false;
                        }
                        # on reconstruit l'image source absente a partir de la chaine des .src
@@ -259,13 +309,15 @@ function _image_valeurs_trans($img, $effet, $forcer_format = false, $fonction_cr
                }
        }
 
-       if ($creer)
-               spip_log("filtre image ".($fonction_creation?reset($fonction_creation):'')."[$effet] sur $fichier","images"._LOG_DEBUG);
+       if ($creer) {
+               spip_log("filtre image " . ($fonction_creation ? reset($fonction_creation) : '') . "[$effet] sur $fichier",
+                       "images" . _LOG_DEBUG);
+       }
 
        // TODO: si une image png est nommee .jpg, le reconnaitre avec le bon $f
-       $ret["fonction_imagecreatefrom"] = "_imagecreatefrom".$term_fonction;
+       $ret["fonction_imagecreatefrom"] = "_imagecreatefrom" . $term_fonction;
        $ret["fichier"] = $fichier;
-       $ret["fonction_image"] = "_image_image".$terminaison_dest;
+       $ret["fonction_image"] = "_image_image" . $terminaison_dest;
        $ret["fichier_dest"] = $fichier_dest;
        $ret["format_source"] = ($terminaison != 'jpeg' ? $terminaison : 'jpg');
        $ret["format_dest"] = $terminaison_dest;
@@ -275,7 +327,7 @@ function _image_valeurs_trans($img, $effet, $forcer_format = false, $fonction_cr
        $ret["alt"] = extraire_attribut($img, 'alt');
        $ret["style"] = extraire_attribut($img, 'style');
        $ret["tag"] = $img;
-       if ($fonction_creation){
+       if ($fonction_creation) {
                $ret["reconstruction"] = $fonction_creation;
                # ecrire ici comment creer le fichier, car il est pas sur qu'on l'ecrira reelement 
                # cas de image_reduire qui finalement ne reduit pas l'image source
@@ -283,183 +335,218 @@ function _image_valeurs_trans($img, $effet, $forcer_format = false, $fonction_cr
                #ecrire_fichier($ret['fichier_dest'].'.src',serialize($ret),true);
        }
 
-       $ret = pipeline('image_preparer_filtre',array(
-                       'args'=>array(
-                               'img'=>$img,
-                               'effet'=>$effet,
-                               'forcer_format'=>$forcer_format,
-                               'fonction_creation'=>$fonction_creation,
-                               'find_in_path'=>$find_in_path,
+       $ret = pipeline('image_preparer_filtre', array(
+                       'args' => array(
+                               'img' => $img,
+                               'effet' => $effet,
+                               'forcer_format' => $forcer_format,
+                               'fonction_creation' => $fonction_creation,
+                               'find_in_path' => $find_in_path,
                        ),
-                       'data'=>$ret)
+                       'data' => $ret
+               )
        );
 
        // une globale pour le debug en cas de crash memoire
        $GLOBALS["derniere_image_calculee"] = $ret;
 
-       if (!function_exists($ret["fonction_imagecreatefrom"])) return false;
+       if (!function_exists($ret["fonction_imagecreatefrom"])) {
+               return false;
+       }
+
        return $ret;
 }
 
 /**
  * Crée une image depuis un fichier ou une URL
+ *
  * Utilise les fonctions spécifiques GD.
  *
  * @param string $filename
- *             Le path vers l'image à traiter (par exemple : IMG/distant/jpg/image.jpg
- *             ou local/cache-vignettes/L180xH51/image.jpg).
+ *     Le path vers l'image à traiter (par exemple : IMG/distant/jpg/image.jpg
+ *     ou local/cache-vignettes/L180xH51/image.jpg).
  * @return ressource
- *             Une ressource de type Image GD.
+ *     Une ressource de type Image GD.
  */
-function _imagecreatefromjpeg($filename){
+function _imagecreatefromjpeg($filename) {
        $img = @imagecreatefromjpeg($filename);
        if (!$img) {
-               spip_log("Erreur lecture imagecreatefromjpeg $filename",_LOG_CRITIQUE);
+               spip_log("Erreur lecture imagecreatefromjpeg $filename", _LOG_CRITIQUE);
                erreur_squelette("Erreur lecture imagecreatefromjpeg $filename");
-               $img = imagecreate(10,10);
+               $img = imagecreate(10, 10);
        }
+
        return $img;
 }
 
 /**
- * Crée une image depuis un fichier ou une URL
+ * Crée une image depuis un fichier ou une URL (au format png)
+ *
  * Utilise les fonctions spécifiques GD.
  *
  * @param string $filename
- *             Le path vers l'image à traiter (par exemple : IMG/distant/png/image.png
- *             ou local/cache-vignettes/L180xH51/image.png).
+ *     Le path vers l'image à traiter (par exemple : IMG/distant/png/image.png
+ *     ou local/cache-vignettes/L180xH51/image.png).
  * @return ressource
- *             Une ressource de type Image GD.
+ *     Une ressource de type Image GD.
  */
-function _imagecreatefrompng($filename){
+function _imagecreatefrompng($filename) {
        $img = @imagecreatefrompng($filename);
        if (!$img) {
-               spip_log("Erreur lecture imagecreatefrompng $filename",_LOG_CRITIQUE);
+               spip_log("Erreur lecture imagecreatefrompng $filename", _LOG_CRITIQUE);
                erreur_squelette("Erreur lecture imagecreatefrompng $filename");
-               $img = imagecreate(10,10);
+               $img = imagecreate(10, 10);
        }
+
        return $img;
 }
 
 /**
- * Crée une image depuis un fichier ou une URL
+ * Crée une image depuis un fichier ou une URL (au format gif)
+ *
  * Utilise les fonctions spécifiques GD.
  *
  * @param string $filename
- *             Le path vers l'image à traiter (par exemple : IMG/distant/gif/image.gif
- *             ou local/cache-vignettes/L180xH51/image.gif).
+ *     Le path vers l'image à traiter (par exemple : IMG/distant/gif/image.gif
+ *     ou local/cache-vignettes/L180xH51/image.gif).
  * @return ressource
- *             Une ressource de type Image GD.
+ *     Une ressource de type Image GD.
  */
-function _imagecreatefromgif($filename){
+function _imagecreatefromgif($filename) {
        $img = @imagecreatefromgif($filename);
        if (!$img) {
-               spip_log("Erreur lecture imagecreatefromgif $filename",_LOG_CRITIQUE);
+               spip_log("Erreur lecture imagecreatefromgif $filename", _LOG_CRITIQUE);
                erreur_squelette("Erreur lecture imagecreatefromgif $filename");
-               $img = imagecreate(10,10);
+               $img = imagecreate(10, 10);
        }
+
        return $img;
 }
 
 /**
  * Affiche ou sauvegarde une image au format PNG
+ *
  * Utilise les fonctions spécifiques GD.
  *
  * @param ressource $img
- *             Une ressource de type Image GD.
+ *     Une ressource de type Image GD.
  * @param string $fichier
- *             Le path vers l'image (ex : local/cache-vignettes/L180xH51/image.png).
+ *     Le path vers l'image (ex : local/cache-vignettes/L180xH51/image.png).
  * @return bool
- *             false si l'image créée a une largeur nulle ou n'existe pas ;
- *             true si une image est bien retournée.
+ *
+ *     - false si l'image créée a une largeur nulle ou n'existe pas ;
+ *     - true si une image est bien retournée.
  */
 function _image_imagepng($img, $fichier) {
-       if (!function_exists('imagepng')) return false;
-       $tmp = $fichier.".tmp";
-       $ret = imagepng($img,$tmp);
-       
-       if(file_exists($tmp)){
+       if (!function_exists('imagepng')) {
+               return false;
+       }
+       $tmp = $fichier . ".tmp";
+       $ret = imagepng($img, $tmp);
+       if (file_exists($tmp)) {
                $taille_test = getimagesize($tmp);
-               if ($taille_test[0] < 1) return false;
-       
+               if ($taille_test[0] < 1) {
+                       return false;
+               }
+
                spip_unlink($fichier); // le fichier peut deja exister
                @rename($tmp, $fichier);
+
                return $ret;
        }
+
        return false;
 }
 
 /**
  * Affiche ou sauvegarde une image au format GIF
+ *
  * Utilise les fonctions spécifiques GD.
  *
  * @param ressource $img
- *             Une ressource de type Image GD.
+ *     Une ressource de type Image GD.
  * @param string $fichier
- *             Le path vers l'image (ex : local/cache-vignettes/L180xH51/image.gif).
+ *     Le path vers l'image (ex : local/cache-vignettes/L180xH51/image.gif).
  * @return bool
- *             false si l'image créée a une largeur nulle ou n'existe pas;
- *             true si une image est bien retournée.
+ *
+ *     - false si l'image créée a une largeur nulle ou n'existe pas ;
+ *     - true si une image est bien retournée.
  */
-function _image_imagegif($img,$fichier) {
-       if  (!function_exists('imagegif')) return false;
-       $tmp = $fichier.".tmp";
-       $ret = imagegif($img,$tmp);
-       
-       if(file_exists($tmp)){
+function _image_imagegif($img, $fichier) {
+       if (!function_exists('imagegif')) {
+               return false;
+       }
+       $tmp = $fichier . ".tmp";
+       $ret = imagegif($img, $tmp);
+       if (file_exists($tmp)) {
                $taille_test = getimagesize($tmp);
-               if ($taille_test[0] < 1) return false;
+               if ($taille_test[0] < 1) {
+                       return false;
+               }
 
                spip_unlink($fichier); // le fichier peut deja exister
                @rename($tmp, $fichier);
+
                return $ret;
        }
+
        return false;
 }
 
 /**
  * Affiche ou sauvegarde une image au format JPG
+ *
  * Utilise les fonctions spécifiques GD.
  *
  * @param ressource $img
- *             Une ressource de type Image GD.
+ *     Une ressource de type Image GD.
  * @param string $fichier
- *             Le path vers l'image (ex : local/cache-vignettes/L180xH51/image.jpg).
+ *     Le path vers l'image (ex : local/cache-vignettes/L180xH51/image.jpg).
  * @param int $qualite
- *             Le niveau de qualité du fichier résultant : de 0 (pire qualité, petit
- *             fichier) à 100 (meilleure qualité, gros fichier). Par défaut, prend la
- *             valeur (85) de la constante _IMG_GD_QUALITE (modifiable depuis
- *             mes_options.php).
+ *     Le niveau de qualité du fichier résultant : de 0 (pire qualité, petit
+ *     fichier) à 100 (meilleure qualité, gros fichier). Par défaut, prend la
+ *     valeur (85) de la constante _IMG_GD_QUALITE (modifiable depuis
+ *     mes_options.php).
  * @return bool
- *             false si l'image créée a une largeur nulle ou n'existe pas ;
- *             true si une image est bien retournée.
+ *
+ *     - false si l'image créée a une largeur nulle ou n'existe pas ;
+ *     - true si une image est bien retournée.
  */
-function _image_imagejpg($img,$fichier,$qualite=_IMG_GD_QUALITE) {
-       if (!function_exists('imagejpeg')) return false;
-       $tmp = $fichier.".tmp";
-       $ret = imagejpeg($img,$tmp, $qualite);
-       
-       if(file_exists($tmp)){
+function _image_imagejpg($img, $fichier, $qualite = _IMG_GD_QUALITE) {
+       if (!function_exists('imagejpeg')) {
+               return false;
+       }
+       $tmp = $fichier . ".tmp";
+       $ret = imagejpeg($img, $tmp, $qualite);
+
+       if (file_exists($tmp)) {
                $taille_test = getimagesize($tmp);
-               if ($taille_test[0] < 1) return false;
-       
+               if ($taille_test[0] < 1) {
+                       return false;
+               }
+
                spip_unlink($fichier); // le fichier peut deja exister
                @rename($tmp, $fichier);
+
                return $ret;
        }
+
        return false;
 }
 
 /**
  * Crée un fichier-image au format ICO
+ *
  * Utilise les fonctions de la classe phpthumb_functions.
  *
+ * @uses phpthumb_functions::GD2ICOstring()
+ *
  * @param ressource $img
- *             Une ressource de type Image GD.
+ *     Une ressource de type Image GD.
  * @param string $fichier
- *             Le path vers l'image (ex : local/cache-vignettes/L180xH51/image.jpg).
+ *     Le path vers l'image (ex : local/cache-vignettes/L180xH51/image.jpg).
  * @return bool
- *             true si le fichier a bien été créé ; false sinon.
+ *     true si le fichier a bien été créé ; false sinon.
  */
 function _image_imageico($img, $fichier) {
        $gd_image_array = array($img);
@@ -469,60 +556,73 @@ function _image_imageico($img, $fichier) {
 
 /**
  * Finalise le traitement GD
+ *
  * Crée un fichier_image temporaire .src ou vérifie que le fichier_image
  * définitif a bien été créé.
  *
+ * @uses statut_effacer_images_temporaires()
+ *
  * @param ressource $img
- *             Une ressource de type Image GD.
+ *     Une ressource de type Image GD.
  * @param array $valeurs
- *             Un tableau des informations (tailles, traitement, path...) accompagnant
- *             l'image.
+ *     Un tableau des informations (tailles, traitement, path...) accompagnant
+ *     l'image.
  * @param int $qualite
- *             N'est utilisé que pour les images jpg.
- *             Le niveau de qualité du fichier résultant : de 0 (pire qualité, petit
- *             fichier) à 100 (meilleure qualité, gros fichier). Par défaut, prend la
- *             valeur (85) de la constante _IMG_GD_QUALITE (modifiable depuis
- *             mes_options.php).
+ *     N'est utilisé que pour les images jpg.
+ *     Le niveau de qualité du fichier résultant : de 0 (pire qualité, petit
+ *     fichier) à 100 (meilleure qualité, gros fichier). Par défaut, prend la
+ *     valeur (85) de la constante _IMG_GD_QUALITE (modifiable depuis
+ *     mes_options.php).
  * @return bool
- *             true si le traitement GD s'est bien finalisé ;
- *             false sinon.
+ *     - true si le traitement GD s'est bien finalisé ;
+ *     - false sinon.
  */
-function _image_gd_output($img,$valeurs, $qualite=_IMG_GD_QUALITE){
-       $fonction = "_image_image".$valeurs['format_dest'];
+function _image_gd_output($img, $valeurs, $qualite = _IMG_GD_QUALITE) {
+       $fonction = "_image_image" . $valeurs['format_dest'];
        $ret = false;
        #un flag pour reperer les images gravees
-       $lock = 
+       $lock =
                !statut_effacer_images_temporaires('get') // si la fonction n'a pas ete activee, on grave tout
-         OR (@file_exists($valeurs['fichier_dest']) AND !@file_exists($valeurs['fichier_dest'].'.src'));
+       or (@file_exists($valeurs['fichier_dest']) and !@file_exists($valeurs['fichier_dest'] . '.src'));
        if (
-            function_exists($fonction) 
-                         && ($ret = $fonction($img,$valeurs['fichier_dest'],$qualite)) # on a reussi a creer l'image
-                         && isset($valeurs['reconstruction']) # et on sait comment la resonctruire le cas echeant
-                         && !$lock
-         )
-               if (@file_exists($valeurs['fichier_dest'])){
+               function_exists($fonction)
+               && ($ret = $fonction($img, $valeurs['fichier_dest'], $qualite)) # on a reussi a creer l'image
+               && isset($valeurs['reconstruction']) # et on sait comment la resonctruire le cas echeant
+               && !$lock
+       ) {
+               if (@file_exists($valeurs['fichier_dest'])) {
                        // dans tous les cas mettre a jour la taille de l'image finale
-                       list ($valeurs["hauteur_dest"],$valeurs["largeur_dest"]) = taille_image($valeurs['fichier_dest']);
+                       list($valeurs["hauteur_dest"], $valeurs["largeur_dest"]) = taille_image($valeurs['fichier_dest']);
                        $valeurs['date'] = @filemtime($valeurs['fichier_dest']); // pour la retrouver apres disparition
-                       ecrire_fichier($valeurs['fichier_dest'].'.src',serialize($valeurs),true);
+                       ecrire_fichier($valeurs['fichier_dest'] . '.src', serialize($valeurs), true);
                }
+       }
+
        return $ret;
 }
 
-// http://doc.spip.org/@reconstruire_image_intermediaire
-function reconstruire_image_intermediaire($fichier_manquant){
+/**
+ * Reconstruit une image à partir des sources de contrôle de son ancienne
+ * construction
+ *
+ * @uses ramasse_miettes()
+ *
+ * @param string $fichier_manquant
+ *     Chemin vers le fichier manquant
+ **/
+function reconstruire_image_intermediaire($fichier_manquant) {
        $reconstruire = array();
        $fichier = $fichier_manquant;
        while (strpos($fichier,"://")===false
                and !@file_exists($fichier)
-               AND lire_fichier($src = "$fichier.src",$source)
-               AND $valeurs=unserialize($source)
-    AND ($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
-    ) {
-                       spip_unlink($src); // si jamais on a un timeout pendant la reconstruction, elle se fera naturellement au hit suivant
-                       $reconstruire[] = $valeurs['reconstruction'];
-   }
-       while (count($reconstruire)){
+               and lire_fichier($src = "$fichier.src", $source)
+               and $valeurs = unserialize($source)
+               and ($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
+       ) {
+               spip_unlink($src); // si jamais on a un timeout pendant la reconstruction, elle se fera naturellement au hit suivant
+               $reconstruire[] = $valeurs['reconstruction'];
+       }
+       while (count($reconstruire)) {
                $r = array_pop($reconstruire);
                $fonction = $r[0];
                $args = $r[1];
@@ -558,11 +658,12 @@ function ramasse_miettes($fichier) {
        }
        spip_unlink($src); # on supprime la reference a sa source pour marquer cette image comme non intermediaire
        while (
-            ($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
-               AND (substr($fichier,0,strlen(_DIR_VAR))==_DIR_VAR) # et est dans local
-               AND (lire_fichier($src = "$fichier.src",$source)) # le fichier a une source connue (c'est donc une image calculee intermediaire)
-               AND ($valeurs=unserialize($source))  # et valide
-               ) {
+               ($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
+               and (substr($fichier, 0, strlen(_DIR_VAR)) == _DIR_VAR) # et est dans local
+               and (lire_fichier($src = "$fichier.src",
+                       $source)) # le fichier a une source connue (c'est donc une image calculee intermediaire)
+               and ($valeurs = unserialize($source))  # et valide
+       ) {
                # on efface le fichier
                spip_unlink($fichier);
                # mais laisse le .src qui permet de savoir comment reconstruire l'image si besoin
@@ -570,127 +671,224 @@ function ramasse_miettes($fichier) {
        }
 }
 
-// http://doc.spip.org/@image_graver
-function image_graver($img){
+
+/**
+ * Clôture une série de filtres d'images
+ *
+ * Ce filtre est automatiquement appelé à la fin d'une série de filtres
+ * d'images dans un squelette.
+ *
+ * @filtre
+ * @uses reconstruire_image_intermediaire()
+ *     Si l'image finale a déjà été supprimée car considérée comme temporaire
+ *     par une autre série de filtres images débutant pareil
+ * @uses ramasse_miettes()
+ *     Pour déclarer l'image définitive et nettoyer les images intermédiaires.
+ *
+ * @pipeline_appel post_image_filtrer
+ *
+ * @param string $img
+ *     Code HTML de l'image
+ * @return string
+ *     Code HTML de l'image
+ **/
+function image_graver($img) {
        // appeler le filtre post_image_filtrer qui permet de faire
        // des traitements auto a la fin d'une serie de filtres
-       $img = pipeline('post_image_filtrer',$img);
+       $img = pipeline('post_image_filtrer', $img);
 
-       $fichier = extraire_attribut($img, 'src');
-       if (($p=strpos($fichier,'?'))!==FALSE)
-               $fichier=substr($fichier,0,$p);
-       if (strlen($fichier) < 1)
+       $fichier_ori = $fichier = extraire_attribut($img, 'src');
+       if (($p = strpos($fichier, '?')) !== false) {
+               $fichier = substr($fichier, 0, $p);
+       }
+       if (strlen($fichier) < 1) {
                $fichier = $img;
+       }
        # si jamais le fichier final n'a pas ete calcule car suppose temporaire
        # et qu'il ne s'agit pas d'une URL
        if (strpos($fichier,"://")===false and !@file_exists($fichier)) {
                reconstruire_image_intermediaire($fichier);
        }
        ramasse_miettes($fichier);
-       return $img; // on ne change rien
+
+       // ajouter le timestamp si besoin
+       if (strpos($fichier_ori, "?") === false) {
+               // on utilise str_replace pour attraper le onmouseover des logo si besoin
+               $img = str_replace($fichier_ori, timestamp($fichier_ori), $img);
+       }
+
+       return $img;
 }
 
-// Transforme une image a palette indexee (256 couleurs max) en "vraies" couleurs RGB
-// Existe seulement pour compatibilite avec PHP < 5.5
-// http://doc.spip.org/@imagepalettetotruecolor
+
 if (!function_exists("imagepalettetotruecolor")) {
-function imagepalettetotruecolor(&$img) {
-       if ($img AND !imageistruecolor($img) AND function_exists('imagecreatetruecolor')) {
-               $w = imagesx($img);
-               $h = imagesy($img);
-               $img1 = imagecreatetruecolor($w,$h);
-               //Conserver la transparence si possible
-               if(function_exists('ImageCopyResampled')) {
-                       if (function_exists("imageAntiAlias")) imageAntiAlias($img1,true); 
-                       @imagealphablending($img1, false); 
-                       @imagesavealpha($img1,true); 
-                       @ImageCopyResampled($img1, $img, 0, 0, 0, 0, $w, $h, $w, $h);
-               } else {
-                       imagecopy($img1,$img,0,0,0,0,$w,$h);
+       /**
+        * Transforme une image à palette indexée (256 couleurs max) en "vraies" couleurs RGB
+        *
+        * @note Pour compatibilité avec PHP < 5.5
+        *
+        * @link http://php.net/manual/fr/function.imagepalettetotruecolor.php
+        *
+        * @param ressource $img
+        * @return bool
+        *     - true si l'image est déjà en vrai RGB ou peut être transformée
+        *     - false si la transformation ne peut être faite.
+        **/
+       function imagepalettetotruecolor(&$img) {
+               if (!$img or !function_exists('imagecreatetruecolor')) {
+                       return false;
+               } elseif (!imageistruecolor($img)) {
+                       $w = imagesx($img);
+                       $h = imagesy($img);
+                       $img1 = imagecreatetruecolor($w, $h);
+                       //Conserver la transparence si possible
+                       if (function_exists('ImageCopyResampled')) {
+                               if (function_exists("imageAntiAlias")) {
+                                       imageAntiAlias($img1, true);
+                               }
+                               @imagealphablending($img1, false);
+                               @imagesavealpha($img1, true);
+                               @ImageCopyResampled($img1, $img, 0, 0, 0, 0, $w, $h, $w, $h);
+                       } else {
+                               imagecopy($img1, $img, 0, 0, 0, 0, $w, $h);
+                       }
+
+                       $img = $img1;
                }
 
-               $img = $img1;
+               return true;
        }
 }
-}
 
-// http://doc.spip.org/@image_tag_changer_taille
-function _image_tag_changer_taille($tag,$width,$height,$style=false){
-       if ($style===false) $style = extraire_attribut($tag,'style');
+/**
+ * Applique des attributs de taille (width, height) à une balise HTML
+ *
+ * Utilisé avec des balises `<img>` tout particulièrement.
+ *
+ * Modifie l'attribut style s'il était renseigné, en enlevant les
+ * informations éventuelles width / height dedans.
+ *
+ * @uses extraire_attribut()
+ * @uses inserer_attribut()
+ *
+ * @param string $tag
+ *     Code html de la balise
+ * @param int $width
+ *     Hauteur
+ * @param int $height
+ *     Largeur
+ * @param bool|string $style
+ *     Attribut html style à appliquer.
+ *     False extrait celui présent dans la balise
+ * @return string
+ *     Code html modifié de la balise.
+ **/
+function _image_tag_changer_taille($tag, $width, $height, $style = false) {
+       if ($style === false) {
+               $style = extraire_attribut($tag, 'style');
+       }
+
        // enlever le width et height du style
-       $style = preg_replace(",(^|;)\s*(width|height)\s*:\s*[^;]+,ims","",$style);
-       if ($style AND $style{0}==';') $style=substr($style,1);
+       $style = preg_replace(",(^|;)\s*(width|height)\s*:\s*[^;]+,ims", "", $style);
+       if ($style and $style{0} == ';') {
+               $style = substr($style, 1);
+       }
+
        // mettre des attributs de width et height sur les images, 
        // ca accelere le rendu du navigateur
        // ca permet aux navigateurs de reserver la bonne taille 
        // quand on a desactive l'affichage des images.
-       $tag = inserer_attribut($tag,'width',$width);
-       $tag = inserer_attribut($tag,'height',$height);
-       
-       // Ancien style inline pour IE6 mais qui casse la possibilité de surcharger en CSS
-       //$style = "height:".$height."px;width:".$width."px;".$style;
-       
+       $tag = inserer_attribut($tag, 'width', $width);
+       $tag = inserer_attribut($tag, 'height', $height);
+
        // attributs deprecies. Transformer en CSS
-       if ($espace = extraire_attribut($tag, 'hspace')){
-               $style = "margin:${espace}px;".$style;
-               $tag = inserer_attribut($tag,'hspace','');
+       if ($espace = extraire_attribut($tag, 'hspace')) {
+               $style = "margin:${espace}px;" . $style;
+               $tag = inserer_attribut($tag, 'hspace', '');
        }
-       $tag = inserer_attribut($tag,'style',$style, true, $style ? false : true);
+
+       $tag = inserer_attribut($tag, 'style', $style, true, $style ? false : true);
+
        return $tag;
 }
 
-// function d'ecriture du de la balise img en sortie des filtre image
-// reprend le tag initial et surcharge les tags modifies
-function _image_ecrire_tag($valeurs,$surcharge=array()){
-       $valeurs = pipeline('image_ecrire_tag_preparer',$valeurs);
 
-       $tag =  str_replace(">","/>",str_replace("/>",">",$valeurs['tag'])); // fermer les tags img pas bien fermes;
-       
+/**
+ * Écriture de la balise img en sortie de filtre image
+ *
+ * Reprend le tag initial et surcharge les attributs modifiés
+ *
+ * @pipeline_appel image_ecrire_tag_preparer
+ * @pipeline_appel image_ecrire_tag_finir
+ *
+ * @uses _image_tag_changer_taille()
+ * @uses extraire_attribut()
+ * @uses inserer_attribut()
+ * @see  _image_valeurs_trans()
+ *
+ * @param array $valeurs
+ *     Description de l'image tel que retourné par `_image_valeurs_trans()`
+ * @param array $surcharge
+ *     Permet de surcharger certaines descriptions présentes dans `$valeurs`
+ *     tel que 'style', 'width', 'height'
+ * @return string
+ *     Retourne le code HTML de l'image
+ **/
+function _image_ecrire_tag($valeurs, $surcharge = array()) {
+       $valeurs = pipeline('image_ecrire_tag_preparer', $valeurs);
+
+       // fermer les tags img pas bien fermes;
+       $tag = str_replace(">", "/>", str_replace("/>", ">", $valeurs['tag']));
+
        // le style
        $style = $valeurs['style'];
-       if (isset($surcharge['style'])){
+       if (isset($surcharge['style'])) {
                $style = $surcharge['style'];
                unset($surcharge['style']);
        }
-       
+
        // traiter specifiquement la largeur et la hauteur
        $width = $valeurs['largeur'];
-       if (isset($surcharge['width'])){
+       if (isset($surcharge['width'])) {
                $width = $surcharge['width'];
                unset($surcharge['width']);
        }
        $height = $valeurs['hauteur'];
-       if (isset($surcharge['height'])){
+       if (isset($surcharge['height'])) {
                $height = $surcharge['height'];
                unset($surcharge['height']);
        }
 
-       $tag = _image_tag_changer_taille($tag,$width,$height,$style);
+       $tag = _image_tag_changer_taille($tag, $width, $height, $style);
        // traiter specifiquement le src qui peut etre repris dans un onmouseout
        // on remplace toute les ref a src dans le tag
-       $src = extraire_attribut($tag,'src');
-       if (isset($surcharge['src'])){
-               $tag = str_replace($src,$surcharge['src'],$tag);
+       $src = extraire_attribut($tag, 'src');
+       if (isset($surcharge['src'])) {
+               $tag = str_replace($src, $surcharge['src'], $tag);
                // si il y a des & dans src, alors ils peuvent provenir d'un &amp
                // pas garanti comme methode, mais mieux que rien
-               if (strpos($src,'&') !== false)
-                       $tag = str_replace(str_replace("&","&amp;",$src),$surcharge['src'],$tag);
+               if (strpos($src, '&') !== false) {
+                       $tag = str_replace(str_replace("&", "&amp;", $src), $surcharge['src'], $tag);
+               }
                $src = $surcharge['src'];
                unset($surcharge['src']);
        }
 
        $class = $valeurs['class'];
-       if (isset($surcharge['class'])){
+       if (isset($surcharge['class'])) {
                $class = $surcharge['class'];
                unset($surcharge['class']);
        }
-       if(strlen($class))
-               $tag = inserer_attribut($tag,'class',$class);
+       if (strlen($class)) {
+               $tag = inserer_attribut($tag, 'class', $class);
+       }
+
+       if (count($surcharge)) {
+               foreach ($surcharge as $attribut => $valeur) {
+                       $tag = inserer_attribut($tag, $attribut, $valeur);
+               }
+       }
 
-       if (count($surcharge))
-               foreach($surcharge as $attribut=>$valeur)
-                       $tag = inserer_attribut($tag,$attribut,$valeur);
-       
        $tag = pipeline('image_ecrire_tag_finir',
                array(
                        'args' => array(
@@ -704,264 +902,388 @@ function _image_ecrire_tag($valeurs,$surcharge=array()){
        return $tag;
 }
 
-function _image_creer_vignette($valeurs, $maxWidth, $maxHeight, $process='AUTO', $force=false, $test_cache_only = false) {
+/**
+ * Crée si possible une miniature d'une image
+ *
+ * @see  _image_valeurs_trans()
+ * @uses _image_ratio()
+ *
+ * @param array $valeurs
+ *     Description de l'image, telle que retournée par `_image_valeurs_trans()`
+ * @param int $maxWidth
+ *     Largeur maximum en px de la miniature à réaliser
+ * @param int $maxHeight
+ *     Hauteur maximum en px de la miniateure à réaliser
+ * @param string $process
+ *     Librairie graphique à utiliser (gd1, gd2, netpbm, convert, imagick).
+ *     AUTO utilise la librairie sélectionnée dans la configuration.
+ * @param bool $force
+ * @return array|null
+ *     Description de l'image, sinon null.
+ **/
+function _image_creer_vignette($valeurs, $maxWidth, $maxHeight, $process = 'AUTO', $force = false) {
        // ordre de preference des formats graphiques pour creer les vignettes
        // le premier format disponible, selon la methode demandee, est utilise
        $image = $valeurs['fichier'];
        $format = $valeurs['format_source'];
        $destdir = dirname($valeurs['fichier_dest']);
-       $destfile = basename($valeurs['fichier_dest'],".".$valeurs["format_dest"]);
-       
+       $destfile = basename($valeurs['fichier_dest'], "." . $valeurs["format_dest"]);
+
        $format_sortie = $valeurs['format_dest'];
-       
+
+       if (($process == 'AUTO') and isset($GLOBALS['meta']['image_process'])) {
+               $process = $GLOBALS['meta']['image_process'];
+       }
+
        // liste des formats qu'on sait lire
        $img = isset($GLOBALS['meta']['formats_graphiques'])
-         ? (strpos($GLOBALS['meta']['formats_graphiques'], $format)!==false)
-         : false;
+               ? (strpos($GLOBALS['meta']['formats_graphiques'], $format) !== false)
+               : false;
 
        // si le doc n'est pas une image, refuser
-       if (!$force AND !$img) return;
+       if (!$force and !$img) {
+               return;
+       }
        $destination = "$destdir/$destfile";
 
-       // chercher un cache
-       $vignette = '';
-       if ($test_cache_only AND !$vignette) return;
+       // calculer la taille
+       if (($srcWidth = $valeurs['largeur']) && ($srcHeight = $valeurs['hauteur'])) {
+               if (!($destWidth = $valeurs['largeur_dest']) || !($destHeight = $valeurs['hauteur_dest'])) {
+                       list($destWidth, $destHeight) = _image_ratio($valeurs['largeur'], $valeurs['hauteur'], $maxWidth, $maxHeight);
+               }
+       } elseif ($process == 'convert' or $process == 'imagick') {
+               $destWidth = $maxWidth;
+               $destHeight = $maxHeight;
+       } else {
+               spip_log("echec $process sur $image");
 
-       // utiliser le cache ?
-       if (!$test_cache_only)
-       if ($force OR !$vignette OR (@filemtime($vignette) < @filemtime($image))) {
+               return;
+       }
 
-               $creation = true;
-               // calculer la taille
-               if (($srcWidth=$valeurs['largeur']) && ($srcHeight=$valeurs['hauteur'])){
-                       if (!($destWidth=$valeurs['largeur_dest']) || !($destHeight=$valeurs['hauteur_dest']))
-                               list ($destWidth,$destHeight) = _image_ratio($valeurs['largeur'], $valeurs['hauteur'], $maxWidth, $maxHeight);
-               }
-               elseif ($process == 'convert' OR $process == 'imagick') {
-                       $destWidth = $maxWidth;
-                       $destHeight = $maxHeight;
-               } else {
-                       spip_log("echec $process sur $image");
-                       return;
+       // Si l'image est de la taille demandee (ou plus petite), simplement la retourner
+       if ($srcWidth and $srcWidth <= $maxWidth and $srcHeight <= $maxHeight) {
+               $vignette = $destination . '.' . $format;
+               @copy($image, $vignette);
+       } // imagemagick en ligne de commande
+       elseif ($process == 'convert') {
+               if (!defined('_CONVERT_COMMAND')) {
+                       define('_CONVERT_COMMAND', 'convert');
+               } // Securite : mes_options.php peut preciser le chemin absolu
+               if (!defined('_RESIZE_COMMAND')) {
+                       define('_RESIZE_COMMAND', _CONVERT_COMMAND . ' -quality ' . _IMG_CONVERT_QUALITE . ' -resize %xx%y! %src %dest');
                }
+               $vignette = $destination . "." . $format_sortie;
+               $commande = str_replace(
+                       array('%x', '%y', '%src', '%dest'),
+                       array(
+                               $destWidth,
+                               $destHeight,
+                               escapeshellcmd($image),
+                               escapeshellcmd($vignette)
+                       ),
+                       _RESIZE_COMMAND);
+               spip_log($commande);
+               exec($commande);
+               if (!@file_exists($vignette)) {
+                       spip_log("echec convert sur $vignette");
 
-               // Si l'image est de la taille demandee (ou plus petite), simplement
-               // la retourner
-               if ($srcWidth
-               AND $srcWidth <= $maxWidth AND $srcHeight <= $maxHeight) {
-                       $vignette = $destination.'.'.$format;
-                       @copy($image, $vignette);
+                       return;  // echec commande
                }
-               // imagemagick en ligne de commande
-               else if ($process == 'convert') {
-                       define('_CONVERT_COMMAND', 'convert');
-                       define ('_RESIZE_COMMAND', _CONVERT_COMMAND.' -quality '._IMG_CONVERT_QUALITE.' -resize %xx%y! %src %dest');
-                       $vignette = $destination.".".$format_sortie;
-                       $commande = str_replace(
-                               array('%x', '%y', '%src', '%dest'),
-                               array(
-                                       $destWidth,
-                                       $destHeight,
-                                       escapeshellcmd($image),
-                                       escapeshellcmd($vignette)
-                               ),
-                               _RESIZE_COMMAND);
-                       spip_log($commande);
-                       exec($commande);
-                       if (!@file_exists($vignette)) {
-                               spip_log("echec convert sur $vignette");
-                               return; // echec commande
-                       }
-               }
-               else
-               // imagick (php4-imagemagick)
-               if ($process == 'imagick') {
+       } // php5 imagemagick
+       elseif ($process == 'imagick') {
+               $vignette = "$destination." . $format_sortie;
 
-                       $vignette = "$destination.".$format_sortie;
+               if (!class_exists('Imagick')) {
+                       spip_log("Classe Imagick absente !", _LOG_ERREUR);
 
-                       $imagick = new Imagick();
-                       $imagick->readImage($image);
-                       $imagick->resizeImage($destWidth, $destHeight, Imagick::FILTER_LANCZOS, 1 );//, IMAGICK_FILTER_LANCZOS, _IMG_IMAGICK_QUALITE / 100);
-                       $imagick->writeImage($vignette);
+                       return;
+               }
+               $imagick = new Imagick();
+               $imagick->readImage($image);
+               $imagick->resizeImage($destWidth, $destHeight, Imagick::FILTER_LANCZOS,
+                       1);//, IMAGICK_FILTER_LANCZOS, _IMG_IMAGICK_QUALITE / 100);
+               $imagick->writeImage($vignette);
 
+               if (!@file_exists($vignette)) {
+                       spip_log("echec imagick sur $vignette");
+
+                       return;
+               }
+       } // netpbm
+       elseif ($process == "netpbm") {
+               if (!defined('_PNMSCALE_COMMAND')) {
+                       define('_PNMSCALE_COMMAND', 'pnmscale');
+               } // Securite : mes_options.php peut preciser le chemin absolu
+               if (_PNMSCALE_COMMAND == '') {
+                       return;
+               }
+               $vignette = $destination . "." . $format_sortie;
+               $pnmtojpeg_command = str_replace("pnmscale", "pnmtojpeg", _PNMSCALE_COMMAND);
+               if ($format == "jpg") {
+
+                       $jpegtopnm_command = str_replace("pnmscale", "jpegtopnm", _PNMSCALE_COMMAND);
+                       exec("$jpegtopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
+                       if (!($s = @filesize($vignette))) {
+                               spip_unlink($vignette);
+                       }
                        if (!@file_exists($vignette)) {
-                               spip_log("echec imagick sur $vignette");
+                               spip_log("echec netpbm-jpg sur $vignette");
+
                                return;
                        }
-               }
-               else
-               // netpbm
-               if ($process == "netpbm") {
-                       define('_PNMSCALE_COMMAND', 'pnmscale'); // chemin a changer dans mes_options
-                       if (_PNMSCALE_COMMAND == '') return;
-                       $vignette = $destination.".".$format_sortie;
-                       $pnmtojpeg_command = str_replace("pnmscale", "pnmtojpeg", _PNMSCALE_COMMAND);
-                       if ($format == "jpg") {
-                               
-                               $jpegtopnm_command = str_replace("pnmscale", "jpegtopnm", _PNMSCALE_COMMAND);
-                               exec("$jpegtopnm_command $image | "._PNMSCALE_COMMAND." -width $destWidth | $pnmtojpeg_command > $vignette");
-                               if (!($s = @filesize($vignette)))
-                                       spip_unlink($vignette);
-                               if (!@file_exists($vignette)) {
-                                       spip_log("echec netpbm-jpg sur $vignette");
-                                       return;
-                               }
-                       } else if ($format == "gif") {
+               } else {
+                       if ($format == "gif") {
                                $giftopnm_command = str_replace("pnmscale", "giftopnm", _PNMSCALE_COMMAND);
-                               exec("$giftopnm_command $image | "._PNMSCALE_COMMAND." -width $destWidth | $pnmtojpeg_command > $vignette");
-                               if (!($s = @filesize($vignette)))
+                               exec("$giftopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
+                               if (!($s = @filesize($vignette))) {
                                        spip_unlink($vignette);
+                               }
                                if (!@file_exists($vignette)) {
                                        spip_log("echec netpbm-gif sur $vignette");
+
                                        return;
                                }
-                       } else if ($format == "png") {
-                               $pngtopnm_command = str_replace("pnmscale", "pngtopnm", _PNMSCALE_COMMAND);
-                               exec("$pngtopnm_command $image | "._PNMSCALE_COMMAND." -width $destWidth | $pnmtojpeg_command > $vignette");
-                               if (!($s = @filesize($vignette)))
-                                       spip_unlink($vignette);
-                               if (!@file_exists($vignette)) {
-                                       spip_log("echec netpbm-png sur $vignette");
-                                       return;
+                       } else {
+                               if ($format == "png") {
+                                       $pngtopnm_command = str_replace("pnmscale", "pngtopnm", _PNMSCALE_COMMAND);
+                                       exec("$pngtopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
+                                       if (!($s = @filesize($vignette))) {
+                                               spip_unlink($vignette);
+                                       }
+                                       if (!@file_exists($vignette)) {
+                                               spip_log("echec netpbm-png sur $vignette");
+
+                                               return;
+                                       }
                                }
                        }
                }
-               // gd ou gd2
-               else if ($process == 'gd1' OR $process == 'gd2') {
-                       if (_IMG_GD_MAX_PIXELS && $srcWidth*$srcHeight>_IMG_GD_MAX_PIXELS){
-                               spip_log("vignette gd1/gd2 impossible : ".$srcWidth*$srcHeight."pixels");
-                               return;
-                       }
-                       $destFormat = $format_sortie;
-                       if (!$destFormat) {
-                               spip_log("pas de format pour $image");
-                               return;
-                       }
+       } // gd ou gd2
+       elseif ($process == 'gd1' or $process == 'gd2') {
+               if (!function_exists('gd_info')) {
+                       spip_log("Librairie GD absente !", _LOG_ERREUR);
 
-                       $fonction_imagecreatefrom = $valeurs['fonction_imagecreatefrom'];
-                       if (!function_exists($fonction_imagecreatefrom))
-                               return '';
-                       $srcImage = @$fonction_imagecreatefrom($image);
-                       if (!$srcImage) { 
-                               spip_log("echec gd1/gd2"); 
-                               return; 
-                       } 
-
-                       // Initialisation de l'image destination 
-                               if ($process == 'gd2' AND $destFormat != "gif") 
-                               $destImage = ImageCreateTrueColor($destWidth, $destHeight); 
-                       if (!$destImage) 
-                               $destImage = ImageCreate($destWidth, $destHeight); 
-
-                       // Recopie de l'image d'origine avec adaptation de la taille 
-                       $ok = false; 
-                       if (($process == 'gd2') AND function_exists('ImageCopyResampled')) { 
-                               if ($format == "gif") { 
-                                       // Si un GIF est transparent, 
-                                       // fabriquer un PNG transparent  
-                                       $transp = imagecolortransparent($srcImage); 
-                                       if ($transp > 0) $destFormat = "png"; 
+                       return;
+               }
+               if (_IMG_GD_MAX_PIXELS && $srcWidth * $srcHeight > _IMG_GD_MAX_PIXELS) {
+                       spip_log("vignette gd1/gd2 impossible : " . $srcWidth * $srcHeight . "pixels");
+
+                       return;
+               }
+               $destFormat = $format_sortie;
+               if (!$destFormat) {
+                       spip_log("pas de format pour $image");
+
+                       return;
+               }
+
+               $fonction_imagecreatefrom = $valeurs['fonction_imagecreatefrom'];
+               if (!function_exists($fonction_imagecreatefrom)) {
+                       return '';
+               }
+               $srcImage = @$fonction_imagecreatefrom($image);
+               if (!$srcImage) {
+                       spip_log("echec gd1/gd2");
+
+                       return;
+               }
+
+               // Initialisation de l'image destination
+               $destImage = null;
+               if ($process == 'gd2' and $destFormat != "gif") {
+                       $destImage = ImageCreateTrueColor($destWidth, $destHeight);
+               }
+               if (!$destImage) {
+                       $destImage = ImageCreate($destWidth, $destHeight);
+               }
+
+               // Recopie de l'image d'origine avec adaptation de la taille 
+               $ok = false;
+               if (($process == 'gd2') and function_exists('ImageCopyResampled')) {
+                       if ($format == "gif") {
+                               // Si un GIF est transparent, 
+                               // fabriquer un PNG transparent  
+                               $transp = imagecolortransparent($srcImage);
+                               if ($transp > 0) {
+                                       $destFormat = "png";
                                }
-                               if ($destFormat == "png") { 
-                                       // Conserver la transparence 
-                                       if (function_exists("imageAntiAlias")) imageAntiAlias($destImage,true); 
-                                       @imagealphablending($destImage, false); 
-                                       @imagesavealpha($destImage,true); 
+                       }
+                       if ($destFormat == "png") {
+                               // Conserver la transparence 
+                               if (function_exists("imageAntiAlias")) {
+                                       imageAntiAlias($destImage, true);
                                }
-                               $ok = @ImageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
+                               @imagealphablending($destImage, false);
+                               @imagesavealpha($destImage, true);
                        }
-                       if (!$ok)
-                               $ok = ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
+                       $ok = @ImageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
+               }
+               if (!$ok) {
+                       $ok = ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
+               }
 
-                       // Sauvegarde de l'image destination
-                       $valeurs['fichier_dest'] = $vignette = "$destination.$destFormat";
-                       $valeurs['format_dest'] = $format = $destFormat;
-                       _image_gd_output($destImage,$valeurs);
+               // Sauvegarde de l'image destination
+               $valeurs['fichier_dest'] = $vignette = "$destination.$destFormat";
+               $valeurs['format_dest'] = $format = $destFormat;
+               _image_gd_output($destImage, $valeurs);
 
-                       if ($srcImage)
-                               ImageDestroy($srcImage);
-                       ImageDestroy($destImage);
+               if ($srcImage) {
+                       ImageDestroy($srcImage);
                }
+               ImageDestroy($destImage);
        }
+
        $size = @getimagesize($vignette);
        // Gaffe: en safe mode, pas d'acces a la vignette,
        // donc risque de balancer "width='0'", ce qui masque l'image sous MSIE
-       if ($size[0] < 1) $size[0] = $destWidth;
-       if ($size[1] < 1) $size[1] = $destHeight;
-       
+       if ($size[0] < 1) {
+               $size[0] = $destWidth;
+       }
+       if ($size[1] < 1) {
+               $size[1] = $destHeight;
+       }
+
        $retour['width'] = $largeur = $size[0];
        $retour['height'] = $hauteur = $size[1];
-       
+
        $retour['fichier'] = $vignette;
        $retour['format'] = $format;
        $retour['date'] = @filemtime($vignette);
-       
+
        // renvoyer l'image
        return $retour;
 }
 
-// Calculer le ratio
-// http://doc.spip.org/@image_ratio
-function _image_ratio ($srcWidth, $srcHeight, $maxWidth, $maxHeight) {
-       $ratioWidth = $srcWidth/$maxWidth;
-       $ratioHeight = $srcHeight/$maxHeight;
-       
-       if ($ratioWidth <=1 AND $ratioHeight <=1) {
+/**
+ * Réduire des dimensions en respectant un ratio
+ *
+ * Réduit des dimensions (hauteur, largeur) pour qu'elles
+ * soient incluses dans une hauteur et largeur maximum fournies
+ * en respectant la proportion d'origine
+ *
+ * @example `image_ratio(1000, 1000, 100, 10)` donne `array(10, 10, 100)`
+ * @see ratio_passe_partout() Assez proche.
+ *
+ * @param int $srcWidth Largeur de l'image source
+ * @param int $srcHeight Hauteur de l'image source
+ * @param int $maxWidth Largeur maximum souhaitée
+ * @param int $maxHeight Hauteur maximum souhaitée
+ * @return array Liste [ largeur, hauteur, ratio de réduction ]
+ **/
+function _image_ratio($srcWidth, $srcHeight, $maxWidth, $maxHeight) {
+       $ratioWidth = $srcWidth / $maxWidth;
+       $ratioHeight = $srcHeight / $maxHeight;
+
+       if ($ratioWidth <= 1 and $ratioHeight <= 1) {
                $destWidth = $srcWidth;
                $destHeight = $srcHeight;
-       } else if ($ratioWidth < $ratioHeight) {
-               $destWidth = $srcWidth/$ratioHeight;
+       } elseif ($ratioWidth < $ratioHeight) {
+               $destWidth = $srcWidth / $ratioHeight;
                $destHeight = $maxHeight;
-       }
-       else {
+       } else {
                $destWidth = $maxWidth;
-               $destHeight = $srcHeight/$ratioWidth;
+               $destHeight = $srcHeight / $ratioWidth;
        }
-       return array (ceil($destWidth), ceil($destHeight),
-               max($ratioWidth,$ratioHeight));
+
+       return array(
+               ceil($destWidth),
+               ceil($destHeight),
+               max($ratioWidth, $ratioHeight)
+       );
 }
 
-// Calculer le ratio ajuste sur la plus petite dimension
-// http://doc.spip.org/@ratio_passe_partout
-function ratio_passe_partout ($srcWidth, $srcHeight, $maxWidth, $maxHeight) {
-       $ratioWidth = $srcWidth/$maxWidth;
-       $ratioHeight = $srcHeight/$maxHeight;
+/**
+ * Réduire des dimensions en respectant un ratio sur la plus petite dimension
+ *
+ * Réduit des dimensions (hauteur, largeur) pour qu'elles
+ * soient incluses dans la plus grande hauteur ou largeur maximum fournie
+ * en respectant la proportion d'origine
+ *
+ * @example `ratio_passe_partout(1000, 1000, 100, 10)` donne `array(100, 100, 10)`
+ * @see _image_ratio() Assez proche.
+ *
+ * @param int $srcWidth Largeur de l'image source
+ * @param int $srcHeight Hauteur de l'image source
+ * @param int $maxWidth Largeur maximum souhaitée
+ * @param int $maxHeight Hauteur maximum souhaitée
+ * @return array Liste [ largeur, hauteur, ratio de réduction ]
+ **/
+function ratio_passe_partout($srcWidth, $srcHeight, $maxWidth, $maxHeight) {
+       $ratioWidth = $srcWidth / $maxWidth;
+       $ratioHeight = $srcHeight / $maxHeight;
 
-       if ($ratioWidth <=1 AND $ratioHeight <=1) {
+       if ($ratioWidth <= 1 and $ratioHeight <= 1) {
                $destWidth = $srcWidth;
                $destHeight = $srcHeight;
-       } else if ($ratioWidth > $ratioHeight) {
-               $destWidth = $srcWidth/$ratioHeight;
+       } elseif ($ratioWidth > $ratioHeight) {
+               $destWidth = $srcWidth / $ratioHeight;
                $destHeight = $maxHeight;
-       }
-       else {
+       } else {
                $destWidth = $maxWidth;
-               $destHeight = $srcHeight/$ratioWidth;
+               $destHeight = $srcHeight / $ratioWidth;
        }
-       return array (ceil($destWidth), ceil($destHeight),
-               min($ratioWidth,$ratioHeight));
+
+       return array(
+               ceil($destWidth),
+               ceil($destHeight),
+               min($ratioWidth, $ratioHeight)
+       );
 }
 
-// http://doc.spip.org/@process_image_reduire
-function process_image_reduire($fonction,$img,$taille,$taille_y,$force,$cherche_image,$process){
+
+/**
+ * Réduit une image
+ *
+ * @uses extraire_attribut()
+ * @uses inserer_attribut()
+ * @uses _image_valeurs_trans()
+ * @uses _image_ratio()
+ * @uses _image_tag_changer_taille()
+ * @uses _image_ecrire_tag()
+ * @uses _image_creer_vignette()
+ *
+ * @param array $fonction
+ *     Un tableau à 2 éléments :
+ *     1) string : indique le nom du filtre de traitement demandé (par exemple : `image_reduire`) ;
+ *     2) array : tableau reprenant la valeur de `$img` et chacun des arguments passés au filtre utilisé.
+ * @param string $img
+ *     Chemin de l'image ou texte contenant une balise img
+ * @param int $taille
+ *     Largeur désirée
+ * @param int $taille_y
+ *     Hauteur désirée
+ * @param bool $force
+ * @param string $process
+ *     Librairie graphique à utiliser (gd1, gd2, netpbm, convert, imagick).
+ *     AUTO utilise la librairie sélectionnée dans la configuration.
+ * @return string
+ *     Code HTML de la balise img produite
+ **/
+function process_image_reduire($fonction, $img, $taille, $taille_y, $force, $process = 'AUTO') {
        $image = false;
-       if (($process == 'AUTO') AND isset($GLOBALS['meta']['image_process']))
+       if (($process == 'AUTO') and isset($GLOBALS['meta']['image_process'])) {
                $process = $GLOBALS['meta']['image_process'];
+       }
        # determiner le format de sortie
        $format_sortie = false; // le choix par defaut sera bon
-       if ($process == "netpbm") $format_sortie = "jpg";
-       else if ($process == 'gd1' OR $process == 'gd2') {
-               $image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}",$format_sortie,$fonction);
+       if ($process == "netpbm") {
+               $format_sortie = "jpg";
+       } elseif ($process == 'gd1' or $process == 'gd2') {
+               $image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}", $format_sortie, $fonction);
 
                // on verifie que l'extension choisie est bonne (en principe oui)
-               $gd_formats = explode(',',$GLOBALS['meta']["gd_formats"]);
-               if (!in_array($image['format_dest'],$gd_formats)
-                 OR ($image['format_dest']=='gif' AND !function_exists('ImageGif'))
-                 ) {
-                       if ($image['format_source'] == 'jpg')
-                               $formats_sortie = array('jpg','png','gif');
-                       else // les gif sont passes en png preferentiellement pour etre homogene aux autres filtres images
-                               $formats_sortie = array('png','jpg','gif');
+               $gd_formats = explode(',', $GLOBALS['meta']["gd_formats"]);
+               if (is_array($image)
+                       and (!in_array($image['format_dest'], $gd_formats)
+                               or ($image['format_dest'] == 'gif' and !function_exists('ImageGif'))
+                       )
+               ) {
+                       if ($image['format_source'] == 'jpg') {
+                               $formats_sortie = array('jpg', 'png', 'gif');
+                       } else // les gif sont passes en png preferentiellement pour etre homogene aux autres filtres images
+                       {
+                               $formats_sortie = array('png', 'jpg', 'gif');
+                       }
                        // Choisir le format destination
                        // - on sauve de preference en JPEG (meilleure compression)
                        // - pour le GIF : les GD recentes peuvent le lire mais pas l'ecrire
@@ -970,8 +1292,9 @@ function process_image_reduire($fonction,$img,$taille,$taille_y,$force,$cherche_
                        $format_sortie = "";
                        foreach ($formats_sortie as $fmt) {
                                if (in_array($fmt, $gd_formats)) {
-                                       if ($fmt <> "gif" OR function_exists('ImageGif'))
+                                       if ($fmt <> "gif" or function_exists('ImageGif')) {
                                                $format_sortie = $fmt;
+                                       }
                                        break;
                                }
                        }
@@ -979,16 +1302,19 @@ function process_image_reduire($fonction,$img,$taille,$taille_y,$force,$cherche_
                }
        }
 
-       if (!$image)
-               $image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}",$format_sortie,$fonction);
+       if (!is_array($image)) {
+               $image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}", $format_sortie, $fonction);
+       }
 
-       if (!$image OR !$image['largeur'] OR !$image['hauteur']){
+       if (!is_array($image) or !$image['largeur'] or !$image['hauteur']) {
                spip_log("image_reduire_src:pas de version locale de $img");
                // on peut resizer en mode html si on dispose des elements
                if ($srcw = extraire_attribut($img, 'width')
-               AND $srch = extraire_attribut($img, 'height')) {
-                       list($w,$h) = _image_ratio($srcw, $srch, $taille, $taille_y);
-                       return _image_tag_changer_taille($img,$w,$h);
+                       and $srch = extraire_attribut($img, 'height')
+               ) {
+                       list($w, $h) = _image_ratio($srcw, $srch, $taille, $taille_y);
+
+                       return _image_tag_changer_taille($img, $w, $h);
                }
                // la on n'a pas d'infos sur l'image source... on refile le truc a css
                // sous la forme style='max-width: NNpx;'
@@ -997,22 +1323,25 @@ function process_image_reduire($fonction,$img,$taille,$taille_y,$force,$cherche_
        }
 
        // si l'image est plus petite que la cible retourner une copie cachee de l'image
-       if (($image['largeur']<=$taille)&&($image['hauteur']<=$taille_y)){
-               if ($image['creer']){
+       if (($image['largeur'] <= $taille) && ($image['hauteur'] <= $taille_y)) {
+               if ($image['creer']) {
                        @copy($image['fichier'], $image['fichier_dest']);
                }
-               return _image_ecrire_tag($image,array('src'=>$image['fichier_dest']));
+
+               return _image_ecrire_tag($image, array('src' => $image['fichier_dest']));
        }
 
-       if ($image['creer']==false && !$force)
-               return _image_ecrire_tag($image,array('src'=>$image['fichier_dest'],'width'=>$image['largeur_dest'],'height'=>$image['hauteur_dest']));
+       if ($image['creer'] == false && !$force) {
+               return _image_ecrire_tag($image,
+                       array('src' => $image['fichier_dest'], 'width' => $image['largeur_dest'], 'height' => $image['hauteur_dest']));
+       }
 
-       if (in_array($image["format_source"],array('jpg','gif','png'))){
+       if (in_array($image["format_source"], array('jpg', 'gif', 'png'))) {
                $destWidth = $image['largeur_dest'];
                $destHeight = $image['hauteur_dest'];
                $logo = $image['fichier'];
                $date = $image["date_src"];
-               $preview = _image_creer_vignette($image, $taille, $taille_y,$process,$force);
+               $preview = _image_creer_vignette($image, $taille, $taille_y, $process, $force);
 
                if ($preview && $preview['fichier']) {
                        $logo = $preview['fichier'];
@@ -1024,25 +1353,30 @@ function process_image_reduire($fonction,$img,$taille,$taille_y,$force,$cherche_
                // de l'image, de facon a tromper le cache du navigateur
                // quand on fait supprimer/reuploader un logo
                // (pas de filemtime si SAFE MODE)
-               $date = test_espace_prive() ? ('?'.$date) : '';
-               return _image_ecrire_tag($image,array('src'=>"$logo$date",'width'=>$destWidth,'height'=>$destHeight));
-       }
-       else
-               # SVG par exemple ? BMP, tiff ... les redacteurs osent tout!
+               $date = test_espace_prive() ? ('?' . $date) : '';
+
+               return _image_ecrire_tag($image, array('src' => "$logo$date", 'width' => $destWidth, 'height' => $destHeight));
+       } else # SVG par exemple ? BMP, tiff ... les redacteurs osent tout!
+       {
                return $img;
+       }
 }
 
 /**
  * Produire des fichiers au format .ico
- * avec du code recupere de :
- * phpThumb() by James Heinrich <info@silisoftware.com>
- * available at http://phpthumb.sourceforge.net
+ *
+ * Avec du code récupéré de phpThumb()
+ *
+ * @author James Heinrich <info@silisoftware.com>
+ * @link http://phpthumb.sourceforge.net
  *
  * Class phpthumb_functions
  */
 class phpthumb_functions {
 
        /**
+        * Retourne la couleur d'un pixel dans une image
+        *
         * @param ressource $img
         * @param int $x
         * @param int $y
@@ -1052,34 +1386,42 @@ class phpthumb_functions {
                if (!is_resource($img)) {
                        return false;
                }
+
                return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));
        }
 
        /**
+        * Retourne un nombre dans une représentation en Little Endian
+        *
         * @param int $number
         * @param int $minbytes
         * @return string
         */
-       public static function LittleEndian2String($number, $minbytes=1) {
+       public static function LittleEndian2String($number, $minbytes = 1) {
                $intstring = '';
                while ($number > 0) {
-                       $intstring = $intstring.chr($number & 255);
+                       $intstring = $intstring . chr($number & 255);
                        $number >>= 8;
                }
+
                return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
        }
 
        /**
+        * Transforme une ressource GD en image au format ICO
+        *
         * @param array $gd_image_array
+        *     Tableau de ressources d'images GD
         * @return string
+        *     Image au format ICO
         */
        public static function GD2ICOstring(&$gd_image_array) {
                foreach ($gd_image_array as $key => $gd_image) {
 
-                       $ImageWidths[$key]  = ImageSX($gd_image);
+                       $ImageWidths[$key] = ImageSX($gd_image);
                        $ImageHeights[$key] = ImageSY($gd_image);
-                       $bpp[$key]                = ImageIsTrueColor($gd_image) ? 32 : 24;
-                       $totalcolors[$key]  = ImageColorsTotal($gd_image);
+                       $bpp[$key] = ImageIsTrueColor($gd_image) ? 32 : 24;
+                       $totalcolors[$key] = ImageColorsTotal($gd_image);
 
                        $icXOR[$key] = '';
                        for ($y = $ImageHeights[$key] - 1; $y >= 0; $y--) {
@@ -1091,9 +1433,9 @@ class phpthumb_functions {
                                        $b = $argb['blue'];
 
                                        if ($bpp[$key] == 32) {
-                                               $icXOR[$key] .= chr($b).chr($g).chr($r).chr($a);
+                                               $icXOR[$key] .= chr($b) . chr($g) . chr($r) . chr($a);
                                        } elseif ($bpp[$key] == 24) {
-                                               $icXOR[$key] .= chr($b).chr($g).chr($r);
+                                               $icXOR[$key] .= chr($b) . chr($g) . chr($r);
                                        }
 
                                        if ($a < 128) {
@@ -1120,43 +1462,45 @@ class phpthumb_functions {
                        $biSizeImage = $ImageWidths[$key] * $ImageHeights[$key] * ($bpp[$key] / 8);
 
                        // BITMAPINFOHEADER - 40 bytes
-                       $BitmapInfoHeader[$key]  = '';
-                       $BitmapInfoHeader[$key] .= "\x28\x00\x00\x00";                                                    // DWORD  biSize;
-                       $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4);        // LONG   biWidth;
+                       $BitmapInfoHeader[$key] = '';
+                       $BitmapInfoHeader[$key] .= "\x28\x00\x00\x00";                // DWORD  biSize;
+                       $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4);    // LONG   biWidth;
                        // The biHeight member specifies the combined
                        // height of the XOR and AND masks.
                        $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG   biHeight;
-                       $BitmapInfoHeader[$key] .= "\x01\x00";                                                                    // WORD   biPlanes;
-                          $BitmapInfoHeader[$key] .= chr($bpp[$key])."\x00";                                             // wBitCount;
-                       $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                                                    // DWORD  biCompression;
-                       $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4);                    // DWORD  biSizeImage;
-                       $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                                                    // LONG   biXPelsPerMeter;
-                       $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                                                    // LONG   biYPelsPerMeter;
-                       $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                                                    // DWORD  biClrUsed;
-                       $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                                                    // DWORD  biClrImportant;
+                       $BitmapInfoHeader[$key] .= "\x01\x00";                    // WORD   biPlanes;
+                       $BitmapInfoHeader[$key] .= chr($bpp[$key]) . "\x00";              // wBitCount;
+                       $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biCompression;
+                       $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4);      // DWORD  biSizeImage;
+                       $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // LONG   biXPelsPerMeter;
+                       $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // LONG   biYPelsPerMeter;
+                       $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biClrUsed;
+                       $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biClrImportant;
                }
 
 
-               $icondata  = "\x00\x00";                                                                          // idReserved;   // Reserved (must be 0)
-               $icondata .= "\x01\x00";                                                                          // idType;       // Resource Type (1 for icons)
+               $icondata = "\x00\x00";                    // idReserved;   // Reserved (must be 0)
+               $icondata .= "\x01\x00";                    // idType;     // Resource Type (1 for icons)
                $icondata .= phpthumb_functions::LittleEndian2String(count($gd_image_array), 2);  // idCount;     // How many images?
 
                $dwImageOffset = 6 + (count($gd_image_array) * 16);
                foreach ($gd_image_array as $key => $gd_image) {
                        // ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
 
-                       $icondata .= chr($ImageWidths[$key]);                                    // bWidth;               // Width, in pixels, of the image
-                       $icondata .= chr($ImageHeights[$key]);                                  // bHeight;              // Height, in pixels, of the image
-                       $icondata .= chr($totalcolors[$key]);                                    // bColorCount;         // Number of colors in image (0 if >=8bpp)
-                       $icondata .= "\x00";                                                                      // bReserved;    // Reserved ( must be 0)
+                       $icondata .= chr($ImageWidths[$key]);           // bWidth;                // Width, in pixels, of the image
+                       $icondata .= chr($ImageHeights[$key]);          // bHeight;              // Height, in pixels, of the image
+                       $icondata .= chr($totalcolors[$key]);           // bColorCount;  // Number of colors in image (0 if >=8bpp)
+                       $icondata .= "\x00";                    // bReserved;      // Reserved ( must be 0)
 
-                       $icondata .= "\x01\x00";                                                                  // wPlanes;            // Color Planes
-                       $icondata .= chr($bpp[$key])."\x00";                                      // wBitCount;    // Bits per pixel
+                       $icondata .= "\x01\x00";                  // wPlanes;            // Color Planes
+                       $icondata .= chr($bpp[$key]) . "\x00";            // wBitCount;    // Bits per pixel
 
                        $dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);
-                       $icondata .= phpthumb_functions::LittleEndian2String($dwBytesInRes, 4);    // dwBytesInRes;     // How many bytes in this resource?
+                       $icondata .= phpthumb_functions::LittleEndian2String($dwBytesInRes,
+                               4);     // dwBytesInRes;        // How many bytes in this resource?
 
-                       $icondata .= phpthumb_functions::LittleEndian2String($dwImageOffset, 4);          // dwImageOffset;   // Where in the file is this image?
+                       $icondata .= phpthumb_functions::LittleEndian2String($dwImageOffset,
+                               4);    // dwImageOffset;   // Where in the file is this image?
                        $dwImageOffset += strlen($BitmapInfoHeader[$key]);
                        $dwImageOffset += strlen($icXOR[$key]);
                        $dwImageOffset += strlen($icAND[$key]);
@@ -1172,5 +1516,3 @@ class phpthumb_functions {
        }
 
 }
-
-?>