Completed
Push — master ( 9310cf...4ccf90 )
by cam
01:23
created
ecrire/inc/filtres_images_lib_mini.php 1 patch
Indentation   +1342 added lines, -1342 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
  */
19 19
 
20 20
 if (!defined('_ECRIRE_INC_VERSION')) {
21
-	return;
21
+    return;
22 22
 }
23 23
 include_spip('inc/filtres'); // par precaution
24 24
 include_spip('inc/filtres_images_mini'); // par precaution
@@ -38,21 +38,21 @@  discard block
 block discarded – undo
38 38
  *     Le code de la couleur en hexadécimal.
39 39
  */
40 40
 function _couleur_dec_to_hex($red, $green, $blue) {
41
-	$red = dechex($red);
42
-	$green = dechex($green);
43
-	$blue = dechex($blue);
44
-
45
-	if (strlen($red) == 1) {
46
-		$red = '0' . $red;
47
-	}
48
-	if (strlen($green) == 1) {
49
-		$green = '0' . $green;
50
-	}
51
-	if (strlen($blue) == 1) {
52
-		$blue = '0' . $blue;
53
-	}
54
-
55
-	return "$red$green$blue";
41
+    $red = dechex($red);
42
+    $green = dechex($green);
43
+    $blue = dechex($blue);
44
+
45
+    if (strlen($red) == 1) {
46
+        $red = '0' . $red;
47
+    }
48
+    if (strlen($green) == 1) {
49
+        $green = '0' . $green;
50
+    }
51
+    if (strlen($blue) == 1) {
52
+        $blue = '0' . $blue;
53
+    }
54
+
55
+    return "$red$green$blue";
56 56
 }
57 57
 
58 58
 /**
@@ -64,17 +64,17 @@  discard block
 block discarded – undo
64 64
  *     Un tableau des 3 éléments : rouge, vert, bleu.
65 65
  */
66 66
 function _couleur_hex_to_dec($couleur) {
67
-	$couleur = couleur_html_to_hex($couleur);
68
-	$couleur = ltrim($couleur, '#');
69
-	if (strlen($couleur) === 3) {
70
-		$couleur = $couleur[0] . $couleur[0] . $couleur[1] . $couleur[1] . $couleur[2] . $couleur[2];
71
-	}
72
-	$retour = [];
73
-	$retour['red'] = hexdec(substr($couleur, 0, 2));
74
-	$retour['green'] = hexdec(substr($couleur, 2, 2));
75
-	$retour['blue'] = hexdec(substr($couleur, 4, 2));
76
-
77
-	return $retour;
67
+    $couleur = couleur_html_to_hex($couleur);
68
+    $couleur = ltrim($couleur, '#');
69
+    if (strlen($couleur) === 3) {
70
+        $couleur = $couleur[0] . $couleur[0] . $couleur[1] . $couleur[1] . $couleur[2] . $couleur[2];
71
+    }
72
+    $retour = [];
73
+    $retour['red'] = hexdec(substr($couleur, 0, 2));
74
+    $retour['green'] = hexdec(substr($couleur, 2, 2));
75
+    $retour['blue'] = hexdec(substr($couleur, 4, 2));
76
+
77
+    return $retour;
78 78
 }
79 79
 
80 80
 
@@ -91,8 +91,8 @@  discard block
 block discarded – undo
91 91
  *     Le code de la couleur en hexadécimal.
92 92
  */
93 93
 function _couleur_hsl_to_hex($hue, $saturation, $lightness) {
94
-	$rgb = _couleur_hsl_to_rgb($hue, $saturation, $lightness);
95
-	return _couleur_dec_to_hex($rgb['r'], $rgb['g'], $rgb['b']);
94
+    $rgb = _couleur_hsl_to_rgb($hue, $saturation, $lightness);
95
+    return _couleur_dec_to_hex($rgb['r'], $rgb['g'], $rgb['b']);
96 96
 }
97 97
 
98 98
 /**
@@ -104,8 +104,8 @@  discard block
 block discarded – undo
104 104
  *     Un tableau des 3 éléments : teinte, saturation, luminosité.
105 105
  */
106 106
 function _couleur_hex_to_hsl($couleur) {
107
-	$rgb = _couleur_hex_to_dec($couleur);
108
-	return _couleur_rgb_to_hsl($rgb['red'], $rgb['green'], $rgb['blue']);
107
+    $rgb = _couleur_hex_to_dec($couleur);
108
+    return _couleur_rgb_to_hsl($rgb['red'], $rgb['green'], $rgb['blue']);
109 109
 }
110 110
 
111 111
 /**
@@ -120,58 +120,58 @@  discard block
 block discarded – undo
120 120
  * @return array
121 121
  */
122 122
 function _couleur_rgb_to_hsl($R, $G, $B) {
123
-	$var_R = ($R / 255); // Where RGB values = 0 ÷ 255
124
-	$var_G = ($G / 255);
125
-	$var_B = ($B / 255);
126
-
127
-	$var_Min = min($var_R, $var_G, $var_B);   //Min. value of RGB
128
-	$var_Max = max($var_R, $var_G, $var_B);   //Max. value of RGB
129
-	$del_Max = $var_Max - $var_Min;           //Delta RGB value
130
-
131
-	$L = ($var_Max + $var_Min) / 2;
132
-
133
-	if ($del_Max == 0) {
134
-		//This is a gray, no chroma...
135
-		$H = 0; //HSL results = 0 ÷ 1
136
-		$S = 0;
137
-	} else {
138
-		// Chromatic data...
139
-		if ($L < 0.5) {
140
-			$S = $del_Max / ($var_Max + $var_Min);
141
-		} else {
142
-			$S = $del_Max / (2 - $var_Max - $var_Min);
143
-		}
144
-
145
-		$del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max;
146
-		$del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max;
147
-		$del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max;
148
-
149
-		if ($var_R == $var_Max) {
150
-			$H = $del_B - $del_G;
151
-		} else {
152
-			if ($var_G == $var_Max) {
153
-				$H = (1 / 3) + $del_R - $del_B;
154
-			} else {
155
-				if ($var_B == $var_Max) {
156
-					$H = (2 / 3) + $del_G - $del_R;
157
-				}
158
-			}
159
-		}
160
-
161
-		if ($H < 0) {
162
-			$H += 1;
163
-		}
164
-		if ($H > 1) {
165
-			$H -= 1;
166
-		}
167
-	}
168
-
169
-	$ret = [];
170
-	$ret['h'] = $H;
171
-	$ret['s'] = $S;
172
-	$ret['l'] = $L;
173
-
174
-	return $ret;
123
+    $var_R = ($R / 255); // Where RGB values = 0 ÷ 255
124
+    $var_G = ($G / 255);
125
+    $var_B = ($B / 255);
126
+
127
+    $var_Min = min($var_R, $var_G, $var_B);   //Min. value of RGB
128
+    $var_Max = max($var_R, $var_G, $var_B);   //Max. value of RGB
129
+    $del_Max = $var_Max - $var_Min;           //Delta RGB value
130
+
131
+    $L = ($var_Max + $var_Min) / 2;
132
+
133
+    if ($del_Max == 0) {
134
+        //This is a gray, no chroma...
135
+        $H = 0; //HSL results = 0 ÷ 1
136
+        $S = 0;
137
+    } else {
138
+        // Chromatic data...
139
+        if ($L < 0.5) {
140
+            $S = $del_Max / ($var_Max + $var_Min);
141
+        } else {
142
+            $S = $del_Max / (2 - $var_Max - $var_Min);
143
+        }
144
+
145
+        $del_R = ((($var_Max - $var_R) / 6) + ($del_Max / 2)) / $del_Max;
146
+        $del_G = ((($var_Max - $var_G) / 6) + ($del_Max / 2)) / $del_Max;
147
+        $del_B = ((($var_Max - $var_B) / 6) + ($del_Max / 2)) / $del_Max;
148
+
149
+        if ($var_R == $var_Max) {
150
+            $H = $del_B - $del_G;
151
+        } else {
152
+            if ($var_G == $var_Max) {
153
+                $H = (1 / 3) + $del_R - $del_B;
154
+            } else {
155
+                if ($var_B == $var_Max) {
156
+                    $H = (2 / 3) + $del_G - $del_R;
157
+                }
158
+            }
159
+        }
160
+
161
+        if ($H < 0) {
162
+            $H += 1;
163
+        }
164
+        if ($H > 1) {
165
+            $H -= 1;
166
+        }
167
+    }
168
+
169
+    $ret = [];
170
+    $ret['h'] = $H;
171
+    $ret['s'] = $S;
172
+    $ret['l'] = $L;
173
+
174
+    return $ret;
175 175
 }
176 176
 
177 177
 
@@ -187,52 +187,52 @@  discard block
 block discarded – undo
187 187
  * @return array
188 188
  */
189 189
 function _couleur_hsl_to_rgb($H, $S, $L) {
190
-	// helper
191
-	$hue_2_rgb = function ($v1, $v2, $vH) {
192
-		if ($vH < 0) {
193
-			$vH += 1;
194
-		}
195
-		if ($vH > 1) {
196
-			$vH -= 1;
197
-		}
198
-		if ((6 * $vH) < 1) {
199
-			return ($v1 + ($v2 - $v1) * 6 * $vH);
200
-		}
201
-		if ((2 * $vH) < 1) {
202
-			return ($v2);
203
-		}
204
-		if ((3 * $vH) < 2) {
205
-			return ($v1 + ($v2 - $v1) * ((2 / 3) - $vH) * 6);
206
-		}
207
-
208
-		return ($v1);
209
-	};
210
-
211
-	if ($S == 0) {
212
-		// HSV values = 0 -> 1
213
-		$R = $L * 255;
214
-		$G = $L * 255;
215
-		$B = $L * 255;
216
-	} else {
217
-		if ($L < 0.5) {
218
-			$var_2 = $L * (1 + $S);
219
-		} else {
220
-			$var_2 = ($L + $S) - ($S * $L);
221
-		}
222
-
223
-		$var_1 = 2 * $L - $var_2;
224
-
225
-		$R = 255 * $hue_2_rgb($var_1, $var_2, $H + (1 / 3));
226
-		$G = 255 * $hue_2_rgb($var_1, $var_2, $H);
227
-		$B = 255 * $hue_2_rgb($var_1, $var_2, $H - (1 / 3));
228
-	}
229
-
230
-	$ret = [];
231
-	$ret['r'] = floor($R);
232
-	$ret['g'] = floor($G);
233
-	$ret['b'] = floor($B);
234
-
235
-	return $ret;
190
+    // helper
191
+    $hue_2_rgb = function ($v1, $v2, $vH) {
192
+        if ($vH < 0) {
193
+            $vH += 1;
194
+        }
195
+        if ($vH > 1) {
196
+            $vH -= 1;
197
+        }
198
+        if ((6 * $vH) < 1) {
199
+            return ($v1 + ($v2 - $v1) * 6 * $vH);
200
+        }
201
+        if ((2 * $vH) < 1) {
202
+            return ($v2);
203
+        }
204
+        if ((3 * $vH) < 2) {
205
+            return ($v1 + ($v2 - $v1) * ((2 / 3) - $vH) * 6);
206
+        }
207
+
208
+        return ($v1);
209
+    };
210
+
211
+    if ($S == 0) {
212
+        // HSV values = 0 -> 1
213
+        $R = $L * 255;
214
+        $G = $L * 255;
215
+        $B = $L * 255;
216
+    } else {
217
+        if ($L < 0.5) {
218
+            $var_2 = $L * (1 + $S);
219
+        } else {
220
+            $var_2 = ($L + $S) - ($S * $L);
221
+        }
222
+
223
+        $var_1 = 2 * $L - $var_2;
224
+
225
+        $R = 255 * $hue_2_rgb($var_1, $var_2, $H + (1 / 3));
226
+        $G = 255 * $hue_2_rgb($var_1, $var_2, $H);
227
+        $B = 255 * $hue_2_rgb($var_1, $var_2, $H - (1 / 3));
228
+    }
229
+
230
+    $ret = [];
231
+    $ret['r'] = floor($R);
232
+    $ret['g'] = floor($G);
233
+    $ret['b'] = floor($B);
234
+
235
+    return $ret;
236 236
 }
237 237
 
238 238
 /**
@@ -249,11 +249,11 @@  discard block
 block discarded – undo
249 249
  *     true si il faut supprimer le fichier temporaire ; false sinon.
250 250
  */
251 251
 function statut_effacer_images_temporaires($stat) {
252
-	static $statut = false; // par defaut on grave toute les images
253
-	if ($stat === 'get') {
254
-		return $statut;
255
-	}
256
-	$statut = $stat ? true : false;
252
+    static $statut = false; // par defaut on grave toute les images
253
+    if ($stat === 'get') {
254
+        return $statut;
255
+    }
256
+    $statut = $stat ? true : false;
257 257
 }
258 258
 
259 259
 
@@ -306,239 +306,239 @@  discard block
 block discarded – undo
306 306
  *     - array : tableau décrivant de l'image
307 307
  */
308 308
 function _image_valeurs_trans($img, $effet, $forcer_format = false, $fonction_creation = null, $find_in_path = false, $support_svg = false) {
309
-	static $images_recalcul = [];
310
-	if (strlen($img) == 0) {
311
-		return false;
312
-	}
313
-
314
-	$source = trim(extraire_attribut($img, 'src'));
315
-	if (strlen($source) < 1) {
316
-		$source = $img;
317
-		$img = "<img src='$source' />";
318
-	} # gerer img src="data:....base64"
319
-	elseif (
320
-		preg_match('@^data:image/([^;]*);base64,(.*)$@isS', $source, $regs)
321
-		and $extension = _image_trouver_extension_depuis_mime('image/' . $regs[1])
322
-		and in_array($extension, _image_extensions_acceptees_en_entree())
323
-	) {
324
-		$local = sous_repertoire(_DIR_VAR, 'image-data') . md5($regs[2]) . '.' . _image_extension_normalisee($extension);
325
-		if (!file_exists($local)) {
326
-			ecrire_fichier($local, base64_decode($regs[2]));
327
-		}
328
-		if ($sanitizer = charger_fonction($extension, 'sanitizer', true)) {
329
-			$sanitizer($local);
330
-		}
331
-		$source = $local;
332
-		$img = inserer_attribut($img, 'src', $source);
333
-		# eviter les mauvaises surprises lors de conversions de format
334
-		$img = inserer_attribut($img, 'width', '');
335
-		$img = inserer_attribut($img, 'height', '');
336
-	}
337
-
338
-	// les protocoles web prennent au moins 3 lettres
339
-	if (tester_url_absolue($source)) {
340
-		include_spip('inc/distant');
341
-		$fichier = _DIR_RACINE . copie_locale($source);
342
-		if (!$fichier) {
343
-			return '';
344
-		}
345
-		if ($extension = _image_trouver_extension($fichier)
346
-		  and $sanitizer = charger_fonction($extension, 'sanitizer', true)) {
347
-			$sanitizer($fichier);
348
-		}
349
-	} else {
350
-		// enlever le timestamp eventuel
351
-		if (strpos($source, '?') !== false) {
352
-			$source = preg_replace(',[?][0-9]+$,', '', $source);
353
-		}
354
-		if (
355
-			strpos($source, '?') !== false
356
-			and strncmp($source, _DIR_IMG, strlen(_DIR_IMG)) == 0
357
-			and file_exists($f = preg_replace(',[?].*$,', '', $source))
358
-		) {
359
-			$source = $f;
360
-		}
361
-		$fichier = $source;
362
-	}
363
-
364
-	$terminaison_dest = '';
365
-	if ($terminaison = _image_trouver_extension($fichier)) {
366
-		$terminaison_dest = ($terminaison == 'gif') ? 'png' : $terminaison;
367
-	}
368
-
369
-	if (
370
-		$forcer_format !== false
371
-		// ignorer forcer_format si on a une image svg, que le filtre appelant ne supporte pas SVG, et que le forcage est un autre format image
372
-		and ($terminaison_dest !== 'svg' or $support_svg or !in_array($forcer_format, _image_extensions_acceptees_en_sortie()))
373
-	) {
374
-		$terminaison_dest = $forcer_format;
375
-	}
376
-
377
-	if (!$terminaison_dest) {
378
-		return false;
379
-	}
380
-
381
-	$nom_fichier = substr($fichier, 0, strlen($fichier) - (strlen($terminaison) + 1));
382
-	$fichier_dest = $nom_fichier;
383
-	if (
384
-		($find_in_path and $f = find_in_path($fichier) and $fichier = $f)
385
-		or @file_exists($f = $fichier)
386
-	) {
387
-		// on passe la balise img a taille image qui exraira les attributs si possible
388
-		// au lieu de faire un acces disque sur le fichier
389
-		list($ret['hauteur'], $ret['largeur']) = taille_image($find_in_path ? $f : $img);
390
-		$date_src = @filemtime($f);
391
-	} elseif (
392
-		@file_exists($f = "$fichier.src")
393
-		and lire_fichier($f, $valeurs)
394
-		and $valeurs = unserialize($valeurs)
395
-		and isset($valeurs['hauteur_dest'])
396
-		and isset($valeurs['largeur_dest'])
397
-	) {
398
-		$ret['hauteur'] = $valeurs['hauteur_dest'];
399
-		$ret['largeur'] = $valeurs['largeur_dest'];
400
-		$date_src = $valeurs['date'];
401
-	} // pas de fichier source par la
402
-	else {
403
-		return false;
404
-	}
405
-
406
-	// pas de taille mesurable
407
-	if (!($ret['hauteur'] or $ret['largeur'])) {
408
-		return false;
409
-	}
410
-
411
-	// les images calculees dependent du chemin du fichier source
412
-	// 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
413
-	// ce n'est pas totalement optimal en terme de stockage, mais chaque image est associee a un fichier .src
414
-	// qui contient la methode de reconstrucion (le filtre + les arguments d'appel) et les arguments different entre prive et public
415
-	// la mise en commun du fichier image cree donc un bug et des problemes qui necessiteraient beaucoup de complexite de code
416
-	// alors que ca concerne peu de site au final
417
-	// la release de r23632+r23633+r23634 a provoque peu de remontee de bug attestant du peu de sites impactes
418
-	$identifiant = $fichier;
419
-
420
-	// cas general :
421
-	// on a un dossier cache commun et un nom de fichier qui varie avec l'effet
422
-	// cas particulier de reduire :
423
-	// un cache par dimension, et le nom de fichier est conserve, suffixe par la dimension aussi
424
-	$cache = 'cache-gd2';
425
-	if (substr($effet, 0, 7) == 'reduire') {
426
-		list(, $maxWidth, $maxHeight) = explode('-', $effet);
427
-		list($destWidth, $destHeight) = _image_ratio($ret['largeur'], $ret['hauteur'], $maxWidth, $maxHeight);
428
-		$ret['largeur_dest'] = $destWidth;
429
-		$ret['hauteur_dest'] = $destHeight;
430
-		$effet = "L{$destWidth}xH$destHeight";
431
-		$cache = 'cache-vignettes';
432
-		$fichier_dest = basename($fichier_dest);
433
-		if (($ret['largeur'] <= $maxWidth) && ($ret['hauteur'] <= $maxHeight)) {
434
-			// on garde la terminaison initiale car image simplement copiee
435
-			// et on postfixe son nom avec un md5 du path
436
-			$terminaison_dest = $terminaison;
437
-			$fichier_dest .= '-' . substr(md5("$identifiant"), 0, 5);
438
-		} else {
439
-			$fichier_dest .= '-' . substr(md5("$identifiant-$effet"), 0, 5);
440
-		}
441
-		$cache = sous_repertoire(_DIR_VAR, $cache);
442
-		$cache = sous_repertoire($cache, $effet);
443
-	} else {
444
-		$fichier_dest = md5("$identifiant-$effet");
445
-		$cache = sous_repertoire(_DIR_VAR, $cache);
446
-		$cache = sous_repertoire($cache, substr($fichier_dest, 0, 2));
447
-		$fichier_dest = substr($fichier_dest, 2);
448
-	}
449
-
450
-	$fichier_dest = $cache . $fichier_dest . '.' . $terminaison_dest;
451
-
452
-	$GLOBALS['images_calculees'][] = $fichier_dest;
453
-
454
-	$creer = true;
455
-	// si recalcul des images demande, recalculer chaque image une fois
456
-	if (defined('_VAR_IMAGES') and _VAR_IMAGES and !isset($images_recalcul[$fichier_dest])) {
457
-		$images_recalcul[$fichier_dest] = true;
458
-	} else {
459
-		if (@file_exists($f = $fichier_dest)) {
460
-			if (filemtime($f) >= $date_src) {
461
-				$creer = false;
462
-			}
463
-		} else {
464
-			if (
465
-				@file_exists($f = "$fichier_dest.src")
466
-				and lire_fichier($f, $valeurs)
467
-				and $valeurs = unserialize($valeurs)
468
-				and $valeurs['date'] >= $date_src
469
-			) {
470
-				$creer = false;
471
-			}
472
-		}
473
-	}
474
-	if ($creer) {
475
-		if (!@file_exists($fichier)) {
476
-			if (!@file_exists("$fichier.src")) {
477
-				spip_log("Image absente : $fichier");
478
-
479
-				return false;
480
-			}
481
-			# on reconstruit l'image source absente a partir de la chaine des .src
482
-			reconstruire_image_intermediaire($fichier);
483
-		}
484
-	}
485
-
486
-	if ($creer) {
487
-		spip_log(
488
-			'filtre image ' . ($fonction_creation ? reset($fonction_creation) : '') . "[$effet] sur $fichier",
489
-			'images' . _LOG_DEBUG
490
-		);
491
-	}
492
-
493
-	$term_fonction = _image_trouver_extension_pertinente($fichier);
494
-	$ret['fonction_imagecreatefrom'] = '_imagecreatefrom' . $term_fonction;
495
-	$ret['fichier'] = $fichier;
496
-	$ret['fonction_image'] = '_image_image' . $terminaison_dest;
497
-	$ret['fichier_dest'] = $fichier_dest;
498
-	$ret['format_source'] = _image_extension_normalisee($terminaison);
499
-	$ret['format_dest'] = $terminaison_dest;
500
-	$ret['date_src'] = $date_src;
501
-	$ret['creer'] = $creer;
502
-	$ret['class'] = extraire_attribut($img, 'class');
503
-	$ret['alt'] = extraire_attribut($img, 'alt');
504
-	$ret['style'] = extraire_attribut($img, 'style');
505
-	$ret['tag'] = $img;
506
-	if ($fonction_creation) {
507
-		$ret['reconstruction'] = $fonction_creation;
508
-		# ecrire ici comment creer le fichier, car il est pas sur qu'on l'ecrira reelement
509
-		# cas de image_reduire qui finalement ne reduit pas l'image source
510
-		# ca evite d'essayer de le creer au prochain hit si il n'est pas la
511
-		#ecrire_fichier($ret['fichier_dest'].'.src',serialize($ret),true);
512
-	}
513
-
514
-	$ret = pipeline('image_preparer_filtre', [
515
-			'args' => [
516
-				'img' => $img,
517
-				'effet' => $effet,
518
-				'forcer_format' => $forcer_format,
519
-				'fonction_creation' => $fonction_creation,
520
-				'find_in_path' => $find_in_path,
521
-			],
522
-			'data' => $ret
523
-		]);
524
-
525
-	// une globale pour le debug en cas de crash memoire
526
-	$GLOBALS['derniere_image_calculee'] = $ret;
527
-
528
-	// traiter le cas particulier des SVG : si le filtre n'a pas annonce explicitement qu'il savait faire, on delegue
529
-	if ($term_fonction === 'svg') {
530
-		if ($creer and !$support_svg) {
531
-			process_image_svg_identite($ret);
532
-			$ret['creer'] = false;
533
-		}
534
-	}
535
-	else {
536
-		if (!function_exists($ret['fonction_imagecreatefrom'])) {
537
-			return false;
538
-		}
539
-	}
540
-
541
-	return $ret;
309
+    static $images_recalcul = [];
310
+    if (strlen($img) == 0) {
311
+        return false;
312
+    }
313
+
314
+    $source = trim(extraire_attribut($img, 'src'));
315
+    if (strlen($source) < 1) {
316
+        $source = $img;
317
+        $img = "<img src='$source' />";
318
+    } # gerer img src="data:....base64"
319
+    elseif (
320
+        preg_match('@^data:image/([^;]*);base64,(.*)$@isS', $source, $regs)
321
+        and $extension = _image_trouver_extension_depuis_mime('image/' . $regs[1])
322
+        and in_array($extension, _image_extensions_acceptees_en_entree())
323
+    ) {
324
+        $local = sous_repertoire(_DIR_VAR, 'image-data') . md5($regs[2]) . '.' . _image_extension_normalisee($extension);
325
+        if (!file_exists($local)) {
326
+            ecrire_fichier($local, base64_decode($regs[2]));
327
+        }
328
+        if ($sanitizer = charger_fonction($extension, 'sanitizer', true)) {
329
+            $sanitizer($local);
330
+        }
331
+        $source = $local;
332
+        $img = inserer_attribut($img, 'src', $source);
333
+        # eviter les mauvaises surprises lors de conversions de format
334
+        $img = inserer_attribut($img, 'width', '');
335
+        $img = inserer_attribut($img, 'height', '');
336
+    }
337
+
338
+    // les protocoles web prennent au moins 3 lettres
339
+    if (tester_url_absolue($source)) {
340
+        include_spip('inc/distant');
341
+        $fichier = _DIR_RACINE . copie_locale($source);
342
+        if (!$fichier) {
343
+            return '';
344
+        }
345
+        if ($extension = _image_trouver_extension($fichier)
346
+          and $sanitizer = charger_fonction($extension, 'sanitizer', true)) {
347
+            $sanitizer($fichier);
348
+        }
349
+    } else {
350
+        // enlever le timestamp eventuel
351
+        if (strpos($source, '?') !== false) {
352
+            $source = preg_replace(',[?][0-9]+$,', '', $source);
353
+        }
354
+        if (
355
+            strpos($source, '?') !== false
356
+            and strncmp($source, _DIR_IMG, strlen(_DIR_IMG)) == 0
357
+            and file_exists($f = preg_replace(',[?].*$,', '', $source))
358
+        ) {
359
+            $source = $f;
360
+        }
361
+        $fichier = $source;
362
+    }
363
+
364
+    $terminaison_dest = '';
365
+    if ($terminaison = _image_trouver_extension($fichier)) {
366
+        $terminaison_dest = ($terminaison == 'gif') ? 'png' : $terminaison;
367
+    }
368
+
369
+    if (
370
+        $forcer_format !== false
371
+        // ignorer forcer_format si on a une image svg, que le filtre appelant ne supporte pas SVG, et que le forcage est un autre format image
372
+        and ($terminaison_dest !== 'svg' or $support_svg or !in_array($forcer_format, _image_extensions_acceptees_en_sortie()))
373
+    ) {
374
+        $terminaison_dest = $forcer_format;
375
+    }
376
+
377
+    if (!$terminaison_dest) {
378
+        return false;
379
+    }
380
+
381
+    $nom_fichier = substr($fichier, 0, strlen($fichier) - (strlen($terminaison) + 1));
382
+    $fichier_dest = $nom_fichier;
383
+    if (
384
+        ($find_in_path and $f = find_in_path($fichier) and $fichier = $f)
385
+        or @file_exists($f = $fichier)
386
+    ) {
387
+        // on passe la balise img a taille image qui exraira les attributs si possible
388
+        // au lieu de faire un acces disque sur le fichier
389
+        list($ret['hauteur'], $ret['largeur']) = taille_image($find_in_path ? $f : $img);
390
+        $date_src = @filemtime($f);
391
+    } elseif (
392
+        @file_exists($f = "$fichier.src")
393
+        and lire_fichier($f, $valeurs)
394
+        and $valeurs = unserialize($valeurs)
395
+        and isset($valeurs['hauteur_dest'])
396
+        and isset($valeurs['largeur_dest'])
397
+    ) {
398
+        $ret['hauteur'] = $valeurs['hauteur_dest'];
399
+        $ret['largeur'] = $valeurs['largeur_dest'];
400
+        $date_src = $valeurs['date'];
401
+    } // pas de fichier source par la
402
+    else {
403
+        return false;
404
+    }
405
+
406
+    // pas de taille mesurable
407
+    if (!($ret['hauteur'] or $ret['largeur'])) {
408
+        return false;
409
+    }
410
+
411
+    // les images calculees dependent du chemin du fichier source
412
+    // 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
413
+    // ce n'est pas totalement optimal en terme de stockage, mais chaque image est associee a un fichier .src
414
+    // qui contient la methode de reconstrucion (le filtre + les arguments d'appel) et les arguments different entre prive et public
415
+    // la mise en commun du fichier image cree donc un bug et des problemes qui necessiteraient beaucoup de complexite de code
416
+    // alors que ca concerne peu de site au final
417
+    // la release de r23632+r23633+r23634 a provoque peu de remontee de bug attestant du peu de sites impactes
418
+    $identifiant = $fichier;
419
+
420
+    // cas general :
421
+    // on a un dossier cache commun et un nom de fichier qui varie avec l'effet
422
+    // cas particulier de reduire :
423
+    // un cache par dimension, et le nom de fichier est conserve, suffixe par la dimension aussi
424
+    $cache = 'cache-gd2';
425
+    if (substr($effet, 0, 7) == 'reduire') {
426
+        list(, $maxWidth, $maxHeight) = explode('-', $effet);
427
+        list($destWidth, $destHeight) = _image_ratio($ret['largeur'], $ret['hauteur'], $maxWidth, $maxHeight);
428
+        $ret['largeur_dest'] = $destWidth;
429
+        $ret['hauteur_dest'] = $destHeight;
430
+        $effet = "L{$destWidth}xH$destHeight";
431
+        $cache = 'cache-vignettes';
432
+        $fichier_dest = basename($fichier_dest);
433
+        if (($ret['largeur'] <= $maxWidth) && ($ret['hauteur'] <= $maxHeight)) {
434
+            // on garde la terminaison initiale car image simplement copiee
435
+            // et on postfixe son nom avec un md5 du path
436
+            $terminaison_dest = $terminaison;
437
+            $fichier_dest .= '-' . substr(md5("$identifiant"), 0, 5);
438
+        } else {
439
+            $fichier_dest .= '-' . substr(md5("$identifiant-$effet"), 0, 5);
440
+        }
441
+        $cache = sous_repertoire(_DIR_VAR, $cache);
442
+        $cache = sous_repertoire($cache, $effet);
443
+    } else {
444
+        $fichier_dest = md5("$identifiant-$effet");
445
+        $cache = sous_repertoire(_DIR_VAR, $cache);
446
+        $cache = sous_repertoire($cache, substr($fichier_dest, 0, 2));
447
+        $fichier_dest = substr($fichier_dest, 2);
448
+    }
449
+
450
+    $fichier_dest = $cache . $fichier_dest . '.' . $terminaison_dest;
451
+
452
+    $GLOBALS['images_calculees'][] = $fichier_dest;
453
+
454
+    $creer = true;
455
+    // si recalcul des images demande, recalculer chaque image une fois
456
+    if (defined('_VAR_IMAGES') and _VAR_IMAGES and !isset($images_recalcul[$fichier_dest])) {
457
+        $images_recalcul[$fichier_dest] = true;
458
+    } else {
459
+        if (@file_exists($f = $fichier_dest)) {
460
+            if (filemtime($f) >= $date_src) {
461
+                $creer = false;
462
+            }
463
+        } else {
464
+            if (
465
+                @file_exists($f = "$fichier_dest.src")
466
+                and lire_fichier($f, $valeurs)
467
+                and $valeurs = unserialize($valeurs)
468
+                and $valeurs['date'] >= $date_src
469
+            ) {
470
+                $creer = false;
471
+            }
472
+        }
473
+    }
474
+    if ($creer) {
475
+        if (!@file_exists($fichier)) {
476
+            if (!@file_exists("$fichier.src")) {
477
+                spip_log("Image absente : $fichier");
478
+
479
+                return false;
480
+            }
481
+            # on reconstruit l'image source absente a partir de la chaine des .src
482
+            reconstruire_image_intermediaire($fichier);
483
+        }
484
+    }
485
+
486
+    if ($creer) {
487
+        spip_log(
488
+            'filtre image ' . ($fonction_creation ? reset($fonction_creation) : '') . "[$effet] sur $fichier",
489
+            'images' . _LOG_DEBUG
490
+        );
491
+    }
492
+
493
+    $term_fonction = _image_trouver_extension_pertinente($fichier);
494
+    $ret['fonction_imagecreatefrom'] = '_imagecreatefrom' . $term_fonction;
495
+    $ret['fichier'] = $fichier;
496
+    $ret['fonction_image'] = '_image_image' . $terminaison_dest;
497
+    $ret['fichier_dest'] = $fichier_dest;
498
+    $ret['format_source'] = _image_extension_normalisee($terminaison);
499
+    $ret['format_dest'] = $terminaison_dest;
500
+    $ret['date_src'] = $date_src;
501
+    $ret['creer'] = $creer;
502
+    $ret['class'] = extraire_attribut($img, 'class');
503
+    $ret['alt'] = extraire_attribut($img, 'alt');
504
+    $ret['style'] = extraire_attribut($img, 'style');
505
+    $ret['tag'] = $img;
506
+    if ($fonction_creation) {
507
+        $ret['reconstruction'] = $fonction_creation;
508
+        # ecrire ici comment creer le fichier, car il est pas sur qu'on l'ecrira reelement
509
+        # cas de image_reduire qui finalement ne reduit pas l'image source
510
+        # ca evite d'essayer de le creer au prochain hit si il n'est pas la
511
+        #ecrire_fichier($ret['fichier_dest'].'.src',serialize($ret),true);
512
+    }
513
+
514
+    $ret = pipeline('image_preparer_filtre', [
515
+            'args' => [
516
+                'img' => $img,
517
+                'effet' => $effet,
518
+                'forcer_format' => $forcer_format,
519
+                'fonction_creation' => $fonction_creation,
520
+                'find_in_path' => $find_in_path,
521
+            ],
522
+            'data' => $ret
523
+        ]);
524
+
525
+    // une globale pour le debug en cas de crash memoire
526
+    $GLOBALS['derniere_image_calculee'] = $ret;
527
+
528
+    // traiter le cas particulier des SVG : si le filtre n'a pas annonce explicitement qu'il savait faire, on delegue
529
+    if ($term_fonction === 'svg') {
530
+        if ($creer and !$support_svg) {
531
+            process_image_svg_identite($ret);
532
+            $ret['creer'] = false;
533
+        }
534
+    }
535
+    else {
536
+        if (!function_exists($ret['fonction_imagecreatefrom'])) {
537
+            return false;
538
+        }
539
+    }
540
+
541
+    return $ret;
542 542
 }
543 543
 
544 544
 
@@ -547,53 +547,53 @@  discard block
 block discarded – undo
547 547
  * @return array
548 548
  */
549 549
 function _image_extensions_acceptees_en_entree() {
550
-	static $extensions = null;
551
-	if (empty($extensions)) {
552
-		$extensions = ['png', 'gif', 'jpg', 'jpeg'];
553
-		if (!empty($GLOBALS['meta']['gd_formats'])) {
554
-			// action=tester renseigne gd_formats et detecte le support de webp
555
-			$extensions = array_merge(explode(',', $GLOBALS['meta']['gd_formats']));
556
-			$extensions = array_map('trim', $extensions);
557
-			$extensions = array_filter($extensions);
558
-			$extensions = array_unique($extensions);
559
-			if (in_array('jpg', $extensions)) { $extensions[] = 'jpeg';
560
-			}
561
-		}
562
-		$extensions[] = 'svg'; // on le supporte toujours avec des fonctions specifiques
563
-	}
564
-
565
-	return $extensions;
550
+    static $extensions = null;
551
+    if (empty($extensions)) {
552
+        $extensions = ['png', 'gif', 'jpg', 'jpeg'];
553
+        if (!empty($GLOBALS['meta']['gd_formats'])) {
554
+            // action=tester renseigne gd_formats et detecte le support de webp
555
+            $extensions = array_merge(explode(',', $GLOBALS['meta']['gd_formats']));
556
+            $extensions = array_map('trim', $extensions);
557
+            $extensions = array_filter($extensions);
558
+            $extensions = array_unique($extensions);
559
+            if (in_array('jpg', $extensions)) { $extensions[] = 'jpeg';
560
+            }
561
+        }
562
+        $extensions[] = 'svg'; // on le supporte toujours avec des fonctions specifiques
563
+    }
564
+
565
+    return $extensions;
566 566
 }
567 567
 
568 568
 /**
569 569
  * @return array|string[]|null
570 570
  */
571 571
 function _image_extensions_acceptees_en_sortie() {
572
-	static $extensions = null;
573
-	if (empty($extensions)) {
574
-		$extensions = _image_extensions_acceptees_en_entree();
575
-		$extensions = array_diff($extensions, ['jpeg']);
576
-		if (in_array('gif', $extensions) and !function_exists('imagegif')) {
577
-			$extensions = array_diff($extensions, ['gif']);
578
-		}
579
-		if (in_array('webp', $extensions) and !function_exists('imagewebp')) {
580
-			$extensions = array_diff($extensions, ['webp']);
581
-		}
582
-	}
583
-
584
-	return $extensions;
572
+    static $extensions = null;
573
+    if (empty($extensions)) {
574
+        $extensions = _image_extensions_acceptees_en_entree();
575
+        $extensions = array_diff($extensions, ['jpeg']);
576
+        if (in_array('gif', $extensions) and !function_exists('imagegif')) {
577
+            $extensions = array_diff($extensions, ['gif']);
578
+        }
579
+        if (in_array('webp', $extensions) and !function_exists('imagewebp')) {
580
+            $extensions = array_diff($extensions, ['webp']);
581
+        }
582
+    }
583
+
584
+    return $extensions;
585 585
 }
586 586
 
587 587
 function _image_extension_normalisee($extension) {
588
-	$extension = strtolower($extension);
589
-	if ($extension === 'jpeg') {
590
-		$extension = 'jpg';
591
-	}
592
-	return $extension;
588
+    $extension = strtolower($extension);
589
+    if ($extension === 'jpeg') {
590
+        $extension = 'jpg';
591
+    }
592
+    return $extension;
593 593
 }
594 594
 
595 595
 function _image_extensions_conservent_transparence() {
596
-	return ['png', 'webp'];
596
+    return ['png', 'webp'];
597 597
 }
598 598
 
599 599
 
@@ -603,12 +603,12 @@  discard block
 block discarded – undo
603 603
  * @return string
604 604
  */
605 605
 function _image_trouver_extension($path) {
606
-	$preg_extensions = implode('|', _image_extensions_acceptees_en_entree());
607
-	if (preg_match(",\.($preg_extensions)($|[?]),i", $path, $regs)) {
608
-		$terminaison = strtolower($regs[1]);
609
-		return $terminaison;
610
-	}
611
-	return '';
606
+    $preg_extensions = implode('|', _image_extensions_acceptees_en_entree());
607
+    if (preg_match(",\.($preg_extensions)($|[?]),i", $path, $regs)) {
608
+        $terminaison = strtolower($regs[1]);
609
+        return $terminaison;
610
+    }
611
+    return '';
612 612
 }
613 613
 
614 614
 /**
@@ -619,33 +619,33 @@  discard block
 block discarded – undo
619 619
  * @return string Extension, dans le format attendu par les fonctions 'gd' ('jpeg' pour les .jpg par exemple)
620 620
  */
621 621
 function _image_trouver_extension_pertinente($path) {
622
-	$path = supprimer_timestamp($path);
623
-	$terminaison = _image_trouver_extension($path);
624
-	if ($terminaison == 'jpg') {
625
-		$terminaison = 'jpeg';
626
-	}
627
-
628
-	if (!file_exists($path)) {
629
-		return $terminaison;
630
-	}
631
-
632
-	if (!$info = @spip_getimagesize($path)) {
633
-		return $terminaison;
634
-	}
635
-
636
-	if (isset($info['mime'])) {
637
-		$mime = $info['mime'];
638
-	}
639
-	else {
640
-		$mime = image_type_to_mime_type($info[2]);
641
-	}
642
-
643
-	$_terminaison = _image_trouver_extension_depuis_mime($mime);
644
-	if ($_terminaison and $_terminaison !== $terminaison) {
645
-		spip_log("Mauvaise extension du fichier : $path . Son type mime est : $mime", 'images.' . _LOG_INFO_IMPORTANTE);
646
-		$terminaison = $_terminaison;
647
-	}
648
-	return $terminaison;
622
+    $path = supprimer_timestamp($path);
623
+    $terminaison = _image_trouver_extension($path);
624
+    if ($terminaison == 'jpg') {
625
+        $terminaison = 'jpeg';
626
+    }
627
+
628
+    if (!file_exists($path)) {
629
+        return $terminaison;
630
+    }
631
+
632
+    if (!$info = @spip_getimagesize($path)) {
633
+        return $terminaison;
634
+    }
635
+
636
+    if (isset($info['mime'])) {
637
+        $mime = $info['mime'];
638
+    }
639
+    else {
640
+        $mime = image_type_to_mime_type($info[2]);
641
+    }
642
+
643
+    $_terminaison = _image_trouver_extension_depuis_mime($mime);
644
+    if ($_terminaison and $_terminaison !== $terminaison) {
645
+        spip_log("Mauvaise extension du fichier : $path . Son type mime est : $mime", 'images.' . _LOG_INFO_IMPORTANTE);
646
+        $terminaison = $_terminaison;
647
+    }
648
+    return $terminaison;
649 649
 }
650 650
 
651 651
 /**
@@ -653,36 +653,36 @@  discard block
 block discarded – undo
653 653
  * @return string
654 654
  */
655 655
 function _image_trouver_extension_depuis_mime($mime) {
656
-	switch (strtolower($mime)) {
657
-		case 'image/png':
658
-		case 'image/x-png':
659
-			$terminaison = 'png';
660
-			break;
661
-
662
-		case 'image/jpg':
663
-		case 'image/jpeg':
664
-		case 'image/pjpeg':
665
-			$terminaison = 'jpeg';
666
-			break;
667
-
668
-		case 'image/gif':
669
-			$terminaison = 'gif';
670
-			break;
671
-
672
-		case 'image/webp':
673
-		case 'image/x-webp':
674
-			$terminaison = 'webp';
675
-			break;
676
-
677
-		case 'image/svg+xml':
678
-			$terminaison = 'svg';
679
-			break;
680
-
681
-		default:
682
-			$terminaison = '';
683
-	}
684
-
685
-	return $terminaison;
656
+    switch (strtolower($mime)) {
657
+        case 'image/png':
658
+        case 'image/x-png':
659
+            $terminaison = 'png';
660
+            break;
661
+
662
+        case 'image/jpg':
663
+        case 'image/jpeg':
664
+        case 'image/pjpeg':
665
+            $terminaison = 'jpeg';
666
+            break;
667
+
668
+        case 'image/gif':
669
+            $terminaison = 'gif';
670
+            break;
671
+
672
+        case 'image/webp':
673
+        case 'image/x-webp':
674
+            $terminaison = 'webp';
675
+            break;
676
+
677
+        case 'image/svg+xml':
678
+            $terminaison = 'svg';
679
+            break;
680
+
681
+        default:
682
+            $terminaison = '';
683
+    }
684
+
685
+    return $terminaison;
686 686
 }
687 687
 
688 688
 
@@ -702,18 +702,18 @@  discard block
 block discarded – undo
702 702
  *     Une ressource de type Image GD.
703 703
  */
704 704
 function _imagecreatefrom_func(string $func, string $filename) {
705
-	if (!function_exists($func)) {
706
-		spip_log("GD indisponible : $func inexistante. Traitement $filename impossible.", _LOG_CRITIQUE);
707
-		erreur_squelette("GD indisponible : $func inexistante. Traitement $filename impossible.");
708
-		return null;
709
-	}
710
-	$img = @$func($filename);
711
-	if (!$img) {
712
-		spip_log("Erreur lecture imagecreatefromjpeg $filename", _LOG_CRITIQUE);
713
-		erreur_squelette("Erreur lecture imagecreatefromjpeg $filename");
714
-		$img = imagecreate(10, 10);
715
-	}
716
-	return $img;
705
+    if (!function_exists($func)) {
706
+        spip_log("GD indisponible : $func inexistante. Traitement $filename impossible.", _LOG_CRITIQUE);
707
+        erreur_squelette("GD indisponible : $func inexistante. Traitement $filename impossible.");
708
+        return null;
709
+    }
710
+    $img = @$func($filename);
711
+    if (!$img) {
712
+        spip_log("Erreur lecture imagecreatefromjpeg $filename", _LOG_CRITIQUE);
713
+        erreur_squelette("Erreur lecture imagecreatefromjpeg $filename");
714
+        $img = imagecreate(10, 10);
715
+    }
716
+    return $img;
717 717
 }
718 718
 
719 719
 /**
@@ -729,7 +729,7 @@  discard block
 block discarded – undo
729 729
  *     Une ressource de type Image GD.
730 730
  */
731 731
 function _imagecreatefromjpeg($filename) {
732
-	return _imagecreatefrom_func('imagecreatefromjpeg', $filename);
732
+    return _imagecreatefrom_func('imagecreatefromjpeg', $filename);
733 733
 }
734 734
 
735 735
 /**
@@ -745,7 +745,7 @@  discard block
 block discarded – undo
745 745
  *     Une ressource de type Image GD.
746 746
  */
747 747
 function _imagecreatefrompng($filename) {
748
-	return _imagecreatefrom_func('imagecreatefrompng', $filename);
748
+    return _imagecreatefrom_func('imagecreatefrompng', $filename);
749 749
 }
750 750
 
751 751
 /**
@@ -761,7 +761,7 @@  discard block
 block discarded – undo
761 761
  *     Une ressource de type Image GD.
762 762
  */
763 763
 function _imagecreatefromgif($filename) {
764
-	return _imagecreatefrom_func('imagecreatefromgif', $filename);
764
+    return _imagecreatefrom_func('imagecreatefromgif', $filename);
765 765
 }
766 766
 
767 767
 
@@ -778,7 +778,7 @@  discard block
 block discarded – undo
778 778
  *     Une ressource de type Image GD.
779 779
  */
780 780
 function _imagecreatefromwebp($filename) {
781
-	return _imagecreatefrom_func('imagecreatefromwebp', $filename);
781
+    return _imagecreatefrom_func('imagecreatefromwebp', $filename);
782 782
 }
783 783
 
784 784
 /**
@@ -796,24 +796,24 @@  discard block
 block discarded – undo
796 796
  *     - true si une image est bien retournée.
797 797
  */
798 798
 function _image_imagepng($img, $fichier) {
799
-	if (!function_exists('imagepng')) {
800
-		return false;
801
-	}
802
-	$tmp = $fichier . '.tmp';
803
-	$ret = imagepng($img, $tmp);
804
-	if (file_exists($tmp)) {
805
-		$taille_test = getimagesize($tmp);
806
-		if ($taille_test[0] < 1) {
807
-			return false;
808
-		}
809
-
810
-		spip_unlink($fichier); // le fichier peut deja exister
811
-		@rename($tmp, $fichier);
812
-
813
-		return $ret;
814
-	}
815
-
816
-	return false;
799
+    if (!function_exists('imagepng')) {
800
+        return false;
801
+    }
802
+    $tmp = $fichier . '.tmp';
803
+    $ret = imagepng($img, $tmp);
804
+    if (file_exists($tmp)) {
805
+        $taille_test = getimagesize($tmp);
806
+        if ($taille_test[0] < 1) {
807
+            return false;
808
+        }
809
+
810
+        spip_unlink($fichier); // le fichier peut deja exister
811
+        @rename($tmp, $fichier);
812
+
813
+        return $ret;
814
+    }
815
+
816
+    return false;
817 817
 }
818 818
 
819 819
 /**
@@ -831,24 +831,24 @@  discard block
 block discarded – undo
831 831
  *     - true si une image est bien retournée.
832 832
  */
833 833
 function _image_imagegif($img, $fichier) {
834
-	if (!function_exists('imagegif')) {
835
-		return false;
836
-	}
837
-	$tmp = $fichier . '.tmp';
838
-	$ret = imagegif($img, $tmp);
839
-	if (file_exists($tmp)) {
840
-		$taille_test = getimagesize($tmp);
841
-		if ($taille_test[0] < 1) {
842
-			return false;
843
-		}
844
-
845
-		spip_unlink($fichier); // le fichier peut deja exister
846
-		@rename($tmp, $fichier);
847
-
848
-		return $ret;
849
-	}
850
-
851
-	return false;
834
+    if (!function_exists('imagegif')) {
835
+        return false;
836
+    }
837
+    $tmp = $fichier . '.tmp';
838
+    $ret = imagegif($img, $tmp);
839
+    if (file_exists($tmp)) {
840
+        $taille_test = getimagesize($tmp);
841
+        if ($taille_test[0] < 1) {
842
+            return false;
843
+        }
844
+
845
+        spip_unlink($fichier); // le fichier peut deja exister
846
+        @rename($tmp, $fichier);
847
+
848
+        return $ret;
849
+    }
850
+
851
+    return false;
852 852
 }
853 853
 
854 854
 /**
@@ -871,29 +871,29 @@  discard block
 block discarded – undo
871 871
  *     - true si une image est bien retournée.
872 872
  */
873 873
 function _image_imagejpg($img, $fichier, $qualite = _IMG_GD_QUALITE) {
874
-	if (!function_exists('imagejpeg')) {
875
-		return false;
876
-	}
877
-	$tmp = $fichier . '.tmp';
874
+    if (!function_exists('imagejpeg')) {
875
+        return false;
876
+    }
877
+    $tmp = $fichier . '.tmp';
878 878
 
879
-	// Enable interlancing
880
-	imageinterlace($img, true);
879
+    // Enable interlancing
880
+    imageinterlace($img, true);
881 881
 
882
-	$ret = imagejpeg($img, $tmp, $qualite);
882
+    $ret = imagejpeg($img, $tmp, $qualite);
883 883
 
884
-	if (file_exists($tmp)) {
885
-		$taille_test = getimagesize($tmp);
886
-		if ($taille_test[0] < 1) {
887
-			return false;
888
-		}
884
+    if (file_exists($tmp)) {
885
+        $taille_test = getimagesize($tmp);
886
+        if ($taille_test[0] < 1) {
887
+            return false;
888
+        }
889 889
 
890
-		spip_unlink($fichier); // le fichier peut deja exister
891
-		@rename($tmp, $fichier);
890
+        spip_unlink($fichier); // le fichier peut deja exister
891
+        @rename($tmp, $fichier);
892 892
 
893
-		return $ret;
894
-	}
893
+        return $ret;
894
+    }
895 895
 
896
-	return false;
896
+    return false;
897 897
 }
898 898
 
899 899
 /**
@@ -911,9 +911,9 @@  discard block
 block discarded – undo
911 911
  *     true si le fichier a bien été créé ; false sinon.
912 912
  */
913 913
 function _image_imageico($img, $fichier) {
914
-	$gd_image_array = [$img];
914
+    $gd_image_array = [$img];
915 915
 
916
-	return ecrire_fichier($fichier, phpthumb_functions::GD2ICOstring($gd_image_array));
916
+    return ecrire_fichier($fichier, phpthumb_functions::GD2ICOstring($gd_image_array));
917 917
 }
918 918
 
919 919
 
@@ -932,24 +932,24 @@  discard block
 block discarded – undo
932 932
  *     - true si une image est bien retournée.
933 933
  */
934 934
 function _image_imagewebp($img, $fichier, $qualite = _IMG_GD_QUALITE) {
935
-	if (!function_exists('imagewebp')) {
936
-		return false;
937
-	}
938
-	$tmp = $fichier . '.tmp';
939
-	$ret = imagewebp($img, $tmp, $qualite);
940
-	if (file_exists($tmp)) {
941
-		$taille_test = getimagesize($tmp);
942
-		if ($taille_test[0] < 1) {
943
-			return false;
944
-		}
945
-
946
-		spip_unlink($fichier); // le fichier peut deja exister
947
-		@rename($tmp, $fichier);
948
-
949
-		return $ret;
950
-	}
951
-
952
-	return false;
935
+    if (!function_exists('imagewebp')) {
936
+        return false;
937
+    }
938
+    $tmp = $fichier . '.tmp';
939
+    $ret = imagewebp($img, $tmp, $qualite);
940
+    if (file_exists($tmp)) {
941
+        $taille_test = getimagesize($tmp);
942
+        if ($taille_test[0] < 1) {
943
+            return false;
944
+        }
945
+
946
+        spip_unlink($fichier); // le fichier peut deja exister
947
+        @rename($tmp, $fichier);
948
+
949
+        return $ret;
950
+    }
951
+
952
+    return false;
953 953
 }
954 954
 
955 955
 /**
@@ -969,35 +969,35 @@  discard block
 block discarded – undo
969 969
  */
970 970
 function _image_imagesvg($img, $fichier) {
971 971
 
972
-	$tmp = $fichier . '.tmp';
973
-	if (strpos($img, '<') === false) {
974
-		$img = supprimer_timestamp($img);
975
-		if (!file_exists($img)) {
976
-			return false;
977
-		}
978
-		@copy($img, $tmp);
979
-		if (filesize($tmp) == filesize($img)) {
980
-			spip_unlink($fichier); // le fichier peut deja exister
981
-			@rename($tmp, $fichier);
982
-			return true;
983
-		}
984
-		return false;
985
-	}
986
-
987
-	file_put_contents($tmp, $img);
988
-	if (file_exists($tmp)) {
989
-		$taille_test = spip_getimagesize($tmp);
990
-		if ($taille_test[0] < 1) {
991
-			return false;
992
-		}
993
-
994
-		spip_unlink($fichier); // le fichier peut deja exister
995
-		@rename($tmp, $fichier);
996
-
997
-		return true;
998
-	}
999
-
1000
-	return false;
972
+    $tmp = $fichier . '.tmp';
973
+    if (strpos($img, '<') === false) {
974
+        $img = supprimer_timestamp($img);
975
+        if (!file_exists($img)) {
976
+            return false;
977
+        }
978
+        @copy($img, $tmp);
979
+        if (filesize($tmp) == filesize($img)) {
980
+            spip_unlink($fichier); // le fichier peut deja exister
981
+            @rename($tmp, $fichier);
982
+            return true;
983
+        }
984
+        return false;
985
+    }
986
+
987
+    file_put_contents($tmp, $img);
988
+    if (file_exists($tmp)) {
989
+        $taille_test = spip_getimagesize($tmp);
990
+        if ($taille_test[0] < 1) {
991
+            return false;
992
+        }
993
+
994
+        spip_unlink($fichier); // le fichier peut deja exister
995
+        @rename($tmp, $fichier);
996
+
997
+        return true;
998
+    }
999
+
1000
+    return false;
1001 1001
 }
1002 1002
 
1003 1003
 
@@ -1025,29 +1025,29 @@  discard block
 block discarded – undo
1025 1025
  *     - false sinon.
1026 1026
  */
1027 1027
 function _image_gd_output($img, $valeurs, $qualite = _IMG_GD_QUALITE, $fonction = null) {
1028
-	if (is_null($fonction)) {
1029
-		$fonction = '_image_image' . $valeurs['format_dest'];
1030
-	}
1031
-	$ret = false;
1032
-	#un flag pour reperer les images gravees
1033
-	$lock =
1034
-		!statut_effacer_images_temporaires('get') // si la fonction n'a pas ete activee, on grave tout
1035
-	or (@file_exists($valeurs['fichier_dest']) and !@file_exists($valeurs['fichier_dest'] . '.src'));
1036
-	if (
1037
-		function_exists($fonction)
1038
-		&& ($ret = $fonction($img, $valeurs['fichier_dest'], $qualite)) # on a reussi a creer l'image
1039
-		&& isset($valeurs['reconstruction']) # et on sait comment la resonctruire le cas echeant
1040
-		&& !$lock
1041
-	) {
1042
-		if (@file_exists($valeurs['fichier_dest'])) {
1043
-			// dans tous les cas mettre a jour la taille de l'image finale
1044
-			list($valeurs['hauteur_dest'], $valeurs['largeur_dest']) = taille_image($valeurs['fichier_dest']);
1045
-			$valeurs['date'] = @filemtime($valeurs['fichier_dest']); // pour la retrouver apres disparition
1046
-			ecrire_fichier($valeurs['fichier_dest'] . '.src', serialize($valeurs), true);
1047
-		}
1048
-	}
1049
-
1050
-	return $ret;
1028
+    if (is_null($fonction)) {
1029
+        $fonction = '_image_image' . $valeurs['format_dest'];
1030
+    }
1031
+    $ret = false;
1032
+    #un flag pour reperer les images gravees
1033
+    $lock =
1034
+        !statut_effacer_images_temporaires('get') // si la fonction n'a pas ete activee, on grave tout
1035
+    or (@file_exists($valeurs['fichier_dest']) and !@file_exists($valeurs['fichier_dest'] . '.src'));
1036
+    if (
1037
+        function_exists($fonction)
1038
+        && ($ret = $fonction($img, $valeurs['fichier_dest'], $qualite)) # on a reussi a creer l'image
1039
+        && isset($valeurs['reconstruction']) # et on sait comment la resonctruire le cas echeant
1040
+        && !$lock
1041
+    ) {
1042
+        if (@file_exists($valeurs['fichier_dest'])) {
1043
+            // dans tous les cas mettre a jour la taille de l'image finale
1044
+            list($valeurs['hauteur_dest'], $valeurs['largeur_dest']) = taille_image($valeurs['fichier_dest']);
1045
+            $valeurs['date'] = @filemtime($valeurs['fichier_dest']); // pour la retrouver apres disparition
1046
+            ecrire_fichier($valeurs['fichier_dest'] . '.src', serialize($valeurs), true);
1047
+        }
1048
+    }
1049
+
1050
+    return $ret;
1051 1051
 }
1052 1052
 
1053 1053
 /**
@@ -1060,27 +1060,27 @@  discard block
 block discarded – undo
1060 1060
  *     Chemin vers le fichier manquant
1061 1061
  **/
1062 1062
 function reconstruire_image_intermediaire($fichier_manquant) {
1063
-	$reconstruire = [];
1064
-	$fichier = $fichier_manquant;
1065
-	while (
1066
-		strpos($fichier, '://') === false
1067
-		and !@file_exists($fichier)
1068
-		and lire_fichier($src = "$fichier.src", $source)
1069
-		and $valeurs = unserialize($source)
1070
-		and ($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
1071
-	) {
1072
-		spip_unlink($src); // si jamais on a un timeout pendant la reconstruction, elle se fera naturellement au hit suivant
1073
-		$reconstruire[] = $valeurs['reconstruction'];
1074
-	}
1075
-	while (count($reconstruire)) {
1076
-		$r = array_pop($reconstruire);
1077
-		$fonction = $r[0];
1078
-		$args = $r[1];
1079
-		call_user_func_array($fonction, $args);
1080
-	}
1081
-	// cette image intermediaire est commune a plusieurs series de filtre, il faut la conserver
1082
-	// mais l'on peut nettoyer les miettes de sa creation
1083
-	ramasse_miettes($fichier_manquant);
1063
+    $reconstruire = [];
1064
+    $fichier = $fichier_manquant;
1065
+    while (
1066
+        strpos($fichier, '://') === false
1067
+        and !@file_exists($fichier)
1068
+        and lire_fichier($src = "$fichier.src", $source)
1069
+        and $valeurs = unserialize($source)
1070
+        and ($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
1071
+    ) {
1072
+        spip_unlink($src); // si jamais on a un timeout pendant la reconstruction, elle se fera naturellement au hit suivant
1073
+        $reconstruire[] = $valeurs['reconstruction'];
1074
+    }
1075
+    while (count($reconstruire)) {
1076
+        $r = array_pop($reconstruire);
1077
+        $fonction = $r[0];
1078
+        $args = $r[1];
1079
+        call_user_func_array($fonction, $args);
1080
+    }
1081
+    // cette image intermediaire est commune a plusieurs series de filtre, il faut la conserver
1082
+    // mais l'on peut nettoyer les miettes de sa creation
1083
+    ramasse_miettes($fichier_manquant);
1084 1084
 }
1085 1085
 
1086 1086
 /**
@@ -1100,28 +1100,28 @@  discard block
 block discarded – undo
1100 1100
  *     Chemin du fichier d'image calculé
1101 1101
  **/
1102 1102
 function ramasse_miettes($fichier) {
1103
-	if (
1104
-		strpos($fichier, '://') !== false
1105
-		or !lire_fichier($src = "$fichier.src", $source)
1106
-		or !$valeurs = unserialize($source)
1107
-	) {
1108
-		return;
1109
-	}
1110
-	spip_unlink($src); # on supprime la reference a sa source pour marquer cette image comme non intermediaire
1111
-	while (
1112
-		($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
1113
-		and (substr($fichier, 0, strlen(_DIR_VAR)) == _DIR_VAR) # et est dans local
1114
-		and (lire_fichier(
1115
-			$src = "$fichier.src",
1116
-			$source
1117
-		)) # le fichier a une source connue (c'est donc une image calculee intermediaire)
1118
-		and ($valeurs = unserialize($source))  # et valide
1119
-	) {
1120
-		# on efface le fichier
1121
-		spip_unlink($fichier);
1122
-		# mais laisse le .src qui permet de savoir comment reconstruire l'image si besoin
1123
-		#spip_unlink($src);
1124
-	}
1103
+    if (
1104
+        strpos($fichier, '://') !== false
1105
+        or !lire_fichier($src = "$fichier.src", $source)
1106
+        or !$valeurs = unserialize($source)
1107
+    ) {
1108
+        return;
1109
+    }
1110
+    spip_unlink($src); # on supprime la reference a sa source pour marquer cette image comme non intermediaire
1111
+    while (
1112
+        ($fichier = $valeurs['fichier']) # l'origine est connue (on ne verifie pas son existence, qu'importe ...)
1113
+        and (substr($fichier, 0, strlen(_DIR_VAR)) == _DIR_VAR) # et est dans local
1114
+        and (lire_fichier(
1115
+            $src = "$fichier.src",
1116
+            $source
1117
+        )) # le fichier a une source connue (c'est donc une image calculee intermediaire)
1118
+        and ($valeurs = unserialize($source))  # et valide
1119
+    ) {
1120
+        # on efface le fichier
1121
+        spip_unlink($fichier);
1122
+        # mais laisse le .src qui permet de savoir comment reconstruire l'image si besoin
1123
+        #spip_unlink($src);
1124
+    }
1125 1125
 }
1126 1126
 
1127 1127
 
@@ -1146,71 +1146,71 @@  discard block
 block discarded – undo
1146 1146
  *     Code HTML de l'image
1147 1147
  **/
1148 1148
 function image_graver($img) {
1149
-	// appeler le filtre post_image_filtrer qui permet de faire
1150
-	// des traitements auto a la fin d'une serie de filtres
1151
-	$img = pipeline('post_image_filtrer', $img);
1152
-
1153
-	$fichier_ori = $fichier = extraire_attribut($img, 'src');
1154
-	if (($p = strpos($fichier, '?')) !== false) {
1155
-		$fichier = substr($fichier, 0, $p);
1156
-	}
1157
-	if (strlen($fichier) < 1) {
1158
-		$fichier = $img;
1159
-	}
1160
-	# si jamais le fichier final n'a pas ete calcule car suppose temporaire
1161
-	# et qu'il ne s'agit pas d'une URL
1162
-	if (strpos($fichier, '://') === false and !@file_exists($fichier)) {
1163
-		reconstruire_image_intermediaire($fichier);
1164
-	}
1165
-	ramasse_miettes($fichier);
1166
-
1167
-	// ajouter le timestamp si besoin
1168
-	if (strpos($fichier_ori, '?') === false) {
1169
-		// on utilise str_replace pour attraper le onmouseover des logo si besoin
1170
-		$img = str_replace($fichier_ori, timestamp($fichier_ori), $img);
1171
-	}
1172
-
1173
-	return $img;
1149
+    // appeler le filtre post_image_filtrer qui permet de faire
1150
+    // des traitements auto a la fin d'une serie de filtres
1151
+    $img = pipeline('post_image_filtrer', $img);
1152
+
1153
+    $fichier_ori = $fichier = extraire_attribut($img, 'src');
1154
+    if (($p = strpos($fichier, '?')) !== false) {
1155
+        $fichier = substr($fichier, 0, $p);
1156
+    }
1157
+    if (strlen($fichier) < 1) {
1158
+        $fichier = $img;
1159
+    }
1160
+    # si jamais le fichier final n'a pas ete calcule car suppose temporaire
1161
+    # et qu'il ne s'agit pas d'une URL
1162
+    if (strpos($fichier, '://') === false and !@file_exists($fichier)) {
1163
+        reconstruire_image_intermediaire($fichier);
1164
+    }
1165
+    ramasse_miettes($fichier);
1166
+
1167
+    // ajouter le timestamp si besoin
1168
+    if (strpos($fichier_ori, '?') === false) {
1169
+        // on utilise str_replace pour attraper le onmouseover des logo si besoin
1170
+        $img = str_replace($fichier_ori, timestamp($fichier_ori), $img);
1171
+    }
1172
+
1173
+    return $img;
1174 1174
 }
1175 1175
 
1176 1176
 
1177 1177
 if (!function_exists('imagepalettetotruecolor')) {
1178
-	/**
1179
-	 * Transforme une image à palette indexée (256 couleurs max) en "vraies" couleurs RGB
1180
-	 *
1181
-	 * @note Pour compatibilité avec PHP < 5.5
1182
-	 *
1183
-	 * @link http://php.net/manual/fr/function.imagepalettetotruecolor.php
1184
-	 *
1185
-	 * @param ressource $img
1186
-	 * @return bool
1187
-	 *     - true si l'image est déjà en vrai RGB ou peut être transformée
1188
-	 *     - false si la transformation ne peut être faite.
1189
-	 **/
1190
-	function imagepalettetotruecolor(&$img) {
1191
-		if (!$img or !function_exists('imagecreatetruecolor')) {
1192
-			return false;
1193
-		} elseif (!imageistruecolor($img)) {
1194
-			$w = imagesx($img);
1195
-			$h = imagesy($img);
1196
-			$img1 = imagecreatetruecolor($w, $h);
1197
-			//Conserver la transparence si possible
1198
-			if (function_exists('ImageCopyResampled')) {
1199
-				if (function_exists('imageAntiAlias')) {
1200
-					imageAntiAlias($img1, true);
1201
-				}
1202
-				@imagealphablending($img1, false);
1203
-				@imagesavealpha($img1, true);
1204
-				@ImageCopyResampled($img1, $img, 0, 0, 0, 0, $w, $h, $w, $h);
1205
-			} else {
1206
-				imagecopy($img1, $img, 0, 0, 0, 0, $w, $h);
1207
-			}
1208
-
1209
-			$img = $img1;
1210
-		}
1211
-
1212
-		return true;
1213
-	}
1178
+    /**
1179
+     * Transforme une image à palette indexée (256 couleurs max) en "vraies" couleurs RGB
1180
+     *
1181
+     * @note Pour compatibilité avec PHP < 5.5
1182
+     *
1183
+     * @link http://php.net/manual/fr/function.imagepalettetotruecolor.php
1184
+     *
1185
+     * @param ressource $img
1186
+     * @return bool
1187
+     *     - true si l'image est déjà en vrai RGB ou peut être transformée
1188
+     *     - false si la transformation ne peut être faite.
1189
+     **/
1190
+    function imagepalettetotruecolor(&$img) {
1191
+        if (!$img or !function_exists('imagecreatetruecolor')) {
1192
+            return false;
1193
+        } elseif (!imageistruecolor($img)) {
1194
+            $w = imagesx($img);
1195
+            $h = imagesy($img);
1196
+            $img1 = imagecreatetruecolor($w, $h);
1197
+            //Conserver la transparence si possible
1198
+            if (function_exists('ImageCopyResampled')) {
1199
+                if (function_exists('imageAntiAlias')) {
1200
+                    imageAntiAlias($img1, true);
1201
+                }
1202
+                @imagealphablending($img1, false);
1203
+                @imagesavealpha($img1, true);
1204
+                @ImageCopyResampled($img1, $img, 0, 0, 0, 0, $w, $h, $w, $h);
1205
+            } else {
1206
+                imagecopy($img1, $img, 0, 0, 0, 0, $w, $h);
1207
+            }
1208
+
1209
+            $img = $img1;
1210
+        }
1211
+
1212
+        return true;
1213
+    }
1214 1214
 }
1215 1215
 
1216 1216
 /**
@@ -1237,32 +1237,32 @@  discard block
 block discarded – undo
1237 1237
  *     Code html modifié de la balise.
1238 1238
  **/
1239 1239
 function _image_tag_changer_taille($tag, $width, $height, $style = false) {
1240
-	if ($style === false) {
1241
-		$style = extraire_attribut($tag, 'style');
1242
-	}
1243
-
1244
-	// enlever le width et height du style
1245
-	$style = preg_replace(',(^|;)\s*(width|height)\s*:\s*[^;]+,ims', '', $style);
1246
-	if ($style and $style[0] == ';') {
1247
-		$style = substr($style, 1);
1248
-	}
1249
-
1250
-	// mettre des attributs de width et height sur les images,
1251
-	// ca accelere le rendu du navigateur
1252
-	// ca permet aux navigateurs de reserver la bonne taille
1253
-	// quand on a desactive l'affichage des images.
1254
-	$tag = inserer_attribut($tag, 'width', round($width));
1255
-	$tag = inserer_attribut($tag, 'height', round($height));
1256
-
1257
-	// attributs deprecies. Transformer en CSS
1258
-	if ($espace = extraire_attribut($tag, 'hspace')) {
1259
-		$style = "margin:${espace}px;" . $style;
1260
-		$tag = inserer_attribut($tag, 'hspace', '');
1261
-	}
1262
-
1263
-	$tag = inserer_attribut($tag, 'style', $style, true, $style ? false : true);
1264
-
1265
-	return $tag;
1240
+    if ($style === false) {
1241
+        $style = extraire_attribut($tag, 'style');
1242
+    }
1243
+
1244
+    // enlever le width et height du style
1245
+    $style = preg_replace(',(^|;)\s*(width|height)\s*:\s*[^;]+,ims', '', $style);
1246
+    if ($style and $style[0] == ';') {
1247
+        $style = substr($style, 1);
1248
+    }
1249
+
1250
+    // mettre des attributs de width et height sur les images,
1251
+    // ca accelere le rendu du navigateur
1252
+    // ca permet aux navigateurs de reserver la bonne taille
1253
+    // quand on a desactive l'affichage des images.
1254
+    $tag = inserer_attribut($tag, 'width', round($width));
1255
+    $tag = inserer_attribut($tag, 'height', round($height));
1256
+
1257
+    // attributs deprecies. Transformer en CSS
1258
+    if ($espace = extraire_attribut($tag, 'hspace')) {
1259
+        $style = "margin:${espace}px;" . $style;
1260
+        $tag = inserer_attribut($tag, 'hspace', '');
1261
+    }
1262
+
1263
+    $tag = inserer_attribut($tag, 'style', $style, true, $style ? false : true);
1264
+
1265
+    return $tag;
1266 1266
 }
1267 1267
 
1268 1268
 
@@ -1288,72 +1288,72 @@  discard block
 block discarded – undo
1288 1288
  *     Retourne le code HTML de l'image
1289 1289
  **/
1290 1290
 function _image_ecrire_tag($valeurs, $surcharge = []) {
1291
-	$valeurs = pipeline('image_ecrire_tag_preparer', $valeurs);
1292
-
1293
-	// fermer les tags img pas bien fermes;
1294
-	$tag = str_replace('>', '/>', str_replace('/>', '>', $valeurs['tag']));
1295
-
1296
-	// le style
1297
-	$style = $valeurs['style'];
1298
-	if (isset($surcharge['style'])) {
1299
-		$style = $surcharge['style'];
1300
-		unset($surcharge['style']);
1301
-	}
1302
-
1303
-	// traiter specifiquement la largeur et la hauteur
1304
-	$width = $valeurs['largeur'];
1305
-	if (isset($surcharge['width'])) {
1306
-		$width = $surcharge['width'];
1307
-		unset($surcharge['width']);
1308
-	}
1309
-	$height = $valeurs['hauteur'];
1310
-	if (isset($surcharge['height'])) {
1311
-		$height = $surcharge['height'];
1312
-		unset($surcharge['height']);
1313
-	}
1314
-
1315
-	$tag = _image_tag_changer_taille($tag, $width, $height, $style);
1316
-	// traiter specifiquement le src qui peut etre repris dans un onmouseout
1317
-	// on remplace toute les ref a src dans le tag
1318
-	$src = extraire_attribut($tag, 'src');
1319
-	if (isset($surcharge['src'])) {
1320
-		$tag = str_replace($src, $surcharge['src'], $tag);
1321
-		// si il y a des & dans src, alors ils peuvent provenir d'un &amp
1322
-		// pas garanti comme methode, mais mieux que rien
1323
-		if (strpos($src, '&') !== false) {
1324
-			$tag = str_replace(str_replace('&', '&amp;', $src), $surcharge['src'], $tag);
1325
-		}
1326
-		$src = $surcharge['src'];
1327
-		unset($surcharge['src']);
1328
-	}
1329
-
1330
-	$class = $valeurs['class'];
1331
-	if (isset($surcharge['class'])) {
1332
-		$class = $surcharge['class'];
1333
-		unset($surcharge['class']);
1334
-	}
1335
-	if (strlen($class)) {
1336
-		$tag = inserer_attribut($tag, 'class', $class);
1337
-	}
1338
-
1339
-	if (count($surcharge)) {
1340
-		foreach ($surcharge as $attribut => $valeur) {
1341
-			$tag = inserer_attribut($tag, $attribut, $valeur);
1342
-		}
1343
-	}
1344
-
1345
-	$tag = pipeline(
1346
-		'image_ecrire_tag_finir',
1347
-		[
1348
-			'args' => [
1349
-				'valeurs' => $valeurs,
1350
-				'surcharge' => $surcharge,
1351
-			],
1352
-			'data' => $tag
1353
-		]
1354
-	);
1355
-
1356
-	return $tag;
1291
+    $valeurs = pipeline('image_ecrire_tag_preparer', $valeurs);
1292
+
1293
+    // fermer les tags img pas bien fermes;
1294
+    $tag = str_replace('>', '/>', str_replace('/>', '>', $valeurs['tag']));
1295
+
1296
+    // le style
1297
+    $style = $valeurs['style'];
1298
+    if (isset($surcharge['style'])) {
1299
+        $style = $surcharge['style'];
1300
+        unset($surcharge['style']);
1301
+    }
1302
+
1303
+    // traiter specifiquement la largeur et la hauteur
1304
+    $width = $valeurs['largeur'];
1305
+    if (isset($surcharge['width'])) {
1306
+        $width = $surcharge['width'];
1307
+        unset($surcharge['width']);
1308
+    }
1309
+    $height = $valeurs['hauteur'];
1310
+    if (isset($surcharge['height'])) {
1311
+        $height = $surcharge['height'];
1312
+        unset($surcharge['height']);
1313
+    }
1314
+
1315
+    $tag = _image_tag_changer_taille($tag, $width, $height, $style);
1316
+    // traiter specifiquement le src qui peut etre repris dans un onmouseout
1317
+    // on remplace toute les ref a src dans le tag
1318
+    $src = extraire_attribut($tag, 'src');
1319
+    if (isset($surcharge['src'])) {
1320
+        $tag = str_replace($src, $surcharge['src'], $tag);
1321
+        // si il y a des & dans src, alors ils peuvent provenir d'un &amp
1322
+        // pas garanti comme methode, mais mieux que rien
1323
+        if (strpos($src, '&') !== false) {
1324
+            $tag = str_replace(str_replace('&', '&amp;', $src), $surcharge['src'], $tag);
1325
+        }
1326
+        $src = $surcharge['src'];
1327
+        unset($surcharge['src']);
1328
+    }
1329
+
1330
+    $class = $valeurs['class'];
1331
+    if (isset($surcharge['class'])) {
1332
+        $class = $surcharge['class'];
1333
+        unset($surcharge['class']);
1334
+    }
1335
+    if (strlen($class)) {
1336
+        $tag = inserer_attribut($tag, 'class', $class);
1337
+    }
1338
+
1339
+    if (count($surcharge)) {
1340
+        foreach ($surcharge as $attribut => $valeur) {
1341
+            $tag = inserer_attribut($tag, $attribut, $valeur);
1342
+        }
1343
+    }
1344
+
1345
+    $tag = pipeline(
1346
+        'image_ecrire_tag_finir',
1347
+        [
1348
+            'args' => [
1349
+                'valeurs' => $valeurs,
1350
+                'surcharge' => $surcharge,
1351
+            ],
1352
+            'data' => $tag
1353
+        ]
1354
+    );
1355
+
1356
+    return $tag;
1357 1357
 }
1358 1358
 
1359 1359
 /**
@@ -1376,257 +1376,257 @@  discard block
 block discarded – undo
1376 1376
  *     Description de l'image, sinon null.
1377 1377
  **/
1378 1378
 function _image_creer_vignette($valeurs, $maxWidth, $maxHeight, $process = 'AUTO', $force = false) {
1379
-	// ordre de preference des formats graphiques pour creer les vignettes
1380
-	// le premier format disponible, selon la methode demandee, est utilise
1381
-	$image = $valeurs['fichier'];
1382
-	$format = $valeurs['format_source'];
1383
-	$destdir = dirname($valeurs['fichier_dest']);
1384
-	$destfile = basename($valeurs['fichier_dest'], '.' . $valeurs['format_dest']);
1385
-
1386
-	$format_sortie = $valeurs['format_dest'];
1387
-
1388
-	if (($process == 'AUTO') and isset($GLOBALS['meta']['image_process'])) {
1389
-		$process = $GLOBALS['meta']['image_process'];
1390
-	}
1391
-
1392
-	// si le doc n'est pas une image dans un format accetpable, refuser
1393
-	if (!$force and !in_array($format, formats_image_acceptables(in_array($process, ['gd1', 'gd2'])))) {
1394
-		return;
1395
-	}
1396
-	$destination = "$destdir/$destfile";
1397
-
1398
-	// calculer la taille
1399
-	if (($srcWidth = $valeurs['largeur']) && ($srcHeight = $valeurs['hauteur'])) {
1400
-		if (!($destWidth = $valeurs['largeur_dest']) || !($destHeight = $valeurs['hauteur_dest'])) {
1401
-			list($destWidth, $destHeight) = _image_ratio($valeurs['largeur'], $valeurs['hauteur'], $maxWidth, $maxHeight);
1402
-		}
1403
-	} elseif ($process == 'convert' or $process == 'imagick') {
1404
-		$destWidth = $maxWidth;
1405
-		$destHeight = $maxHeight;
1406
-	} else {
1407
-		spip_log("echec $process sur $image");
1408
-
1409
-		return;
1410
-	}
1411
-
1412
-	$vignette = '';
1413
-
1414
-	// Si l'image est de la taille demandee (ou plus petite), simplement la retourner
1415
-	if ($srcWidth and $srcWidth <= $maxWidth and $srcHeight <= $maxHeight) {
1416
-		$vignette = $destination . '.' . $format;
1417
-		@copy($image, $vignette);
1418
-	}
1419
-
1420
-	elseif ($valeurs['format_source'] === 'svg') {
1421
-		if ($svg = svg_redimensionner($valeurs['fichier'], $destWidth, $destHeight)) {
1422
-			$format_sortie = 'svg';
1423
-			$vignette = $destination . '.' . $format_sortie;
1424
-			$valeurs['fichier_dest'] = $vignette;
1425
-			_image_gd_output($svg, $valeurs);
1426
-		}
1427
-	}
1428
-
1429
-	// imagemagick en ligne de commande
1430
-	elseif ($process == 'convert') {
1431
-		if (!defined('_CONVERT_COMMAND')) {
1432
-			define('_CONVERT_COMMAND', 'convert');
1433
-		} // Securite : mes_options.php peut preciser le chemin absolu
1434
-		if (!defined('_RESIZE_COMMAND')) {
1435
-			define('_RESIZE_COMMAND', _CONVERT_COMMAND . ' -quality ' . _IMG_CONVERT_QUALITE . ' -resize %xx%y! %src %dest');
1436
-		}
1437
-		$vignette = $destination . '.' . $format_sortie;
1438
-		$commande = str_replace(
1439
-			['%x', '%y', '%src', '%dest'],
1440
-			[
1441
-				$destWidth,
1442
-				$destHeight,
1443
-				escapeshellcmd($image),
1444
-				escapeshellcmd($vignette)
1445
-			],
1446
-			_RESIZE_COMMAND
1447
-		);
1448
-		spip_log($commande);
1449
-		exec($commande);
1450
-		if (!@file_exists($vignette)) {
1451
-			spip_log("echec convert sur $vignette");
1452
-
1453
-			return;  // echec commande
1454
-		}
1455
-	}
1456
-
1457
-	// php5 imagemagick
1458
-	elseif ($process == 'imagick') {
1459
-		$vignette = "$destination." . $format_sortie;
1460
-
1461
-		if (!class_exists('Imagick')) {
1462
-			spip_log('Classe Imagick absente !', _LOG_ERREUR);
1463
-
1464
-			return;
1465
-		}
1466
-		$imagick = new Imagick();
1467
-		$imagick->readImage($image);
1468
-		$imagick->resizeImage(
1469
-			$destWidth,
1470
-			$destHeight,
1471
-			Imagick::FILTER_LANCZOS,
1472
-			1
1473
-		);//, IMAGICK_FILTER_LANCZOS, _IMG_IMAGICK_QUALITE / 100);
1474
-		$imagick->writeImage($vignette);
1475
-
1476
-		if (!@file_exists($vignette)) {
1477
-			spip_log("echec imagick sur $vignette");
1478
-
1479
-			return;
1480
-		}
1481
-	}
1482
-
1483
-	// netpbm
1484
-	elseif ($process == 'netpbm') {
1485
-		if (!defined('_PNMSCALE_COMMAND')) {
1486
-			define('_PNMSCALE_COMMAND', 'pnmscale');
1487
-		} // Securite : mes_options.php peut preciser le chemin absolu
1488
-		if (_PNMSCALE_COMMAND == '') {
1489
-			return;
1490
-		}
1491
-		$vignette = $destination . '.' . $format_sortie;
1492
-		$pnmtojpeg_command = str_replace('pnmscale', 'pnmtojpeg', _PNMSCALE_COMMAND);
1493
-		if ($format == 'jpg') {
1494
-			$jpegtopnm_command = str_replace('pnmscale', 'jpegtopnm', _PNMSCALE_COMMAND);
1495
-			exec("$jpegtopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1496
-			if (!($s = @filesize($vignette))) {
1497
-				spip_unlink($vignette);
1498
-			}
1499
-			if (!@file_exists($vignette)) {
1500
-				spip_log("echec netpbm-jpg sur $vignette");
1501
-
1502
-				return;
1503
-			}
1504
-		} else {
1505
-			if ($format == 'gif') {
1506
-				$giftopnm_command = str_replace('pnmscale', 'giftopnm', _PNMSCALE_COMMAND);
1507
-				exec("$giftopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1508
-				if (!($s = @filesize($vignette))) {
1509
-					spip_unlink($vignette);
1510
-				}
1511
-				if (!@file_exists($vignette)) {
1512
-					spip_log("echec netpbm-gif sur $vignette");
1513
-
1514
-					return;
1515
-				}
1516
-			} else {
1517
-				if ($format == 'png') {
1518
-					$pngtopnm_command = str_replace('pnmscale', 'pngtopnm', _PNMSCALE_COMMAND);
1519
-					exec("$pngtopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1520
-					if (!($s = @filesize($vignette))) {
1521
-						spip_unlink($vignette);
1522
-					}
1523
-					if (!@file_exists($vignette)) {
1524
-						spip_log("echec netpbm-png sur $vignette");
1525
-
1526
-						return;
1527
-					}
1528
-				}
1529
-			}
1530
-		}
1531
-	}
1532
-
1533
-	// gd ou gd2
1534
-	elseif ($process == 'gd1' or $process == 'gd2') {
1535
-		if (!function_exists('gd_info')) {
1536
-			spip_log('Librairie GD absente !', _LOG_ERREUR);
1537
-
1538
-			return;
1539
-		}
1540
-		if (_IMG_GD_MAX_PIXELS && $srcWidth * $srcHeight > _IMG_GD_MAX_PIXELS) {
1541
-			spip_log('vignette gd1/gd2 impossible : ' . $srcWidth * $srcHeight . 'pixels');
1542
-
1543
-			return;
1544
-		}
1545
-		$destFormat = $format_sortie;
1546
-		if (!$destFormat) {
1547
-			spip_log("pas de format pour $image");
1548
-
1549
-			return;
1550
-		}
1551
-
1552
-		$fonction_imagecreatefrom = $valeurs['fonction_imagecreatefrom'];
1553
-		if (!function_exists($fonction_imagecreatefrom)) {
1554
-			return '';
1555
-		}
1556
-		$srcImage = @$fonction_imagecreatefrom($image);
1557
-		if (!$srcImage) {
1558
-			spip_log('echec gd1/gd2');
1559
-
1560
-			return;
1561
-		}
1562
-
1563
-		// Initialisation de l'image destination
1564
-		$destImage = null;
1565
-		if ($process == 'gd2' and $destFormat != 'gif') {
1566
-			$destImage = ImageCreateTrueColor($destWidth, $destHeight);
1567
-		}
1568
-		if (!$destImage) {
1569
-			$destImage = ImageCreate($destWidth, $destHeight);
1570
-		}
1571
-
1572
-		// Recopie de l'image d'origine avec adaptation de la taille
1573
-		$ok = false;
1574
-		if (($process == 'gd2') and function_exists('ImageCopyResampled')) {
1575
-			if ($format == 'gif') {
1576
-				// Si un GIF est transparent,
1577
-				// fabriquer un PNG transparent
1578
-				$transp = imagecolortransparent($srcImage);
1579
-				if ($transp > 0) {
1580
-					$destFormat = 'png';
1581
-				}
1582
-			}
1583
-			if (in_array($destFormat, _image_extensions_conservent_transparence())) {
1584
-				// Conserver la transparence
1585
-				if (function_exists('imageAntiAlias')) {
1586
-					imageAntiAlias($destImage, true);
1587
-				}
1588
-				@imagealphablending($destImage, false);
1589
-				@imagesavealpha($destImage, true);
1590
-			}
1591
-			$ok = @ImageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
1592
-		}
1593
-		if (!$ok) {
1594
-			$ok = ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
1595
-		}
1596
-
1597
-		// Sauvegarde de l'image destination
1598
-		$valeurs['fichier_dest'] = $vignette = "$destination.$destFormat";
1599
-		$valeurs['format_dest'] = $format = $destFormat;
1600
-		_image_gd_output($destImage, $valeurs);
1601
-
1602
-		if ($srcImage) {
1603
-			ImageDestroy($srcImage);
1604
-		}
1605
-		ImageDestroy($destImage);
1606
-	}
1607
-
1608
-	if (!$vignette or !$size = @spip_getimagesize($vignette)) {
1609
-		$size = [$destWidth, $destHeight];
1610
-	}
1611
-
1612
-	// Gaffe: en safe mode, pas d'acces a la vignette,
1613
-	// donc risque de balancer "width='0'", ce qui masque l'image sous MSIE
1614
-	if ($size[0] < 1) {
1615
-		$size[0] = $destWidth;
1616
-	}
1617
-	if ($size[1] < 1) {
1618
-		$size[1] = $destHeight;
1619
-	}
1620
-
1621
-	$retour['width'] = $largeur = $size[0];
1622
-	$retour['height'] = $hauteur = $size[1];
1623
-
1624
-	$retour['fichier'] = $vignette;
1625
-	$retour['format'] = $format;
1626
-	$retour['date'] = @filemtime($vignette);
1627
-
1628
-	// renvoyer l'image
1629
-	return $retour;
1379
+    // ordre de preference des formats graphiques pour creer les vignettes
1380
+    // le premier format disponible, selon la methode demandee, est utilise
1381
+    $image = $valeurs['fichier'];
1382
+    $format = $valeurs['format_source'];
1383
+    $destdir = dirname($valeurs['fichier_dest']);
1384
+    $destfile = basename($valeurs['fichier_dest'], '.' . $valeurs['format_dest']);
1385
+
1386
+    $format_sortie = $valeurs['format_dest'];
1387
+
1388
+    if (($process == 'AUTO') and isset($GLOBALS['meta']['image_process'])) {
1389
+        $process = $GLOBALS['meta']['image_process'];
1390
+    }
1391
+
1392
+    // si le doc n'est pas une image dans un format accetpable, refuser
1393
+    if (!$force and !in_array($format, formats_image_acceptables(in_array($process, ['gd1', 'gd2'])))) {
1394
+        return;
1395
+    }
1396
+    $destination = "$destdir/$destfile";
1397
+
1398
+    // calculer la taille
1399
+    if (($srcWidth = $valeurs['largeur']) && ($srcHeight = $valeurs['hauteur'])) {
1400
+        if (!($destWidth = $valeurs['largeur_dest']) || !($destHeight = $valeurs['hauteur_dest'])) {
1401
+            list($destWidth, $destHeight) = _image_ratio($valeurs['largeur'], $valeurs['hauteur'], $maxWidth, $maxHeight);
1402
+        }
1403
+    } elseif ($process == 'convert' or $process == 'imagick') {
1404
+        $destWidth = $maxWidth;
1405
+        $destHeight = $maxHeight;
1406
+    } else {
1407
+        spip_log("echec $process sur $image");
1408
+
1409
+        return;
1410
+    }
1411
+
1412
+    $vignette = '';
1413
+
1414
+    // Si l'image est de la taille demandee (ou plus petite), simplement la retourner
1415
+    if ($srcWidth and $srcWidth <= $maxWidth and $srcHeight <= $maxHeight) {
1416
+        $vignette = $destination . '.' . $format;
1417
+        @copy($image, $vignette);
1418
+    }
1419
+
1420
+    elseif ($valeurs['format_source'] === 'svg') {
1421
+        if ($svg = svg_redimensionner($valeurs['fichier'], $destWidth, $destHeight)) {
1422
+            $format_sortie = 'svg';
1423
+            $vignette = $destination . '.' . $format_sortie;
1424
+            $valeurs['fichier_dest'] = $vignette;
1425
+            _image_gd_output($svg, $valeurs);
1426
+        }
1427
+    }
1428
+
1429
+    // imagemagick en ligne de commande
1430
+    elseif ($process == 'convert') {
1431
+        if (!defined('_CONVERT_COMMAND')) {
1432
+            define('_CONVERT_COMMAND', 'convert');
1433
+        } // Securite : mes_options.php peut preciser le chemin absolu
1434
+        if (!defined('_RESIZE_COMMAND')) {
1435
+            define('_RESIZE_COMMAND', _CONVERT_COMMAND . ' -quality ' . _IMG_CONVERT_QUALITE . ' -resize %xx%y! %src %dest');
1436
+        }
1437
+        $vignette = $destination . '.' . $format_sortie;
1438
+        $commande = str_replace(
1439
+            ['%x', '%y', '%src', '%dest'],
1440
+            [
1441
+                $destWidth,
1442
+                $destHeight,
1443
+                escapeshellcmd($image),
1444
+                escapeshellcmd($vignette)
1445
+            ],
1446
+            _RESIZE_COMMAND
1447
+        );
1448
+        spip_log($commande);
1449
+        exec($commande);
1450
+        if (!@file_exists($vignette)) {
1451
+            spip_log("echec convert sur $vignette");
1452
+
1453
+            return;  // echec commande
1454
+        }
1455
+    }
1456
+
1457
+    // php5 imagemagick
1458
+    elseif ($process == 'imagick') {
1459
+        $vignette = "$destination." . $format_sortie;
1460
+
1461
+        if (!class_exists('Imagick')) {
1462
+            spip_log('Classe Imagick absente !', _LOG_ERREUR);
1463
+
1464
+            return;
1465
+        }
1466
+        $imagick = new Imagick();
1467
+        $imagick->readImage($image);
1468
+        $imagick->resizeImage(
1469
+            $destWidth,
1470
+            $destHeight,
1471
+            Imagick::FILTER_LANCZOS,
1472
+            1
1473
+        );//, IMAGICK_FILTER_LANCZOS, _IMG_IMAGICK_QUALITE / 100);
1474
+        $imagick->writeImage($vignette);
1475
+
1476
+        if (!@file_exists($vignette)) {
1477
+            spip_log("echec imagick sur $vignette");
1478
+
1479
+            return;
1480
+        }
1481
+    }
1482
+
1483
+    // netpbm
1484
+    elseif ($process == 'netpbm') {
1485
+        if (!defined('_PNMSCALE_COMMAND')) {
1486
+            define('_PNMSCALE_COMMAND', 'pnmscale');
1487
+        } // Securite : mes_options.php peut preciser le chemin absolu
1488
+        if (_PNMSCALE_COMMAND == '') {
1489
+            return;
1490
+        }
1491
+        $vignette = $destination . '.' . $format_sortie;
1492
+        $pnmtojpeg_command = str_replace('pnmscale', 'pnmtojpeg', _PNMSCALE_COMMAND);
1493
+        if ($format == 'jpg') {
1494
+            $jpegtopnm_command = str_replace('pnmscale', 'jpegtopnm', _PNMSCALE_COMMAND);
1495
+            exec("$jpegtopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1496
+            if (!($s = @filesize($vignette))) {
1497
+                spip_unlink($vignette);
1498
+            }
1499
+            if (!@file_exists($vignette)) {
1500
+                spip_log("echec netpbm-jpg sur $vignette");
1501
+
1502
+                return;
1503
+            }
1504
+        } else {
1505
+            if ($format == 'gif') {
1506
+                $giftopnm_command = str_replace('pnmscale', 'giftopnm', _PNMSCALE_COMMAND);
1507
+                exec("$giftopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1508
+                if (!($s = @filesize($vignette))) {
1509
+                    spip_unlink($vignette);
1510
+                }
1511
+                if (!@file_exists($vignette)) {
1512
+                    spip_log("echec netpbm-gif sur $vignette");
1513
+
1514
+                    return;
1515
+                }
1516
+            } else {
1517
+                if ($format == 'png') {
1518
+                    $pngtopnm_command = str_replace('pnmscale', 'pngtopnm', _PNMSCALE_COMMAND);
1519
+                    exec("$pngtopnm_command $image | " . _PNMSCALE_COMMAND . " -width $destWidth | $pnmtojpeg_command > $vignette");
1520
+                    if (!($s = @filesize($vignette))) {
1521
+                        spip_unlink($vignette);
1522
+                    }
1523
+                    if (!@file_exists($vignette)) {
1524
+                        spip_log("echec netpbm-png sur $vignette");
1525
+
1526
+                        return;
1527
+                    }
1528
+                }
1529
+            }
1530
+        }
1531
+    }
1532
+
1533
+    // gd ou gd2
1534
+    elseif ($process == 'gd1' or $process == 'gd2') {
1535
+        if (!function_exists('gd_info')) {
1536
+            spip_log('Librairie GD absente !', _LOG_ERREUR);
1537
+
1538
+            return;
1539
+        }
1540
+        if (_IMG_GD_MAX_PIXELS && $srcWidth * $srcHeight > _IMG_GD_MAX_PIXELS) {
1541
+            spip_log('vignette gd1/gd2 impossible : ' . $srcWidth * $srcHeight . 'pixels');
1542
+
1543
+            return;
1544
+        }
1545
+        $destFormat = $format_sortie;
1546
+        if (!$destFormat) {
1547
+            spip_log("pas de format pour $image");
1548
+
1549
+            return;
1550
+        }
1551
+
1552
+        $fonction_imagecreatefrom = $valeurs['fonction_imagecreatefrom'];
1553
+        if (!function_exists($fonction_imagecreatefrom)) {
1554
+            return '';
1555
+        }
1556
+        $srcImage = @$fonction_imagecreatefrom($image);
1557
+        if (!$srcImage) {
1558
+            spip_log('echec gd1/gd2');
1559
+
1560
+            return;
1561
+        }
1562
+
1563
+        // Initialisation de l'image destination
1564
+        $destImage = null;
1565
+        if ($process == 'gd2' and $destFormat != 'gif') {
1566
+            $destImage = ImageCreateTrueColor($destWidth, $destHeight);
1567
+        }
1568
+        if (!$destImage) {
1569
+            $destImage = ImageCreate($destWidth, $destHeight);
1570
+        }
1571
+
1572
+        // Recopie de l'image d'origine avec adaptation de la taille
1573
+        $ok = false;
1574
+        if (($process == 'gd2') and function_exists('ImageCopyResampled')) {
1575
+            if ($format == 'gif') {
1576
+                // Si un GIF est transparent,
1577
+                // fabriquer un PNG transparent
1578
+                $transp = imagecolortransparent($srcImage);
1579
+                if ($transp > 0) {
1580
+                    $destFormat = 'png';
1581
+                }
1582
+            }
1583
+            if (in_array($destFormat, _image_extensions_conservent_transparence())) {
1584
+                // Conserver la transparence
1585
+                if (function_exists('imageAntiAlias')) {
1586
+                    imageAntiAlias($destImage, true);
1587
+                }
1588
+                @imagealphablending($destImage, false);
1589
+                @imagesavealpha($destImage, true);
1590
+            }
1591
+            $ok = @ImageCopyResampled($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
1592
+        }
1593
+        if (!$ok) {
1594
+            $ok = ImageCopyResized($destImage, $srcImage, 0, 0, 0, 0, $destWidth, $destHeight, $srcWidth, $srcHeight);
1595
+        }
1596
+
1597
+        // Sauvegarde de l'image destination
1598
+        $valeurs['fichier_dest'] = $vignette = "$destination.$destFormat";
1599
+        $valeurs['format_dest'] = $format = $destFormat;
1600
+        _image_gd_output($destImage, $valeurs);
1601
+
1602
+        if ($srcImage) {
1603
+            ImageDestroy($srcImage);
1604
+        }
1605
+        ImageDestroy($destImage);
1606
+    }
1607
+
1608
+    if (!$vignette or !$size = @spip_getimagesize($vignette)) {
1609
+        $size = [$destWidth, $destHeight];
1610
+    }
1611
+
1612
+    // Gaffe: en safe mode, pas d'acces a la vignette,
1613
+    // donc risque de balancer "width='0'", ce qui masque l'image sous MSIE
1614
+    if ($size[0] < 1) {
1615
+        $size[0] = $destWidth;
1616
+    }
1617
+    if ($size[1] < 1) {
1618
+        $size[1] = $destHeight;
1619
+    }
1620
+
1621
+    $retour['width'] = $largeur = $size[0];
1622
+    $retour['height'] = $hauteur = $size[1];
1623
+
1624
+    $retour['fichier'] = $vignette;
1625
+    $retour['format'] = $format;
1626
+    $retour['date'] = @filemtime($vignette);
1627
+
1628
+    // renvoyer l'image
1629
+    return $retour;
1630 1630
 }
1631 1631
 
1632 1632
 /**
@@ -1646,25 +1646,25 @@  discard block
 block discarded – undo
1646 1646
  * @return array Liste [ largeur, hauteur, ratio de réduction ]
1647 1647
  **/
1648 1648
 function _image_ratio($srcWidth, $srcHeight, $maxWidth, $maxHeight) {
1649
-	$ratioWidth = $srcWidth / $maxWidth;
1650
-	$ratioHeight = $srcHeight / $maxHeight;
1651
-
1652
-	if ($srcWidth <= $maxWidth and $srcHeight <= $maxHeight) {
1653
-		$destWidth = $srcWidth;
1654
-		$destHeight = $srcHeight;
1655
-	} elseif ($ratioWidth < $ratioHeight) {
1656
-		$destWidth = $srcWidth / $ratioHeight;
1657
-		$destHeight = $maxHeight;
1658
-	} else {
1659
-		$destWidth = $maxWidth;
1660
-		$destHeight = $srcHeight / $ratioWidth;
1661
-	}
1662
-
1663
-	return [
1664
-		intval(round($destWidth)),
1665
-		intval(round($destHeight)),
1666
-		max($ratioWidth, $ratioHeight)
1667
-	];
1649
+    $ratioWidth = $srcWidth / $maxWidth;
1650
+    $ratioHeight = $srcHeight / $maxHeight;
1651
+
1652
+    if ($srcWidth <= $maxWidth and $srcHeight <= $maxHeight) {
1653
+        $destWidth = $srcWidth;
1654
+        $destHeight = $srcHeight;
1655
+    } elseif ($ratioWidth < $ratioHeight) {
1656
+        $destWidth = $srcWidth / $ratioHeight;
1657
+        $destHeight = $maxHeight;
1658
+    } else {
1659
+        $destWidth = $maxWidth;
1660
+        $destHeight = $srcHeight / $ratioWidth;
1661
+    }
1662
+
1663
+    return [
1664
+        intval(round($destWidth)),
1665
+        intval(round($destHeight)),
1666
+        max($ratioWidth, $ratioHeight)
1667
+    ];
1668 1668
 }
1669 1669
 
1670 1670
 /**
@@ -1684,25 +1684,25 @@  discard block
 block discarded – undo
1684 1684
  * @return array Liste [ largeur, hauteur, ratio de réduction ]
1685 1685
  **/
1686 1686
 function ratio_passe_partout($srcWidth, $srcHeight, $maxWidth, $maxHeight) {
1687
-	$ratioWidth = $srcWidth / $maxWidth;
1688
-	$ratioHeight = $srcHeight / $maxHeight;
1689
-
1690
-	if ($srcWidth <= $maxWidth and $srcHeight <= $maxHeight) {
1691
-		$destWidth = $srcWidth;
1692
-		$destHeight = $srcHeight;
1693
-	} elseif ($ratioWidth > $ratioHeight) {
1694
-		$destWidth = $srcWidth / $ratioHeight;
1695
-		$destHeight = $maxHeight;
1696
-	} else {
1697
-		$destWidth = $maxWidth;
1698
-		$destHeight = $srcHeight / $ratioWidth;
1699
-	}
1700
-
1701
-	return [
1702
-		intval(round($destWidth)),
1703
-		intval(round($destHeight)),
1704
-		min($ratioWidth, $ratioHeight)
1705
-	];
1687
+    $ratioWidth = $srcWidth / $maxWidth;
1688
+    $ratioHeight = $srcHeight / $maxHeight;
1689
+
1690
+    if ($srcWidth <= $maxWidth and $srcHeight <= $maxHeight) {
1691
+        $destWidth = $srcWidth;
1692
+        $destHeight = $srcHeight;
1693
+    } elseif ($ratioWidth > $ratioHeight) {
1694
+        $destWidth = $srcWidth / $ratioHeight;
1695
+        $destHeight = $maxHeight;
1696
+    } else {
1697
+        $destWidth = $maxWidth;
1698
+        $destHeight = $srcHeight / $ratioWidth;
1699
+    }
1700
+
1701
+    return [
1702
+        intval(round($destWidth)),
1703
+        intval(round($destHeight)),
1704
+        min($ratioWidth, $ratioHeight)
1705
+    ];
1706 1706
 }
1707 1707
 
1708 1708
 
@@ -1715,12 +1715,12 @@  discard block
 block discarded – undo
1715 1715
  * @return string
1716 1716
  */
1717 1717
 function process_image_svg_identite($image) {
1718
-	if ($image['creer']) {
1719
-		$source = $image['fichier'];
1720
-		_image_gd_output($source, $image);
1721
-	}
1718
+    if ($image['creer']) {
1719
+        $source = $image['fichier'];
1720
+        _image_gd_output($source, $image);
1721
+    }
1722 1722
 
1723
-	return _image_ecrire_tag($image, ['src' => $image['fichier_dest']]);
1723
+    return _image_ecrire_tag($image, ['src' => $image['fichier_dest']]);
1724 1724
 }
1725 1725
 
1726 1726
 
@@ -1753,111 +1753,111 @@  discard block
 block discarded – undo
1753 1753
  *     Code HTML de la balise img produite
1754 1754
  **/
1755 1755
 function process_image_reduire($fonction, $img, $taille, $taille_y, $force, $process = 'AUTO') {
1756
-	$image = false;
1757
-	if (($process == 'AUTO') and isset($GLOBALS['meta']['image_process'])) {
1758
-		$process = $GLOBALS['meta']['image_process'];
1759
-	}
1760
-	# determiner le format de sortie
1761
-	$format_sortie = false; // le choix par defaut sera bon
1762
-	if ($process == 'netpbm') {
1763
-		$format_sortie = 'jpg';
1764
-	} elseif ($process == 'gd1' or $process == 'gd2') {
1765
-		$image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}", $format_sortie, $fonction, false, _SVG_SUPPORTED);
1766
-		// on verifie que l'extension choisie est bonne (en principe oui)
1767
-		$gd_formats = formats_image_acceptables(true);
1768
-		if (
1769
-			is_array($image)
1770
-			and (!in_array($image['format_dest'], $gd_formats)
1771
-				or (!in_array($image['format_dest'], _image_extensions_acceptees_en_sortie()))
1772
-			)
1773
-		) {
1774
-			if ($image['format_source'] == 'jpg') {
1775
-				$formats_sortie = ['jpg', 'png', 'gif'];
1776
-			} else // les gif sont passes en png preferentiellement pour etre homogene aux autres filtres images
1777
-			{
1778
-				$formats_sortie = ['png', 'jpg', 'gif'];
1779
-			}
1780
-			// Choisir le format destination
1781
-			// - on sauve de preference en JPEG (meilleure compression)
1782
-			// - pour le GIF : les GD recentes peuvent le lire mais pas l'ecrire
1783
-			# bug : gd_formats contient la liste des fichiers qu'on sait *lire*,
1784
-			# pas *ecrire*
1785
-			$format_sortie = '';
1786
-			foreach ($formats_sortie as $fmt) {
1787
-				if (in_array($fmt, $gd_formats) and in_array($fmt, _image_extensions_acceptees_en_sortie())) {
1788
-					$format_sortie = $fmt;
1789
-					break;
1790
-				}
1791
-			}
1792
-			$image = false;
1793
-		}
1794
-	}
1795
-
1796
-	if (!is_array($image)) {
1797
-		$image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}", $format_sortie, $fonction, false, _SVG_SUPPORTED);
1798
-	}
1799
-
1800
-	if (!is_array($image) or !$image['largeur'] or !$image['hauteur']) {
1801
-		spip_log("image_reduire_src:pas de version locale de $img");
1802
-		// on peut resizer en mode html si on dispose des elements
1803
-		if (
1804
-			$srcw = extraire_attribut($img, 'width')
1805
-			and $srch = extraire_attribut($img, 'height')
1806
-		) {
1807
-			list($w, $h) = _image_ratio($srcw, $srch, $taille, $taille_y);
1808
-
1809
-			return _image_tag_changer_taille($img, $w, $h);
1810
-		}
1811
-		// la on n'a pas d'infos sur l'image source... on refile le truc a css
1812
-		// sous la forme style='max-width: NNpx;'
1813
-		return inserer_attribut(
1814
-			$img,
1815
-			'style',
1816
-			"max-width: ${taille}px; max-height: ${taille_y}px"
1817
-		);
1818
-	}
1819
-
1820
-	// si l'image est plus petite que la cible retourner une copie cachee de l'image
1821
-	if (($image['largeur'] <= $taille) && ($image['hauteur'] <= $taille_y)) {
1822
-		if ($image['creer']) {
1823
-			@copy($image['fichier'], $image['fichier_dest']);
1824
-		}
1825
-
1826
-		return _image_ecrire_tag($image, ['src' => $image['fichier_dest']]);
1827
-	}
1828
-
1829
-	if ($image['creer'] == false && !$force) {
1830
-		return _image_ecrire_tag(
1831
-			$image,
1832
-			['src' => $image['fichier_dest'], 'width' => $image['largeur_dest'], 'height' => $image['hauteur_dest']]
1833
-		);
1834
-	}
1835
-
1836
-	if (in_array($image['format_source'], _image_extensions_acceptees_en_entree())) {
1837
-		$destWidth = $image['largeur_dest'];
1838
-		$destHeight = $image['hauteur_dest'];
1839
-		$logo = $image['fichier'];
1840
-		$date = $image['date_src'];
1841
-		$preview = _image_creer_vignette($image, $taille, $taille_y, $process, $force);
1842
-
1843
-		if ($preview && $preview['fichier']) {
1844
-			$logo = $preview['fichier'];
1845
-			$destWidth = $preview['width'];
1846
-			$destHeight = $preview['height'];
1847
-			$date = $preview['date'];
1848
-		}
1849
-		// dans l'espace prive mettre un timestamp sur l'adresse
1850
-		// de l'image, de facon a tromper le cache du navigateur
1851
-		// quand on fait supprimer/reuploader un logo
1852
-		// (pas de filemtime si SAFE MODE)
1853
-		$date = test_espace_prive() ? ('?' . $date) : '';
1854
-
1855
-		return _image_ecrire_tag($image, ['src' => "$logo$date", 'width' => $destWidth, 'height' => $destHeight]);
1856
-	}
1857
-	else {
1858
-		# BMP, tiff ... les redacteurs osent tout!
1859
-		return $img;
1860
-	}
1756
+    $image = false;
1757
+    if (($process == 'AUTO') and isset($GLOBALS['meta']['image_process'])) {
1758
+        $process = $GLOBALS['meta']['image_process'];
1759
+    }
1760
+    # determiner le format de sortie
1761
+    $format_sortie = false; // le choix par defaut sera bon
1762
+    if ($process == 'netpbm') {
1763
+        $format_sortie = 'jpg';
1764
+    } elseif ($process == 'gd1' or $process == 'gd2') {
1765
+        $image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}", $format_sortie, $fonction, false, _SVG_SUPPORTED);
1766
+        // on verifie que l'extension choisie est bonne (en principe oui)
1767
+        $gd_formats = formats_image_acceptables(true);
1768
+        if (
1769
+            is_array($image)
1770
+            and (!in_array($image['format_dest'], $gd_formats)
1771
+                or (!in_array($image['format_dest'], _image_extensions_acceptees_en_sortie()))
1772
+            )
1773
+        ) {
1774
+            if ($image['format_source'] == 'jpg') {
1775
+                $formats_sortie = ['jpg', 'png', 'gif'];
1776
+            } else // les gif sont passes en png preferentiellement pour etre homogene aux autres filtres images
1777
+            {
1778
+                $formats_sortie = ['png', 'jpg', 'gif'];
1779
+            }
1780
+            // Choisir le format destination
1781
+            // - on sauve de preference en JPEG (meilleure compression)
1782
+            // - pour le GIF : les GD recentes peuvent le lire mais pas l'ecrire
1783
+            # bug : gd_formats contient la liste des fichiers qu'on sait *lire*,
1784
+            # pas *ecrire*
1785
+            $format_sortie = '';
1786
+            foreach ($formats_sortie as $fmt) {
1787
+                if (in_array($fmt, $gd_formats) and in_array($fmt, _image_extensions_acceptees_en_sortie())) {
1788
+                    $format_sortie = $fmt;
1789
+                    break;
1790
+                }
1791
+            }
1792
+            $image = false;
1793
+        }
1794
+    }
1795
+
1796
+    if (!is_array($image)) {
1797
+        $image = _image_valeurs_trans($img, "reduire-{$taille}-{$taille_y}", $format_sortie, $fonction, false, _SVG_SUPPORTED);
1798
+    }
1799
+
1800
+    if (!is_array($image) or !$image['largeur'] or !$image['hauteur']) {
1801
+        spip_log("image_reduire_src:pas de version locale de $img");
1802
+        // on peut resizer en mode html si on dispose des elements
1803
+        if (
1804
+            $srcw = extraire_attribut($img, 'width')
1805
+            and $srch = extraire_attribut($img, 'height')
1806
+        ) {
1807
+            list($w, $h) = _image_ratio($srcw, $srch, $taille, $taille_y);
1808
+
1809
+            return _image_tag_changer_taille($img, $w, $h);
1810
+        }
1811
+        // la on n'a pas d'infos sur l'image source... on refile le truc a css
1812
+        // sous la forme style='max-width: NNpx;'
1813
+        return inserer_attribut(
1814
+            $img,
1815
+            'style',
1816
+            "max-width: ${taille}px; max-height: ${taille_y}px"
1817
+        );
1818
+    }
1819
+
1820
+    // si l'image est plus petite que la cible retourner une copie cachee de l'image
1821
+    if (($image['largeur'] <= $taille) && ($image['hauteur'] <= $taille_y)) {
1822
+        if ($image['creer']) {
1823
+            @copy($image['fichier'], $image['fichier_dest']);
1824
+        }
1825
+
1826
+        return _image_ecrire_tag($image, ['src' => $image['fichier_dest']]);
1827
+    }
1828
+
1829
+    if ($image['creer'] == false && !$force) {
1830
+        return _image_ecrire_tag(
1831
+            $image,
1832
+            ['src' => $image['fichier_dest'], 'width' => $image['largeur_dest'], 'height' => $image['hauteur_dest']]
1833
+        );
1834
+    }
1835
+
1836
+    if (in_array($image['format_source'], _image_extensions_acceptees_en_entree())) {
1837
+        $destWidth = $image['largeur_dest'];
1838
+        $destHeight = $image['hauteur_dest'];
1839
+        $logo = $image['fichier'];
1840
+        $date = $image['date_src'];
1841
+        $preview = _image_creer_vignette($image, $taille, $taille_y, $process, $force);
1842
+
1843
+        if ($preview && $preview['fichier']) {
1844
+            $logo = $preview['fichier'];
1845
+            $destWidth = $preview['width'];
1846
+            $destHeight = $preview['height'];
1847
+            $date = $preview['date'];
1848
+        }
1849
+        // dans l'espace prive mettre un timestamp sur l'adresse
1850
+        // de l'image, de facon a tromper le cache du navigateur
1851
+        // quand on fait supprimer/reuploader un logo
1852
+        // (pas de filemtime si SAFE MODE)
1853
+        $date = test_espace_prive() ? ('?' . $date) : '';
1854
+
1855
+        return _image_ecrire_tag($image, ['src' => "$logo$date", 'width' => $destWidth, 'height' => $destHeight]);
1856
+    }
1857
+    else {
1858
+        # BMP, tiff ... les redacteurs osent tout!
1859
+        return $img;
1860
+    }
1861 1861
 }
1862 1862
 
1863 1863
 /**
@@ -1872,145 +1872,145 @@  discard block
 block discarded – undo
1872 1872
  */
1873 1873
 class phpthumb_functions {
1874 1874
 
1875
-	/**
1876
-	 * Retourne la couleur d'un pixel dans une image
1877
-	 *
1878
-	 * @param ressource $img
1879
-	 * @param int $x
1880
-	 * @param int $y
1881
-	 * @return array|bool
1882
-	 */
1883
-	public static function GetPixelColor(&$img, $x, $y) {
1884
-		if (is_resource($img) || (is_object($img) && $img instanceof \GdImage)) {
1885
-			return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));
1886
-		}
1887
-		return false;
1888
-	}
1889
-
1890
-	/**
1891
-	 * Retourne un nombre dans une représentation en Little Endian
1892
-	 *
1893
-	 * @param int $number
1894
-	 * @param int $minbytes
1895
-	 * @return string
1896
-	 */
1897
-	public static function LittleEndian2String($number, $minbytes = 1) {
1898
-		$intstring = '';
1899
-		while ($number > 0) {
1900
-			$intstring = $intstring . chr($number & 255);
1901
-			$number >>= 8;
1902
-		}
1903
-
1904
-		return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
1905
-	}
1906
-
1907
-	/**
1908
-	 * Transforme une ressource GD en image au format ICO
1909
-	 *
1910
-	 * @param array $gd_image_array
1911
-	 *     Tableau de ressources d'images GD
1912
-	 * @return string
1913
-	 *     Image au format ICO
1914
-	 */
1915
-	public static function GD2ICOstring(&$gd_image_array) {
1916
-		foreach ($gd_image_array as $key => $gd_image) {
1917
-			$ImageWidths[$key] = ImageSX($gd_image);
1918
-			$ImageHeights[$key] = ImageSY($gd_image);
1919
-			$bpp[$key] = ImageIsTrueColor($gd_image) ? 32 : 24;
1920
-			$totalcolors[$key] = ImageColorsTotal($gd_image);
1921
-
1922
-			$icXOR[$key] = '';
1923
-			for ($y = $ImageHeights[$key] - 1; $y >= 0; $y--) {
1924
-				for ($x = 0; $x < $ImageWidths[$key]; $x++) {
1925
-					$argb = phpthumb_functions::GetPixelColor($gd_image, $x, $y);
1926
-					$a = round(255 * ((127 - $argb['alpha']) / 127));
1927
-					$r = $argb['red'];
1928
-					$g = $argb['green'];
1929
-					$b = $argb['blue'];
1930
-
1931
-					if ($bpp[$key] == 32) {
1932
-						$icXOR[$key] .= chr($b) . chr($g) . chr($r) . chr($a);
1933
-					} elseif ($bpp[$key] == 24) {
1934
-						$icXOR[$key] .= chr($b) . chr($g) . chr($r);
1935
-					}
1936
-
1937
-					if ($a < 128) {
1938
-						@$icANDmask[$key][$y] .= '1';
1939
-					} else {
1940
-						@$icANDmask[$key][$y] .= '0';
1941
-					}
1942
-				}
1943
-				// mask bits are 32-bit aligned per scanline
1944
-				while (strlen($icANDmask[$key][$y]) % 32) {
1945
-					$icANDmask[$key][$y] .= '0';
1946
-				}
1947
-			}
1948
-			$icAND[$key] = '';
1949
-			foreach ($icANDmask[$key] as $y => $scanlinemaskbits) {
1950
-				for ($i = 0; $i < strlen($scanlinemaskbits); $i += 8) {
1951
-					$icAND[$key] .= chr(bindec(str_pad(substr($scanlinemaskbits, $i, 8), 8, '0', STR_PAD_LEFT)));
1952
-				}
1953
-			}
1954
-		}
1955
-
1956
-		foreach ($gd_image_array as $key => $gd_image) {
1957
-			$biSizeImage = $ImageWidths[$key] * $ImageHeights[$key] * ($bpp[$key] / 8);
1958
-
1959
-			// BITMAPINFOHEADER - 40 bytes
1960
-			$BitmapInfoHeader[$key] = '';
1961
-			$BitmapInfoHeader[$key] .= "\x28\x00\x00\x00";                // DWORD  biSize;
1962
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4);    // LONG   biWidth;
1963
-			// The biHeight member specifies the combined
1964
-			// height of the XOR and AND masks.
1965
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG   biHeight;
1966
-			$BitmapInfoHeader[$key] .= "\x01\x00";                    // WORD   biPlanes;
1967
-			$BitmapInfoHeader[$key] .= chr($bpp[$key]) . "\x00";              // wBitCount;
1968
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biCompression;
1969
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4);      // DWORD  biSizeImage;
1970
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // LONG   biXPelsPerMeter;
1971
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // LONG   biYPelsPerMeter;
1972
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biClrUsed;
1973
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biClrImportant;
1974
-		}
1975
-
1976
-
1977
-		$icondata = "\x00\x00";                    // idReserved;   // Reserved (must be 0)
1978
-		$icondata .= "\x01\x00";                    // idType;	   // Resource Type (1 for icons)
1979
-		$icondata .= phpthumb_functions::LittleEndian2String(count($gd_image_array), 2);  // idCount;	  // How many images?
1980
-
1981
-		$dwImageOffset = 6 + (count($gd_image_array) * 16);
1982
-		foreach ($gd_image_array as $key => $gd_image) {
1983
-			// ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
1984
-
1985
-			$icondata .= chr($ImageWidths[$key]);           // bWidth;		  // Width, in pixels, of the image
1986
-			$icondata .= chr($ImageHeights[$key]);          // bHeight;		 // Height, in pixels, of the image
1987
-			$icondata .= chr($totalcolors[$key]);           // bColorCount;	 // Number of colors in image (0 if >=8bpp)
1988
-			$icondata .= "\x00";                    // bReserved;	   // Reserved ( must be 0)
1989
-
1990
-			$icondata .= "\x01\x00";                  // wPlanes;		 // Color Planes
1991
-			$icondata .= chr($bpp[$key]) . "\x00";            // wBitCount;	   // Bits per pixel
1992
-
1993
-			$dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);
1994
-			$icondata .= phpthumb_functions::LittleEndian2String(
1995
-				$dwBytesInRes,
1996
-				4
1997
-			);     // dwBytesInRes;	// How many bytes in this resource?
1998
-
1999
-			$icondata .= phpthumb_functions::LittleEndian2String(
2000
-				$dwImageOffset,
2001
-				4
2002
-			);    // dwImageOffset;   // Where in the file is this image?
2003
-			$dwImageOffset += strlen($BitmapInfoHeader[$key]);
2004
-			$dwImageOffset += strlen($icXOR[$key]);
2005
-			$dwImageOffset += strlen($icAND[$key]);
2006
-		}
2007
-
2008
-		foreach ($gd_image_array as $key => $gd_image) {
2009
-			$icondata .= $BitmapInfoHeader[$key];
2010
-			$icondata .= $icXOR[$key];
2011
-			$icondata .= $icAND[$key];
2012
-		}
2013
-
2014
-		return $icondata;
2015
-	}
1875
+    /**
1876
+     * Retourne la couleur d'un pixel dans une image
1877
+     *
1878
+     * @param ressource $img
1879
+     * @param int $x
1880
+     * @param int $y
1881
+     * @return array|bool
1882
+     */
1883
+    public static function GetPixelColor(&$img, $x, $y) {
1884
+        if (is_resource($img) || (is_object($img) && $img instanceof \GdImage)) {
1885
+            return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));
1886
+        }
1887
+        return false;
1888
+    }
1889
+
1890
+    /**
1891
+     * Retourne un nombre dans une représentation en Little Endian
1892
+     *
1893
+     * @param int $number
1894
+     * @param int $minbytes
1895
+     * @return string
1896
+     */
1897
+    public static function LittleEndian2String($number, $minbytes = 1) {
1898
+        $intstring = '';
1899
+        while ($number > 0) {
1900
+            $intstring = $intstring . chr($number & 255);
1901
+            $number >>= 8;
1902
+        }
1903
+
1904
+        return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
1905
+    }
1906
+
1907
+    /**
1908
+     * Transforme une ressource GD en image au format ICO
1909
+     *
1910
+     * @param array $gd_image_array
1911
+     *     Tableau de ressources d'images GD
1912
+     * @return string
1913
+     *     Image au format ICO
1914
+     */
1915
+    public static function GD2ICOstring(&$gd_image_array) {
1916
+        foreach ($gd_image_array as $key => $gd_image) {
1917
+            $ImageWidths[$key] = ImageSX($gd_image);
1918
+            $ImageHeights[$key] = ImageSY($gd_image);
1919
+            $bpp[$key] = ImageIsTrueColor($gd_image) ? 32 : 24;
1920
+            $totalcolors[$key] = ImageColorsTotal($gd_image);
1921
+
1922
+            $icXOR[$key] = '';
1923
+            for ($y = $ImageHeights[$key] - 1; $y >= 0; $y--) {
1924
+                for ($x = 0; $x < $ImageWidths[$key]; $x++) {
1925
+                    $argb = phpthumb_functions::GetPixelColor($gd_image, $x, $y);
1926
+                    $a = round(255 * ((127 - $argb['alpha']) / 127));
1927
+                    $r = $argb['red'];
1928
+                    $g = $argb['green'];
1929
+                    $b = $argb['blue'];
1930
+
1931
+                    if ($bpp[$key] == 32) {
1932
+                        $icXOR[$key] .= chr($b) . chr($g) . chr($r) . chr($a);
1933
+                    } elseif ($bpp[$key] == 24) {
1934
+                        $icXOR[$key] .= chr($b) . chr($g) . chr($r);
1935
+                    }
1936
+
1937
+                    if ($a < 128) {
1938
+                        @$icANDmask[$key][$y] .= '1';
1939
+                    } else {
1940
+                        @$icANDmask[$key][$y] .= '0';
1941
+                    }
1942
+                }
1943
+                // mask bits are 32-bit aligned per scanline
1944
+                while (strlen($icANDmask[$key][$y]) % 32) {
1945
+                    $icANDmask[$key][$y] .= '0';
1946
+                }
1947
+            }
1948
+            $icAND[$key] = '';
1949
+            foreach ($icANDmask[$key] as $y => $scanlinemaskbits) {
1950
+                for ($i = 0; $i < strlen($scanlinemaskbits); $i += 8) {
1951
+                    $icAND[$key] .= chr(bindec(str_pad(substr($scanlinemaskbits, $i, 8), 8, '0', STR_PAD_LEFT)));
1952
+                }
1953
+            }
1954
+        }
1955
+
1956
+        foreach ($gd_image_array as $key => $gd_image) {
1957
+            $biSizeImage = $ImageWidths[$key] * $ImageHeights[$key] * ($bpp[$key] / 8);
1958
+
1959
+            // BITMAPINFOHEADER - 40 bytes
1960
+            $BitmapInfoHeader[$key] = '';
1961
+            $BitmapInfoHeader[$key] .= "\x28\x00\x00\x00";                // DWORD  biSize;
1962
+            $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4);    // LONG   biWidth;
1963
+            // The biHeight member specifies the combined
1964
+            // height of the XOR and AND masks.
1965
+            $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG   biHeight;
1966
+            $BitmapInfoHeader[$key] .= "\x01\x00";                    // WORD   biPlanes;
1967
+            $BitmapInfoHeader[$key] .= chr($bpp[$key]) . "\x00";              // wBitCount;
1968
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biCompression;
1969
+            $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4);      // DWORD  biSizeImage;
1970
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // LONG   biXPelsPerMeter;
1971
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // LONG   biYPelsPerMeter;
1972
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biClrUsed;
1973
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                // DWORD  biClrImportant;
1974
+        }
1975
+
1976
+
1977
+        $icondata = "\x00\x00";                    // idReserved;   // Reserved (must be 0)
1978
+        $icondata .= "\x01\x00";                    // idType;	   // Resource Type (1 for icons)
1979
+        $icondata .= phpthumb_functions::LittleEndian2String(count($gd_image_array), 2);  // idCount;	  // How many images?
1980
+
1981
+        $dwImageOffset = 6 + (count($gd_image_array) * 16);
1982
+        foreach ($gd_image_array as $key => $gd_image) {
1983
+            // ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
1984
+
1985
+            $icondata .= chr($ImageWidths[$key]);           // bWidth;		  // Width, in pixels, of the image
1986
+            $icondata .= chr($ImageHeights[$key]);          // bHeight;		 // Height, in pixels, of the image
1987
+            $icondata .= chr($totalcolors[$key]);           // bColorCount;	 // Number of colors in image (0 if >=8bpp)
1988
+            $icondata .= "\x00";                    // bReserved;	   // Reserved ( must be 0)
1989
+
1990
+            $icondata .= "\x01\x00";                  // wPlanes;		 // Color Planes
1991
+            $icondata .= chr($bpp[$key]) . "\x00";            // wBitCount;	   // Bits per pixel
1992
+
1993
+            $dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);
1994
+            $icondata .= phpthumb_functions::LittleEndian2String(
1995
+                $dwBytesInRes,
1996
+                4
1997
+            );     // dwBytesInRes;	// How many bytes in this resource?
1998
+
1999
+            $icondata .= phpthumb_functions::LittleEndian2String(
2000
+                $dwImageOffset,
2001
+                4
2002
+            );    // dwImageOffset;   // Where in the file is this image?
2003
+            $dwImageOffset += strlen($BitmapInfoHeader[$key]);
2004
+            $dwImageOffset += strlen($icXOR[$key]);
2005
+            $dwImageOffset += strlen($icAND[$key]);
2006
+        }
2007
+
2008
+        foreach ($gd_image_array as $key => $gd_image) {
2009
+            $icondata .= $BitmapInfoHeader[$key];
2010
+            $icondata .= $icXOR[$key];
2011
+            $icondata .= $icAND[$key];
2012
+        }
2013
+
2014
+        return $icondata;
2015
+    }
2016 2016
 }
Please login to merge, or discard this patch.