Test Failed
Pull Request — master (#592)
by Lucio
10:17
created
htdocs/modules/system/class/thumbs/phpthumb.gif.php 4 patches
Indentation   +1075 added lines, -1075 removed lines patch added patch discarded remove patch
@@ -23,11 +23,11 @@  discard block
 block discarded – undo
23 23
 
24 24
 function gif_loadFile($lpszFileName, $iIndex = 0)
25 25
 {
26
-	$gif = new CGIF();
27
-	if ($gif->loadFile($lpszFileName, $iIndex)) {
28
-		return $gif;
29
-	}
30
-	return false;
26
+    $gif = new CGIF();
27
+    if ($gif->loadFile($lpszFileName, $iIndex)) {
28
+        return $gif;
29
+    }
30
+    return false;
31 31
 }
32 32
 
33 33
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -35,1141 +35,1141 @@  discard block
 block discarded – undo
35 35
 // Added by James Heinrich <[email protected]> - December 10, 2003
36 36
 function gif_loadFileToGDimageResource($gifFilename, $bgColor = -1)
37 37
 {
38
-	if ($gif = gif_loadFile($gifFilename)) {
39
-
40
-		if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
41
-			// shouldn't take nearly this long
42
-			set_time_limit(120);
43
-		}
44
-		// general strategy: convert raw data to PNG then convert PNG data to GD image resource
45
-		$PNGdata = $gif->getPng($bgColor);
46
-		if ($img = @imagecreatefromstring($PNGdata)) {
47
-
48
-			// excellent - PNG image data successfully converted to GD image
49
-			return $img;
50
-
51
-		} elseif ($img = $gif->getGD_PixelPlotterVersion()) {
52
-
53
-			// problem: imagecreatefromstring() didn't like the PNG image data.
54
-			//   This has been known to happen in PHP v4.0.6
55
-			// solution: take the raw image data and create a new GD image and plot
56
-			//   pixel-by-pixel on the GD image. This is extremely slow, but it does
57
-			//   work and a slow solution is better than no solution, right? :)
58
-			return $img;
59
-
60
-		}
61
-	}
62
-	return false;
38
+    if ($gif = gif_loadFile($gifFilename)) {
39
+
40
+        if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
41
+            // shouldn't take nearly this long
42
+            set_time_limit(120);
43
+        }
44
+        // general strategy: convert raw data to PNG then convert PNG data to GD image resource
45
+        $PNGdata = $gif->getPng($bgColor);
46
+        if ($img = @imagecreatefromstring($PNGdata)) {
47
+
48
+            // excellent - PNG image data successfully converted to GD image
49
+            return $img;
50
+
51
+        } elseif ($img = $gif->getGD_PixelPlotterVersion()) {
52
+
53
+            // problem: imagecreatefromstring() didn't like the PNG image data.
54
+            //   This has been known to happen in PHP v4.0.6
55
+            // solution: take the raw image data and create a new GD image and plot
56
+            //   pixel-by-pixel on the GD image. This is extremely slow, but it does
57
+            //   work and a slow solution is better than no solution, right? :)
58
+            return $img;
59
+
60
+        }
61
+    }
62
+    return false;
63 63
 }
64 64
 
65 65
 ///////////////////////////////////////////////////////////////////////////////////////////////////
66 66
 
67 67
 function gif_outputAsBmp($gif, $lpszFileName, $bgColor = -1)
68 68
 {
69
-	if (!isset($gif) || (@get_class($gif) <> 'cgif') || !$gif->loaded() || ($lpszFileName == '')) {
70
-		return false;
71
-	}
72
-
73
-	$fd = $gif->getBmp($bgColor);
74
-	if (strlen($fd) <= 0) {
75
-		return false;
76
-	}
77
-
78
-	if (!($fh = @fopen($lpszFileName, 'wb'))) {
79
-		return false;
80
-	}
81
-	@fwrite($fh, $fd, strlen($fd));
82
-	@fflush($fh);
83
-	@fclose($fh);
84
-	return true;
69
+    if (!isset($gif) || (@get_class($gif) <> 'cgif') || !$gif->loaded() || ($lpszFileName == '')) {
70
+        return false;
71
+    }
72
+
73
+    $fd = $gif->getBmp($bgColor);
74
+    if (strlen($fd) <= 0) {
75
+        return false;
76
+    }
77
+
78
+    if (!($fh = @fopen($lpszFileName, 'wb'))) {
79
+        return false;
80
+    }
81
+    @fwrite($fh, $fd, strlen($fd));
82
+    @fflush($fh);
83
+    @fclose($fh);
84
+    return true;
85 85
 }
86 86
 
87 87
 ///////////////////////////////////////////////////////////////////////////////////////////////////
88 88
 
89 89
 function gif_outputAsPng($gif, $lpszFileName, $bgColor = -1)
90 90
 {
91
-	if (!isSet($gif) || (@get_class($gif) <> 'cgif') || !$gif->loaded() || ($lpszFileName == '')) {
92
-		return false;
93
-	}
94
-
95
-	$fd = $gif->getPng($bgColor);
96
-	if (strlen($fd) <= 0) {
97
-		return false;
98
-	}
99
-
100
-	if (!($fh = @fopen($lpszFileName, 'wb'))) {
101
-		return false;
102
-	}
103
-	@fwrite($fh, $fd, strlen($fd));
104
-	@fflush($fh);
105
-	@fclose($fh);
106
-	return true;
91
+    if (!isSet($gif) || (@get_class($gif) <> 'cgif') || !$gif->loaded() || ($lpszFileName == '')) {
92
+        return false;
93
+    }
94
+
95
+    $fd = $gif->getPng($bgColor);
96
+    if (strlen($fd) <= 0) {
97
+        return false;
98
+    }
99
+
100
+    if (!($fh = @fopen($lpszFileName, 'wb'))) {
101
+        return false;
102
+    }
103
+    @fwrite($fh, $fd, strlen($fd));
104
+    @fflush($fh);
105
+    @fclose($fh);
106
+    return true;
107 107
 }
108 108
 
109 109
 ///////////////////////////////////////////////////////////////////////////////////////////////////
110 110
 
111 111
 function gif_outputAsJpeg($gif, $lpszFileName, $bgColor = -1)
112 112
 {
113
-	// JPEG output that does not require cjpeg added by James Heinrich <[email protected]> - December 10, 2003
114
-	if ((strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') && (file_exists('/usr/local/bin/cjpeg') || `which cjpeg`)) {
113
+    // JPEG output that does not require cjpeg added by James Heinrich <[email protected]> - December 10, 2003
114
+    if ((strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') && (file_exists('/usr/local/bin/cjpeg') || `which cjpeg`)) {
115 115
 
116
-		if (gif_outputAsBmp($gif, $lpszFileName.'.bmp', $bgColor)) {
117
-			exec('cjpeg '.$lpszFileName.'.bmp >'.$lpszFileName.' 2>/dev/null');
118
-			@unlink($lpszFileName.'.bmp');
116
+        if (gif_outputAsBmp($gif, $lpszFileName.'.bmp', $bgColor)) {
117
+            exec('cjpeg '.$lpszFileName.'.bmp >'.$lpszFileName.' 2>/dev/null');
118
+            @unlink($lpszFileName.'.bmp');
119 119
 
120
-			if (@file_exists($lpszFileName)) {
121
-				if (@filesize($lpszFileName) > 0) {
122
-					return true;
123
-				}
120
+            if (@file_exists($lpszFileName)) {
121
+                if (@filesize($lpszFileName) > 0) {
122
+                    return true;
123
+                }
124 124
 
125
-				@unlink($lpszFileName);
126
-			}
127
-		}
125
+                @unlink($lpszFileName);
126
+            }
127
+        }
128 128
 
129
-	} else {
129
+    } else {
130 130
 
131
-		// either Windows, or cjpeg not found in path
132
-		if ($img = @imagecreatefromstring($gif->getPng($bgColor))) {
133
-			if (@imagejpeg($img, $lpszFileName)) {
134
-				return true;
135
-			}
136
-		}
131
+        // either Windows, or cjpeg not found in path
132
+        if ($img = @imagecreatefromstring($gif->getPng($bgColor))) {
133
+            if (@imagejpeg($img, $lpszFileName)) {
134
+                return true;
135
+            }
136
+        }
137 137
 
138
-	}
138
+    }
139 139
 
140
-	return false;
140
+    return false;
141 141
 }
142 142
 
143 143
 ///////////////////////////////////////////////////////////////////////////////////////////////////
144 144
 
145 145
 function gif_getSize($gif, &$width, &$height)
146 146
 {
147
-	if (isSet($gif) && (@get_class($gif) == 'cgif') && $gif->loaded()) {
148
-		$width  = $gif->width();
149
-		$height = $gif->height();
150
-	} elseif (@file_exists($gif)) {
151
-		$myGIF = new CGIF();
152
-		if (!$myGIF->getSize($gif, $width, $height)) {
153
-			return false;
154
-		}
155
-	} else {
156
-		return false;
157
-	}
158
-
159
-	return true;
147
+    if (isSet($gif) && (@get_class($gif) == 'cgif') && $gif->loaded()) {
148
+        $width  = $gif->width();
149
+        $height = $gif->height();
150
+    } elseif (@file_exists($gif)) {
151
+        $myGIF = new CGIF();
152
+        if (!$myGIF->getSize($gif, $width, $height)) {
153
+            return false;
154
+        }
155
+    } else {
156
+        return false;
157
+    }
158
+
159
+    return true;
160 160
 }
161 161
 
162 162
 ///////////////////////////////////////////////////////////////////////////////////////////////////
163 163
 
164 164
 class CGIFLZW
165 165
 {
166
-	public $MAX_LZW_BITS;
167
-	public $Fresh, $CodeSize, $SetCodeSize, $MaxCode, $MaxCodeSize, $FirstCode, $OldCode;
168
-	public $ClearCode, $EndCode, $Next, $Vals, $Stack, $sp, $Buf, $CurBit, $LastBit, $Done, $LastByte;
169
-
170
-	///////////////////////////////////////////////////////////////////////////
171
-
172
-	// CONSTRUCTOR
173
-	public function __construct()
174
-	{
175
-		$this->MAX_LZW_BITS = 12;
176
-		unSet($this->Next);
177
-		unSet($this->Vals);
178
-		unSet($this->Stack);
179
-		unSet($this->Buf);
180
-
181
-		$this->Next  = range(0, (1 << $this->MAX_LZW_BITS)       - 1);
182
-		$this->Vals  = range(0, (1 << $this->MAX_LZW_BITS)       - 1);
183
-		$this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1);
184
-		$this->Buf   = range(0, 279);
185
-	}
186
-
187
-	///////////////////////////////////////////////////////////////////////////
188
-
189
-	public function deCompress($data, &$datLen)
190
-	{
191
-		$stLen  = strlen($data);
192
-		$datLen = 0;
193
-		$ret    = '';
194
-
195
-		// INITIALIZATION
196
-		$this->LZWCommand($data, true);
197
-
198
-		while (($iIndex = $this->LZWCommand($data, false)) >= 0) {
199
-			$ret .= chr($iIndex);
200
-		}
201
-
202
-		$datLen = $stLen - strlen($data);
203
-
204
-		if ($iIndex != -2) {
205
-			return false;
206
-		}
207
-
208
-		return $ret;
209
-	}
210
-
211
-	///////////////////////////////////////////////////////////////////////////
212
-
213
-	public function LZWCommand(&$data, $bInit)
214
-	{
215
-		if ($bInit) {
216
-			$this->SetCodeSize = ord($data{0});
217
-			$data = substr($data, 1);
218
-
219
-			$this->CodeSize    = $this->SetCodeSize + 1;
220
-			$this->ClearCode   = 1 << $this->SetCodeSize;
221
-			$this->EndCode     = $this->ClearCode + 1;
222
-			$this->MaxCode     = $this->ClearCode + 2;
223
-			$this->MaxCodeSize = $this->ClearCode << 1;
224
-
225
-			$this->GetCode($data, $bInit);
226
-
227
-			$this->Fresh = 1;
228
-			for ($i = 0; $i < $this->ClearCode; $i++) {
229
-				$this->Next[$i] = 0;
230
-				$this->Vals[$i] = $i;
231
-			}
232
-
233
-			for (; $i < (1 << $this->MAX_LZW_BITS); $i++) {
234
-				$this->Next[$i] = 0;
235
-				$this->Vals[$i] = 0;
236
-			}
237
-
238
-			$this->sp = 0;
239
-			return 1;
240
-		}
241
-
242
-		if ($this->Fresh) {
243
-			$this->Fresh = 0;
244
-			do {
245
-				$this->FirstCode = $this->GetCode($data, $bInit);
246
-				$this->OldCode   = $this->FirstCode;
247
-			}
248
-			while ($this->FirstCode == $this->ClearCode);
249
-
250
-			return $this->FirstCode;
251
-		}
252
-
253
-		if ($this->sp > 0) {
254
-			$this->sp--;
255
-			return $this->Stack[$this->sp];
256
-		}
257
-
258
-		while (($Code = $this->GetCode($data, $bInit)) >= 0) {
259
-			if ($Code == $this->ClearCode) {
260
-				for ($i = 0; $i < $this->ClearCode; $i++) {
261
-					$this->Next[$i] = 0;
262
-					$this->Vals[$i] = $i;
263
-				}
264
-
265
-				for (; $i < (1 << $this->MAX_LZW_BITS); $i++) {
266
-					$this->Next[$i] = 0;
267
-					$this->Vals[$i] = 0;
268
-				}
269
-
270
-				$this->CodeSize    = $this->SetCodeSize + 1;
271
-				$this->MaxCodeSize = $this->ClearCode << 1;
272
-				$this->MaxCode     = $this->ClearCode + 2;
273
-				$this->sp          = 0;
274
-				$this->FirstCode   = $this->GetCode($data, $bInit);
275
-				$this->OldCode     = $this->FirstCode;
276
-
277
-				return $this->FirstCode;
278
-			}
279
-
280
-			if ($Code == $this->EndCode) {
281
-				return -2;
282
-			}
283
-
284
-			$InCode = $Code;
285
-			if ($Code >= $this->MaxCode) {
286
-				$this->Stack[$this->sp] = $this->FirstCode;
287
-				$this->sp++;
288
-				$Code = $this->OldCode;
289
-			}
290
-
291
-			while ($Code >= $this->ClearCode) {
292
-				$this->Stack[$this->sp] = $this->Vals[$Code];
293
-				$this->sp++;
294
-
295
-				if ($Code == $this->Next[$Code]) // Circular table entry, big GIF Error!
296
-					return -1;
297
-
298
-				$Code = $this->Next[$Code];
299
-			}
300
-
301
-			$this->FirstCode = $this->Vals[$Code];
302
-			$this->Stack[$this->sp] = $this->FirstCode;
303
-			$this->sp++;
304
-
305
-			if (($Code = $this->MaxCode) < (1 << $this->MAX_LZW_BITS)) {
306
-				$this->Next[$Code] = $this->OldCode;
307
-				$this->Vals[$Code] = $this->FirstCode;
308
-				$this->MaxCode++;
309
-
310
-				if (($this->MaxCode >= $this->MaxCodeSize) && ($this->MaxCodeSize < (1 << $this->MAX_LZW_BITS))) {
311
-					$this->MaxCodeSize *= 2;
312
-					$this->CodeSize++;
313
-				}
314
-			}
315
-
316
-			$this->OldCode = $InCode;
317
-			if ($this->sp > 0) {
318
-				$this->sp--;
319
-				return $this->Stack[$this->sp];
320
-			}
321
-		}
322
-
323
-		return $Code;
324
-	}
325
-
326
-	///////////////////////////////////////////////////////////////////////////
327
-
328
-	public function GetCode(&$data, $bInit)
329
-	{
330
-		if ($bInit) {
331
-			$this->CurBit   = 0;
332
-			$this->LastBit  = 0;
333
-			$this->Done     = 0;
334
-			$this->LastByte = 2;
335
-			return 1;
336
-		}
337
-
338
-		if (($this->CurBit + $this->CodeSize) >= $this->LastBit) {
339
-			if ($this->Done) {
340
-				if ($this->CurBit >= $this->LastBit) {
341
-					// Ran off the end of my bits
342
-					return 0;
343
-				}
344
-				return -1;
345
-			}
346
-
347
-			$this->Buf[0] = $this->Buf[$this->LastByte - 2];
348
-			$this->Buf[1] = $this->Buf[$this->LastByte - 1];
349
-
350
-			$Count = ord($data{0});
351
-			$data  = substr($data, 1);
352
-
353
-			if ($Count) {
354
-				for ($i = 0; $i < $Count; $i++) {
355
-					$this->Buf[2 + $i] = ord($data{$i});
356
-				}
357
-				$data = substr($data, $Count);
358
-			} else {
359
-				$this->Done = 1;
360
-			}
361
-
362
-			$this->LastByte = 2 + $Count;
363
-			$this->CurBit   = ($this->CurBit - $this->LastBit) + 16;
364
-			$this->LastBit  = (2 + $Count) << 3;
365
-		}
366
-
367
-		$iRet = 0;
368
-		for ($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) {
369
-			$iRet |= (($this->Buf[ (int) ($i / 8) ] & (1 << ($i % 8))) != 0) << $j;
370
-		}
371
-
372
-		$this->CurBit += $this->CodeSize;
373
-		return $iRet;
374
-	}
166
+    public $MAX_LZW_BITS;
167
+    public $Fresh, $CodeSize, $SetCodeSize, $MaxCode, $MaxCodeSize, $FirstCode, $OldCode;
168
+    public $ClearCode, $EndCode, $Next, $Vals, $Stack, $sp, $Buf, $CurBit, $LastBit, $Done, $LastByte;
169
+
170
+    ///////////////////////////////////////////////////////////////////////////
171
+
172
+    // CONSTRUCTOR
173
+    public function __construct()
174
+    {
175
+        $this->MAX_LZW_BITS = 12;
176
+        unSet($this->Next);
177
+        unSet($this->Vals);
178
+        unSet($this->Stack);
179
+        unSet($this->Buf);
180
+
181
+        $this->Next  = range(0, (1 << $this->MAX_LZW_BITS)       - 1);
182
+        $this->Vals  = range(0, (1 << $this->MAX_LZW_BITS)       - 1);
183
+        $this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1);
184
+        $this->Buf   = range(0, 279);
185
+    }
186
+
187
+    ///////////////////////////////////////////////////////////////////////////
188
+
189
+    public function deCompress($data, &$datLen)
190
+    {
191
+        $stLen  = strlen($data);
192
+        $datLen = 0;
193
+        $ret    = '';
194
+
195
+        // INITIALIZATION
196
+        $this->LZWCommand($data, true);
197
+
198
+        while (($iIndex = $this->LZWCommand($data, false)) >= 0) {
199
+            $ret .= chr($iIndex);
200
+        }
201
+
202
+        $datLen = $stLen - strlen($data);
203
+
204
+        if ($iIndex != -2) {
205
+            return false;
206
+        }
207
+
208
+        return $ret;
209
+    }
210
+
211
+    ///////////////////////////////////////////////////////////////////////////
212
+
213
+    public function LZWCommand(&$data, $bInit)
214
+    {
215
+        if ($bInit) {
216
+            $this->SetCodeSize = ord($data{0});
217
+            $data = substr($data, 1);
218
+
219
+            $this->CodeSize    = $this->SetCodeSize + 1;
220
+            $this->ClearCode   = 1 << $this->SetCodeSize;
221
+            $this->EndCode     = $this->ClearCode + 1;
222
+            $this->MaxCode     = $this->ClearCode + 2;
223
+            $this->MaxCodeSize = $this->ClearCode << 1;
224
+
225
+            $this->GetCode($data, $bInit);
226
+
227
+            $this->Fresh = 1;
228
+            for ($i = 0; $i < $this->ClearCode; $i++) {
229
+                $this->Next[$i] = 0;
230
+                $this->Vals[$i] = $i;
231
+            }
232
+
233
+            for (; $i < (1 << $this->MAX_LZW_BITS); $i++) {
234
+                $this->Next[$i] = 0;
235
+                $this->Vals[$i] = 0;
236
+            }
237
+
238
+            $this->sp = 0;
239
+            return 1;
240
+        }
241
+
242
+        if ($this->Fresh) {
243
+            $this->Fresh = 0;
244
+            do {
245
+                $this->FirstCode = $this->GetCode($data, $bInit);
246
+                $this->OldCode   = $this->FirstCode;
247
+            }
248
+            while ($this->FirstCode == $this->ClearCode);
249
+
250
+            return $this->FirstCode;
251
+        }
252
+
253
+        if ($this->sp > 0) {
254
+            $this->sp--;
255
+            return $this->Stack[$this->sp];
256
+        }
257
+
258
+        while (($Code = $this->GetCode($data, $bInit)) >= 0) {
259
+            if ($Code == $this->ClearCode) {
260
+                for ($i = 0; $i < $this->ClearCode; $i++) {
261
+                    $this->Next[$i] = 0;
262
+                    $this->Vals[$i] = $i;
263
+                }
264
+
265
+                for (; $i < (1 << $this->MAX_LZW_BITS); $i++) {
266
+                    $this->Next[$i] = 0;
267
+                    $this->Vals[$i] = 0;
268
+                }
269
+
270
+                $this->CodeSize    = $this->SetCodeSize + 1;
271
+                $this->MaxCodeSize = $this->ClearCode << 1;
272
+                $this->MaxCode     = $this->ClearCode + 2;
273
+                $this->sp          = 0;
274
+                $this->FirstCode   = $this->GetCode($data, $bInit);
275
+                $this->OldCode     = $this->FirstCode;
276
+
277
+                return $this->FirstCode;
278
+            }
279
+
280
+            if ($Code == $this->EndCode) {
281
+                return -2;
282
+            }
283
+
284
+            $InCode = $Code;
285
+            if ($Code >= $this->MaxCode) {
286
+                $this->Stack[$this->sp] = $this->FirstCode;
287
+                $this->sp++;
288
+                $Code = $this->OldCode;
289
+            }
290
+
291
+            while ($Code >= $this->ClearCode) {
292
+                $this->Stack[$this->sp] = $this->Vals[$Code];
293
+                $this->sp++;
294
+
295
+                if ($Code == $this->Next[$Code]) // Circular table entry, big GIF Error!
296
+                    return -1;
297
+
298
+                $Code = $this->Next[$Code];
299
+            }
300
+
301
+            $this->FirstCode = $this->Vals[$Code];
302
+            $this->Stack[$this->sp] = $this->FirstCode;
303
+            $this->sp++;
304
+
305
+            if (($Code = $this->MaxCode) < (1 << $this->MAX_LZW_BITS)) {
306
+                $this->Next[$Code] = $this->OldCode;
307
+                $this->Vals[$Code] = $this->FirstCode;
308
+                $this->MaxCode++;
309
+
310
+                if (($this->MaxCode >= $this->MaxCodeSize) && ($this->MaxCodeSize < (1 << $this->MAX_LZW_BITS))) {
311
+                    $this->MaxCodeSize *= 2;
312
+                    $this->CodeSize++;
313
+                }
314
+            }
315
+
316
+            $this->OldCode = $InCode;
317
+            if ($this->sp > 0) {
318
+                $this->sp--;
319
+                return $this->Stack[$this->sp];
320
+            }
321
+        }
322
+
323
+        return $Code;
324
+    }
325
+
326
+    ///////////////////////////////////////////////////////////////////////////
327
+
328
+    public function GetCode(&$data, $bInit)
329
+    {
330
+        if ($bInit) {
331
+            $this->CurBit   = 0;
332
+            $this->LastBit  = 0;
333
+            $this->Done     = 0;
334
+            $this->LastByte = 2;
335
+            return 1;
336
+        }
337
+
338
+        if (($this->CurBit + $this->CodeSize) >= $this->LastBit) {
339
+            if ($this->Done) {
340
+                if ($this->CurBit >= $this->LastBit) {
341
+                    // Ran off the end of my bits
342
+                    return 0;
343
+                }
344
+                return -1;
345
+            }
346
+
347
+            $this->Buf[0] = $this->Buf[$this->LastByte - 2];
348
+            $this->Buf[1] = $this->Buf[$this->LastByte - 1];
349
+
350
+            $Count = ord($data{0});
351
+            $data  = substr($data, 1);
352
+
353
+            if ($Count) {
354
+                for ($i = 0; $i < $Count; $i++) {
355
+                    $this->Buf[2 + $i] = ord($data{$i});
356
+                }
357
+                $data = substr($data, $Count);
358
+            } else {
359
+                $this->Done = 1;
360
+            }
361
+
362
+            $this->LastByte = 2 + $Count;
363
+            $this->CurBit   = ($this->CurBit - $this->LastBit) + 16;
364
+            $this->LastBit  = (2 + $Count) << 3;
365
+        }
366
+
367
+        $iRet = 0;
368
+        for ($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) {
369
+            $iRet |= (($this->Buf[ (int) ($i / 8) ] & (1 << ($i % 8))) != 0) << $j;
370
+        }
371
+
372
+        $this->CurBit += $this->CodeSize;
373
+        return $iRet;
374
+    }
375 375
 }
376 376
 
377 377
 ///////////////////////////////////////////////////////////////////////////////////////////////////
378 378
 
379 379
 class CGIFCOLORTABLE
380 380
 {
381
-	public $m_nColors;
382
-	public $m_arColors;
383
-
384
-	///////////////////////////////////////////////////////////////////////////
385
-
386
-	// CONSTRUCTOR
387
-	public function __construct()
388
-	{
389
-		unSet($this->m_nColors);
390
-		unSet($this->m_arColors);
391
-	}
392
-
393
-	///////////////////////////////////////////////////////////////////////////
394
-
395
-	public function load($lpData, $num)
396
-	{
397
-		$this->m_nColors  = 0;
398
-		$this->m_arColors = array();
399
-
400
-		for ($i = 0; $i < $num; $i++) {
401
-			$rgb = substr($lpData, $i * 3, 3);
402
-			if (strlen($rgb) < 3) {
403
-				return false;
404
-			}
405
-
406
-			$this->m_arColors[] = (ord($rgb{2}) << 16) + (ord($rgb{1}) << 8) + ord($rgb{0});
407
-			$this->m_nColors++;
408
-		}
409
-
410
-		return true;
411
-	}
412
-
413
-	///////////////////////////////////////////////////////////////////////////
414
-
415
-	public function toString()
416
-	{
417
-		$ret = '';
418
-
419
-		for ($i = 0; $i < $this->m_nColors; $i++) {
420
-			$ret .=
421
-				chr(($this->m_arColors[$i] & 0x000000FF))       . // R
422
-				chr(($this->m_arColors[$i] & 0x0000FF00) >>  8) . // G
423
-				chr(($this->m_arColors[$i] & 0x00FF0000) >> 16);  // B
424
-		}
425
-
426
-		return $ret;
427
-	}
428
-
429
-	///////////////////////////////////////////////////////////////////////////
430
-
431
-	public function toRGBQuad()
432
-	{
433
-		$ret = '';
434
-
435
-		for ($i = 0; $i < $this->m_nColors; $i++) {
436
-			$ret .=
437
-				chr(($this->m_arColors[$i] & 0x00FF0000) >> 16) . // B
438
-				chr(($this->m_arColors[$i] & 0x0000FF00) >>  8) . // G
439
-				chr(($this->m_arColors[$i] & 0x000000FF))       . // R
440
-				"\x00";
441
-		}
442
-
443
-		return $ret;
444
-	}
445
-
446
-	///////////////////////////////////////////////////////////////////////////
447
-
448
-	public function colorIndex($rgb)
449
-	{
450
-		$rgb = (int) $rgb & 0xFFFFFF;
451
-		$r1  = ($rgb & 0x0000FF);
452
-		$g1  = ($rgb & 0x00FF00) >>  8;
453
-		$b1  = ($rgb & 0xFF0000) >> 16;
454
-		$idx = -1;
455
-		$dif = 0;
456
-
457
-		for ($i = 0; $i < $this->m_nColors; $i++) {
458
-			$r2 = ($this->m_arColors[$i] & 0x000000FF);
459
-			$g2 = ($this->m_arColors[$i] & 0x0000FF00) >>  8;
460
-			$b2 = ($this->m_arColors[$i] & 0x00FF0000) >> 16;
461
-			$d  = abs($r2 - $r1) + abs($g2 - $g1) + abs($b2 - $b1);
462
-
463
-			if (($idx == -1) || ($d < $dif)) {
464
-				$idx = $i;
465
-				$dif = $d;
466
-			}
467
-		}
468
-
469
-		return $idx;
470
-	}
381
+    public $m_nColors;
382
+    public $m_arColors;
383
+
384
+    ///////////////////////////////////////////////////////////////////////////
385
+
386
+    // CONSTRUCTOR
387
+    public function __construct()
388
+    {
389
+        unSet($this->m_nColors);
390
+        unSet($this->m_arColors);
391
+    }
392
+
393
+    ///////////////////////////////////////////////////////////////////////////
394
+
395
+    public function load($lpData, $num)
396
+    {
397
+        $this->m_nColors  = 0;
398
+        $this->m_arColors = array();
399
+
400
+        for ($i = 0; $i < $num; $i++) {
401
+            $rgb = substr($lpData, $i * 3, 3);
402
+            if (strlen($rgb) < 3) {
403
+                return false;
404
+            }
405
+
406
+            $this->m_arColors[] = (ord($rgb{2}) << 16) + (ord($rgb{1}) << 8) + ord($rgb{0});
407
+            $this->m_nColors++;
408
+        }
409
+
410
+        return true;
411
+    }
412
+
413
+    ///////////////////////////////////////////////////////////////////////////
414
+
415
+    public function toString()
416
+    {
417
+        $ret = '';
418
+
419
+        for ($i = 0; $i < $this->m_nColors; $i++) {
420
+            $ret .=
421
+                chr(($this->m_arColors[$i] & 0x000000FF))       . // R
422
+                chr(($this->m_arColors[$i] & 0x0000FF00) >>  8) . // G
423
+                chr(($this->m_arColors[$i] & 0x00FF0000) >> 16);  // B
424
+        }
425
+
426
+        return $ret;
427
+    }
428
+
429
+    ///////////////////////////////////////////////////////////////////////////
430
+
431
+    public function toRGBQuad()
432
+    {
433
+        $ret = '';
434
+
435
+        for ($i = 0; $i < $this->m_nColors; $i++) {
436
+            $ret .=
437
+                chr(($this->m_arColors[$i] & 0x00FF0000) >> 16) . // B
438
+                chr(($this->m_arColors[$i] & 0x0000FF00) >>  8) . // G
439
+                chr(($this->m_arColors[$i] & 0x000000FF))       . // R
440
+                "\x00";
441
+        }
442
+
443
+        return $ret;
444
+    }
445
+
446
+    ///////////////////////////////////////////////////////////////////////////
447
+
448
+    public function colorIndex($rgb)
449
+    {
450
+        $rgb = (int) $rgb & 0xFFFFFF;
451
+        $r1  = ($rgb & 0x0000FF);
452
+        $g1  = ($rgb & 0x00FF00) >>  8;
453
+        $b1  = ($rgb & 0xFF0000) >> 16;
454
+        $idx = -1;
455
+        $dif = 0;
456
+
457
+        for ($i = 0; $i < $this->m_nColors; $i++) {
458
+            $r2 = ($this->m_arColors[$i] & 0x000000FF);
459
+            $g2 = ($this->m_arColors[$i] & 0x0000FF00) >>  8;
460
+            $b2 = ($this->m_arColors[$i] & 0x00FF0000) >> 16;
461
+            $d  = abs($r2 - $r1) + abs($g2 - $g1) + abs($b2 - $b1);
462
+
463
+            if (($idx == -1) || ($d < $dif)) {
464
+                $idx = $i;
465
+                $dif = $d;
466
+            }
467
+        }
468
+
469
+        return $idx;
470
+    }
471 471
 }
472 472
 
473 473
 ///////////////////////////////////////////////////////////////////////////////////////////////////
474 474
 
475 475
 class CGIFFILEHEADER
476 476
 {
477
-	public $m_lpVer;
478
-	public $m_nWidth;
479
-	public $m_nHeight;
480
-	public $m_bGlobalClr;
481
-	public $m_nColorRes;
482
-	public $m_bSorted;
483
-	public $m_nTableSize;
484
-	public $m_nBgColor;
485
-	public $m_nPixelRatio;
486
-	public $m_colorTable;
487
-
488
-	///////////////////////////////////////////////////////////////////////////
489
-
490
-	// CONSTRUCTOR
491
-	public function __construct()
492
-	{
493
-		unSet($this->m_lpVer);
494
-		unSet($this->m_nWidth);
495
-		unSet($this->m_nHeight);
496
-		unSet($this->m_bGlobalClr);
497
-		unSet($this->m_nColorRes);
498
-		unSet($this->m_bSorted);
499
-		unSet($this->m_nTableSize);
500
-		unSet($this->m_nBgColor);
501
-		unSet($this->m_nPixelRatio);
502
-		unSet($this->m_colorTable);
503
-	}
504
-
505
-	///////////////////////////////////////////////////////////////////////////
506
-
507
-	public function load($lpData, &$hdrLen)
508
-	{
509
-		$hdrLen = 0;
510
-
511
-		$this->m_lpVer = substr($lpData, 0, 6);
512
-		if (($this->m_lpVer <> 'GIF87a') && ($this->m_lpVer <> 'GIF89a')) {
513
-			return false;
514
-		}
515
-
516
-		$this->m_nWidth  = $this->w2i(substr($lpData, 6, 2));
517
-		$this->m_nHeight = $this->w2i(substr($lpData, 8, 2));
518
-		if (!$this->m_nWidth || !$this->m_nHeight) {
519
-			return false;
520
-		}
521
-
522
-		$b = ord($lpData[ 10 ]);
523
-		$this->m_bGlobalClr  = ($b & 0x80) ? true : false;
524
-		$this->m_nColorRes   = ($b & 0x70) >> 4;
525
-		$this->m_bSorted     = ($b & 0x08) ? true : false;
526
-		$this->m_nTableSize  = 2 << ($b & 0x07);
527
-		$this->m_nBgColor    = ord($lpData[ 11 ]);
528
-		$this->m_nPixelRatio = ord($lpData[ 12 ]);
529
-		$hdrLen = 13;
530
-
531
-		if ($this->m_bGlobalClr) {
532
-			$this->m_colorTable = new CGIFCOLORTABLE();
533
-			if (!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
534
-				return false;
535
-			}
536
-			$hdrLen += 3 * $this->m_nTableSize;
537
-		}
538
-
539
-		return true;
540
-	}
541
-
542
-	///////////////////////////////////////////////////////////////////////////
543
-
544
-	public function w2i($str)
545
-	{
546
-		return ord($str[ 0 ]) + (ord($str[ 1 ]) << 8);
547
-	}
477
+    public $m_lpVer;
478
+    public $m_nWidth;
479
+    public $m_nHeight;
480
+    public $m_bGlobalClr;
481
+    public $m_nColorRes;
482
+    public $m_bSorted;
483
+    public $m_nTableSize;
484
+    public $m_nBgColor;
485
+    public $m_nPixelRatio;
486
+    public $m_colorTable;
487
+
488
+    ///////////////////////////////////////////////////////////////////////////
489
+
490
+    // CONSTRUCTOR
491
+    public function __construct()
492
+    {
493
+        unSet($this->m_lpVer);
494
+        unSet($this->m_nWidth);
495
+        unSet($this->m_nHeight);
496
+        unSet($this->m_bGlobalClr);
497
+        unSet($this->m_nColorRes);
498
+        unSet($this->m_bSorted);
499
+        unSet($this->m_nTableSize);
500
+        unSet($this->m_nBgColor);
501
+        unSet($this->m_nPixelRatio);
502
+        unSet($this->m_colorTable);
503
+    }
504
+
505
+    ///////////////////////////////////////////////////////////////////////////
506
+
507
+    public function load($lpData, &$hdrLen)
508
+    {
509
+        $hdrLen = 0;
510
+
511
+        $this->m_lpVer = substr($lpData, 0, 6);
512
+        if (($this->m_lpVer <> 'GIF87a') && ($this->m_lpVer <> 'GIF89a')) {
513
+            return false;
514
+        }
515
+
516
+        $this->m_nWidth  = $this->w2i(substr($lpData, 6, 2));
517
+        $this->m_nHeight = $this->w2i(substr($lpData, 8, 2));
518
+        if (!$this->m_nWidth || !$this->m_nHeight) {
519
+            return false;
520
+        }
521
+
522
+        $b = ord($lpData[ 10 ]);
523
+        $this->m_bGlobalClr  = ($b & 0x80) ? true : false;
524
+        $this->m_nColorRes   = ($b & 0x70) >> 4;
525
+        $this->m_bSorted     = ($b & 0x08) ? true : false;
526
+        $this->m_nTableSize  = 2 << ($b & 0x07);
527
+        $this->m_nBgColor    = ord($lpData[ 11 ]);
528
+        $this->m_nPixelRatio = ord($lpData[ 12 ]);
529
+        $hdrLen = 13;
530
+
531
+        if ($this->m_bGlobalClr) {
532
+            $this->m_colorTable = new CGIFCOLORTABLE();
533
+            if (!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
534
+                return false;
535
+            }
536
+            $hdrLen += 3 * $this->m_nTableSize;
537
+        }
538
+
539
+        return true;
540
+    }
541
+
542
+    ///////////////////////////////////////////////////////////////////////////
543
+
544
+    public function w2i($str)
545
+    {
546
+        return ord($str[ 0 ]) + (ord($str[ 1 ]) << 8);
547
+    }
548 548
 }
549 549
 
550 550
 ///////////////////////////////////////////////////////////////////////////////////////////////////
551 551
 
552 552
 class CGIFIMAGEHEADER
553 553
 {
554
-	public $m_nLeft;
555
-	public $m_nTop;
556
-	public $m_nWidth;
557
-	public $m_nHeight;
558
-	public $m_bLocalClr;
559
-	public $m_bInterlace;
560
-	public $m_bSorted;
561
-	public $m_nTableSize;
562
-	public $m_colorTable;
563
-
564
-	///////////////////////////////////////////////////////////////////////////
565
-
566
-	// CONSTRUCTOR
567
-	public function __construct()
568
-	{
569
-		unSet($this->m_nLeft);
570
-		unSet($this->m_nTop);
571
-		unSet($this->m_nWidth);
572
-		unSet($this->m_nHeight);
573
-		unSet($this->m_bLocalClr);
574
-		unSet($this->m_bInterlace);
575
-		unSet($this->m_bSorted);
576
-		unSet($this->m_nTableSize);
577
-		unSet($this->m_colorTable);
578
-	}
579
-
580
-	///////////////////////////////////////////////////////////////////////////
581
-
582
-	public function load($lpData, &$hdrLen)
583
-	{
584
-		$hdrLen = 0;
585
-
586
-		$this->m_nLeft   = $this->w2i(substr($lpData, 0, 2));
587
-		$this->m_nTop    = $this->w2i(substr($lpData, 2, 2));
588
-		$this->m_nWidth  = $this->w2i(substr($lpData, 4, 2));
589
-		$this->m_nHeight = $this->w2i(substr($lpData, 6, 2));
590
-
591
-		if (!$this->m_nWidth || !$this->m_nHeight) {
592
-			return false;
593
-		}
594
-
595
-		$b = ord($lpData{8});
596
-		$this->m_bLocalClr  = ($b & 0x80) ? true : false;
597
-		$this->m_bInterlace = ($b & 0x40) ? true : false;
598
-		$this->m_bSorted    = ($b & 0x20) ? true : false;
599
-		$this->m_nTableSize = 2 << ($b & 0x07);
600
-		$hdrLen = 9;
601
-
602
-		if ($this->m_bLocalClr) {
603
-			$this->m_colorTable = new CGIFCOLORTABLE();
604
-			if (!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
605
-				return false;
606
-			}
607
-			$hdrLen += 3 * $this->m_nTableSize;
608
-		}
609
-
610
-		return true;
611
-	}
612
-
613
-	///////////////////////////////////////////////////////////////////////////
614
-
615
-	public function w2i($str)
616
-	{
617
-		return ord($str[ 0 ]) + (ord($str[ 1 ]) << 8);
618
-	}
554
+    public $m_nLeft;
555
+    public $m_nTop;
556
+    public $m_nWidth;
557
+    public $m_nHeight;
558
+    public $m_bLocalClr;
559
+    public $m_bInterlace;
560
+    public $m_bSorted;
561
+    public $m_nTableSize;
562
+    public $m_colorTable;
563
+
564
+    ///////////////////////////////////////////////////////////////////////////
565
+
566
+    // CONSTRUCTOR
567
+    public function __construct()
568
+    {
569
+        unSet($this->m_nLeft);
570
+        unSet($this->m_nTop);
571
+        unSet($this->m_nWidth);
572
+        unSet($this->m_nHeight);
573
+        unSet($this->m_bLocalClr);
574
+        unSet($this->m_bInterlace);
575
+        unSet($this->m_bSorted);
576
+        unSet($this->m_nTableSize);
577
+        unSet($this->m_colorTable);
578
+    }
579
+
580
+    ///////////////////////////////////////////////////////////////////////////
581
+
582
+    public function load($lpData, &$hdrLen)
583
+    {
584
+        $hdrLen = 0;
585
+
586
+        $this->m_nLeft   = $this->w2i(substr($lpData, 0, 2));
587
+        $this->m_nTop    = $this->w2i(substr($lpData, 2, 2));
588
+        $this->m_nWidth  = $this->w2i(substr($lpData, 4, 2));
589
+        $this->m_nHeight = $this->w2i(substr($lpData, 6, 2));
590
+
591
+        if (!$this->m_nWidth || !$this->m_nHeight) {
592
+            return false;
593
+        }
594
+
595
+        $b = ord($lpData{8});
596
+        $this->m_bLocalClr  = ($b & 0x80) ? true : false;
597
+        $this->m_bInterlace = ($b & 0x40) ? true : false;
598
+        $this->m_bSorted    = ($b & 0x20) ? true : false;
599
+        $this->m_nTableSize = 2 << ($b & 0x07);
600
+        $hdrLen = 9;
601
+
602
+        if ($this->m_bLocalClr) {
603
+            $this->m_colorTable = new CGIFCOLORTABLE();
604
+            if (!$this->m_colorTable->load(substr($lpData, $hdrLen), $this->m_nTableSize)) {
605
+                return false;
606
+            }
607
+            $hdrLen += 3 * $this->m_nTableSize;
608
+        }
609
+
610
+        return true;
611
+    }
612
+
613
+    ///////////////////////////////////////////////////////////////////////////
614
+
615
+    public function w2i($str)
616
+    {
617
+        return ord($str[ 0 ]) + (ord($str[ 1 ]) << 8);
618
+    }
619 619
 }
620 620
 
621 621
 ///////////////////////////////////////////////////////////////////////////////////////////////////
622 622
 
623 623
 class CGIFIMAGE
624 624
 {
625
-	public $m_disp;
626
-	public $m_bUser;
627
-	public $m_bTrans;
628
-	public $m_nDelay;
629
-	public $m_nTrans;
630
-	public $m_lpComm;
631
-	public $m_gih;
632
-	public $m_data;
633
-	public $m_lzw;
634
-
635
-	///////////////////////////////////////////////////////////////////////////
636
-
637
-	public function __construct()
638
-	{
639
-		unSet($this->m_disp);
640
-		unSet($this->m_bUser);
641
-		unSet($this->m_bTrans);
642
-		unSet($this->m_nDelay);
643
-		unSet($this->m_nTrans);
644
-		unSet($this->m_lpComm);
645
-		unSet($this->m_data);
646
-		$this->m_gih = new CGIFIMAGEHEADER();
647
-		$this->m_lzw = new CGIFLZW();
648
-	}
649
-
650
-	///////////////////////////////////////////////////////////////////////////
651
-
652
-	public function load($data, &$datLen)
653
-	{
654
-		$datLen = 0;
655
-
656
-		while (true) {
657
-			$b = ord($data{0});
658
-			$data = substr($data, 1);
659
-			$datLen++;
660
-
661
-			switch($b) {
662
-			case 0x21: // Extension
663
-				if (!$this->skipExt($data, $len = 0)) {
664
-					return false;
665
-				}
666
-				$datLen += $len;
667
-				break;
668
-
669
-			case 0x2C: // Image
670
-				// LOAD HEADER & COLOR TABLE
671
-				if (!$this->m_gih->load($data, $len = 0)) {
672
-					return false;
673
-				}
674
-				$data = substr($data, $len);
675
-				$datLen += $len;
676
-
677
-				// ALLOC BUFFER
678
-				if (!($this->m_data = $this->m_lzw->deCompress($data, $len = 0))) {
679
-					return false;
680
-				}
681
-				$data = substr($data, $len);
682
-				$datLen += $len;
683
-
684
-				if ($this->m_gih->m_bInterlace) {
685
-					$this->deInterlace();
686
-				}
687
-				return true;
688
-
689
-			case 0x3B: // EOF
690
-			default:
691
-				return false;
692
-			}
693
-		}
694
-		return false;
695
-	}
696
-
697
-	///////////////////////////////////////////////////////////////////////////
698
-
699
-	public function skipExt(&$data, &$extLen)
700
-	{
701
-		$extLen = 0;
702
-
703
-		$b = ord($data{0});
704
-		$data = substr($data, 1);
705
-		$extLen++;
706
-
707
-		switch($b) {
708
-		case 0xF9: // Graphic Control
709
-			$b = ord($data{1});
710
-			$this->m_disp   = ($b & 0x1C) >> 2;
711
-			$this->m_bUser  = ($b & 0x02) ? true : false;
712
-			$this->m_bTrans = ($b & 0x01) ? true : false;
713
-			$this->m_nDelay = $this->w2i(substr($data, 2, 2));
714
-			$this->m_nTrans = ord($data{4});
715
-			break;
716
-
717
-		case 0xFE: // Comment
718
-			$this->m_lpComm = substr($data, 1, ord($data{0}));
719
-			break;
720
-
721
-		case 0x01: // Plain text
722
-			break;
723
-
724
-		case 0xFF: // Application
725
-			break;
726
-		}
727
-
728
-		// SKIP DEFAULT AS DEFS MAY CHANGE
729
-		$b = ord($data{0});
730
-		$data = substr($data, 1);
731
-		$extLen++;
732
-		while ($b > 0) {
733
-			$data = substr($data, $b);
734
-			$extLen += $b;
735
-			$b    = ord($data{0});
736
-			$data = substr($data, 1);
737
-			$extLen++;
738
-		}
739
-		return true;
740
-	}
741
-
742
-	///////////////////////////////////////////////////////////////////////////
743
-
744
-	public function w2i($str)
745
-	{
746
-		return ord($str[ 0 ]) + (ord($str[ 1 ]) << 8);
747
-	}
748
-
749
-	///////////////////////////////////////////////////////////////////////////
750
-
751
-	public function deInterlace()
752
-	{
753
-		$data = $this->m_data;
754
-		$s = 0;
755
-		$y = 0;
756
-
757
-		for ($i = 0; $i < 4; $i++) {
758
-			switch($i) {
759
-			case 0:
760
-				$s = 8;
761
-				$y = 0;
762
-				break;
763
-
764
-			case 1:
765
-				$s = 8;
766
-				$y = 4;
767
-				break;
768
-
769
-			case 2:
770
-				$s = 4;
771
-				$y = 2;
772
-				break;
773
-
774
-			case 3:
775
-				$s = 2;
776
-				$y = 1;
777
-				break;
778
-			}
779
-
780
-			for (; $y < $this->m_gih->m_nHeight; $y += $s) {
781
-				$lne = substr($this->m_data, 0, $this->m_gih->m_nWidth);
782
-				$this->m_data = substr($this->m_data, $this->m_gih->m_nWidth);
783
-
784
-				$data =
785
-					substr($data, 0, $y * $this->m_gih->m_nWidth) .
786
-					$lne .
787
-					substr($data, ($y + 1) * $this->m_gih->m_nWidth);
788
-			}
789
-		}
790
-
791
-		$this->m_data = $data;
792
-	}
625
+    public $m_disp;
626
+    public $m_bUser;
627
+    public $m_bTrans;
628
+    public $m_nDelay;
629
+    public $m_nTrans;
630
+    public $m_lpComm;
631
+    public $m_gih;
632
+    public $m_data;
633
+    public $m_lzw;
634
+
635
+    ///////////////////////////////////////////////////////////////////////////
636
+
637
+    public function __construct()
638
+    {
639
+        unSet($this->m_disp);
640
+        unSet($this->m_bUser);
641
+        unSet($this->m_bTrans);
642
+        unSet($this->m_nDelay);
643
+        unSet($this->m_nTrans);
644
+        unSet($this->m_lpComm);
645
+        unSet($this->m_data);
646
+        $this->m_gih = new CGIFIMAGEHEADER();
647
+        $this->m_lzw = new CGIFLZW();
648
+    }
649
+
650
+    ///////////////////////////////////////////////////////////////////////////
651
+
652
+    public function load($data, &$datLen)
653
+    {
654
+        $datLen = 0;
655
+
656
+        while (true) {
657
+            $b = ord($data{0});
658
+            $data = substr($data, 1);
659
+            $datLen++;
660
+
661
+            switch($b) {
662
+            case 0x21: // Extension
663
+                if (!$this->skipExt($data, $len = 0)) {
664
+                    return false;
665
+                }
666
+                $datLen += $len;
667
+                break;
668
+
669
+            case 0x2C: // Image
670
+                // LOAD HEADER & COLOR TABLE
671
+                if (!$this->m_gih->load($data, $len = 0)) {
672
+                    return false;
673
+                }
674
+                $data = substr($data, $len);
675
+                $datLen += $len;
676
+
677
+                // ALLOC BUFFER
678
+                if (!($this->m_data = $this->m_lzw->deCompress($data, $len = 0))) {
679
+                    return false;
680
+                }
681
+                $data = substr($data, $len);
682
+                $datLen += $len;
683
+
684
+                if ($this->m_gih->m_bInterlace) {
685
+                    $this->deInterlace();
686
+                }
687
+                return true;
688
+
689
+            case 0x3B: // EOF
690
+            default:
691
+                return false;
692
+            }
693
+        }
694
+        return false;
695
+    }
696
+
697
+    ///////////////////////////////////////////////////////////////////////////
698
+
699
+    public function skipExt(&$data, &$extLen)
700
+    {
701
+        $extLen = 0;
702
+
703
+        $b = ord($data{0});
704
+        $data = substr($data, 1);
705
+        $extLen++;
706
+
707
+        switch($b) {
708
+        case 0xF9: // Graphic Control
709
+            $b = ord($data{1});
710
+            $this->m_disp   = ($b & 0x1C) >> 2;
711
+            $this->m_bUser  = ($b & 0x02) ? true : false;
712
+            $this->m_bTrans = ($b & 0x01) ? true : false;
713
+            $this->m_nDelay = $this->w2i(substr($data, 2, 2));
714
+            $this->m_nTrans = ord($data{4});
715
+            break;
716
+
717
+        case 0xFE: // Comment
718
+            $this->m_lpComm = substr($data, 1, ord($data{0}));
719
+            break;
720
+
721
+        case 0x01: // Plain text
722
+            break;
723
+
724
+        case 0xFF: // Application
725
+            break;
726
+        }
727
+
728
+        // SKIP DEFAULT AS DEFS MAY CHANGE
729
+        $b = ord($data{0});
730
+        $data = substr($data, 1);
731
+        $extLen++;
732
+        while ($b > 0) {
733
+            $data = substr($data, $b);
734
+            $extLen += $b;
735
+            $b    = ord($data{0});
736
+            $data = substr($data, 1);
737
+            $extLen++;
738
+        }
739
+        return true;
740
+    }
741
+
742
+    ///////////////////////////////////////////////////////////////////////////
743
+
744
+    public function w2i($str)
745
+    {
746
+        return ord($str[ 0 ]) + (ord($str[ 1 ]) << 8);
747
+    }
748
+
749
+    ///////////////////////////////////////////////////////////////////////////
750
+
751
+    public function deInterlace()
752
+    {
753
+        $data = $this->m_data;
754
+        $s = 0;
755
+        $y = 0;
756
+
757
+        for ($i = 0; $i < 4; $i++) {
758
+            switch($i) {
759
+            case 0:
760
+                $s = 8;
761
+                $y = 0;
762
+                break;
763
+
764
+            case 1:
765
+                $s = 8;
766
+                $y = 4;
767
+                break;
768
+
769
+            case 2:
770
+                $s = 4;
771
+                $y = 2;
772
+                break;
773
+
774
+            case 3:
775
+                $s = 2;
776
+                $y = 1;
777
+                break;
778
+            }
779
+
780
+            for (; $y < $this->m_gih->m_nHeight; $y += $s) {
781
+                $lne = substr($this->m_data, 0, $this->m_gih->m_nWidth);
782
+                $this->m_data = substr($this->m_data, $this->m_gih->m_nWidth);
783
+
784
+                $data =
785
+                    substr($data, 0, $y * $this->m_gih->m_nWidth) .
786
+                    $lne .
787
+                    substr($data, ($y + 1) * $this->m_gih->m_nWidth);
788
+            }
789
+        }
790
+
791
+        $this->m_data = $data;
792
+    }
793 793
 }
794 794
 
795 795
 ///////////////////////////////////////////////////////////////////////////////////////////////////
796 796
 
797 797
 class CGIF
798 798
 {
799
-	public $m_gfh;
800
-	public $m_lpData;
801
-	public $m_img;
802
-	public $m_bLoaded;
803
-
804
-	///////////////////////////////////////////////////////////////////////////
805
-
806
-	// CONSTRUCTOR
807
-	public function __construct()
808
-	{
809
-		$this->m_gfh     = new CGIFFILEHEADER();
810
-		$this->m_img     = new CGIFIMAGE();
811
-		$this->m_lpData  = '';
812
-		$this->m_bLoaded = false;
813
-	}
814
-
815
-	///////////////////////////////////////////////////////////////////////////
816
-
817
-	public function loadFile($lpszFileName, $iIndex)
818
-	{
819
-		if ($iIndex < 0) {
820
-			return false;
821
-		}
822
-
823
-		// READ FILE
824
-		if (!($fh = @fopen($lpszFileName, 'rb'))) {
825
-			return false;
826
-		}
827
-		$this->m_lpData = @fread($fh, @filesize($lpszFileName));
828
-		fclose($fh);
829
-
830
-		// GET FILE HEADER
831
-		if (!$this->m_gfh->load($this->m_lpData, $len = 0)) {
832
-			return false;
833
-		}
834
-		$this->m_lpData = substr($this->m_lpData, $len);
835
-
836
-		do {
837
-			if (!$this->m_img->load($this->m_lpData, $imgLen = 0)) {
838
-				return false;
839
-			}
840
-			$this->m_lpData = substr($this->m_lpData, $imgLen);
841
-		}
842
-		while ($iIndex-- > 0);
843
-
844
-		$this->m_bLoaded = true;
845
-		return true;
846
-	}
847
-
848
-	///////////////////////////////////////////////////////////////////////////
849
-
850
-	public function getSize($lpszFileName, &$width, &$height)
851
-	{
852
-		if (!($fh = @fopen($lpszFileName, 'rb'))) {
853
-			return false;
854
-		}
855
-		$data = @fread($fh, @filesize($lpszFileName));
856
-		@fclose($fh);
857
-
858
-		$gfh = new CGIFFILEHEADER();
859
-		if (!$gfh->load($data, $len = 0)) {
860
-			return false;
861
-		}
862
-
863
-		$width  = $gfh->m_nWidth;
864
-		$height = $gfh->m_nHeight;
865
-		return true;
866
-	}
867
-
868
-	///////////////////////////////////////////////////////////////////////////
869
-
870
-	public function getBmp($bgColor)
871
-	{
872
-		$out = '';
873
-
874
-		if (!$this->m_bLoaded) {
875
-			return false;
876
-		}
877
-
878
-		// PREPARE COLOR TABLE (RGBQUADs)
879
-		if ($this->m_img->m_gih->m_bLocalClr) {
880
-			$nColors = $this->m_img->m_gih->m_nTableSize;
881
-			$rgbq    = $this->m_img->m_gih->m_colorTable->toRGBQuad();
882
-			if ($bgColor != -1) {
883
-				$bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
884
-			}
885
-		} elseif ($this->m_gfh->m_bGlobalClr) {
886
-			$nColors = $this->m_gfh->m_nTableSize;
887
-			$rgbq    = $this->m_gfh->m_colorTable->toRGBQuad();
888
-			if ($bgColor != -1) {
889
-				$bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
890
-			}
891
-		} else {
892
-			$nColors =  0;
893
-			$rgbq    = '';
894
-			$bgColor = -1;
895
-		}
896
-
897
-		// PREPARE BITMAP BITS
898
-		$data = $this->m_img->m_data;
899
-		$nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth;
900
-		$bmp  = '';
901
-		$nPad = ($this->m_gfh->m_nWidth % 4) ? 4 - ($this->m_gfh->m_nWidth % 4) : 0;
902
-		for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
903
-			for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
904
-				if (
905
-					($x >= $this->m_img->m_gih->m_nLeft) &&
906
-					($y >= $this->m_img->m_gih->m_nTop) &&
907
-					($x <  ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
908
-					($y <  ($this->m_img->m_gih->m_nTop  + $this->m_img->m_gih->m_nHeight))) {
909
-					// PART OF IMAGE
910
-					if (@$this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
911
-						// TRANSPARENT -> BACKGROUND
912
-						if ($bgColor == -1) {
913
-							$bmp .= chr($this->m_gfh->m_nBgColor);
914
-						} else {
915
-							$bmp .= chr($bgColor);
916
-						}
917
-					} else {
918
-						$bmp .= $data{$nPxl};
919
-					}
920
-				} else {
921
-					// BACKGROUND
922
-					if ($bgColor == -1) {
923
-						$bmp .= chr($this->m_gfh->m_nBgColor);
924
-					} else {
925
-						$bmp .= chr($bgColor);
926
-					}
927
-				}
928
-			}
929
-			$nPxl -= $this->m_gfh->m_nWidth << 1;
930
-
931
-			// ADD PADDING
932
-			for ($x = 0; $x < $nPad; $x++) {
933
-				$bmp .= "\x00";
934
-			}
935
-		}
936
-
937
-		// BITMAPFILEHEADER
938
-		$out .= 'BM';
939
-		$out .= $this->dword(14 + 40 + ($nColors << 2) + strlen($bmp));
940
-		$out .= "\x00\x00";
941
-		$out .= "\x00\x00";
942
-		$out .= $this->dword(14 + 40 + ($nColors << 2));
943
-
944
-		// BITMAPINFOHEADER
945
-		$out .= $this->dword(40);
946
-		$out .= $this->dword($this->m_gfh->m_nWidth);
947
-		$out .= $this->dword($this->m_gfh->m_nHeight);
948
-		$out .= "\x01\x00";
949
-		$out .= "\x08\x00";
950
-		$out .= "\x00\x00\x00\x00";
951
-		$out .= "\x00\x00\x00\x00";
952
-		$out .= "\x12\x0B\x00\x00";
953
-		$out .= "\x12\x0B\x00\x00";
954
-		$out .= $this->dword($nColors % 256);
955
-		$out .= "\x00\x00\x00\x00";
956
-
957
-		// COLOR TABLE
958
-		if ($nColors > 0) {
959
-			$out .= $rgbq;
960
-		}
961
-
962
-		// DATA
963
-		$out .= $bmp;
964
-
965
-		return $out;
966
-	}
967
-
968
-	///////////////////////////////////////////////////////////////////////////
969
-
970
-	public function getPng($bgColor)
971
-	{
972
-		$out = '';
973
-
974
-		if (!$this->m_bLoaded) {
975
-			return false;
976
-		}
977
-
978
-		// PREPARE COLOR TABLE (RGBQUADs)
979
-		if ($this->m_img->m_gih->m_bLocalClr) {
980
-			$nColors = $this->m_img->m_gih->m_nTableSize;
981
-			$pal     = $this->m_img->m_gih->m_colorTable->toString();
982
-			if ($bgColor != -1) {
983
-				$bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
984
-			}
985
-		} elseif ($this->m_gfh->m_bGlobalClr) {
986
-			$nColors = $this->m_gfh->m_nTableSize;
987
-			$pal     = $this->m_gfh->m_colorTable->toString();
988
-			if ($bgColor != -1) {
989
-				$bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
990
-			}
991
-		} else {
992
-			$nColors =  0;
993
-			$pal     = '';
994
-			$bgColor = -1;
995
-		}
996
-
997
-		// PREPARE BITMAP BITS
998
-		$data = $this->m_img->m_data;
999
-		$nPxl = 0;
1000
-		$bmp  = '';
1001
-		for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
1002
-			$bmp .= "\x00";
1003
-			for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
1004
-				if (
1005
-					($x >= $this->m_img->m_gih->m_nLeft) &&
1006
-					($y >= $this->m_img->m_gih->m_nTop) &&
1007
-					($x <  ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1008
-					($y <  ($this->m_img->m_gih->m_nTop  + $this->m_img->m_gih->m_nHeight))) {
1009
-					// PART OF IMAGE
1010
-					$bmp .= $data{$nPxl};
1011
-				} else {
1012
-					// BACKGROUND
1013
-					if ($bgColor == -1) {
1014
-						$bmp .= chr($this->m_gfh->m_nBgColor);
1015
-					} else {
1016
-						$bmp .= chr($bgColor);
1017
-					}
1018
-				}
1019
-			}
1020
-		}
1021
-		$bmp = gzcompress($bmp, 9);
1022
-
1023
-		///////////////////////////////////////////////////////////////////////
1024
-		// SIGNATURE
1025
-		$out .= "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
1026
-		///////////////////////////////////////////////////////////////////////
1027
-		// HEADER
1028
-		$out .= "\x00\x00\x00\x0D";
1029
-		$tmp  = 'IHDR';
1030
-		$tmp .= $this->ndword($this->m_gfh->m_nWidth);
1031
-		$tmp .= $this->ndword($this->m_gfh->m_nHeight);
1032
-		$tmp .= "\x08\x03\x00\x00\x00";
1033
-		$out .= $tmp;
1034
-		$out .= $this->ndword(crc32($tmp));
1035
-		///////////////////////////////////////////////////////////////////////
1036
-		// PALETTE
1037
-		if ($nColors > 0) {
1038
-			$out .= $this->ndword($nColors * 3);
1039
-			$tmp  = 'PLTE';
1040
-			$tmp .= $pal;
1041
-			$out .= $tmp;
1042
-			$out .= $this->ndword(crc32($tmp));
1043
-		}
1044
-		///////////////////////////////////////////////////////////////////////
1045
-		// TRANSPARENCY
1046
-		if (@$this->m_img->m_bTrans && ($nColors > 0)) {
1047
-			$out .= $this->ndword($nColors);
1048
-			$tmp  = 'tRNS';
1049
-			for ($i = 0; $i < $nColors; $i++) {
1050
-				$tmp .= ($i == $this->m_img->m_nTrans) ? "\x00" : "\xFF";
1051
-			}
1052
-			$out .= $tmp;
1053
-			$out .= $this->ndword(crc32($tmp));
1054
-		}
1055
-		///////////////////////////////////////////////////////////////////////
1056
-		// DATA BITS
1057
-		$out .= $this->ndword(strlen($bmp));
1058
-		$tmp  = 'IDAT';
1059
-		$tmp .= $bmp;
1060
-		$out .= $tmp;
1061
-		$out .= $this->ndword(crc32($tmp));
1062
-		///////////////////////////////////////////////////////////////////////
1063
-		// END OF FILE
1064
-		$out .= "\x00\x00\x00\x00IEND\xAE\x42\x60\x82";
1065
-
1066
-		return $out;
1067
-	}
1068
-
1069
-	///////////////////////////////////////////////////////////////////////////
1070
-
1071
-	// Added by James Heinrich <[email protected]> - January 5, 2003
1072
-
1073
-	// Takes raw image data and plots it pixel-by-pixel on a new GD image and returns that
1074
-	// It's extremely slow, but the only solution when imagecreatefromstring() fails
1075
-	public function getGD_PixelPlotterVersion()
1076
-	{
1077
-		if (!$this->m_bLoaded) {
1078
-			return false;
1079
-		}
1080
-
1081
-		// PREPARE COLOR TABLE (RGBQUADs)
1082
-		if ($this->m_img->m_gih->m_bLocalClr) {
1083
-			$pal = $this->m_img->m_gih->m_colorTable->toString();
1084
-		} elseif ($this->m_gfh->m_bGlobalClr) {
1085
-			$pal = $this->m_gfh->m_colorTable->toString();
1086
-		} else {
1087
-			die('No color table available in getGD_PixelPlotterVersion()');
1088
-		}
1089
-
1090
-		$PlottingIMG = imagecreate($this->m_gfh->m_nWidth, $this->m_gfh->m_nHeight);
1091
-		$NumColorsInPal = floor(strlen($pal) / 3);
1092
-		$ThisImageColor = array();
1093
-		for ($i = 0; $i < $NumColorsInPal; $i++) {
1094
-			$ThisImageColor[$i] = imagecolorallocate(
1095
-									$PlottingIMG,
1096
-									ord($pal{(($i * 3) + 0)}),
1097
-									ord($pal{(($i * 3) + 1)}),
1098
-									ord($pal{(($i * 3) + 2)}));
1099
-		}
1100
-
1101
-		// PREPARE BITMAP BITS
1102
-		$data = $this->m_img->m_data;
1103
-		$nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth;
1104
-		for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
1105
-			if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
1106
-				set_time_limit(30);
1107
-			}
1108
-			for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
1109
-				if (
1110
-					($x >= $this->m_img->m_gih->m_nLeft) &&
1111
-					($y >= $this->m_img->m_gih->m_nTop) &&
1112
-					($x <  ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1113
-					($y <  ($this->m_img->m_gih->m_nTop  + $this->m_img->m_gih->m_nHeight))) {
1114
-					// PART OF IMAGE
1115
-					if (@$this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
1116
-						imagesetpixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[$this->m_gfh->m_nBgColor]);
1117
-					} else {
1118
-						imagesetpixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[ord($data{$nPxl})]);
1119
-					}
1120
-				} else {
1121
-					// BACKGROUND
1122
-					imagesetpixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[$this->m_gfh->m_nBgColor]);
1123
-				}
1124
-			}
1125
-			$nPxl -= $this->m_gfh->m_nWidth << 1;
1126
-
1127
-		}
1128
-
1129
-		return $PlottingIMG;
1130
-	}
1131
-
1132
-	///////////////////////////////////////////////////////////////////////////
1133
-
1134
-	public function dword($val)
1135
-	{
1136
-		$val = (int) $val;
1137
-		return chr($val & 0xFF).chr(($val & 0xFF00) >> 8).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF000000) >> 24);
1138
-	}
1139
-
1140
-	///////////////////////////////////////////////////////////////////////////
1141
-
1142
-	public function ndword($val)
1143
-	{
1144
-		$val = (int) $val;
1145
-		return chr(($val & 0xFF000000) >> 24).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF00) >> 8).chr($val & 0xFF);
1146
-	}
1147
-
1148
-	///////////////////////////////////////////////////////////////////////////
1149
-
1150
-	public function width()
1151
-	{
1152
-		return $this->m_gfh->m_nWidth;
1153
-	}
1154
-
1155
-	///////////////////////////////////////////////////////////////////////////
1156
-
1157
-	public function height()
1158
-	{
1159
-		return $this->m_gfh->m_nHeight;
1160
-	}
1161
-
1162
-	///////////////////////////////////////////////////////////////////////////
1163
-
1164
-	public function comment()
1165
-	{
1166
-		return $this->m_img->m_lpComm;
1167
-	}
1168
-
1169
-	///////////////////////////////////////////////////////////////////////////
1170
-
1171
-	public function loaded()
1172
-	{
1173
-		return $this->m_bLoaded;
1174
-	}
799
+    public $m_gfh;
800
+    public $m_lpData;
801
+    public $m_img;
802
+    public $m_bLoaded;
803
+
804
+    ///////////////////////////////////////////////////////////////////////////
805
+
806
+    // CONSTRUCTOR
807
+    public function __construct()
808
+    {
809
+        $this->m_gfh     = new CGIFFILEHEADER();
810
+        $this->m_img     = new CGIFIMAGE();
811
+        $this->m_lpData  = '';
812
+        $this->m_bLoaded = false;
813
+    }
814
+
815
+    ///////////////////////////////////////////////////////////////////////////
816
+
817
+    public function loadFile($lpszFileName, $iIndex)
818
+    {
819
+        if ($iIndex < 0) {
820
+            return false;
821
+        }
822
+
823
+        // READ FILE
824
+        if (!($fh = @fopen($lpszFileName, 'rb'))) {
825
+            return false;
826
+        }
827
+        $this->m_lpData = @fread($fh, @filesize($lpszFileName));
828
+        fclose($fh);
829
+
830
+        // GET FILE HEADER
831
+        if (!$this->m_gfh->load($this->m_lpData, $len = 0)) {
832
+            return false;
833
+        }
834
+        $this->m_lpData = substr($this->m_lpData, $len);
835
+
836
+        do {
837
+            if (!$this->m_img->load($this->m_lpData, $imgLen = 0)) {
838
+                return false;
839
+            }
840
+            $this->m_lpData = substr($this->m_lpData, $imgLen);
841
+        }
842
+        while ($iIndex-- > 0);
843
+
844
+        $this->m_bLoaded = true;
845
+        return true;
846
+    }
847
+
848
+    ///////////////////////////////////////////////////////////////////////////
849
+
850
+    public function getSize($lpszFileName, &$width, &$height)
851
+    {
852
+        if (!($fh = @fopen($lpszFileName, 'rb'))) {
853
+            return false;
854
+        }
855
+        $data = @fread($fh, @filesize($lpszFileName));
856
+        @fclose($fh);
857
+
858
+        $gfh = new CGIFFILEHEADER();
859
+        if (!$gfh->load($data, $len = 0)) {
860
+            return false;
861
+        }
862
+
863
+        $width  = $gfh->m_nWidth;
864
+        $height = $gfh->m_nHeight;
865
+        return true;
866
+    }
867
+
868
+    ///////////////////////////////////////////////////////////////////////////
869
+
870
+    public function getBmp($bgColor)
871
+    {
872
+        $out = '';
873
+
874
+        if (!$this->m_bLoaded) {
875
+            return false;
876
+        }
877
+
878
+        // PREPARE COLOR TABLE (RGBQUADs)
879
+        if ($this->m_img->m_gih->m_bLocalClr) {
880
+            $nColors = $this->m_img->m_gih->m_nTableSize;
881
+            $rgbq    = $this->m_img->m_gih->m_colorTable->toRGBQuad();
882
+            if ($bgColor != -1) {
883
+                $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
884
+            }
885
+        } elseif ($this->m_gfh->m_bGlobalClr) {
886
+            $nColors = $this->m_gfh->m_nTableSize;
887
+            $rgbq    = $this->m_gfh->m_colorTable->toRGBQuad();
888
+            if ($bgColor != -1) {
889
+                $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
890
+            }
891
+        } else {
892
+            $nColors =  0;
893
+            $rgbq    = '';
894
+            $bgColor = -1;
895
+        }
896
+
897
+        // PREPARE BITMAP BITS
898
+        $data = $this->m_img->m_data;
899
+        $nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth;
900
+        $bmp  = '';
901
+        $nPad = ($this->m_gfh->m_nWidth % 4) ? 4 - ($this->m_gfh->m_nWidth % 4) : 0;
902
+        for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
903
+            for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
904
+                if (
905
+                    ($x >= $this->m_img->m_gih->m_nLeft) &&
906
+                    ($y >= $this->m_img->m_gih->m_nTop) &&
907
+                    ($x <  ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
908
+                    ($y <  ($this->m_img->m_gih->m_nTop  + $this->m_img->m_gih->m_nHeight))) {
909
+                    // PART OF IMAGE
910
+                    if (@$this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
911
+                        // TRANSPARENT -> BACKGROUND
912
+                        if ($bgColor == -1) {
913
+                            $bmp .= chr($this->m_gfh->m_nBgColor);
914
+                        } else {
915
+                            $bmp .= chr($bgColor);
916
+                        }
917
+                    } else {
918
+                        $bmp .= $data{$nPxl};
919
+                    }
920
+                } else {
921
+                    // BACKGROUND
922
+                    if ($bgColor == -1) {
923
+                        $bmp .= chr($this->m_gfh->m_nBgColor);
924
+                    } else {
925
+                        $bmp .= chr($bgColor);
926
+                    }
927
+                }
928
+            }
929
+            $nPxl -= $this->m_gfh->m_nWidth << 1;
930
+
931
+            // ADD PADDING
932
+            for ($x = 0; $x < $nPad; $x++) {
933
+                $bmp .= "\x00";
934
+            }
935
+        }
936
+
937
+        // BITMAPFILEHEADER
938
+        $out .= 'BM';
939
+        $out .= $this->dword(14 + 40 + ($nColors << 2) + strlen($bmp));
940
+        $out .= "\x00\x00";
941
+        $out .= "\x00\x00";
942
+        $out .= $this->dword(14 + 40 + ($nColors << 2));
943
+
944
+        // BITMAPINFOHEADER
945
+        $out .= $this->dword(40);
946
+        $out .= $this->dword($this->m_gfh->m_nWidth);
947
+        $out .= $this->dword($this->m_gfh->m_nHeight);
948
+        $out .= "\x01\x00";
949
+        $out .= "\x08\x00";
950
+        $out .= "\x00\x00\x00\x00";
951
+        $out .= "\x00\x00\x00\x00";
952
+        $out .= "\x12\x0B\x00\x00";
953
+        $out .= "\x12\x0B\x00\x00";
954
+        $out .= $this->dword($nColors % 256);
955
+        $out .= "\x00\x00\x00\x00";
956
+
957
+        // COLOR TABLE
958
+        if ($nColors > 0) {
959
+            $out .= $rgbq;
960
+        }
961
+
962
+        // DATA
963
+        $out .= $bmp;
964
+
965
+        return $out;
966
+    }
967
+
968
+    ///////////////////////////////////////////////////////////////////////////
969
+
970
+    public function getPng($bgColor)
971
+    {
972
+        $out = '';
973
+
974
+        if (!$this->m_bLoaded) {
975
+            return false;
976
+        }
977
+
978
+        // PREPARE COLOR TABLE (RGBQUADs)
979
+        if ($this->m_img->m_gih->m_bLocalClr) {
980
+            $nColors = $this->m_img->m_gih->m_nTableSize;
981
+            $pal     = $this->m_img->m_gih->m_colorTable->toString();
982
+            if ($bgColor != -1) {
983
+                $bgColor = $this->m_img->m_gih->m_colorTable->colorIndex($bgColor);
984
+            }
985
+        } elseif ($this->m_gfh->m_bGlobalClr) {
986
+            $nColors = $this->m_gfh->m_nTableSize;
987
+            $pal     = $this->m_gfh->m_colorTable->toString();
988
+            if ($bgColor != -1) {
989
+                $bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
990
+            }
991
+        } else {
992
+            $nColors =  0;
993
+            $pal     = '';
994
+            $bgColor = -1;
995
+        }
996
+
997
+        // PREPARE BITMAP BITS
998
+        $data = $this->m_img->m_data;
999
+        $nPxl = 0;
1000
+        $bmp  = '';
1001
+        for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
1002
+            $bmp .= "\x00";
1003
+            for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
1004
+                if (
1005
+                    ($x >= $this->m_img->m_gih->m_nLeft) &&
1006
+                    ($y >= $this->m_img->m_gih->m_nTop) &&
1007
+                    ($x <  ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1008
+                    ($y <  ($this->m_img->m_gih->m_nTop  + $this->m_img->m_gih->m_nHeight))) {
1009
+                    // PART OF IMAGE
1010
+                    $bmp .= $data{$nPxl};
1011
+                } else {
1012
+                    // BACKGROUND
1013
+                    if ($bgColor == -1) {
1014
+                        $bmp .= chr($this->m_gfh->m_nBgColor);
1015
+                    } else {
1016
+                        $bmp .= chr($bgColor);
1017
+                    }
1018
+                }
1019
+            }
1020
+        }
1021
+        $bmp = gzcompress($bmp, 9);
1022
+
1023
+        ///////////////////////////////////////////////////////////////////////
1024
+        // SIGNATURE
1025
+        $out .= "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
1026
+        ///////////////////////////////////////////////////////////////////////
1027
+        // HEADER
1028
+        $out .= "\x00\x00\x00\x0D";
1029
+        $tmp  = 'IHDR';
1030
+        $tmp .= $this->ndword($this->m_gfh->m_nWidth);
1031
+        $tmp .= $this->ndword($this->m_gfh->m_nHeight);
1032
+        $tmp .= "\x08\x03\x00\x00\x00";
1033
+        $out .= $tmp;
1034
+        $out .= $this->ndword(crc32($tmp));
1035
+        ///////////////////////////////////////////////////////////////////////
1036
+        // PALETTE
1037
+        if ($nColors > 0) {
1038
+            $out .= $this->ndword($nColors * 3);
1039
+            $tmp  = 'PLTE';
1040
+            $tmp .= $pal;
1041
+            $out .= $tmp;
1042
+            $out .= $this->ndword(crc32($tmp));
1043
+        }
1044
+        ///////////////////////////////////////////////////////////////////////
1045
+        // TRANSPARENCY
1046
+        if (@$this->m_img->m_bTrans && ($nColors > 0)) {
1047
+            $out .= $this->ndword($nColors);
1048
+            $tmp  = 'tRNS';
1049
+            for ($i = 0; $i < $nColors; $i++) {
1050
+                $tmp .= ($i == $this->m_img->m_nTrans) ? "\x00" : "\xFF";
1051
+            }
1052
+            $out .= $tmp;
1053
+            $out .= $this->ndword(crc32($tmp));
1054
+        }
1055
+        ///////////////////////////////////////////////////////////////////////
1056
+        // DATA BITS
1057
+        $out .= $this->ndword(strlen($bmp));
1058
+        $tmp  = 'IDAT';
1059
+        $tmp .= $bmp;
1060
+        $out .= $tmp;
1061
+        $out .= $this->ndword(crc32($tmp));
1062
+        ///////////////////////////////////////////////////////////////////////
1063
+        // END OF FILE
1064
+        $out .= "\x00\x00\x00\x00IEND\xAE\x42\x60\x82";
1065
+
1066
+        return $out;
1067
+    }
1068
+
1069
+    ///////////////////////////////////////////////////////////////////////////
1070
+
1071
+    // Added by James Heinrich <[email protected]> - January 5, 2003
1072
+
1073
+    // Takes raw image data and plots it pixel-by-pixel on a new GD image and returns that
1074
+    // It's extremely slow, but the only solution when imagecreatefromstring() fails
1075
+    public function getGD_PixelPlotterVersion()
1076
+    {
1077
+        if (!$this->m_bLoaded) {
1078
+            return false;
1079
+        }
1080
+
1081
+        // PREPARE COLOR TABLE (RGBQUADs)
1082
+        if ($this->m_img->m_gih->m_bLocalClr) {
1083
+            $pal = $this->m_img->m_gih->m_colorTable->toString();
1084
+        } elseif ($this->m_gfh->m_bGlobalClr) {
1085
+            $pal = $this->m_gfh->m_colorTable->toString();
1086
+        } else {
1087
+            die('No color table available in getGD_PixelPlotterVersion()');
1088
+        }
1089
+
1090
+        $PlottingIMG = imagecreate($this->m_gfh->m_nWidth, $this->m_gfh->m_nHeight);
1091
+        $NumColorsInPal = floor(strlen($pal) / 3);
1092
+        $ThisImageColor = array();
1093
+        for ($i = 0; $i < $NumColorsInPal; $i++) {
1094
+            $ThisImageColor[$i] = imagecolorallocate(
1095
+                                    $PlottingIMG,
1096
+                                    ord($pal{(($i * 3) + 0)}),
1097
+                                    ord($pal{(($i * 3) + 1)}),
1098
+                                    ord($pal{(($i * 3) + 2)}));
1099
+        }
1100
+
1101
+        // PREPARE BITMAP BITS
1102
+        $data = $this->m_img->m_data;
1103
+        $nPxl = ($this->m_gfh->m_nHeight - 1) * $this->m_gfh->m_nWidth;
1104
+        for ($y = 0; $y < $this->m_gfh->m_nHeight; $y++) {
1105
+            if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
1106
+                set_time_limit(30);
1107
+            }
1108
+            for ($x = 0; $x < $this->m_gfh->m_nWidth; $x++, $nPxl++) {
1109
+                if (
1110
+                    ($x >= $this->m_img->m_gih->m_nLeft) &&
1111
+                    ($y >= $this->m_img->m_gih->m_nTop) &&
1112
+                    ($x <  ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1113
+                    ($y <  ($this->m_img->m_gih->m_nTop  + $this->m_img->m_gih->m_nHeight))) {
1114
+                    // PART OF IMAGE
1115
+                    if (@$this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
1116
+                        imagesetpixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[$this->m_gfh->m_nBgColor]);
1117
+                    } else {
1118
+                        imagesetpixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[ord($data{$nPxl})]);
1119
+                    }
1120
+                } else {
1121
+                    // BACKGROUND
1122
+                    imagesetpixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[$this->m_gfh->m_nBgColor]);
1123
+                }
1124
+            }
1125
+            $nPxl -= $this->m_gfh->m_nWidth << 1;
1126
+
1127
+        }
1128
+
1129
+        return $PlottingIMG;
1130
+    }
1131
+
1132
+    ///////////////////////////////////////////////////////////////////////////
1133
+
1134
+    public function dword($val)
1135
+    {
1136
+        $val = (int) $val;
1137
+        return chr($val & 0xFF).chr(($val & 0xFF00) >> 8).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF000000) >> 24);
1138
+    }
1139
+
1140
+    ///////////////////////////////////////////////////////////////////////////
1141
+
1142
+    public function ndword($val)
1143
+    {
1144
+        $val = (int) $val;
1145
+        return chr(($val & 0xFF000000) >> 24).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF00) >> 8).chr($val & 0xFF);
1146
+    }
1147
+
1148
+    ///////////////////////////////////////////////////////////////////////////
1149
+
1150
+    public function width()
1151
+    {
1152
+        return $this->m_gfh->m_nWidth;
1153
+    }
1154
+
1155
+    ///////////////////////////////////////////////////////////////////////////
1156
+
1157
+    public function height()
1158
+    {
1159
+        return $this->m_gfh->m_nHeight;
1160
+    }
1161
+
1162
+    ///////////////////////////////////////////////////////////////////////////
1163
+
1164
+    public function comment()
1165
+    {
1166
+        return $this->m_img->m_lpComm;
1167
+    }
1168
+
1169
+    ///////////////////////////////////////////////////////////////////////////
1170
+
1171
+    public function loaded()
1172
+    {
1173
+        return $this->m_bLoaded;
1174
+    }
1175 1175
 }
Please login to merge, or discard this patch.
Switch Indentation   +67 added lines, -67 removed lines patch added patch discarded remove patch
@@ -659,36 +659,36 @@  discard block
 block discarded – undo
659 659
 			$datLen++;
660 660
 
661 661
 			switch($b) {
662
-			case 0x21: // Extension
663
-				if (!$this->skipExt($data, $len = 0)) {
664
-					return false;
665
-				}
666
-				$datLen += $len;
667
-				break;
668
-
669
-			case 0x2C: // Image
670
-				// LOAD HEADER & COLOR TABLE
671
-				if (!$this->m_gih->load($data, $len = 0)) {
672
-					return false;
673
-				}
674
-				$data = substr($data, $len);
675
-				$datLen += $len;
676
-
677
-				// ALLOC BUFFER
678
-				if (!($this->m_data = $this->m_lzw->deCompress($data, $len = 0))) {
679
-					return false;
680
-				}
681
-				$data = substr($data, $len);
682
-				$datLen += $len;
683
-
684
-				if ($this->m_gih->m_bInterlace) {
685
-					$this->deInterlace();
686
-				}
687
-				return true;
688
-
689
-			case 0x3B: // EOF
690
-			default:
691
-				return false;
662
+			    case 0x21: // Extension
663
+				    if (!$this->skipExt($data, $len = 0)) {
664
+					    return false;
665
+				    }
666
+				    $datLen += $len;
667
+				    break;
668
+
669
+			    case 0x2C: // Image
670
+				    // LOAD HEADER & COLOR TABLE
671
+				    if (!$this->m_gih->load($data, $len = 0)) {
672
+					    return false;
673
+				    }
674
+				    $data = substr($data, $len);
675
+				    $datLen += $len;
676
+
677
+				    // ALLOC BUFFER
678
+				    if (!($this->m_data = $this->m_lzw->deCompress($data, $len = 0))) {
679
+					    return false;
680
+				    }
681
+				    $data = substr($data, $len);
682
+				    $datLen += $len;
683
+
684
+				    if ($this->m_gih->m_bInterlace) {
685
+					    $this->deInterlace();
686
+				    }
687
+				    return true;
688
+
689
+			    case 0x3B: // EOF
690
+			    default:
691
+				    return false;
692 692
 			}
693 693
 		}
694 694
 		return false;
@@ -705,24 +705,24 @@  discard block
 block discarded – undo
705 705
 		$extLen++;
706 706
 
707 707
 		switch($b) {
708
-		case 0xF9: // Graphic Control
709
-			$b = ord($data{1});
710
-			$this->m_disp   = ($b & 0x1C) >> 2;
711
-			$this->m_bUser  = ($b & 0x02) ? true : false;
712
-			$this->m_bTrans = ($b & 0x01) ? true : false;
713
-			$this->m_nDelay = $this->w2i(substr($data, 2, 2));
714
-			$this->m_nTrans = ord($data{4});
715
-			break;
716
-
717
-		case 0xFE: // Comment
718
-			$this->m_lpComm = substr($data, 1, ord($data{0}));
719
-			break;
720
-
721
-		case 0x01: // Plain text
722
-			break;
723
-
724
-		case 0xFF: // Application
725
-			break;
708
+		    case 0xF9: // Graphic Control
709
+			    $b = ord($data{1});
710
+			    $this->m_disp   = ($b & 0x1C) >> 2;
711
+			    $this->m_bUser  = ($b & 0x02) ? true : false;
712
+			    $this->m_bTrans = ($b & 0x01) ? true : false;
713
+			    $this->m_nDelay = $this->w2i(substr($data, 2, 2));
714
+			    $this->m_nTrans = ord($data{4});
715
+			    break;
716
+
717
+		    case 0xFE: // Comment
718
+			    $this->m_lpComm = substr($data, 1, ord($data{0}));
719
+			    break;
720
+
721
+		    case 0x01: // Plain text
722
+			    break;
723
+
724
+		    case 0xFF: // Application
725
+			    break;
726 726
 		}
727 727
 
728 728
 		// SKIP DEFAULT AS DEFS MAY CHANGE
@@ -756,25 +756,25 @@  discard block
 block discarded – undo
756 756
 
757 757
 		for ($i = 0; $i < 4; $i++) {
758 758
 			switch($i) {
759
-			case 0:
760
-				$s = 8;
761
-				$y = 0;
762
-				break;
763
-
764
-			case 1:
765
-				$s = 8;
766
-				$y = 4;
767
-				break;
768
-
769
-			case 2:
770
-				$s = 4;
771
-				$y = 2;
772
-				break;
773
-
774
-			case 3:
775
-				$s = 2;
776
-				$y = 1;
777
-				break;
759
+			    case 0:
760
+				    $s = 8;
761
+				    $y = 0;
762
+				    break;
763
+
764
+			    case 1:
765
+				    $s = 8;
766
+				    $y = 4;
767
+				    break;
768
+
769
+			    case 2:
770
+				    $s = 4;
771
+				    $y = 2;
772
+				    break;
773
+
774
+			    case 3:
775
+				    $s = 2;
776
+				    $y = 1;
777
+				    break;
778 778
 			}
779 779
 
780 780
 			for (; $y < $this->m_gih->m_nHeight; $y += $s) {
Please login to merge, or discard this patch.
Spacing   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -178,8 +178,8 @@  discard block
 block discarded – undo
178 178
 		unSet($this->Stack);
179 179
 		unSet($this->Buf);
180 180
 
181
-		$this->Next  = range(0, (1 << $this->MAX_LZW_BITS)       - 1);
182
-		$this->Vals  = range(0, (1 << $this->MAX_LZW_BITS)       - 1);
181
+		$this->Next  = range(0, (1 << $this->MAX_LZW_BITS) - 1);
182
+		$this->Vals  = range(0, (1 << $this->MAX_LZW_BITS) - 1);
183 183
 		$this->Stack = range(0, (1 << ($this->MAX_LZW_BITS + 1)) - 1);
184 184
 		$this->Buf   = range(0, 279);
185 185
 	}
@@ -366,7 +366,7 @@  discard block
 block discarded – undo
366 366
 
367 367
 		$iRet = 0;
368 368
 		for ($i = $this->CurBit, $j = 0; $j < $this->CodeSize; $i++, $j++) {
369
-			$iRet |= (($this->Buf[ (int) ($i / 8) ] & (1 << ($i % 8))) != 0) << $j;
369
+			$iRet |= (($this->Buf[(int)($i / 8)] & (1 << ($i % 8))) != 0) << $j;
370 370
 		}
371 371
 
372 372
 		$this->CurBit += $this->CodeSize;
@@ -418,9 +418,9 @@  discard block
 block discarded – undo
418 418
 
419 419
 		for ($i = 0; $i < $this->m_nColors; $i++) {
420 420
 			$ret .=
421
-				chr(($this->m_arColors[$i] & 0x000000FF))       . // R
422
-				chr(($this->m_arColors[$i] & 0x0000FF00) >>  8) . // G
423
-				chr(($this->m_arColors[$i] & 0x00FF0000) >> 16);  // B
421
+				chr(($this->m_arColors[$i] & 0x000000FF)).// R
422
+				chr(($this->m_arColors[$i] & 0x0000FF00) >> 8).// G
423
+				chr(($this->m_arColors[$i] & 0x00FF0000) >> 16); // B
424 424
 		}
425 425
 
426 426
 		return $ret;
@@ -434,9 +434,9 @@  discard block
 block discarded – undo
434 434
 
435 435
 		for ($i = 0; $i < $this->m_nColors; $i++) {
436 436
 			$ret .=
437
-				chr(($this->m_arColors[$i] & 0x00FF0000) >> 16) . // B
438
-				chr(($this->m_arColors[$i] & 0x0000FF00) >>  8) . // G
439
-				chr(($this->m_arColors[$i] & 0x000000FF))       . // R
437
+				chr(($this->m_arColors[$i] & 0x00FF0000) >> 16).// B
438
+				chr(($this->m_arColors[$i] & 0x0000FF00) >> 8).// G
439
+				chr(($this->m_arColors[$i] & 0x000000FF)).// R
440 440
 				"\x00";
441 441
 		}
442 442
 
@@ -447,16 +447,16 @@  discard block
 block discarded – undo
447 447
 
448 448
 	public function colorIndex($rgb)
449 449
 	{
450
-		$rgb = (int) $rgb & 0xFFFFFF;
450
+		$rgb = (int)$rgb & 0xFFFFFF;
451 451
 		$r1  = ($rgb & 0x0000FF);
452
-		$g1  = ($rgb & 0x00FF00) >>  8;
452
+		$g1  = ($rgb & 0x00FF00) >> 8;
453 453
 		$b1  = ($rgb & 0xFF0000) >> 16;
454 454
 		$idx = -1;
455 455
 		$dif = 0;
456 456
 
457 457
 		for ($i = 0; $i < $this->m_nColors; $i++) {
458 458
 			$r2 = ($this->m_arColors[$i] & 0x000000FF);
459
-			$g2 = ($this->m_arColors[$i] & 0x0000FF00) >>  8;
459
+			$g2 = ($this->m_arColors[$i] & 0x0000FF00) >> 8;
460 460
 			$b2 = ($this->m_arColors[$i] & 0x00FF0000) >> 16;
461 461
 			$d  = abs($r2 - $r1) + abs($g2 - $g1) + abs($b2 - $b1);
462 462
 
@@ -519,13 +519,13 @@  discard block
 block discarded – undo
519 519
 			return false;
520 520
 		}
521 521
 
522
-		$b = ord($lpData[ 10 ]);
522
+		$b = ord($lpData[10]);
523 523
 		$this->m_bGlobalClr  = ($b & 0x80) ? true : false;
524 524
 		$this->m_nColorRes   = ($b & 0x70) >> 4;
525 525
 		$this->m_bSorted     = ($b & 0x08) ? true : false;
526 526
 		$this->m_nTableSize  = 2 << ($b & 0x07);
527
-		$this->m_nBgColor    = ord($lpData[ 11 ]);
528
-		$this->m_nPixelRatio = ord($lpData[ 12 ]);
527
+		$this->m_nBgColor    = ord($lpData[11]);
528
+		$this->m_nPixelRatio = ord($lpData[12]);
529 529
 		$hdrLen = 13;
530 530
 
531 531
 		if ($this->m_bGlobalClr) {
@@ -543,7 +543,7 @@  discard block
 block discarded – undo
543 543
 
544 544
 	public function w2i($str)
545 545
 	{
546
-		return ord($str[ 0 ]) + (ord($str[ 1 ]) << 8);
546
+		return ord($str[0]) + (ord($str[1]) << 8);
547 547
 	}
548 548
 }
549 549
 
@@ -614,7 +614,7 @@  discard block
 block discarded – undo
614 614
 
615 615
 	public function w2i($str)
616 616
 	{
617
-		return ord($str[ 0 ]) + (ord($str[ 1 ]) << 8);
617
+		return ord($str[0]) + (ord($str[1]) << 8);
618 618
 	}
619 619
 }
620 620
 
@@ -658,7 +658,7 @@  discard block
 block discarded – undo
658 658
 			$data = substr($data, 1);
659 659
 			$datLen++;
660 660
 
661
-			switch($b) {
661
+			switch ($b) {
662 662
 			case 0x21: // Extension
663 663
 				if (!$this->skipExt($data, $len = 0)) {
664 664
 					return false;
@@ -704,7 +704,7 @@  discard block
 block discarded – undo
704 704
 		$data = substr($data, 1);
705 705
 		$extLen++;
706 706
 
707
-		switch($b) {
707
+		switch ($b) {
708 708
 		case 0xF9: // Graphic Control
709 709
 			$b = ord($data{1});
710 710
 			$this->m_disp   = ($b & 0x1C) >> 2;
@@ -743,7 +743,7 @@  discard block
 block discarded – undo
743 743
 
744 744
 	public function w2i($str)
745 745
 	{
746
-		return ord($str[ 0 ]) + (ord($str[ 1 ]) << 8);
746
+		return ord($str[0]) + (ord($str[1]) << 8);
747 747
 	}
748 748
 
749 749
 	///////////////////////////////////////////////////////////////////////////
@@ -755,7 +755,7 @@  discard block
 block discarded – undo
755 755
 		$y = 0;
756 756
 
757 757
 		for ($i = 0; $i < 4; $i++) {
758
-			switch($i) {
758
+			switch ($i) {
759 759
 			case 0:
760 760
 				$s = 8;
761 761
 				$y = 0;
@@ -782,8 +782,8 @@  discard block
 block discarded – undo
782 782
 				$this->m_data = substr($this->m_data, $this->m_gih->m_nWidth);
783 783
 
784 784
 				$data =
785
-					substr($data, 0, $y * $this->m_gih->m_nWidth) .
786
-					$lne .
785
+					substr($data, 0, $y * $this->m_gih->m_nWidth).
786
+					$lne.
787 787
 					substr($data, ($y + 1) * $this->m_gih->m_nWidth);
788 788
 			}
789 789
 		}
@@ -889,7 +889,7 @@  discard block
 block discarded – undo
889 889
 				$bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
890 890
 			}
891 891
 		} else {
892
-			$nColors =  0;
892
+			$nColors = 0;
893 893
 			$rgbq    = '';
894 894
 			$bgColor = -1;
895 895
 		}
@@ -904,8 +904,8 @@  discard block
 block discarded – undo
904 904
 				if (
905 905
 					($x >= $this->m_img->m_gih->m_nLeft) &&
906 906
 					($y >= $this->m_img->m_gih->m_nTop) &&
907
-					($x <  ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
908
-					($y <  ($this->m_img->m_gih->m_nTop  + $this->m_img->m_gih->m_nHeight))) {
907
+					($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
908
+					($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
909 909
 					// PART OF IMAGE
910 910
 					if (@$this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
911 911
 						// TRANSPARENT -> BACKGROUND
@@ -989,7 +989,7 @@  discard block
 block discarded – undo
989 989
 				$bgColor = $this->m_gfh->m_colorTable->colorIndex($bgColor);
990 990
 			}
991 991
 		} else {
992
-			$nColors =  0;
992
+			$nColors = 0;
993 993
 			$pal     = '';
994 994
 			$bgColor = -1;
995 995
 		}
@@ -1004,8 +1004,8 @@  discard block
 block discarded – undo
1004 1004
 				if (
1005 1005
 					($x >= $this->m_img->m_gih->m_nLeft) &&
1006 1006
 					($y >= $this->m_img->m_gih->m_nTop) &&
1007
-					($x <  ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1008
-					($y <  ($this->m_img->m_gih->m_nTop  + $this->m_img->m_gih->m_nHeight))) {
1007
+					($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1008
+					($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
1009 1009
 					// PART OF IMAGE
1010 1010
 					$bmp .= $data{$nPxl};
1011 1011
 				} else {
@@ -1109,8 +1109,8 @@  discard block
 block discarded – undo
1109 1109
 				if (
1110 1110
 					($x >= $this->m_img->m_gih->m_nLeft) &&
1111 1111
 					($y >= $this->m_img->m_gih->m_nTop) &&
1112
-					($x <  ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1113
-					($y <  ($this->m_img->m_gih->m_nTop  + $this->m_img->m_gih->m_nHeight))) {
1112
+					($x < ($this->m_img->m_gih->m_nLeft + $this->m_img->m_gih->m_nWidth)) &&
1113
+					($y < ($this->m_img->m_gih->m_nTop + $this->m_img->m_gih->m_nHeight))) {
1114 1114
 					// PART OF IMAGE
1115 1115
 					if (@$this->m_img->m_bTrans && (ord($data{$nPxl}) == $this->m_img->m_nTrans)) {
1116 1116
 						imagesetpixel($PlottingIMG, $x, $this->m_gfh->m_nHeight - $y - 1, $ThisImageColor[$this->m_gfh->m_nBgColor]);
@@ -1133,7 +1133,7 @@  discard block
 block discarded – undo
1133 1133
 
1134 1134
 	public function dword($val)
1135 1135
 	{
1136
-		$val = (int) $val;
1136
+		$val = (int)$val;
1137 1137
 		return chr($val & 0xFF).chr(($val & 0xFF00) >> 8).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF000000) >> 24);
1138 1138
 	}
1139 1139
 
@@ -1141,7 +1141,7 @@  discard block
 block discarded – undo
1141 1141
 
1142 1142
 	public function ndword($val)
1143 1143
 	{
1144
-		$val = (int) $val;
1144
+		$val = (int)$val;
1145 1145
 		return chr(($val & 0xFF000000) >> 24).chr(($val & 0xFF0000) >> 16).chr(($val & 0xFF00) >> 8).chr($val & 0xFF);
1146 1146
 	}
1147 1147
 
Please login to merge, or discard this patch.
Braces   +3 added lines, -1 removed lines patch added patch discarded remove patch
@@ -292,8 +292,10 @@
 block discarded – undo
292 292
 				$this->Stack[$this->sp] = $this->Vals[$Code];
293 293
 				$this->sp++;
294 294
 
295
-				if ($Code == $this->Next[$Code]) // Circular table entry, big GIF Error!
295
+				if ($Code == $this->Next[$Code]) {
296
+				    // Circular table entry, big GIF Error!
296 297
 					return -1;
298
+				}
297 299
 
298 300
 				$Code = $this->Next[$Code];
299 301
 			}
Please login to merge, or discard this patch.
htdocs/modules/system/class/thumbs/phpThumb.config.php 2 patches
Indentation   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -112,12 +112,12 @@  discard block
 block discarded – undo
112 112
 $PHPTHUMB_CONFIG['prefer_imagemagick']        = true;  // If true, use ImageMagick to resize thumbnails if possible, since it is usually faster than GD functions; if false only use ImageMagick if PHP memory limit is too low.
113 113
 $PHPTHUMB_CONFIG['imagemagick_use_thumbnail'] = true;  // If true, use ImageMagick's "-thumbnail" resizing parameter (if available) which removes extra non-image metadata (profiles, EXIF info, etc) resulting in much smaller filesize; if false, use "-resize" paramter which retains this info
114 114
 if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
115
-	// Windows: set absolute pathname
116
-	$PHPTHUMB_CONFIG['imagemagick_path'] = 'C:/ImageMagick/convert.exe';
115
+    // Windows: set absolute pathname
116
+    $PHPTHUMB_CONFIG['imagemagick_path'] = 'C:/ImageMagick/convert.exe';
117 117
 } else {
118
-	// *nix: set absolute pathname to "convert", or leave as null if "convert" is in the path (location detected with `which`)
119
-	//$PHPTHUMB_CONFIG['imagemagick_path'] = '/usr/local/bin/convert';
120
-	$PHPTHUMB_CONFIG['imagemagick_path'] = null;
118
+    // *nix: set absolute pathname to "convert", or leave as null if "convert" is in the path (location detected with `which`)
119
+    //$PHPTHUMB_CONFIG['imagemagick_path'] = '/usr/local/bin/convert';
120
+    $PHPTHUMB_CONFIG['imagemagick_path'] = null;
121 121
 }
122 122
 
123 123
 
@@ -248,22 +248,22 @@  discard block
 block discarded – undo
248 248
 $GLOBALS['PHPTHUMB_CONFIG'] = $PHPTHUMB_CONFIG;
249 249
 function phpThumbURL($ParameterString, $path_to_phpThumb='phpThumb.php') {
250 250
     global $PHPTHUMB_CONFIG;
251
-	if (is_array($ParameterString)) {
252
-		$ParameterStringArray = $ParameterString;
253
-	} else {
254
-		parse_str($ParameterString, $ParameterStringArray);
255
-	}
256
-	$ParamterStringEncodedArray = array();
257
-	foreach ($ParameterStringArray as $key => $value) {
258
-		if (is_array($value)) {
259
-			// e.g. fltr[] is passed as an array
260
-			foreach ($value as $subvalue) {
261
-				$ParamterStringEncodedArray[] = $key.'[]='.rawurlencode($subvalue);
262
-			}
263
-		} else {
264
-			$ParamterStringEncodedArray[] = $key.'='.rawurlencode($value);
265
-		}
266
-	}
267
-	$ParameterString = implode($PHPTHUMB_CONFIG['high_security_url_separator'], $ParamterStringEncodedArray);
268
-	return $path_to_phpThumb.'?'.$ParameterString.$PHPTHUMB_CONFIG['high_security_url_separator'].'hash='.md5($ParameterString.$PHPTHUMB_CONFIG['high_security_password']);
251
+    if (is_array($ParameterString)) {
252
+        $ParameterStringArray = $ParameterString;
253
+    } else {
254
+        parse_str($ParameterString, $ParameterStringArray);
255
+    }
256
+    $ParamterStringEncodedArray = array();
257
+    foreach ($ParameterStringArray as $key => $value) {
258
+        if (is_array($value)) {
259
+            // e.g. fltr[] is passed as an array
260
+            foreach ($value as $subvalue) {
261
+                $ParamterStringEncodedArray[] = $key.'[]='.rawurlencode($subvalue);
262
+            }
263
+        } else {
264
+            $ParamterStringEncodedArray[] = $key.'='.rawurlencode($value);
265
+        }
266
+    }
267
+    $ParameterString = implode($PHPTHUMB_CONFIG['high_security_url_separator'], $ParamterStringEncodedArray);
268
+    return $path_to_phpThumb.'?'.$ParameterString.$PHPTHUMB_CONFIG['high_security_url_separator'].'hash='.md5($ParameterString.$PHPTHUMB_CONFIG['high_security_password']);
269 269
 }
Please login to merge, or discard this patch.
Spacing   +53 added lines, -53 removed lines patch added patch discarded remove patch
@@ -10,13 +10,13 @@  discard block
 block discarded – undo
10 10
 //            THIS CONFIG FILE ONLY APPLIES TO phpThumb.php //
11 11
 //                                                         ///
12 12
 //////////////////////////////////////////////////////////////
13
-require dirname(dirname(__DIR__)) . '/header.php';
13
+require dirname(dirname(__DIR__)).'/header.php';
14 14
 define('phpThumbConfigFileVersion', '1.7.15');
15 15
 ob_start();
16 16
 if (!class_exists('phpthumb_functions')) { // normally include_once should take care of this, but see https://github.com/JamesHeinrich/phpThumb/issues/94
17
-if (!file_exists(__DIR__ . '/phpthumb.functions.php') || !include_once(__DIR__ . '/phpthumb.functions.php')) {
17
+if (!file_exists(__DIR__.'/phpthumb.functions.php') || !include_once(__DIR__.'/phpthumb.functions.php')) {
18 18
     ob_end_flush();
19
-    die('failed to include_once(phpthumb.functions.php) - realpath="' . realpath(__DIR__ . '/phpthumb.functions.php') . '"');
19
+    die('failed to include_once(phpthumb.functions.php) - realpath="'.realpath(__DIR__.'/phpthumb.functions.php').'"');
20 20
 }
21 21
 }
22 22
 ob_end_clean();
@@ -25,7 +25,7 @@  discard block
 block discarded – undo
25 25
 
26 26
 /****************************************************************************************/
27 27
 /* START USER CONFIGURATION SECTION: */
28
-global $PHPTHUMB_CONFIG;  // declare as global to prevent scope issues (when including phpThumb.config.php inside functions inside included files, etc)
28
+global $PHPTHUMB_CONFIG; // declare as global to prevent scope issues (when including phpThumb.config.php inside functions inside included files, etc)
29 29
 $PHPTHUMB_CONFIG = array();
30 30
 
31 31
 // * DocumentRoot configuration
@@ -40,20 +40,20 @@  discard block
 block discarded – undo
40 40
 
41 41
 
42 42
 // * Security configuration
43
-$PHPTHUMB_CONFIG['disable_debug']               = true;    // DO NOT DISABLE THIS ON ANY PUBLIC-ACCESSIBLE SERVER. Prevents phpThumb from displaying any information about your system. If true, phpThumbDebug and error messages will be disabled. If set to false (debug messages enabled) then debug mode will be FORCED -- ONLY debug output will be presented, no actual thumbnail (to avoid accidentally leaving debug mode enabled on a production server)
44
-$PHPTHUMB_CONFIG['high_security_enabled']       = true;    // DO NOT DISABLE THIS ON ANY PUBLIC-ACCESSIBLE SERVER. If disabled, your server is more vulnerable to hacking attempts, both on your server and via your server to other servers. When enabled, requires 'high_security_password' set to be set and requires the use of phpThumbURL() function (at the bottom of phpThumb.config.php) to generate hashed URLs
45
-$PHPTHUMB_CONFIG['high_security_password']      = '';      // required if 'high_security_enabled' is true, and must be at complex (uppercase, lowercase, numbers, punctuation, etc -- punctuation is strongest, lowercase is weakest; see PasswordStrength() in phpthumb.functions.php). You can use a password generator like http://silisoftware.com/tools/password-random.php to generate a strong password
46
-
47
-$PHPTHUMB_CONFIG['high_security_url_separator'] = '&';     // should almost always be left as '&'. Must be a single character. Do not change to '&amp;' -- htmlspecialchars wrapped around phpThumbURL() takes care of this without breaking the hash
48
-$PHPTHUMB_CONFIG['allow_src_above_docroot']     = false;   // if false (default) only allow src within document_root; if true, allow src to be anywhere in filesystem
49
-$PHPTHUMB_CONFIG['allow_src_above_phpthumb']    = true;    // if true (default), allow src to be anywhere in filesystem; if false only allow src within sub-directory of phpThumb installation
50
-$PHPTHUMB_CONFIG['auto_allow_symlinks']         = true;    // if true (default), allow symlink target directories without explicitly whitelisting them
43
+$PHPTHUMB_CONFIG['disable_debug']               = true; // DO NOT DISABLE THIS ON ANY PUBLIC-ACCESSIBLE SERVER. Prevents phpThumb from displaying any information about your system. If true, phpThumbDebug and error messages will be disabled. If set to false (debug messages enabled) then debug mode will be FORCED -- ONLY debug output will be presented, no actual thumbnail (to avoid accidentally leaving debug mode enabled on a production server)
44
+$PHPTHUMB_CONFIG['high_security_enabled']       = true; // DO NOT DISABLE THIS ON ANY PUBLIC-ACCESSIBLE SERVER. If disabled, your server is more vulnerable to hacking attempts, both on your server and via your server to other servers. When enabled, requires 'high_security_password' set to be set and requires the use of phpThumbURL() function (at the bottom of phpThumb.config.php) to generate hashed URLs
45
+$PHPTHUMB_CONFIG['high_security_password']      = ''; // required if 'high_security_enabled' is true, and must be at complex (uppercase, lowercase, numbers, punctuation, etc -- punctuation is strongest, lowercase is weakest; see PasswordStrength() in phpthumb.functions.php). You can use a password generator like http://silisoftware.com/tools/password-random.php to generate a strong password
46
+
47
+$PHPTHUMB_CONFIG['high_security_url_separator'] = '&'; // should almost always be left as '&'. Must be a single character. Do not change to '&amp;' -- htmlspecialchars wrapped around phpThumbURL() takes care of this without breaking the hash
48
+$PHPTHUMB_CONFIG['allow_src_above_docroot']     = false; // if false (default) only allow src within document_root; if true, allow src to be anywhere in filesystem
49
+$PHPTHUMB_CONFIG['allow_src_above_phpthumb']    = true; // if true (default), allow src to be anywhere in filesystem; if false only allow src within sub-directory of phpThumb installation
50
+$PHPTHUMB_CONFIG['auto_allow_symlinks']         = true; // if true (default), allow symlink target directories without explicitly whitelisting them
51 51
 $PHPTHUMB_CONFIG['additional_allowed_dirs']     = array(); // array of additional directories to allow source images to be read from
52 52
 
53 53
 // * Cache directory configuration (choose only one of these - leave the other lines commented-out):
54 54
 // Note: this directory must be writable (usually chmod 777 is neccesary) for caching to work.
55 55
 // If the directory is not writable no error will be generated but caching will be disabled.
56
-$PHPTHUMB_CONFIG['cache_directory'] = XOOPS_CACHE_PATH;                            // set the cache directory relative to the phpThumb() installation
56
+$PHPTHUMB_CONFIG['cache_directory'] = XOOPS_CACHE_PATH; // set the cache directory relative to the phpThumb() installation
57 57
 //$PHPTHUMB_CONFIG['cache_directory'] = $PHPTHUMB_CONFIG['document_root'].'/phpthumb/cache/'; // set the cache directory to an absolute directory for all source images
58 58
 //$PHPTHUMB_CONFIG['cache_directory'] = './cache/';                                           // set the cache directory relative to the source image - must start with '.' (will not work to cache URL- or database-sourced images, please use an absolute directory name)
59 59
 //$PHPTHUMB_CONFIG['cache_directory'] = null;                                                 // disable thumbnail caching (not recommended)
@@ -69,35 +69,35 @@  discard block
 block discarded – undo
69 69
 //   based on last-access date and/or number of files and/or total filesize.
70 70
 
71 71
 //$PHPTHUMB_CONFIG['cache_maxage'] = null;            // never delete cached thumbnails based on last-access time
72
-$PHPTHUMB_CONFIG['cache_maxage'] = 86400 * 30;        // delete cached thumbnails that haven't been accessed in more than [30 days] (value is maximum time since last access in seconds to avoid deletion)
72
+$PHPTHUMB_CONFIG['cache_maxage'] = 86400 * 30; // delete cached thumbnails that haven't been accessed in more than [30 days] (value is maximum time since last access in seconds to avoid deletion)
73 73
 
74 74
 //$PHPTHUMB_CONFIG['cache_maxsize'] = null;           // never delete cached thumbnails based on byte size of cache directory
75 75
 $PHPTHUMB_CONFIG['cache_maxsize'] = 10 * 1024 * 1024; // delete least-recently-accessed cached thumbnails when more than [10MB] of cached files are present (value is maximum bytesize of all cached files). Note: this only counts file size, does not count space "wasted" by directory entries in the cache structure -- see notes under $PHPTHUMB_CONFIG['cache_directory_depth']
76 76
 
77 77
 //$PHPTHUMB_CONFIG['cache_maxfiles'] = null;          // never delete cached thumbnails based on number of cached files
78
-$PHPTHUMB_CONFIG['cache_maxfiles'] = 200;             // delete least-recently-accessed cached thumbnails when more than [200] cached files are present (value is maximum number of cached files to keep)
78
+$PHPTHUMB_CONFIG['cache_maxfiles'] = 200; // delete least-recently-accessed cached thumbnails when more than [200] cached files are present (value is maximum number of cached files to keep)
79 79
 
80 80
 // * Source image cache configuration
81
-$PHPTHUMB_CONFIG['cache_source_enabled']   = true;                               // if true, source images obtained via HTTP are cached to $PHPTHUMB_CONFIG['cache_source_directory']
82
-$PHPTHUMB_CONFIG['cache_source_directory'] = XOOPS_CACHE_PATH;  // set the cache directory for unprocessed source images
81
+$PHPTHUMB_CONFIG['cache_source_enabled']   = true; // if true, source images obtained via HTTP are cached to $PHPTHUMB_CONFIG['cache_source_directory']
82
+$PHPTHUMB_CONFIG['cache_source_directory'] = XOOPS_CACHE_PATH; // set the cache directory for unprocessed source images
83 83
 
84 84
 // * cache source modification date configuration
85 85
 $PHPTHUMB_CONFIG['cache_source_filemtime_ignore_local']  = false; // if true, local source images will not be checked for modification date and cached image will be used if available, even if source image is changed or removed
86
-$PHPTHUMB_CONFIG['cache_source_filemtime_ignore_remote'] = true;  // if true, remote source images will not be checked for modification date and cached image will be used if available, even if source image is changed or removed. WARNING: cached performance MUCH slower if this is set to false.
86
+$PHPTHUMB_CONFIG['cache_source_filemtime_ignore_remote'] = true; // if true, remote source images will not be checked for modification date and cached image will be used if available, even if source image is changed or removed. WARNING: cached performance MUCH slower if this is set to false.
87 87
 
88 88
 // * Simplified cache filename configuration
89 89
 // Instead of creating unique cache filenames for all parameter combinations, create "simple" cache files (eg: "pic_thumb.jpg")
90 90
 // If cache_default_only_suffix is non-empty, GETstring parameters (except 'src') are ignored and only $PHPTHUMB_DEFAULTS
91 91
 // parameters (set at the bottom of phpThumb.config.php) are used for processing.
92 92
 // The '*' character MUST be used to represent the source image name
93
-$PHPTHUMB_CONFIG['cache_default_only_suffix'] = '';           // cached in normal phpThumb manner
93
+$PHPTHUMB_CONFIG['cache_default_only_suffix'] = ''; // cached in normal phpThumb manner
94 94
 //$PHPTHUMB_CONFIG['cache_default_only_suffix'] = '*_thumb';  // cache 'pic.jpg' becomes 'pic_thumb.jpg' (or 'pic_thumb.png' if PNG output is selected, etc)
95 95
 //$PHPTHUMB_CONFIG['cache_default_only_suffix'] = 'small-*';  // cache 'pic.jpg' becomes 'small-pic.jpg' (or 'small-pic.png' if PNG output is selected, etc)
96 96
 
97
-$PHPTHUMB_CONFIG['cache_prefix'] = 'phpThumb_cache_' . (isset($_SERVER['SERVER_NAME']) ? str_replace('www.', '', $_SERVER['SERVER_NAME']) . '_' : ''); // keep cache file separate by domain
97
+$PHPTHUMB_CONFIG['cache_prefix'] = 'phpThumb_cache_'.(isset($_SERVER['SERVER_NAME']) ? str_replace('www.', '', $_SERVER['SERVER_NAME']).'_' : ''); // keep cache file separate by domain
98 98
 //$PHPTHUMB_CONFIG['cache_prefix'] = 'phpThumb_cache';                                                                                             // allow phpThumb to share 1 set of cached files even if accessed under different servername/domains on same server
99 99
 
100
-$PHPTHUMB_CONFIG['cache_force_passthru'] = true;  // if true, cached image data will always be passed to browser; if false, HTTP redirect will be used instead
100
+$PHPTHUMB_CONFIG['cache_force_passthru'] = true; // if true, cached image data will always be passed to browser; if false, HTTP redirect will be used instead
101 101
 
102 102
 // * Temp directory configuration
103 103
 // phpThumb() may need to create temp files. Usually the system temp dir is writable and can be used.
@@ -105,12 +105,12 @@  discard block
 block discarded – undo
105 105
 // you should change this to a full pathname to a directory you do have write access to.
106 106
 //$PHPTHUMB_CONFIG['temp_directory'] = null;                               // attempt to auto-detect
107 107
 //$PHPTHUMB_CONFIG['temp_directory'] = '/tmp/persistent/phpthumb/cache/';  // set to absolute path
108
-$PHPTHUMB_CONFIG['temp_directory'] = $PHPTHUMB_CONFIG['cache_directory'];  // set to same as cache directory
108
+$PHPTHUMB_CONFIG['temp_directory'] = $PHPTHUMB_CONFIG['cache_directory']; // set to same as cache directory
109 109
 
110 110
 
111 111
 // ImageMagick configuration
112
-$PHPTHUMB_CONFIG['prefer_imagemagick']        = true;  // If true, use ImageMagick to resize thumbnails if possible, since it is usually faster than GD functions; if false only use ImageMagick if PHP memory limit is too low.
113
-$PHPTHUMB_CONFIG['imagemagick_use_thumbnail'] = true;  // If true, use ImageMagick's "-thumbnail" resizing parameter (if available) which removes extra non-image metadata (profiles, EXIF info, etc) resulting in much smaller filesize; if false, use "-resize" paramter which retains this info
112
+$PHPTHUMB_CONFIG['prefer_imagemagick']        = true; // If true, use ImageMagick to resize thumbnails if possible, since it is usually faster than GD functions; if false only use ImageMagick if PHP memory limit is too low.
113
+$PHPTHUMB_CONFIG['imagemagick_use_thumbnail'] = true; // If true, use ImageMagick's "-thumbnail" resizing parameter (if available) which removes extra non-image metadata (profiles, EXIF info, etc) resulting in much smaller filesize; if false, use "-resize" paramter which retains this info
114 114
 if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
115 115
 	// Windows: set absolute pathname
116 116
 	$PHPTHUMB_CONFIG['imagemagick_path'] = 'C:/ImageMagick/convert.exe';
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
 // As a general guideline, this number will be about 20% of your PHP memory configuration, so 8M = 1,677,722; 16M = 3,355,443; 32M = 6,710,886; etc.
132 132
 if (phpthumb_functions::version_compare_replacement(phpversion(), '4.3.2', '>=') && !defined('memory_get_usage') && !@ini_get('memory_limit')) {
133 133
     // memory_get_usage() will only be defined if your PHP is compiled with the --enable-memory-limit configuration option.
134
-    $PHPTHUMB_CONFIG['max_source_pixels'] = 0;         // no memory limit
134
+    $PHPTHUMB_CONFIG['max_source_pixels'] = 0; // no memory limit
135 135
 } else {
136 136
     // calculate default max_source_pixels as 1/6 of memory limit configuration
137 137
     $PHPTHUMB_CONFIG['max_source_pixels'] = round(max((int)(ini_get('memory_limit')), (int)(get_cfg_var('memory_limit'))) * 1048576 / 6);
@@ -144,41 +144,41 @@  discard block
 block discarded – undo
144 144
 
145 145
 // * Default output configuration:
146 146
 $PHPTHUMB_CONFIG['output_format']    = 'png'; // default output format ('jpeg', 'png' or 'gif') - thumbnail will be output in this format (if available in your version of GD or ImageMagick). This is only used if the "f" parameter is not specified, and if the thumbnail can't be output in the input format.
147
-$PHPTHUMB_CONFIG['output_maxwidth']  = 0;      // default maximum thumbnail width.  If this is zero then default width  is the width  of the source image. This is always overridden by ?w=___ GETstring parameter
148
-$PHPTHUMB_CONFIG['output_maxheight'] = 0;      // default maximum thumbnail height. If this is zero then default height is the height of the source image. This is always overridden by ?h=___ GETstring parameter
149
-$PHPTHUMB_CONFIG['output_interlace'] = true;   // if true: interlaced output for GIF/PNG, progressive output for JPEG; if false: non-interlaced for GIF/PNG, baseline for JPEG.
147
+$PHPTHUMB_CONFIG['output_maxwidth']  = 0; // default maximum thumbnail width.  If this is zero then default width  is the width  of the source image. This is always overridden by ?w=___ GETstring parameter
148
+$PHPTHUMB_CONFIG['output_maxheight'] = 0; // default maximum thumbnail height. If this is zero then default height is the height of the source image. This is always overridden by ?h=___ GETstring parameter
149
+$PHPTHUMB_CONFIG['output_interlace'] = true; // if true: interlaced output for GIF/PNG, progressive output for JPEG; if false: non-interlaced for GIF/PNG, baseline for JPEG.
150 150
 
151 151
 // * Error message configuration
152
-$PHPTHUMB_CONFIG['error_image_width']           = 300;      // default width for error images
153
-$PHPTHUMB_CONFIG['error_image_height']          = 100;      // default height for error images
154
-$PHPTHUMB_CONFIG['error_message_image_default'] = '';       // Set this to the name of a generic error image (e.g. '/images/error.png') that you want displayed in place of any error message that may occur. This setting is overridden by the 'err' parameter, which does the same thing.
152
+$PHPTHUMB_CONFIG['error_image_width']           = 300; // default width for error images
153
+$PHPTHUMB_CONFIG['error_image_height']          = 100; // default height for error images
154
+$PHPTHUMB_CONFIG['error_message_image_default'] = ''; // Set this to the name of a generic error image (e.g. '/images/error.png') that you want displayed in place of any error message that may occur. This setting is overridden by the 'err' parameter, which does the same thing.
155 155
 $PHPTHUMB_CONFIG['error_bgcolor']               = 'CCCCFF'; // background color of error message images
156 156
 $PHPTHUMB_CONFIG['error_textcolor']             = 'FF0000'; // color of text in error messages
157
-$PHPTHUMB_CONFIG['error_fontsize']              = 1;        // size of text in error messages, from 1 (smallest) to 5 (largest)
158
-$PHPTHUMB_CONFIG['error_die_on_error']          = true;     // die with error message on any fatal error (recommended with standalone phpThumb.php)
159
-$PHPTHUMB_CONFIG['error_silent_die_on_error']   = false;    // simply die with no output of any kind on fatal errors (not recommended)
160
-$PHPTHUMB_CONFIG['error_die_on_source_failure'] = true;     // die with error message if source image cannot be processed by phpThumb() (usually because source image is corrupt in some way). If false the source image will be passed through unprocessed, if true (default) an error message will be displayed.
157
+$PHPTHUMB_CONFIG['error_fontsize']              = 1; // size of text in error messages, from 1 (smallest) to 5 (largest)
158
+$PHPTHUMB_CONFIG['error_die_on_error']          = true; // die with error message on any fatal error (recommended with standalone phpThumb.php)
159
+$PHPTHUMB_CONFIG['error_silent_die_on_error']   = false; // simply die with no output of any kind on fatal errors (not recommended)
160
+$PHPTHUMB_CONFIG['error_die_on_source_failure'] = true; // die with error message if source image cannot be processed by phpThumb() (usually because source image is corrupt in some way). If false the source image will be passed through unprocessed, if true (default) an error message will be displayed.
161 161
 
162 162
 // * Off-server Thumbnailing Configuration:
163
-$PHPTHUMB_CONFIG['nohotlink_enabled']       = false;                                    // If false will allow thumbnailing from any source domain, if true then only domains in 'nohotlink_valid_domains' will be accepted
164
-$PHPTHUMB_CONFIG['nohotlink_valid_domains'] = array(@$_SERVER['HTTP_HOST']);            // This is the list of domains for which thumbnails are allowed to be created. Note: domain only, do not include port numbers. The default value of the current domain should be fine in most cases, but if neccesary you can add more domains in here, in the format "www.example.com"
165
-$PHPTHUMB_CONFIG['nohotlink_erase_image']   = true;                                     // if true thumbnail is covered up with $PHPTHUMB_CONFIG['nohotlink_fill_color'] before text is applied, if false text is written over top of thumbnail
163
+$PHPTHUMB_CONFIG['nohotlink_enabled']       = false; // If false will allow thumbnailing from any source domain, if true then only domains in 'nohotlink_valid_domains' will be accepted
164
+$PHPTHUMB_CONFIG['nohotlink_valid_domains'] = array(@$_SERVER['HTTP_HOST']); // This is the list of domains for which thumbnails are allowed to be created. Note: domain only, do not include port numbers. The default value of the current domain should be fine in most cases, but if neccesary you can add more domains in here, in the format "www.example.com"
165
+$PHPTHUMB_CONFIG['nohotlink_erase_image']   = true; // if true thumbnail is covered up with $PHPTHUMB_CONFIG['nohotlink_fill_color'] before text is applied, if false text is written over top of thumbnail
166 166
 $PHPTHUMB_CONFIG['nohotlink_text_message']  = 'Off-server thumbnailing is not allowed'; // text of error message
167 167
 
168 168
 // * Off-server Linking Configuration:
169
-$PHPTHUMB_CONFIG['nooffsitelink_enabled']       = false;                                       // If false will allow thumbnails to be linked to from any domain, if true only domains listed below in 'nooffsitelink_valid_domains' will be allowed.
170
-$PHPTHUMB_CONFIG['nooffsitelink_valid_domains'] = array(@$_SERVER['HTTP_HOST']);              // This is the list of domains for which thumbnails are allowed to be created. The default value of the current domain should be fine in most cases, but if neccesary you can add more domains in here, in the format 'www.example.com'
171
-$PHPTHUMB_CONFIG['nooffsitelink_require_refer'] = false;                                      // If false will allow standalone calls to phpThumb(). If true then only requests with a $_SERVER['HTTP_REFERER'] value in 'nooffsitelink_valid_domains' are allowed.
172
-$PHPTHUMB_CONFIG['nooffsitelink_erase_image']   = false;                                      // if true thumbnail is covered up with $PHPTHUMB_CONFIG['nohotlink_fill_color'] before text is applied, if false text is written over top of thumbnail
173
-$PHPTHUMB_CONFIG['nooffsitelink_watermark_src'] = '/demo/images/watermark.png';                // webroot-relative image to overlay on hotlinked images
174
-$PHPTHUMB_CONFIG['nooffsitelink_text_message']  = 'Image taken from ' . @$_SERVER['HTTP_HOST']; // text of error message (used if [nooffsitelink_watermark_src] is not a valid image)
169
+$PHPTHUMB_CONFIG['nooffsitelink_enabled']       = false; // If false will allow thumbnails to be linked to from any domain, if true only domains listed below in 'nooffsitelink_valid_domains' will be allowed.
170
+$PHPTHUMB_CONFIG['nooffsitelink_valid_domains'] = array(@$_SERVER['HTTP_HOST']); // This is the list of domains for which thumbnails are allowed to be created. The default value of the current domain should be fine in most cases, but if neccesary you can add more domains in here, in the format 'www.example.com'
171
+$PHPTHUMB_CONFIG['nooffsitelink_require_refer'] = false; // If false will allow standalone calls to phpThumb(). If true then only requests with a $_SERVER['HTTP_REFERER'] value in 'nooffsitelink_valid_domains' are allowed.
172
+$PHPTHUMB_CONFIG['nooffsitelink_erase_image']   = false; // if true thumbnail is covered up with $PHPTHUMB_CONFIG['nohotlink_fill_color'] before text is applied, if false text is written over top of thumbnail
173
+$PHPTHUMB_CONFIG['nooffsitelink_watermark_src'] = '/demo/images/watermark.png'; // webroot-relative image to overlay on hotlinked images
174
+$PHPTHUMB_CONFIG['nooffsitelink_text_message']  = 'Image taken from '.@$_SERVER['HTTP_HOST']; // text of error message (used if [nooffsitelink_watermark_src] is not a valid image)
175 175
 
176 176
 // * Border & Background default colors
177 177
 $PHPTHUMB_CONFIG['border_hexcolor']     = '000000'; // Default border color - usual HTML-style hex color notation (overidden with 'bc' parameter)
178 178
 $PHPTHUMB_CONFIG['background_hexcolor'] = 'FFFFFF'; // Default background color when thumbnail aspect ratio does not match fixed-dimension box - usual HTML-style hex color notation (overridden with 'bg' parameter)
179 179
 
180 180
 // * Watermark configuration
181
-$PHPTHUMB_CONFIG['ttf_directory'] = __DIR__ . '/fonts'; // Base directory for TTF font files
181
+$PHPTHUMB_CONFIG['ttf_directory'] = __DIR__.'/fonts'; // Base directory for TTF font files
182 182
 //$PHPTHUMB_CONFIG['ttf_directory'] = 'c:/windows/fonts';
183 183
 
184 184
 // * MySQL configuration
@@ -201,18 +201,18 @@  discard block
 block discarded – undo
201 201
 //$PHPTHUMB_CONFIG['http_user_agent'] = '';                                                                                      // PHP default: none
202 202
 //$PHPTHUMB_CONFIG['http_user_agent'] = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)';                                    // Windows XP, Internet Explorer
203 203
 //$PHPTHUMB_CONFIG['http_user_agent'] = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7'; // Windows XP, Firefox
204
-$PHPTHUMB_CONFIG['http_user_agent'] = @$_SERVER['HTTP_USER_AGENT'];                                                                // use client user-agent
204
+$PHPTHUMB_CONFIG['http_user_agent'] = @$_SERVER['HTTP_USER_AGENT']; // use client user-agent
205 205
 
206 206
 
207 207
 // * Compatability settings
208
-$PHPTHUMB_CONFIG['disable_pathinfo_parsing']        = false;   // if true, $_SERVER[PATH_INFO] is not parsed. May be needed on some server configurations to allow normal behavior.
209
-$PHPTHUMB_CONFIG['disable_imagecopyresampled']      = false;  // if true, imagecopyresampled is replaced with ImageCopyResampleBicubic. May be needed for buggy versions of PHP-GD.
210
-$PHPTHUMB_CONFIG['disable_onlycreateable_passthru'] = true;   // if true, any image that can be parsed by getimagesize() can be passed through; if false, only images that can be converted to GD by ImageCreateFrom(JPEG|GIF|PNG) functions are allowed
211
-$PHPTHUMB_CONFIG['disable_realpath']                = false;  // PHP realpath() function requires that "the running script must have executable permissions on all directories in the hierarchy, otherwise realpath() will return FALSE". Set config_disable_realpath=false to enable alternate filename-parsing that does not use realpath() function (but also does not resolve symbolic links)
208
+$PHPTHUMB_CONFIG['disable_pathinfo_parsing']        = false; // if true, $_SERVER[PATH_INFO] is not parsed. May be needed on some server configurations to allow normal behavior.
209
+$PHPTHUMB_CONFIG['disable_imagecopyresampled']      = false; // if true, imagecopyresampled is replaced with ImageCopyResampleBicubic. May be needed for buggy versions of PHP-GD.
210
+$PHPTHUMB_CONFIG['disable_onlycreateable_passthru'] = true; // if true, any image that can be parsed by getimagesize() can be passed through; if false, only images that can be converted to GD by ImageCreateFrom(JPEG|GIF|PNG) functions are allowed
211
+$PHPTHUMB_CONFIG['disable_realpath']                = false; // PHP realpath() function requires that "the running script must have executable permissions on all directories in the hierarchy, otherwise realpath() will return FALSE". Set config_disable_realpath=false to enable alternate filename-parsing that does not use realpath() function (but also does not resolve symbolic links)
212 212
 
213 213
 
214 214
 // * HTTP remote file opening settings
215
-$PHPTHUMB_CONFIG['http_fopen_timeout']   = 10;   // timeout (in seconds) for fopen / curl / fsockopen
215
+$PHPTHUMB_CONFIG['http_fopen_timeout']   = 10; // timeout (in seconds) for fopen / curl / fsockopen
216 216
 $PHPTHUMB_CONFIG['http_follow_redirect'] = true; // if true (default), follow "302 Found" redirects to new URL; if false, return error message
217 217
 
218 218
 // * Speed optimizations configuration
@@ -227,7 +227,7 @@  discard block
 block discarded – undo
227 227
 /* START DEFAULT PARAMETERS SECTION */
228 228
 // If any parameters are constant across ALL images, you can set them here
229 229
 
230
-$PHPTHUMB_DEFAULTS_GETSTRINGOVERRIDE = true;  // if true, any parameters in the URL will override the defaults set here; if false, any parameters set here cannot be overridden in the URL
230
+$PHPTHUMB_DEFAULTS_GETSTRINGOVERRIDE = true; // if true, any parameters in the URL will override the defaults set here; if false, any parameters set here cannot be overridden in the URL
231 231
 $PHPTHUMB_DEFAULTS_DISABLEGETPARAMS  = false; // if true, GETstring parameters will be ignored (except for 'src') and only below default parameters will be used; if false, both default and GETstring parameters will be used (depending on $PHPTHUMB_DEFAULTS_GETSTRINGOVERRIDE). Will be auto-set true if !empty($PHPTHUMB_CONFIG['cache_default_only_suffix'])
232 232
 
233 233
 //$PHPTHUMB_DEFAULTS['w']    = 200;
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
 //   echo '<img src="'.htmlspecialchars(phpThumbURL('src=/images/pic.jpg&w=50', '/phpThumb/phpThumb.php')).'">';
247 247
 
248 248
 $GLOBALS['PHPTHUMB_CONFIG'] = $PHPTHUMB_CONFIG;
249
-function phpThumbURL($ParameterString, $path_to_phpThumb='phpThumb.php') {
249
+function phpThumbURL($ParameterString, $path_to_phpThumb = 'phpThumb.php') {
250 250
     global $PHPTHUMB_CONFIG;
251 251
 	if (is_array($ParameterString)) {
252 252
 		$ParameterStringArray = $ParameterString;
Please login to merge, or discard this patch.
htdocs/modules/system/class/thumbs/phpthumb.unsharp.php 2 patches
Indentation   +103 added lines, -103 removed lines patch added patch discarded remove patch
@@ -43,107 +43,107 @@
 block discarded – undo
43 43
 
44 44
 class phpUnsharpMask {
45 45
 
46
-	public static function applyUnsharpMask(&$img, $amount, $radius, $threshold) {
47
-
48
-		// $img is an image that is already created within php using
49
-		// imgcreatetruecolor. No url! $img must be a truecolor image.
50
-
51
-		// Attempt to calibrate the parameters to Photoshop:
52
-		$amount = min($amount, 500) * 0.016;
53
-		$radius = abs(round(min(50, $radius) * 2)); // Only integers make sense.
54
-		$threshold = min(255, $threshold);
55
-		if ($radius == 0) {
56
-			return true;
57
-		}
58
-		$w = imagesx($img);
59
-		$h = imagesy($img);
60
-		$imgCanvas = imagecreatetruecolor($w, $h);
61
-		$imgBlur   = imagecreatetruecolor($w, $h);
62
-
63
-		// Gaussian blur matrix:
64
-		//
65
-		//    1    2    1
66
-		//    2    4    2
67
-		//    1    2    1
68
-		//
69
-		//////////////////////////////////////////////////
70
-
71
-		if (function_exists('imageconvolution')) { // PHP >= 5.1
72
-			$matrix = array(
73
-				array(1, 2, 1),
74
-				array(2, 4, 2),
75
-				array(1, 2, 1)
76
-			);
77
-			imagecopy($imgBlur, $img, 0, 0, 0, 0, $w, $h);
78
-			imageconvolution($imgBlur, $matrix, 16, 0);
79
-
80
-		} else {
81
-
82
-			// Move copies of the image around one pixel at the time and merge them with weight
83
-			// according to the matrix. The same matrix is simply repeated for higher radii.
84
-			for ($i = 0; $i < $radius; $i++)    {
85
-				imagecopy(     $imgBlur,   $img,       0, 0, 1, 0, $w - 1, $h);               // left
86
-				imagecopymerge($imgBlur,   $img,       1, 0, 0, 0, $w    , $h,     50);       // right
87
-				imagecopymerge($imgBlur,   $img,       0, 0, 0, 0, $w    , $h,     50);       // center
88
-				imagecopy(     $imgCanvas, $imgBlur,   0, 0, 0, 0, $w    , $h);
89
-				imagecopymerge($imgBlur,   $imgCanvas, 0, 0, 0, 1, $w    , $h - 1, 33.33333); // up
90
-				imagecopymerge($imgBlur,   $imgCanvas, 0, 1, 0, 0, $w    , $h,     25);       // down
91
-			}
92
-		}
93
-
94
-		if ($threshold > 0){
95
-			// Calculate the difference between the blurred pixels and the original
96
-			// and set the pixels
97
-			for ($x = 0; $x < $w-1; $x++)    { // each row
98
-				for ($y = 0; $y < $h; $y++)    { // each pixel
99
-
100
-					$rgbOrig = imagecolorat($img, $x, $y);
101
-					$rOrig = (($rgbOrig >> 16) & 0xFF);
102
-					$gOrig = (($rgbOrig >>  8) & 0xFF);
103
-					$bOrig =  ($rgbOrig        & 0xFF);
104
-
105
-					$rgbBlur = imagecolorat($imgBlur, $x, $y);
106
-
107
-					$rBlur = (($rgbBlur >> 16) & 0xFF);
108
-					$gBlur = (($rgbBlur >>  8) & 0xFF);
109
-					$bBlur =  ($rgbBlur        & 0xFF);
110
-
111
-					// When the masked pixels differ less from the original
112
-					// than the threshold specifies, they are set to their original value.
113
-					$rNew = ((abs($rOrig - $rBlur) >= $threshold) ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig)) : $rOrig);
114
-					$gNew = ((abs($gOrig - $gBlur) >= $threshold) ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig)) : $gOrig);
115
-					$bNew = ((abs($bOrig - $bBlur) >= $threshold) ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig)) : $bOrig);
116
-
117
-					if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) {
118
-						$pixCol = imagecolorallocate($img, $rNew, $gNew, $bNew);
119
-						imagesetpixel($img, $x, $y, $pixCol);
120
-					}
121
-				}
122
-			}
123
-		} else {
124
-			for ($x = 0; $x < $w; $x++)    { // each row
125
-				for ($y = 0; $y < $h; $y++)    { // each pixel
126
-					$rgbOrig = imagecolorat($img, $x, $y);
127
-					$rOrig = (($rgbOrig >> 16) & 0xFF);
128
-					$gOrig = (($rgbOrig >>  8) & 0xFF);
129
-					$bOrig =  ($rgbOrig        & 0xFF);
130
-
131
-					$rgbBlur = imagecolorat($imgBlur, $x, $y);
132
-
133
-					$rBlur = (($rgbBlur >> 16) & 0xFF);
134
-					$gBlur = (($rgbBlur >>  8) & 0xFF);
135
-					$bBlur =  ($rgbBlur        & 0xFF);
136
-
137
-					$rNew = min(255, max(0, ($amount * ($rOrig - $rBlur)) + $rOrig));
138
-					$gNew = min(255, max(0, ($amount * ($gOrig - $gBlur)) + $gOrig));
139
-					$bNew = min(255, max(0, ($amount * ($bOrig - $bBlur)) + $bOrig));
140
-					$rgbNew = ($rNew << 16) + ($gNew <<8) + $bNew;
141
-					imagesetpixel($img, $x, $y, $rgbNew);
142
-				}
143
-			}
144
-		}
145
-		imagedestroy($imgCanvas);
146
-		imagedestroy($imgBlur);
147
-		return true;
148
-	}
46
+    public static function applyUnsharpMask(&$img, $amount, $radius, $threshold) {
47
+
48
+        // $img is an image that is already created within php using
49
+        // imgcreatetruecolor. No url! $img must be a truecolor image.
50
+
51
+        // Attempt to calibrate the parameters to Photoshop:
52
+        $amount = min($amount, 500) * 0.016;
53
+        $radius = abs(round(min(50, $radius) * 2)); // Only integers make sense.
54
+        $threshold = min(255, $threshold);
55
+        if ($radius == 0) {
56
+            return true;
57
+        }
58
+        $w = imagesx($img);
59
+        $h = imagesy($img);
60
+        $imgCanvas = imagecreatetruecolor($w, $h);
61
+        $imgBlur   = imagecreatetruecolor($w, $h);
62
+
63
+        // Gaussian blur matrix:
64
+        //
65
+        //    1    2    1
66
+        //    2    4    2
67
+        //    1    2    1
68
+        //
69
+        //////////////////////////////////////////////////
70
+
71
+        if (function_exists('imageconvolution')) { // PHP >= 5.1
72
+            $matrix = array(
73
+                array(1, 2, 1),
74
+                array(2, 4, 2),
75
+                array(1, 2, 1)
76
+            );
77
+            imagecopy($imgBlur, $img, 0, 0, 0, 0, $w, $h);
78
+            imageconvolution($imgBlur, $matrix, 16, 0);
79
+
80
+        } else {
81
+
82
+            // Move copies of the image around one pixel at the time and merge them with weight
83
+            // according to the matrix. The same matrix is simply repeated for higher radii.
84
+            for ($i = 0; $i < $radius; $i++)    {
85
+                imagecopy(     $imgBlur,   $img,       0, 0, 1, 0, $w - 1, $h);               // left
86
+                imagecopymerge($imgBlur,   $img,       1, 0, 0, 0, $w    , $h,     50);       // right
87
+                imagecopymerge($imgBlur,   $img,       0, 0, 0, 0, $w    , $h,     50);       // center
88
+                imagecopy(     $imgCanvas, $imgBlur,   0, 0, 0, 0, $w    , $h);
89
+                imagecopymerge($imgBlur,   $imgCanvas, 0, 0, 0, 1, $w    , $h - 1, 33.33333); // up
90
+                imagecopymerge($imgBlur,   $imgCanvas, 0, 1, 0, 0, $w    , $h,     25);       // down
91
+            }
92
+        }
93
+
94
+        if ($threshold > 0){
95
+            // Calculate the difference between the blurred pixels and the original
96
+            // and set the pixels
97
+            for ($x = 0; $x < $w-1; $x++)    { // each row
98
+                for ($y = 0; $y < $h; $y++)    { // each pixel
99
+
100
+                    $rgbOrig = imagecolorat($img, $x, $y);
101
+                    $rOrig = (($rgbOrig >> 16) & 0xFF);
102
+                    $gOrig = (($rgbOrig >>  8) & 0xFF);
103
+                    $bOrig =  ($rgbOrig        & 0xFF);
104
+
105
+                    $rgbBlur = imagecolorat($imgBlur, $x, $y);
106
+
107
+                    $rBlur = (($rgbBlur >> 16) & 0xFF);
108
+                    $gBlur = (($rgbBlur >>  8) & 0xFF);
109
+                    $bBlur =  ($rgbBlur        & 0xFF);
110
+
111
+                    // When the masked pixels differ less from the original
112
+                    // than the threshold specifies, they are set to their original value.
113
+                    $rNew = ((abs($rOrig - $rBlur) >= $threshold) ? max(0, min(255, ($amount * ($rOrig - $rBlur)) + $rOrig)) : $rOrig);
114
+                    $gNew = ((abs($gOrig - $gBlur) >= $threshold) ? max(0, min(255, ($amount * ($gOrig - $gBlur)) + $gOrig)) : $gOrig);
115
+                    $bNew = ((abs($bOrig - $bBlur) >= $threshold) ? max(0, min(255, ($amount * ($bOrig - $bBlur)) + $bOrig)) : $bOrig);
116
+
117
+                    if (($rOrig != $rNew) || ($gOrig != $gNew) || ($bOrig != $bNew)) {
118
+                        $pixCol = imagecolorallocate($img, $rNew, $gNew, $bNew);
119
+                        imagesetpixel($img, $x, $y, $pixCol);
120
+                    }
121
+                }
122
+            }
123
+        } else {
124
+            for ($x = 0; $x < $w; $x++)    { // each row
125
+                for ($y = 0; $y < $h; $y++)    { // each pixel
126
+                    $rgbOrig = imagecolorat($img, $x, $y);
127
+                    $rOrig = (($rgbOrig >> 16) & 0xFF);
128
+                    $gOrig = (($rgbOrig >>  8) & 0xFF);
129
+                    $bOrig =  ($rgbOrig        & 0xFF);
130
+
131
+                    $rgbBlur = imagecolorat($imgBlur, $x, $y);
132
+
133
+                    $rBlur = (($rgbBlur >> 16) & 0xFF);
134
+                    $gBlur = (($rgbBlur >>  8) & 0xFF);
135
+                    $bBlur =  ($rgbBlur        & 0xFF);
136
+
137
+                    $rNew = min(255, max(0, ($amount * ($rOrig - $rBlur)) + $rOrig));
138
+                    $gNew = min(255, max(0, ($amount * ($gOrig - $gBlur)) + $gOrig));
139
+                    $bNew = min(255, max(0, ($amount * ($bOrig - $bBlur)) + $bOrig));
140
+                    $rgbNew = ($rNew << 16) + ($gNew <<8) + $bNew;
141
+                    imagesetpixel($img, $x, $y, $rgbNew);
142
+                }
143
+            }
144
+        }
145
+        imagedestroy($imgCanvas);
146
+        imagedestroy($imgBlur);
147
+        return true;
148
+    }
149 149
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -81,32 +81,32 @@  discard block
 block discarded – undo
81 81
 
82 82
 			// Move copies of the image around one pixel at the time and merge them with weight
83 83
 			// according to the matrix. The same matrix is simply repeated for higher radii.
84
-			for ($i = 0; $i < $radius; $i++)    {
85
-				imagecopy(     $imgBlur,   $img,       0, 0, 1, 0, $w - 1, $h);               // left
86
-				imagecopymerge($imgBlur,   $img,       1, 0, 0, 0, $w    , $h,     50);       // right
87
-				imagecopymerge($imgBlur,   $img,       0, 0, 0, 0, $w    , $h,     50);       // center
88
-				imagecopy(     $imgCanvas, $imgBlur,   0, 0, 0, 0, $w    , $h);
89
-				imagecopymerge($imgBlur,   $imgCanvas, 0, 0, 0, 1, $w    , $h - 1, 33.33333); // up
90
-				imagecopymerge($imgBlur,   $imgCanvas, 0, 1, 0, 0, $w    , $h,     25);       // down
84
+			for ($i = 0; $i < $radius; $i++) {
85
+				imagecopy($imgBlur, $img, 0, 0, 1, 0, $w - 1, $h); // left
86
+				imagecopymerge($imgBlur, $img, 1, 0, 0, 0, $w, $h, 50); // right
87
+				imagecopymerge($imgBlur, $img, 0, 0, 0, 0, $w, $h, 50); // center
88
+				imagecopy($imgCanvas, $imgBlur, 0, 0, 0, 0, $w, $h);
89
+				imagecopymerge($imgBlur, $imgCanvas, 0, 0, 0, 1, $w, $h - 1, 33.33333); // up
90
+				imagecopymerge($imgBlur, $imgCanvas, 0, 1, 0, 0, $w, $h, 25); // down
91 91
 			}
92 92
 		}
93 93
 
94
-		if ($threshold > 0){
94
+		if ($threshold > 0) {
95 95
 			// Calculate the difference between the blurred pixels and the original
96 96
 			// and set the pixels
97
-			for ($x = 0; $x < $w-1; $x++)    { // each row
98
-				for ($y = 0; $y < $h; $y++)    { // each pixel
97
+			for ($x = 0; $x < $w - 1; $x++) { // each row
98
+				for ($y = 0; $y < $h; $y++) { // each pixel
99 99
 
100 100
 					$rgbOrig = imagecolorat($img, $x, $y);
101 101
 					$rOrig = (($rgbOrig >> 16) & 0xFF);
102
-					$gOrig = (($rgbOrig >>  8) & 0xFF);
103
-					$bOrig =  ($rgbOrig        & 0xFF);
102
+					$gOrig = (($rgbOrig >> 8) & 0xFF);
103
+					$bOrig = ($rgbOrig & 0xFF);
104 104
 
105 105
 					$rgbBlur = imagecolorat($imgBlur, $x, $y);
106 106
 
107 107
 					$rBlur = (($rgbBlur >> 16) & 0xFF);
108
-					$gBlur = (($rgbBlur >>  8) & 0xFF);
109
-					$bBlur =  ($rgbBlur        & 0xFF);
108
+					$gBlur = (($rgbBlur >> 8) & 0xFF);
109
+					$bBlur = ($rgbBlur & 0xFF);
110 110
 
111 111
 					// When the masked pixels differ less from the original
112 112
 					// than the threshold specifies, they are set to their original value.
@@ -121,23 +121,23 @@  discard block
 block discarded – undo
121 121
 				}
122 122
 			}
123 123
 		} else {
124
-			for ($x = 0; $x < $w; $x++)    { // each row
125
-				for ($y = 0; $y < $h; $y++)    { // each pixel
124
+			for ($x = 0; $x < $w; $x++) { // each row
125
+				for ($y = 0; $y < $h; $y++) { // each pixel
126 126
 					$rgbOrig = imagecolorat($img, $x, $y);
127 127
 					$rOrig = (($rgbOrig >> 16) & 0xFF);
128
-					$gOrig = (($rgbOrig >>  8) & 0xFF);
129
-					$bOrig =  ($rgbOrig        & 0xFF);
128
+					$gOrig = (($rgbOrig >> 8) & 0xFF);
129
+					$bOrig = ($rgbOrig & 0xFF);
130 130
 
131 131
 					$rgbBlur = imagecolorat($imgBlur, $x, $y);
132 132
 
133 133
 					$rBlur = (($rgbBlur >> 16) & 0xFF);
134
-					$gBlur = (($rgbBlur >>  8) & 0xFF);
135
-					$bBlur =  ($rgbBlur        & 0xFF);
134
+					$gBlur = (($rgbBlur >> 8) & 0xFF);
135
+					$bBlur = ($rgbBlur & 0xFF);
136 136
 
137 137
 					$rNew = min(255, max(0, ($amount * ($rOrig - $rBlur)) + $rOrig));
138 138
 					$gNew = min(255, max(0, ($amount * ($gOrig - $gBlur)) + $gOrig));
139 139
 					$bNew = min(255, max(0, ($amount * ($bOrig - $bBlur)) + $bOrig));
140
-					$rgbNew = ($rNew << 16) + ($gNew <<8) + $bNew;
140
+					$rgbNew = ($rNew << 16) + ($gNew << 8) + $bNew;
141 141
 					imagesetpixel($img, $x, $y, $rgbNew);
142 142
 				}
143 143
 			}
Please login to merge, or discard this patch.
htdocs/modules/system/class/thumbs/phpthumb.filters.php 2 patches
Indentation   +1506 added lines, -1506 removed lines patch added patch discarded remove patch
@@ -11,68 +11,68 @@  discard block
 block discarded – undo
11 11
 
12 12
 class phpthumb_filters {
13 13
 
14
-	/**
15
-	* @var phpthumb
16
-	*/
17
-
18
-	public $phpThumbObject = null;
19
-
20
-
21
-	public function DebugMessage($message, $file='', $line='') {
22
-		if (is_object($this->phpThumbObject)) {
23
-			return $this->phpThumbObject->DebugMessage($message, $file, $line);
24
-		}
25
-		return false;
26
-	}
27
-
28
-
29
-	public function ApplyMask(&$gdimg_mask, &$gdimg_image) {
30
-		if (phpthumb_functions::gd_version() < 2) {
31
-			$this->DebugMessage('Skipping ApplyMask() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
32
-			return false;
33
-		}
34
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.3.2', '>=')) {
35
-
36
-			$this->DebugMessage('Using alpha ApplyMask() technique', __FILE__, __LINE__);
37
-			if ($gdimg_mask_resized = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_image), imagesy($gdimg_image))) {
38
-
39
-				imagecopyresampled($gdimg_mask_resized, $gdimg_mask, 0, 0, 0, 0, imagesx($gdimg_image), imagesy($gdimg_image), imagesx($gdimg_mask), imagesy($gdimg_mask));
40
-				if ($gdimg_mask_blendtemp = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_image), imagesy($gdimg_image))) {
41
-
42
-					$color_background = imagecolorallocate($gdimg_mask_blendtemp, 0, 0, 0);
43
-					imagefilledrectangle($gdimg_mask_blendtemp, 0, 0, imagesx($gdimg_mask_blendtemp), imagesy($gdimg_mask_blendtemp), $color_background);
44
-					imagealphablending($gdimg_mask_blendtemp, false);
45
-					imagesavealpha($gdimg_mask_blendtemp, true);
46
-					for ($x = 0, $xMax = imagesx($gdimg_image); $x < $xMax; $x++) {
47
-						for ($y = 0, $yMax = imagesy($gdimg_image); $y < $yMax; $y++) {
48
-							//$RealPixel = phpthumb_functions::GetPixelColor($gdimg_mask_blendtemp, $x, $y);
49
-							$RealPixel = phpthumb_functions::GetPixelColor($gdimg_image, $x, $y);
50
-							$MaskPixel = phpthumb_functions::GrayscalePixel(phpthumb_functions::GetPixelColor($gdimg_mask_resized, $x, $y));
51
-							$MaskAlpha = 127 - (floor($MaskPixel['red'] / 2) * (1 - ($RealPixel['alpha'] / 127)));
52
-							$newcolor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_mask_blendtemp, $RealPixel['red'], $RealPixel['green'], $RealPixel['blue'], $MaskAlpha);
53
-							imagesetpixel($gdimg_mask_blendtemp, $x, $y, $newcolor);
54
-						}
55
-					}
56
-					imagealphablending($gdimg_image, false);
57
-					imagesavealpha($gdimg_image, true);
58
-					imagecopy($gdimg_image, $gdimg_mask_blendtemp, 0, 0, 0, 0, imagesx($gdimg_mask_blendtemp), imagesy($gdimg_mask_blendtemp));
59
-					imagedestroy($gdimg_mask_blendtemp);
60
-
61
-				} else {
62
-					$this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
63
-				}
64
-				imagedestroy($gdimg_mask_resized);
65
-
66
-			} else {
67
-				$this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
68
-			}
69
-
70
-		} else {
71
-			// alpha merging requires PHP v4.3.2+
72
-			$this->DebugMessage('Skipping ApplyMask() technique because PHP is v"'. PHP_VERSION .'"', __FILE__, __LINE__);
73
-		}
74
-		return true;
75
-	}
14
+    /**
15
+     * @var phpthumb
16
+     */
17
+
18
+    public $phpThumbObject = null;
19
+
20
+
21
+    public function DebugMessage($message, $file='', $line='') {
22
+        if (is_object($this->phpThumbObject)) {
23
+            return $this->phpThumbObject->DebugMessage($message, $file, $line);
24
+        }
25
+        return false;
26
+    }
27
+
28
+
29
+    public function ApplyMask(&$gdimg_mask, &$gdimg_image) {
30
+        if (phpthumb_functions::gd_version() < 2) {
31
+            $this->DebugMessage('Skipping ApplyMask() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
32
+            return false;
33
+        }
34
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.3.2', '>=')) {
35
+
36
+            $this->DebugMessage('Using alpha ApplyMask() technique', __FILE__, __LINE__);
37
+            if ($gdimg_mask_resized = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_image), imagesy($gdimg_image))) {
38
+
39
+                imagecopyresampled($gdimg_mask_resized, $gdimg_mask, 0, 0, 0, 0, imagesx($gdimg_image), imagesy($gdimg_image), imagesx($gdimg_mask), imagesy($gdimg_mask));
40
+                if ($gdimg_mask_blendtemp = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_image), imagesy($gdimg_image))) {
41
+
42
+                    $color_background = imagecolorallocate($gdimg_mask_blendtemp, 0, 0, 0);
43
+                    imagefilledrectangle($gdimg_mask_blendtemp, 0, 0, imagesx($gdimg_mask_blendtemp), imagesy($gdimg_mask_blendtemp), $color_background);
44
+                    imagealphablending($gdimg_mask_blendtemp, false);
45
+                    imagesavealpha($gdimg_mask_blendtemp, true);
46
+                    for ($x = 0, $xMax = imagesx($gdimg_image); $x < $xMax; $x++) {
47
+                        for ($y = 0, $yMax = imagesy($gdimg_image); $y < $yMax; $y++) {
48
+                            //$RealPixel = phpthumb_functions::GetPixelColor($gdimg_mask_blendtemp, $x, $y);
49
+                            $RealPixel = phpthumb_functions::GetPixelColor($gdimg_image, $x, $y);
50
+                            $MaskPixel = phpthumb_functions::GrayscalePixel(phpthumb_functions::GetPixelColor($gdimg_mask_resized, $x, $y));
51
+                            $MaskAlpha = 127 - (floor($MaskPixel['red'] / 2) * (1 - ($RealPixel['alpha'] / 127)));
52
+                            $newcolor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_mask_blendtemp, $RealPixel['red'], $RealPixel['green'], $RealPixel['blue'], $MaskAlpha);
53
+                            imagesetpixel($gdimg_mask_blendtemp, $x, $y, $newcolor);
54
+                        }
55
+                    }
56
+                    imagealphablending($gdimg_image, false);
57
+                    imagesavealpha($gdimg_image, true);
58
+                    imagecopy($gdimg_image, $gdimg_mask_blendtemp, 0, 0, 0, 0, imagesx($gdimg_mask_blendtemp), imagesy($gdimg_mask_blendtemp));
59
+                    imagedestroy($gdimg_mask_blendtemp);
60
+
61
+                } else {
62
+                    $this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
63
+                }
64
+                imagedestroy($gdimg_mask_resized);
65
+
66
+            } else {
67
+                $this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
68
+            }
69
+
70
+        } else {
71
+            // alpha merging requires PHP v4.3.2+
72
+            $this->DebugMessage('Skipping ApplyMask() technique because PHP is v"'. PHP_VERSION .'"', __FILE__, __LINE__);
73
+        }
74
+        return true;
75
+    }
76 76
 
77 77
 
78 78
     public function Bevel(&$gdimg, $width, $hexcolor1, $hexcolor2) {
@@ -95,1449 +95,1449 @@  discard block
 block discarded – undo
95 95
     }
96 96
 
97 97
 
98
-	public function Blur(&$gdimg, $radius=0.5) {
99
-		// Taken from Torstein Hønsi's phpUnsharpMask (see phpthumb.unsharp.php)
100
-
101
-		$radius = round(max(0, min($radius, 50)) * 2);
102
-		if (!$radius) {
103
-			return false;
104
-		}
105
-
106
-		$w = imagesx($gdimg);
107
-		$h = imagesy($gdimg);
108
-		if ($imgBlur = imagecreatetruecolor($w, $h)) {
109
-			// Gaussian blur matrix:
110
-			//	1	2	1
111
-			//	2	4	2
112
-			//	1	2	1
113
-
114
-			// Move copies of the image around one pixel at the time and merge them with weight
115
-			// according to the matrix. The same matrix is simply repeated for higher radii.
116
-			for ($i = 0; $i < $radius; $i++)	{
117
-				imagecopy     ($imgBlur, $gdimg, 0, 0, 1, 1, $w - 1, $h - 1);            // up left
118
-				imagecopymerge($imgBlur, $gdimg, 1, 1, 0, 0, $w,     $h,     50.00000);  // down right
119
-				imagecopymerge($imgBlur, $gdimg, 0, 1, 1, 0, $w - 1, $h,     33.33333);  // down left
120
-				imagecopymerge($imgBlur, $gdimg, 1, 0, 0, 1, $w,     $h - 1, 25.00000);  // up right
121
-				imagecopymerge($imgBlur, $gdimg, 0, 0, 1, 0, $w - 1, $h,     33.33333);  // left
122
-				imagecopymerge($imgBlur, $gdimg, 1, 0, 0, 0, $w,     $h,     25.00000);  // right
123
-				imagecopymerge($imgBlur, $gdimg, 0, 0, 0, 1, $w,     $h - 1, 20.00000);  // up
124
-				imagecopymerge($imgBlur, $gdimg, 0, 1, 0, 0, $w,     $h,     16.666667); // down
125
-				imagecopymerge($imgBlur, $gdimg, 0, 0, 0, 0, $w,     $h,     50.000000); // center
126
-				imagecopy     ($gdimg, $imgBlur, 0, 0, 0, 0, $w,     $h);
127
-			}
128
-			return true;
129
-		}
130
-		return false;
131
-	}
132
-
133
-
134
-	public function BlurGaussian(&$gdimg) {
135
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
136
-			if (imagefilter($gdimg, IMG_FILTER_GAUSSIAN_BLUR)) {
137
-				return true;
138
-			}
139
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_GAUSSIAN_BLUR)', __FILE__, __LINE__);
140
-			// fall through and try it the hard way
141
-		}
142
-		$this->DebugMessage('FAILED: phpthumb_filters::BlurGaussian($gdimg) [using phpthumb_filters::Blur() instead]', __FILE__, __LINE__);
143
-		return self::Blur($gdimg, 0.5);
144
-	}
145
-
146
-
147
-	public function BlurSelective(&$gdimg) {
148
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
149
-			if (imagefilter($gdimg, IMG_FILTER_SELECTIVE_BLUR)) {
150
-				return true;
151
-			}
152
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_SELECTIVE_BLUR)', __FILE__, __LINE__);
153
-			// fall through and try it the hard way
154
-		}
155
-		// currently not implemented "the hard way"
156
-		$this->DebugMessage('FAILED: phpthumb_filters::BlurSelective($gdimg) [function not implemented]', __FILE__, __LINE__);
157
-		return false;
158
-	}
159
-
160
-
161
-	public function Brightness(&$gdimg, $amount=0) {
162
-		if ($amount == 0) {
163
-			return true;
164
-		}
165
-		$amount = max(-255, min(255, $amount));
166
-
167
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
168
-			if (imagefilter($gdimg, IMG_FILTER_BRIGHTNESS, $amount)) {
169
-				return true;
170
-			}
171
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_BRIGHTNESS, '.$amount.')', __FILE__, __LINE__);
172
-			// fall through and try it the hard way
173
-		}
174
-
175
-		$scaling = (255 - abs($amount)) / 255;
176
-		$baseamount = (($amount > 0) ? $amount : 0);
177
-		for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
178
-			for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
179
-				$OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
180
-				$NewPixel = array();
181
-				foreach ($OriginalPixel as $key => $value) {
182
-					$NewPixel[$key] = round($baseamount + ($OriginalPixel[$key] * $scaling));
183
-				}
184
-				$newColor = imagecolorallocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
185
-				imagesetpixel($gdimg, $x, $y, $newColor);
186
-			}
187
-		}
188
-		return true;
189
-	}
190
-
191
-
192
-	public function Contrast(&$gdimg, $amount=0) {
193
-		if ($amount == 0) {
194
-			return true;
195
-		}
196
-		$amount = max(-255, min(255, $amount));
197
-
198
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
199
-			// imagefilter(IMG_FILTER_CONTRAST) has range +100 to -100 (positive numbers make it darker!)
200
-			$amount = ($amount / 255) * -100;
201
-			if (imagefilter($gdimg, IMG_FILTER_CONTRAST, $amount)) {
202
-				return true;
203
-			}
204
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_CONTRAST, '.$amount.')', __FILE__, __LINE__);
205
-			// fall through and try it the hard way
206
-		}
207
-
208
-		if ($amount > 0) {
209
-			$scaling = 1 + ($amount / 255);
210
-		} else {
211
-			$scaling = (255 - abs($amount)) / 255;
212
-		}
213
-		for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
214
-			for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
215
-				$OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
216
-				$NewPixel = array();
217
-				foreach ($OriginalPixel as $key => $value) {
218
-					$NewPixel[$key] = min(255, max(0, round($OriginalPixel[$key] * $scaling)));
219
-				}
220
-				$newColor = imagecolorallocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
221
-				imagesetpixel($gdimg, $x, $y, $newColor);
222
-			}
223
-		}
224
-		return true;
225
-	}
226
-
227
-
228
-	public function Colorize(&$gdimg, $amount, $targetColor) {
229
-		$amount      = (is_numeric($amount)                          ? $amount      : 25);
230
-		$amountPct   = $amount / 100;
231
-		$targetColor = (phpthumb_functions::IsHexColor($targetColor) ? $targetColor : 'gray');
232
-
233
-		if ($amount == 0) {
234
-			return true;
235
-		}
236
-
237
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
238
-			if ($targetColor == 'gray') {
239
-				$targetColor = '808080';
240
-			}
241
-			$r = round($amountPct * hexdec(substr($targetColor, 0, 2)));
242
-			$g = round($amountPct * hexdec(substr($targetColor, 2, 2)));
243
-			$b = round($amountPct * hexdec(substr($targetColor, 4, 2)));
244
-			if (imagefilter($gdimg, IMG_FILTER_COLORIZE, $r, $g, $b)) {
245
-				return true;
246
-			}
247
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_COLORIZE)', __FILE__, __LINE__);
248
-			// fall through and try it the hard way
249
-		}
250
-
251
-		// overridden below for grayscale
252
-		$TargetPixel = array();
253
-		if ($targetColor != 'gray') {
254
-			$TargetPixel['red']   = hexdec(substr($targetColor, 0, 2));
255
-			$TargetPixel['green'] = hexdec(substr($targetColor, 2, 2));
256
-			$TargetPixel['blue']  = hexdec(substr($targetColor, 4, 2));
257
-		}
258
-
259
-		for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
260
-			for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
261
-				$OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
262
-				if ($targetColor == 'gray') {
263
-					$TargetPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
264
-				}
265
-				$NewPixel = array();
266
-				foreach ($TargetPixel as $key => $value) {
267
-					$NewPixel[$key] = round(max(0, min(255, ($OriginalPixel[$key] * ((100 - $amount) / 100)) + ($TargetPixel[$key] * $amountPct))));
268
-				}
269
-				//$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue'], $OriginalPixel['alpha']);
270
-				$newColor = imagecolorallocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
271
-				imagesetpixel($gdimg, $x, $y, $newColor);
272
-			}
273
-		}
274
-		return true;
275
-	}
276
-
277
-
278
-	public function Crop(&$gdimg, $left=0, $right=0, $top=0, $bottom=0) {
279
-		if (!$left && !$right && !$top && !$bottom) {
280
-			return true;
281
-		}
282
-		$oldW = imagesx($gdimg);
283
-		$oldH = imagesy($gdimg);
284
-		if (($left   > 0) && ($left   < 1)) { $left   = round($left   * $oldW); }
285
-		if (($right  > 0) && ($right  < 1)) { $right  = round($right  * $oldW); }
286
-		if (($top    > 0) && ($top    < 1)) { $top    = round($top    * $oldH); }
287
-		if (($bottom > 0) && ($bottom < 1)) { $bottom = round($bottom * $oldH); }
288
-		$right  = min($oldW - $left - 1, $right);
289
-		$bottom = min($oldH - $top  - 1, $bottom);
290
-		$newW = $oldW - $left - $right;
291
-		$newH = $oldH - $top  - $bottom;
292
-
293
-		if ($imgCropped = imagecreatetruecolor($newW, $newH)) {
294
-			imagecopy($imgCropped, $gdimg, 0, 0, $left, $top, $newW, $newH);
295
-			if ($gdimg = imagecreatetruecolor($newW, $newH)) {
296
-				imagecopy($gdimg, $imgCropped, 0, 0, 0, 0, $newW, $newH);
297
-				imagedestroy($imgCropped);
298
-				return true;
299
-			}
300
-			imagedestroy($imgCropped);
301
-		}
302
-		return false;
303
-	}
304
-
305
-
306
-	public function Desaturate(&$gdimg, $amount, $color='') {
307
-		if ($amount == 0) {
308
-			return true;
309
-		}
310
-		return self::Colorize($gdimg, $amount, (phpthumb_functions::IsHexColor($color) ? $color : 'gray'));
311
-	}
312
-
313
-
314
-	public function DropShadow(&$gdimg, $distance, $width, $hexcolor, $angle, $alpha) {
315
-		if (phpthumb_functions::gd_version() < 2) {
316
-			return false;
317
-		}
318
-		$distance =                 ($distance ? $distance : 10);
319
-		$width    =                 ($width    ? $width    : 10);
320
-		$hexcolor =                 ($hexcolor ? $hexcolor : '000000');
321
-		$angle    =                 ($angle    ? $angle    : 225) % 360;
322
-		$alpha    = max(0, min(100, ($alpha    ? $alpha    : 100)));
323
-
324
-		if ($alpha <= 0) {
325
-			// invisible shadow, nothing to do
326
-			return true;
327
-		}
328
-		if ($distance <= 0) {
329
-			// shadow completely obscured by source image, nothing to do
330
-			return true;
331
-		}
332
-
333
-		//$width_shadow  = cos(deg2rad($angle)) * ($distance + $width);
334
-		//$height_shadow = sin(deg2rad($angle)) * ($distance + $width);
335
-		//$scaling = min(imagesx($gdimg) / (imagesx($gdimg) + abs($width_shadow)), imagesy($gdimg) / (imagesy($gdimg) + abs($height_shadow)));
336
-
337
-		$Offset = array();
338
-		for ($i = 0; $i < $width; $i++) {
339
-			$WidthAlpha[$i] = (abs(($width / 2) - $i) / $width);
340
-			$Offset['x'] = cos(deg2rad($angle)) * ($distance + $i);
341
-			$Offset['y'] = sin(deg2rad($angle)) * ($distance + $i);
342
-		}
343
-
344
-		$tempImageWidth  = imagesx($gdimg)  + abs($Offset['x']);
345
-		$tempImageHeight = imagesy($gdimg) + abs($Offset['y']);
346
-
347
-		if ($gdimg_dropshadow_temp = phpthumb_functions::ImageCreateFunction($tempImageWidth, $tempImageHeight)) {
348
-
349
-			imagealphablending($gdimg_dropshadow_temp, false);
350
-			imagesavealpha($gdimg_dropshadow_temp, true);
351
-			$transparent1 = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_dropshadow_temp, 0, 0, 0, 127);
352
-			imagefill($gdimg_dropshadow_temp, 0, 0, $transparent1);
353
-
354
-			$PixelMap = array();
355
-			for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
356
-				for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
357
-					$PixelMap[$x][$y] = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
358
-				}
359
-			}
360
-			for ($x = 0; $x < $tempImageWidth; $x++) {
361
-				for ($y = 0; $y < $tempImageHeight; $y++) {
362
-					//for ($i = 0; $i < $width; $i++) {
363
-					for ($i = 0; $i < 1; $i++) {
364
-						if (!isset($PixelMap[$x][$y]['alpha']) || ($PixelMap[$x][$y]['alpha'] > 0)) {
365
-							if (isset($PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha']) && ($PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha'] < 127)) {
366
-								$thisColor = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor, false, $PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha']);
367
-								imagesetpixel($gdimg_dropshadow_temp, $x, $y, $thisColor);
368
-							}
369
-						}
370
-					}
371
-				}
372
-			}
373
-
374
-			imagealphablending($gdimg_dropshadow_temp, true);
375
-			for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
376
-				for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
377
-					if ($PixelMap[$x][$y]['alpha'] < 127) {
378
-						$thisColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_dropshadow_temp, $PixelMap[$x][$y]['red'], $PixelMap[$x][$y]['green'], $PixelMap[$x][$y]['blue'], $PixelMap[$x][$y]['alpha']);
379
-						imagesetpixel($gdimg_dropshadow_temp, $x, $y, $thisColor);
380
-					}
381
-				}
382
-			}
383
-
384
-			imagesavealpha($gdimg, true);
385
-			imagealphablending($gdimg, false);
386
-			//$this->is_alpha = true;
387
-			$transparent2 = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0, 0, 0, 127);
388
-			imagefilledrectangle($gdimg, 0, 0, imagesx($gdimg), imagesy($gdimg), $transparent2);
389
-			imagecopyresampled($gdimg, $gdimg_dropshadow_temp, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg), imagesx($gdimg_dropshadow_temp), imagesy($gdimg_dropshadow_temp));
390
-
391
-			imagedestroy($gdimg_dropshadow_temp);
392
-		}
393
-		return true;
394
-	}
395
-
396
-
397
-	public function EdgeDetect(&$gdimg) {
398
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
399
-			if (imagefilter($gdimg, IMG_FILTER_EDGEDETECT)) {
400
-				return true;
401
-			}
402
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_EDGEDETECT)', __FILE__, __LINE__);
403
-			// fall through and try it the hard way
404
-		}
405
-		// currently not implemented "the hard way"
406
-		$this->DebugMessage('FAILED: phpthumb_filters::EdgeDetect($gdimg) [function not implemented]', __FILE__, __LINE__);
407
-		return false;
408
-	}
409
-
410
-
411
-	public function Ellipse($gdimg) {
412
-		if (phpthumb_functions::gd_version() < 2) {
413
-			return false;
414
-		}
415
-		// generate mask at twice desired resolution and downsample afterwards for easy antialiasing
416
-		if ($gdimg_ellipsemask_double = phpthumb_functions::ImageCreateFunction(imagesx($gdimg) * 2, imagesy($gdimg) * 2)) {
417
-			if ($gdimg_ellipsemask = phpthumb_functions::ImageCreateFunction(imagesx($gdimg), imagesy($gdimg))) {
418
-
419
-				$color_transparent = imagecolorallocate($gdimg_ellipsemask_double, 255, 255, 255);
420
-				imagefilledellipse($gdimg_ellipsemask_double, imagesx($gdimg), imagesy($gdimg), (imagesx($gdimg) - 1) * 2, (imagesy($gdimg) - 1) * 2, $color_transparent);
421
-				imagecopyresampled($gdimg_ellipsemask, $gdimg_ellipsemask_double, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg), imagesx($gdimg) * 2, imagesy($gdimg) * 2);
422
-
423
-				self::ApplyMask($gdimg_ellipsemask, $gdimg);
424
-				imagedestroy($gdimg_ellipsemask);
425
-				return true;
426
-
427
-			} else {
428
-				$this->DebugMessage('$gdimg_ellipsemask = phpthumb_functions::ImageCreateFunction() failed', __FILE__, __LINE__);
429
-			}
430
-			imagedestroy($gdimg_ellipsemask_double);
431
-		} else {
432
-			$this->DebugMessage('$gdimg_ellipsemask_double = phpthumb_functions::ImageCreateFunction() failed', __FILE__, __LINE__);
433
-		}
434
-		return false;
435
-	}
436
-
437
-
438
-	public function Emboss(&$gdimg) {
439
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
440
-			if (imagefilter($gdimg, IMG_FILTER_EMBOSS)) {
441
-				return true;
442
-			}
443
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_EMBOSS)', __FILE__, __LINE__);
444
-			// fall through and try it the hard way
445
-		}
446
-		// currently not implemented "the hard way"
447
-		$this->DebugMessage('FAILED: phpthumb_filters::Emboss($gdimg) [function not implemented]', __FILE__, __LINE__);
448
-		return false;
449
-	}
450
-
451
-
452
-	public function Flip(&$gdimg, $x=false, $y=false) {
453
-		if (!$x && !$y) {
454
-			return false;
455
-		}
456
-		if ($tempImage = phpthumb_functions::ImageCreateFunction(imagesx($gdimg), imagesy($gdimg))) {
457
-			if ($x) {
458
-				imagecopy($tempImage, $gdimg, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg));
459
-				for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
460
-					imagecopy($gdimg, $tempImage, imagesx($gdimg) - 1 - $x, 0, $x, 0, 1, imagesy($gdimg));
461
-				}
462
-			}
463
-			if ($y) {
464
-				imagecopy($tempImage, $gdimg, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg));
465
-				for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
466
-					imagecopy($gdimg, $tempImage, 0, imagesy($gdimg) - 1 - $y, 0, $y, imagesx($gdimg), 1);
467
-				}
468
-			}
469
-			imagedestroy($tempImage);
470
-		}
471
-		return true;
472
-	}
473
-
474
-
475
-	public function Frame(&$gdimg, $frame_width, $edge_width, $hexcolor_frame, $hexcolor1, $hexcolor2) {
476
-		$frame_width    = ($frame_width    ? $frame_width    : 5);
477
-		$edge_width     = ($edge_width     ? $edge_width     : 1);
478
-		$hexcolor_frame = ($hexcolor_frame ? $hexcolor_frame : 'CCCCCC');
479
-		$hexcolor1      = ($hexcolor1      ? $hexcolor1      : 'FFFFFF');
480
-		$hexcolor2      = ($hexcolor2      ? $hexcolor2      : '000000');
481
-
482
-		$color_frame = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor_frame);
483
-		$color1      = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor1);
484
-		$color2      = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor2);
485
-		for ($i = 0; $i < $edge_width; $i++) {
486
-			// outer bevel
487
-			imageline($gdimg,                   $i,                   $i,                   $i, imagesy($gdimg) - $i, $color1); // left
488
-			imageline($gdimg,                   $i,                   $i, imagesx($gdimg) - $i,                   $i, $color1); // top
489
-			imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i, imagesx($gdimg) - $i,                   $i, $color2); // right
490
-			imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i,                   $i, imagesy($gdimg) - $i, $color2); // bottom
491
-		}
492
-		for ($i = 0; $i < $frame_width; $i++) {
493
-			// actual frame
494
-			imagerectangle($gdimg, $edge_width + $i, $edge_width + $i, imagesx($gdimg) - $edge_width - $i, imagesy($gdimg) - $edge_width - $i, $color_frame);
495
-		}
496
-		for ($i = 0; $i < $edge_width; $i++) {
497
-			// inner bevel
498
-			imageline($gdimg,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $color2); // left
499
-			imageline($gdimg,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i, imagesx($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, $color2); // top
500
-			imageline($gdimg, imagesx($gdimg) - $frame_width - $edge_width - $i, imagesy($gdimg) - $frame_width - $edge_width - $i, imagesx($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, $color1); // right
501
-			imageline($gdimg, imagesx($gdimg) - $frame_width - $edge_width - $i, imagesy($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $color1); // bottom
502
-		}
503
-		return true;
504
-	}
505
-
506
-
507
-	public function Gamma(&$gdimg, $amount) {
508
-		if (number_format($amount, 4) == '1.0000') {
509
-			return true;
510
-		}
511
-		return imagegammacorrect($gdimg, 1.0, $amount);
512
-	}
513
-
514
-
515
-	public function Grayscale(&$gdimg) {
516
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
517
-			if (imagefilter($gdimg, IMG_FILTER_GRAYSCALE)) {
518
-				return true;
519
-			}
520
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_GRAYSCALE)', __FILE__, __LINE__);
521
-			// fall through and try it the hard way
522
-		}
523
-		return self::Colorize($gdimg, 100, 'gray');
524
-	}
525
-
526
-
527
-	public function HistogramAnalysis(&$gdimg, $calculateGray=false) {
528
-		$ImageSX = imagesx($gdimg);
529
-		$ImageSY = imagesy($gdimg);
530
-		$Analysis = array();
531
-		for ($x = 0; $x < $ImageSX; $x++) {
532
-			for ($y = 0; $y < $ImageSY; $y++) {
533
-				$OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
534
-				@$Analysis['red'][$OriginalPixel['red']]++;
535
-				@$Analysis['green'][$OriginalPixel['green']]++;
536
-				@$Analysis['blue'][$OriginalPixel['blue']]++;
537
-				@$Analysis['alpha'][$OriginalPixel['alpha']]++;
538
-				if ($calculateGray) {
539
-					$GrayPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
540
-					@$Analysis['gray'][$GrayPixel['red']]++;
541
-				}
542
-			}
543
-		}
544
-		$keys = array('red', 'green', 'blue', 'alpha');
545
-		if ($calculateGray) {
546
-			$keys[] = 'gray';
547
-		}
548
-		foreach ($keys as $dummy => $key) {
549
-			ksort($Analysis[$key]);
550
-		}
551
-		return $Analysis;
552
-	}
553
-
554
-
555
-	public function HistogramStretch(&$gdimg, $band='*', $method=0, $threshold=0.1) {
556
-		// equivalent of "Auto Contrast" in Adobe Photoshop
557
-		// method 0 stretches according to RGB colors. Gives a more conservative stretch.
558
-		// method 1 band stretches according to grayscale which is color-biased (59% green, 30% red, 11% blue). May give a punchier / more aggressive stretch, possibly appearing over-saturated
559
-		$Analysis = self::HistogramAnalysis($gdimg, true);
560
-		$keys = array('r'=>'red', 'g'=>'green', 'b'=>'blue', 'a'=>'alpha', '*'=>(($method == 0) ? 'all' : 'gray'));
561
-		$band = $band[ 0 ];
562
-		if (!isset($keys[$band])) {
563
-			return false;
564
-		}
565
-		$key = $keys[$band];
566
-
567
-		// If the absolute brightest and darkest pixels are used then one random
568
-		// pixel in the image could throw off the whole system. Instead, count up/down
569
-		// from the limit and allow <threshold> (default = 0.1%) of brightest/darkest
570
-		// pixels to be clipped to min/max
571
-		$threshold = (float) $threshold / 100;
572
-		$clip_threshold = imagesx($gdimg) * imagesx($gdimg) * $threshold;
573
-
574
-		$countsum  = 0;
575
-		$range_min = 0;
576
-		for ($i = 0; $i <= 255; $i++) {
577
-			if ($method == 0) {
578
-				$countsum = max(@$Analysis['red'][$i], @$Analysis['green'][$i], @$Analysis['blue'][$i]);
579
-			} else {
580
-				$countsum += @$Analysis[$key][$i];
581
-			}
582
-			if ($countsum >= $clip_threshold) {
583
-				$range_min = $i - 1;
584
-				break;
585
-			}
586
-		}
587
-		$range_min = max($range_min, 0);
588
-
589
-		$countsum  =   0;
590
-		$range_max = 255;
591
-		for ($i = 255; $i >= 0; $i--) {
592
-			if ($method == 0) {
593
-				$countsum = max(@$Analysis['red'][$i], @$Analysis['green'][$i], @$Analysis['blue'][$i]);
594
-			} else {
595
-				$countsum += @$Analysis[$key][$i];
596
-			}
597
-			if ($countsum >= $clip_threshold) {
598
-				$range_max = $i + 1;
599
-				break;
600
-			}
601
-		}
602
-		$range_max = min($range_max, 255);
603
-
604
-		$range_scale = (($range_max == $range_min) ? 1 : (255 / ($range_max - $range_min)));
605
-		if (($range_min == 0) && ($range_max == 255)) {
606
-			// no adjustment necessary - don't waste CPU time!
607
-			return true;
608
-		}
609
-
610
-		$ImageSX = imagesx($gdimg);
611
-		$ImageSY = imagesy($gdimg);
612
-		for ($x = 0; $x < $ImageSX; $x++) {
613
-			for ($y = 0; $y < $ImageSY; $y++) {
614
-				$OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
615
-				if ($band == '*') {
616
-					$new['red']   = min(255, max(0, ($OriginalPixel['red']   - $range_min) * $range_scale));
617
-					$new['green'] = min(255, max(0, ($OriginalPixel['green'] - $range_min) * $range_scale));
618
-					$new['blue']  = min(255, max(0, ($OriginalPixel['blue']  - $range_min) * $range_scale));
619
-					$new['alpha'] = min(255, max(0, ($OriginalPixel['alpha'] - $range_min) * $range_scale));
620
-				} else {
621
-					$new = $OriginalPixel;
622
-					$new[$key] = min(255, max(0, ($OriginalPixel[$key] - $range_min) * $range_scale));
623
-				}
624
-				$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $new['red'], $new['green'], $new['blue'], $new['alpha']);
625
-				imagesetpixel($gdimg, $x, $y, $newColor);
626
-			}
627
-		}
628
-
629
-		return true;
630
-	}
631
-
632
-
633
-	public function HistogramOverlay(&$gdimg, $bands='*', $colors='', $width=0.25, $height=0.25, $alignment='BR', $opacity=50, $margin_x=5, $margin_y=null) {
634
-		$margin_y = (null === $margin_y ? $margin_x : $margin_y);
635
-
636
-		$Analysis = self::HistogramAnalysis($gdimg, true);
637
-		$histW = round(($width > 1) ? min($width, imagesx($gdimg)) : imagesx($gdimg) * $width);
638
-		$histH = round(($width > 1) ? min($width, imagesx($gdimg)) : imagesx($gdimg) * $width);
639
-		if ($gdHist = imagecreatetruecolor($histW, $histH)) {
640
-			$color_back = phpthumb_functions::ImageColorAllocateAlphaSafe($gdHist, 0, 0, 0, 127);
641
-			imagefilledrectangle($gdHist, 0, 0, $histW, $histH, $color_back);
642
-			imagealphablending($gdHist, false);
643
-			imagesavealpha($gdHist, true);
644
-
645
-			$HistogramTempWidth  = 256;
646
-			$HistogramTempHeight = 100;
647
-			if ($gdHistTemp = imagecreatetruecolor($HistogramTempWidth, $HistogramTempHeight)) {
648
-				$color_back_temp = phpthumb_functions::ImageColorAllocateAlphaSafe($gdHistTemp, 255, 0, 255, 127);
649
-				imagealphablending($gdHistTemp, false);
650
-				imagesavealpha($gdHistTemp, true);
651
-				imagefilledrectangle($gdHistTemp, 0, 0, imagesx($gdHistTemp), imagesy($gdHistTemp), $color_back_temp);
652
-
653
-				$DefaultColors = array('r'=>'FF0000', 'g'=>'00FF00', 'b'=>'0000FF', 'a'=>'999999', '*'=>'FFFFFF');
654
-				$Colors = explode(';', $colors);
655
-				$BandsToGraph = array_unique(preg_split('##', $bands));
656
-				$keys = array('r'=>'red', 'g'=>'green', 'b'=>'blue', 'a'=>'alpha', '*'=>'gray');
657
-				foreach ($BandsToGraph as $key => $band) {
658
-					if (!isset($keys[$band])) {
659
-						continue;
660
-					}
661
-					$PeakValue = max($Analysis[$keys[$band]]);
662
-					$thisColor = phpthumb_functions::ImageHexColorAllocate($gdHistTemp, phpthumb_functions::IsHexColor(@$Colors[$key]) ? $Colors[$key] : $DefaultColors[$band]);
663
-					for ($x = 0; $x < $HistogramTempWidth; $x++) {
664
-						imageline($gdHistTemp, $x, $HistogramTempHeight - 1, $x, $HistogramTempHeight - 1 - round(@$Analysis[$keys[$band]][$x] / $PeakValue * $HistogramTempHeight), $thisColor);
665
-					}
666
-					imageline($gdHistTemp, 0, $HistogramTempHeight - 1, $HistogramTempWidth - 1, $HistogramTempHeight - 1, $thisColor);
667
-					imageline($gdHistTemp, 0, $HistogramTempHeight - 2, $HistogramTempWidth - 1, $HistogramTempHeight - 2, $thisColor);
668
-				}
669
-				imagecopyresampled($gdHist, $gdHistTemp, 0, 0, 0, 0, imagesx($gdHist), imagesy($gdHist), imagesx($gdHistTemp), imagesy($gdHistTemp));
670
-				imagedestroy($gdHistTemp);
671
-			} else {
672
-				return false;
673
-			}
674
-
675
-			self::WatermarkOverlay($gdimg, $gdHist, $alignment, $opacity, $margin_x, $margin_y);
676
-			imagedestroy($gdHist);
677
-			return true;
678
-		}
679
-		return false;
680
-	}
681
-
682
-
683
-	public function ImageBorder(&$gdimg, $border_width, $radius_x, $radius_y, $hexcolor_border) {
684
-		$border_width = ($border_width ? $border_width : 1);
685
-		$radius_x     = ($radius_x     ? $radius_x     : 0);
686
-		$radius_y     = ($radius_y     ? $radius_y     : 0);
687
-
688
-		$output_width  = imagesx($gdimg);
689
-		$output_height = imagesy($gdimg);
690
-
691
-		list($new_width, $new_height) = phpthumb_functions::ProportionalResize($output_width, $output_height, $output_width - max($border_width * 2, $radius_x), $output_height - max($border_width * 2, $radius_y));
692
-		$offset_x = ($radius_x ? $output_width  - $new_width  - $radius_x : 0);
693
-
694
-		if ($gd_border_canvas = phpthumb_functions::ImageCreateFunction($output_width, $output_height)) {
695
-
696
-			imagesavealpha($gd_border_canvas, true);
697
-			imagealphablending($gd_border_canvas, false);
698
-			$color_background = phpthumb_functions::ImageColorAllocateAlphaSafe($gd_border_canvas, 255, 255, 255, 127);
699
-			imagefilledrectangle($gd_border_canvas, 0, 0, $output_width, $output_height, $color_background);
700
-
701
-			$color_border = phpthumb_functions::ImageHexColorAllocate($gd_border_canvas, (phpthumb_functions::IsHexColor($hexcolor_border) ? $hexcolor_border : '000000'));
702
-
703
-			for ($i = 0; $i < $border_width; $i++) {
704
-				imageline($gd_border_canvas,             floor($offset_x / 2) + $radius_x,                      $i, $output_width - $radius_x - ceil($offset_x / 2),                         $i, $color_border); // top
705
-				imageline($gd_border_canvas,             floor($offset_x / 2) + $radius_x, $output_height - 1 - $i, $output_width - $radius_x - ceil($offset_x / 2),    $output_height - 1 - $i, $color_border); // bottom
706
-				imageline($gd_border_canvas,                    floor($offset_x / 2) + $i,               $radius_y,                      floor($offset_x / 2) +  $i, $output_height - $radius_y, $color_border); // left
707
-				imageline($gd_border_canvas, $output_width - 1 - $i - ceil($offset_x / 2),               $radius_y,    $output_width - 1 - $i - ceil($offset_x / 2), $output_height - $radius_y, $color_border); // right
708
-			}
709
-
710
-			if ($radius_x && $radius_y) {
711
-
712
-				// PHP bug: imagearc() with thicknesses > 1 give bad/undesirable/unpredicatable results
713
-				// Solution: Draw multiple 1px arcs side-by-side.
714
-
715
-				// Problem: parallel arcs give strange/ugly antialiasing problems
716
-				// Solution: draw non-parallel arcs, from one side of the line thickness at the start angle
717
-				//   to the opposite edge of the line thickness at the terminating angle
718
-				for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) {
719
-					imagearc($gd_border_canvas, floor($offset_x / 2) + 1 +                 $radius_x,              $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
720
-					imagearc($gd_border_canvas,                     $output_width - $radius_x - 1 - ceil($offset_x / 2),              $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
721
-					imagearc($gd_border_canvas,                     $output_width - $radius_x - 1 - ceil($offset_x / 2), $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2,   0,  90, $color_border); // bottom-right
722
-					imagearc($gd_border_canvas, floor($offset_x / 2) + 1 +                 $radius_x, $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2,  90, 180, $color_border); // bottom-left
723
-				}
724
-				if ($border_width > 1) {
725
-					for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) {
726
-						imagearc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x,                                      $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
727
-						imagearc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2),                                      $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
728
-						imagearc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2),                     $output_height - $radius_y, $radius_x * 2, $radius_y * 2,   0,  90, $color_border); // bottom-right
729
-						imagearc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x,                     $output_height - $radius_y, $radius_x * 2, $radius_y * 2,  90, 180, $color_border); // bottom-left
730
-					}
731
-				}
732
-
733
-			}
734
-			$this->phpThumbObject->ImageResizeFunction($gd_border_canvas, $gdimg, floor(($output_width - $new_width) / 2), round(($output_height - $new_height) / 2), 0, 0, $new_width, $new_height, $output_width, $output_height);
735
-
736
-			imagedestroy($gdimg);
737
-			$gdimg = phpthumb_functions::ImageCreateFunction($output_width, $output_height);
738
-			imagesavealpha($gdimg, true);
739
-			imagealphablending($gdimg, false);
740
-			$gdimg_color_background = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 255, 255, 255, 127);
741
-			imagefilledrectangle($gdimg, 0, 0, $output_width, $output_height, $gdimg_color_background);
742
-
743
-			imagecopy($gdimg, $gd_border_canvas, 0, 0, 0, 0, $output_width, $output_height);
744
-			imagedestroy($gd_border_canvas);
745
-			return true;
746
-
747
-
748
-		} else {
749
-			$this->DebugMessage('FAILED: $gd_border_canvas = phpthumb_functions::ImageCreateFunction('.$output_width.', '.$output_height.')', __FILE__, __LINE__);
750
-		}
751
-		return false;
752
-	}
753
-
754
-
755
-	public static function ImprovedImageRotate(&$gdimg_source, $rotate_angle=0, $config_background_hexcolor='FFFFFF', $bg=null, &$phpThumbObject) {
756
-		while ($rotate_angle < 0) {
757
-			$rotate_angle += 360;
758
-		}
759
-		$rotate_angle %= 360;
760
-		if ($rotate_angle != 0) {
761
-
762
-			$background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_source, $config_background_hexcolor);
763
-
764
-			if ((phpthumb_functions::gd_version() >= 2) && !$bg && ($rotate_angle % 90)) {
765
-
766
-				//$this->DebugMessage('Using alpha rotate', __FILE__, __LINE__);
767
-				if ($gdimg_rotate_mask = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_source), imagesy($gdimg_source))) {
768
-
769
-					$color_mask = array();
770
-					for ($i = 0; $i <= 255; $i++) {
771
-						$color_mask[$i] = imagecolorallocate($gdimg_rotate_mask, $i, $i, $i);
772
-					}
773
-					imagefilledrectangle($gdimg_rotate_mask, 0, 0, imagesx($gdimg_rotate_mask), imagesy($gdimg_rotate_mask), $color_mask[255]);
774
-					$imageX = imagesx($gdimg_source);
775
-					$imageY = imagesy($gdimg_source);
776
-					for ($x = 0; $x < $imageX; $x++) {
777
-						for ($y = 0; $y < $imageY; $y++) {
778
-							$pixelcolor = phpthumb_functions::GetPixelColor($gdimg_source, $x, $y);
779
-							imagesetpixel($gdimg_rotate_mask, $x, $y, $color_mask[255 - round($pixelcolor['alpha'] * 255 / 127)]);
780
-						}
781
-					}
782
-					$gdimg_rotate_mask = imagerotate($gdimg_rotate_mask, $rotate_angle, $color_mask[0]);
783
-					$gdimg_source      = imagerotate($gdimg_source,      $rotate_angle, $background_color);
784
-
785
-					imagealphablending($gdimg_source, false);
786
-					imagesavealpha($gdimg_source, true);
787
-					//$this->is_alpha = true;
788
-					$phpThumbFilters = new self();
789
-					//$phpThumbFilters->phpThumbObject = $this;
790
-					$phpThumbFilters->phpThumbObject = $phpThumbObject;
791
-					$phpThumbFilters->ApplyMask($gdimg_rotate_mask, $gdimg_source);
792
-
793
-					imagedestroy($gdimg_rotate_mask);
794
-
795
-				} else {
796
-					//$this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
797
-				}
798
-
799
-			} else {
800
-
801
-				if (phpthumb_functions::gd_version() < 2) {
802
-					//$this->DebugMessage('Using non-alpha rotate because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
803
-				} elseif ($bg) {
804
-					//$this->DebugMessage('Using non-alpha rotate because $this->bg is "'.$bg.'"', __FILE__, __LINE__);
805
-				} elseif ($rotate_angle % 90) {
806
-					//$this->DebugMessage('Using non-alpha rotate because ($rotate_angle % 90) = "'.($rotate_angle % 90).'"', __FILE__, __LINE__);
807
-				} else {
808
-					//$this->DebugMessage('Using non-alpha rotate because $this->thumbnailFormat is "'.$this->thumbnailFormat.'"', __FILE__, __LINE__);
809
-				}
810
-
811
-				if (imagecolortransparent($gdimg_source) >= 0) {
812
-					// imagerotate() forgets all about an image's transparency and sets the transparent color to black
813
-					// To compensate, flood-fill the transparent color of the source image with the specified background color first
814
-					// then rotate and the colors should match
815
-
816
-					if (!function_exists('imageistruecolor') || !imageistruecolor($gdimg_source)) {
817
-						// convert paletted image to true-color before rotating to prevent nasty aliasing artifacts
818
-
819
-						//$this->source_width  = imagesx($gdimg_source);
820
-						//$this->source_height = imagesy($gdimg_source);
821
-						$gdimg_newsrc = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_source), imagesy($gdimg_source));
822
-						$background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_newsrc, $config_background_hexcolor);
823
-						imagefilledrectangle($gdimg_newsrc, 0, 0, imagesx($gdimg_source), imagesy($gdimg_source), phpthumb_functions::ImageHexColorAllocate($gdimg_newsrc, $config_background_hexcolor));
824
-						imagecopy($gdimg_newsrc, $gdimg_source, 0, 0, 0, 0, imagesx($gdimg_source), imagesy($gdimg_source));
825
-						imagedestroy($gdimg_source);
826
-						unset($gdimg_source);
827
-						$gdimg_source = $gdimg_newsrc;
828
-						unset($gdimg_newsrc);
829
-
830
-					} else {
831
-
832
-						imagecolorset(
833
-							$gdimg_source,
834
-							imagecolortransparent($gdimg_source),
835
-							hexdec(substr($config_background_hexcolor, 0, 2)),
836
-							hexdec(substr($config_background_hexcolor, 2, 2)),
837
-							hexdec(substr($config_background_hexcolor, 4, 2)));
838
-
839
-						imagecolortransparent($gdimg_source, -1);
840
-
841
-					}
842
-				}
843
-
844
-				$gdimg_source = imagerotate($gdimg_source, $rotate_angle, $background_color);
845
-
846
-			}
847
-		}
848
-		return true;
849
-	}
850
-
851
-
852
-	public function MeanRemoval(&$gdimg) {
853
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
854
-			if (imagefilter($gdimg, IMG_FILTER_MEAN_REMOVAL)) {
855
-				return true;
856
-			}
857
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_MEAN_REMOVAL)', __FILE__, __LINE__);
858
-			// fall through and try it the hard way
859
-		}
860
-		// currently not implemented "the hard way"
861
-		$this->DebugMessage('FAILED: phpthumb_filters::MeanRemoval($gdimg) [function not implemented]', __FILE__, __LINE__);
862
-		return false;
863
-	}
864
-
865
-
866
-	public function Negative(&$gdimg) {
867
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
868
-			if (imagefilter($gdimg, IMG_FILTER_NEGATE)) {
869
-				return true;
870
-			}
871
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_NEGATE)', __FILE__, __LINE__);
872
-			// fall through and try it the hard way
873
-		}
874
-		$ImageSX = imagesx($gdimg);
875
-		$ImageSY = imagesy($gdimg);
876
-		for ($x = 0; $x < $ImageSX; $x++) {
877
-			for ($y = 0; $y < $ImageSY; $y++) {
878
-				$currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
879
-				$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, (~$currentPixel['red'] & 0xFF), (~$currentPixel['green'] & 0xFF), (~$currentPixel['blue'] & 0xFF), $currentPixel['alpha']);
880
-				imagesetpixel($gdimg, $x, $y, $newColor);
881
-			}
882
-		}
883
-		return true;
884
-	}
885
-
886
-
887
-	public function RoundedImageCorners(&$gdimg, $radius_x, $radius_y) {
888
-		// generate mask at twice desired resolution and downsample afterwards for easy antialiasing
889
-		// mask is generated as a white double-size ellipse on a triple-size black background and copy-paste-resampled
890
-		// onto a correct-size mask image as 4 corners due to errors when the entire mask is resampled at once (gray edges)
891
-		if ($gdimg_cornermask_triple = phpthumb_functions::ImageCreateFunction($radius_x * 6, $radius_y * 6)) {
892
-			if ($gdimg_cornermask = phpthumb_functions::ImageCreateFunction(imagesx($gdimg), imagesy($gdimg))) {
893
-
894
-				$color_transparent = imagecolorallocate($gdimg_cornermask_triple, 255, 255, 255);
895
-				imagefilledellipse($gdimg_cornermask_triple, $radius_x * 3, $radius_y * 3, $radius_x * 4, $radius_y * 4, $color_transparent);
896
-
897
-				imagefilledrectangle($gdimg_cornermask, 0, 0, imagesx($gdimg), imagesy($gdimg), $color_transparent);
898
-
899
-				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple,                           0,                           0,     $radius_x,     $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
900
-				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple,                           0, imagesy($gdimg) - $radius_y,     $radius_x, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
901
-				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, imagesx($gdimg) - $radius_x, imagesy($gdimg) - $radius_y, $radius_x * 3, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
902
-				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, imagesx($gdimg) - $radius_x,                           0, $radius_x * 3,     $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
903
-
904
-				self::ApplyMask($gdimg_cornermask, $gdimg);
905
-				imagedestroy($gdimg_cornermask);
906
-				$this->DebugMessage('RoundedImageCorners('.$radius_x.', '.$radius_y.') succeeded', __FILE__, __LINE__);
907
-				return true;
908
-
909
-			} else {
910
-				$this->DebugMessage('FAILED: $gdimg_cornermask = phpthumb_functions::ImageCreateFunction('.imagesx($gdimg).', '.imagesy($gdimg).')', __FILE__, __LINE__);
911
-			}
912
-			imagedestroy($gdimg_cornermask_triple);
913
-
914
-		} else {
915
-			$this->DebugMessage('FAILED: $gdimg_cornermask_triple = phpthumb_functions::ImageCreateFunction('.($radius_x * 6).', '.($radius_y * 6).')', __FILE__, __LINE__);
916
-		}
917
-		return false;
918
-	}
919
-
920
-
921
-	public function Saturation(&$gdimg, $amount, $color='') {
922
-		if ($amount == 0) {
923
-			return true;
924
-		} elseif ($amount > 0) {
925
-			$amount = 0 - $amount;
926
-		} else {
927
-			$amount = abs($amount);
928
-		}
929
-		return self::Desaturate($gdimg, $amount, $color);
930
-	}
931
-
932
-
933
-	public function Sepia(&$gdimg, $amount, $targetColor) {
934
-		$amount      = (is_numeric($amount) ? max(0, min(100, $amount)) : 50);
935
-		$amountPct   = $amount / 100;
936
-		$targetColor = (phpthumb_functions::IsHexColor($targetColor) ? $targetColor : 'A28065');
937
-
938
-		if ($amount == 0) {
939
-			return true;
940
-		}
941
-
942
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
943
-			if (imagefilter($gdimg, IMG_FILTER_GRAYSCALE)) {
944
-
945
-				$r = round($amountPct * hexdec(substr($targetColor, 0, 2)));
946
-				$g = round($amountPct * hexdec(substr($targetColor, 2, 2)));
947
-				$b = round($amountPct * hexdec(substr($targetColor, 4, 2)));
948
-				if (imagefilter($gdimg, IMG_FILTER_COLORIZE, $r, $g, $b)) {
949
-					return true;
950
-				}
951
-				$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_COLORIZE)', __FILE__, __LINE__);
952
-				// fall through and try it the hard way
953
-
954
-			} else {
955
-
956
-				$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_GRAYSCALE)', __FILE__, __LINE__);
957
-				// fall through and try it the hard way
958
-
959
-			}
960
-		}
961
-
962
-		$TargetPixel['red']   = hexdec(substr($targetColor, 0, 2));
963
-		$TargetPixel['green'] = hexdec(substr($targetColor, 2, 2));
964
-		$TargetPixel['blue']  = hexdec(substr($targetColor, 4, 2));
965
-
966
-		$ImageSX = imagesx($gdimg);
967
-		$ImageSY = imagesy($gdimg);
968
-		for ($x = 0; $x < $ImageSX; $x++) {
969
-			for ($y = 0; $y < $ImageSY; $y++) {
970
-				$OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
971
-				$GrayPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
972
-
973
-				// http://www.gimpguru.org/Tutorials/SepiaToning/
974
-				// "In the traditional sepia toning process, the tinting occurs most in
975
-				// the mid-tones: the lighter and darker areas appear to be closer to B&W."
976
-				$SepiaAmount = ((128 - abs($GrayPixel['red'] - 128)) / 128) * $amountPct;
977
-
978
-				$NewPixel = array();
979
-				foreach ($TargetPixel as $key => $value) {
980
-					$NewPixel[$key] = round(max(0, min(255, $GrayPixel[$key] * (1 - $SepiaAmount) + ($TargetPixel[$key] * $SepiaAmount))));
981
-				}
982
-				$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue'], $OriginalPixel['alpha']);
983
-				imagesetpixel($gdimg, $x, $y, $newColor);
984
-			}
985
-		}
986
-		return true;
987
-	}
988
-
989
-
990
-	public function Smooth(&$gdimg, $amount=6) {
991
-		$amount = min(25, max(0, $amount));
992
-		if ($amount == 0) {
993
-			return true;
994
-		}
995
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
996
-			if (imagefilter($gdimg, IMG_FILTER_SMOOTH, $amount)) {
997
-				return true;
998
-			}
999
-			$this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_SMOOTH, '.$amount.')', __FILE__, __LINE__);
1000
-			// fall through and try it the hard way
1001
-		}
1002
-		// currently not implemented "the hard way"
1003
-		$this->DebugMessage('FAILED: phpthumb_filters::Smooth($gdimg, '.$amount.') [function not implemented]', __FILE__, __LINE__);
1004
-		return false;
1005
-	}
1006
-
1007
-
1008
-	public function SourceTransparentColorMask(&$gdimg, $hexcolor, $min_limit=5, $max_limit=10) {
1009
-		$width  = imagesx($gdimg);
1010
-		$height = imagesy($gdimg);
1011
-		if ($gdimg_mask = imagecreatetruecolor($width, $height)) {
1012
-			$R = hexdec(substr($hexcolor, 0, 2));
1013
-			$G = hexdec(substr($hexcolor, 2, 2));
1014
-			$B = hexdec(substr($hexcolor, 4, 2));
1015
-			$targetPixel = array('red'=>$R, 'green'=>$G, 'blue'=>$B);
1016
-			$cutoffRange = $max_limit - $min_limit;
1017
-			for ($x = 0; $x < $width; $x++) {
1018
-				for ($y = 0; $y < $height; $y++) {
1019
-					$currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1020
-					$colorDiff = phpthumb_functions::PixelColorDifferencePercent($currentPixel, $targetPixel);
1021
-					$grayLevel = min($cutoffRange, max(0, -$min_limit + $colorDiff)) * (255 / max(1, $cutoffRange));
1022
-					$newColor = imagecolorallocate($gdimg_mask, $grayLevel, $grayLevel, $grayLevel);
1023
-					imagesetpixel($gdimg_mask, $x, $y, $newColor);
1024
-				}
1025
-			}
1026
-			return $gdimg_mask;
1027
-		}
1028
-		return false;
1029
-	}
1030
-
1031
-
1032
-	public function Threshold(&$gdimg, $cutoff) {
1033
-		$width  = imagesx($gdimg);
1034
-		$height = imagesy($gdimg);
1035
-		$cutoff = min(255, max(0, ($cutoff ? $cutoff : 128)));
1036
-		for ($x = 0; $x < $width; $x++) {
1037
-			for ($y = 0; $y < $height; $y++) {
1038
-				$currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1039
-				$grayPixel = phpthumb_functions::GrayscalePixel($currentPixel);
1040
-				if ($grayPixel['red'] < $cutoff) {
1041
-					$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0x00, 0x00, 0x00, $currentPixel['alpha']);
1042
-				} else {
1043
-					$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0xFF, 0xFF, 0xFF, $currentPixel['alpha']);
1044
-				}
1045
-				imagesetpixel($gdimg, $x, $y, $newColor);
1046
-			}
1047
-		}
1048
-		return true;
1049
-	}
1050
-
1051
-
1052
-	public function ImageTrueColorToPalette2(&$image, $dither, $ncolors) {
1053
-		// http://www.php.net/manual/en/function.imagetruecolortopalette.php
1054
-		// zmorris at zsculpt dot com (17-Aug-2004 06:58)
1055
-		$width  = imagesx($image);
1056
-		$height = imagesy($image);
1057
-		$image_copy = imagecreatetruecolor($width, $height);
1058
-		//imagecopymerge($image_copy, $image, 0, 0, 0, 0, $width, $height, 100);
1059
-		imagecopy($image_copy, $image, 0, 0, 0, 0, $width, $height);
1060
-		imagetruecolortopalette($image, $dither, $ncolors);
1061
-		imagecolormatch($image_copy, $image);
1062
-		imagedestroy($image_copy);
1063
-		return true;
1064
-	}
1065
-
1066
-	public function ReduceColorDepth(&$gdimg, $colors=256, $dither=true) {
1067
-		$colors = max(min($colors, 256), 2);
1068
-		// imagetruecolortopalette usually makes ugly colors, the replacement is a bit better
1069
-		//imagetruecolortopalette($gdimg, $dither, $colors);
1070
-		self::ImageTrueColorToPalette2($gdimg, $dither, $colors);
1071
-		return true;
1072
-	}
1073
-
1074
-
1075
-	public function WhiteBalance(&$gdimg, $targetColor='') {
1076
-		if (phpthumb_functions::IsHexColor($targetColor)) {
1077
-			$targetPixel = array(
1078
-				'red'   => hexdec(substr($targetColor, 0, 2)),
1079
-				'green' => hexdec(substr($targetColor, 2, 2)),
1080
-				'blue'  => hexdec(substr($targetColor, 4, 2))
1081
-			);
1082
-		} else {
1083
-			$Analysis = self::HistogramAnalysis($gdimg, false);
1084
-			$targetPixel = array(
1085
-				'red'   => max(array_keys($Analysis['red'])),
1086
-				'green' => max(array_keys($Analysis['green'])),
1087
-				'blue'  => max(array_keys($Analysis['blue']))
1088
-			);
1089
-		}
1090
-		$grayValue = phpthumb_functions::GrayscaleValue($targetPixel['red'], $targetPixel['green'], $targetPixel['blue']);
1091
-		$scaleR = $grayValue / $targetPixel['red'];
1092
-		$scaleG = $grayValue / $targetPixel['green'];
1093
-		$scaleB = $grayValue / $targetPixel['blue'];
1094
-
1095
-		for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
1096
-			for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
1097
-				$currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1098
-				$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe(
1099
-					$gdimg,
1100
-					max(0, min(255, round($currentPixel['red']   * $scaleR))),
1101
-					max(0, min(255, round($currentPixel['green'] * $scaleG))),
1102
-					max(0, min(255, round($currentPixel['blue']  * $scaleB))),
1103
-					$currentPixel['alpha']
1104
-				);
1105
-				imagesetpixel($gdimg, $x, $y, $newColor);
1106
-			}
1107
-		}
1108
-		return true;
1109
-	}
1110
-
1111
-
1112
-	public function WatermarkText(&$gdimg, $text, $size, $alignment, $hex_color='000000', $ttffont='', $opacity=100, $margin=5, $angle=0, $bg_color=false, $bg_opacity=0, $fillextend='', $lineheight=1.0) {
1113
-		// text watermark requested
1114
-		if (!$text) {
1115
-			return false;
1116
-		}
1117
-		imagealphablending($gdimg, true);
1118
-
1119
-		if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)(@[LCR])?$#i', $alignment, $matches)) {
1120
-			$originOffsetX = (int) $matches[ 1];
1121
-			$originOffsetY = (int) $matches[ 2];
1122
-			$alignment = (@$matches[4] ? $matches[4] : 'L');
1123
-			$margin = 0;
1124
-		} else {
1125
-			$originOffsetX = 0;
1126
-			$originOffsetY = 0;
1127
-		}
1128
-		$lineheight = min(100.0, max(0.01, (float) $lineheight));
1129
-
1130
-		$metaTextArray = array(
1131
-			'^Fb' =>       $this->phpThumbObject->getimagesizeinfo['filesize'],
1132
-			'^Fk' => round($this->phpThumbObject->getimagesizeinfo['filesize'] / 1024),
1133
-			'^Fm' => round($this->phpThumbObject->getimagesizeinfo['filesize'] / 1048576),
1134
-			'^X'  => $this->phpThumbObject->getimagesizeinfo[0],
1135
-			'^Y'  => $this->phpThumbObject->getimagesizeinfo[1],
1136
-			'^x'  => imagesx($gdimg),
1137
-			'^y'  => imagesy($gdimg),
1138
-			'^^'  => '^',
1139
-		);
1140
-		$text = strtr($text, $metaTextArray);
1141
-
1142
-		$text = str_replace(array(
1143
-			"\r\n",
1144
-			"\r"
1145
-		), "\n", $text);
1146
-		$textlines = explode("\n", $text);
1147
-		$this->DebugMessage('Processing '.count($textlines).' lines of text', __FILE__, __LINE__);
1148
-
1149
-		if (@is_readable($ttffont) && is_file($ttffont)) {
1150
-
1151
-			$opacity = 100 - (int) max(min($opacity, 100), 0);
1152
-			$letter_color_text = phpthumb_functions::ImageHexColorAllocate($gdimg, $hex_color, false, $opacity * 1.27);
1153
-
1154
-			$this->DebugMessage('Using TTF font "'.$ttffont.'"', __FILE__, __LINE__);
1155
-
1156
-			$TTFbox = imagettfbbox($size, $angle, $ttffont, $text);
1157
-
1158
-			$min_x = min($TTFbox[0], $TTFbox[2], $TTFbox[4], $TTFbox[6]);
1159
-			$max_x = max($TTFbox[0], $TTFbox[2], $TTFbox[4], $TTFbox[6]);
1160
-			//$text_width = round($max_x - $min_x + ($size * 0.5));
1161
-			$text_width = round($max_x - $min_x);
1162
-
1163
-			$min_y = min($TTFbox[1], $TTFbox[3], $TTFbox[5], $TTFbox[7]);
1164
-			$max_y = max($TTFbox[1], $TTFbox[3], $TTFbox[5], $TTFbox[7]);
1165
-			//$text_height = round($max_y - $min_y + ($size * 0.5));
1166
-			$text_height = round($max_y - $min_y);
1167
-
1168
-			$TTFboxChar = imagettfbbox($size, $angle, $ttffont, 'jH');
1169
-			$char_min_y = min($TTFboxChar[1], $TTFboxChar[3], $TTFboxChar[5], $TTFboxChar[7]);
1170
-			$char_max_y = max($TTFboxChar[1], $TTFboxChar[3], $TTFboxChar[5], $TTFboxChar[7]);
1171
-			$char_height = round($char_max_y - $char_min_y);
1172
-
1173
-			if ($alignment == '*') {
1174
-
1175
-				$text_origin_y = $char_height + $margin;
1176
-				while (($text_origin_y - $text_height) < imagesy($gdimg)) {
1177
-					$text_origin_x = $margin;
1178
-					while ($text_origin_x < imagesx($gdimg)) {
1179
-						imagettftext($gdimg, $size, $angle, $text_origin_x, $text_origin_y, $letter_color_text, $ttffont, $text);
1180
-						$text_origin_x += ($text_width + $margin);
1181
-					}
1182
-					$text_origin_y += ($text_height + $margin) * $lineheight;
1183
-				}
1184
-
1185
-			} else {
1186
-
1187
-				// this block for background color only
1188
-
1189
-				$text_origin_x = 0;
1190
-				$text_origin_y = 0;
1191
-				switch ($alignment) {
1192
-					case '*':
1193
-						// handled separately
1194
-						break;
1195
-
1196
-					case 'T':
1197
-						$text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((imagesx($gdimg) - $text_width) / 2));
1198
-						$text_origin_y = $char_height + $margin + $originOffsetY;
1199
-						break;
1200
-
1201
-					case 'B':
1202
-						$text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((imagesx($gdimg) - $text_width) / 2));
1203
-						$text_origin_y = imagesy($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1204
-						break;
1205
-
1206
-					case 'L':
1207
-						$text_origin_x = $margin + $originOffsetX;
1208
-						$text_origin_y = ($originOffsetY ? $originOffsetY : round((imagesy($gdimg) - $text_height) / 2) + $char_height);
1209
-						break;
1210
-
1211
-					case 'R':
1212
-						$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1213
-						$text_origin_y = ($originOffsetY ? $originOffsetY : round((imagesy($gdimg) - $text_height) / 2) + $char_height);
1214
-						break;
1215
-
1216
-					case 'C':
1217
-						$text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((imagesx($gdimg) - $text_width) / 2));
1218
-						$text_origin_y = ($originOffsetY ? $originOffsetY : round((imagesy($gdimg) - $text_height) / 2) + $char_height);
1219
-						break;
1220
-
1221
-					case 'TL':
1222
-						$text_origin_x = $margin + $originOffsetX;
1223
-						$text_origin_y = $char_height + $margin + $originOffsetY;
1224
-						break;
1225
-
1226
-					case 'TR':
1227
-						$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1228
-						$text_origin_y = $char_height + $margin + $originOffsetY;
1229
-						break;
1230
-
1231
-					case 'BL':
1232
-						$text_origin_x = $margin + $originOffsetX;
1233
-						$text_origin_y = imagesy($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1234
-						break;
1235
-
1236
-					case 'BR':
1237
-					default:
1238
-						$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1239
-						$text_origin_y = imagesy($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1240
-						break;
1241
-				}
1242
-
1243
-				if (phpthumb_functions::IsHexColor($bg_color)) {
1244
-					$text_background_alpha = round(127 * ((100 - min(max(0, $bg_opacity), 100)) / 100));
1245
-					$text_color_background = phpthumb_functions::ImageHexColorAllocate($gdimg, $bg_color, false, $text_background_alpha);
1246
-				} else {
1247
-					$text_color_background = phpthumb_functions::ImageHexColorAllocate($gdimg, 'FFFFFF', false, 127);
1248
-				}
1249
-				$x1 = $text_origin_x + $min_x;
1250
-				$y1 = $text_origin_y + $TTFbox[1];
1251
-				$x2 = $text_origin_x + $min_x + $text_width;
1252
-				$y2 = $text_origin_y + $TTFbox[1] - $text_height;
1253
-				$x_TL = false !== stripos($fillextend, "x") ?               0 : min($x1, $x2);
1254
-				$y_TL = false !== stripos($fillextend, "y") ?               0 : min($y1, $y2);
1255
-				$x_BR = false !== stripos($fillextend, "x") ? imagesx($gdimg) : max($x1, $x2);
1256
-				$y_BR = false !== stripos($fillextend, "y") ? imagesy($gdimg) : max($y1, $y2);
1257
-				$this->DebugMessage('WatermarkText() calling imagefilledrectangle($gdimg, '.$x_TL.', '.$y_TL.', '.$x_BR.', '.$y_BR.', $text_color_background)', __FILE__, __LINE__);
1258
-				imagefilledrectangle($gdimg, $x_TL, $y_TL, $x_BR, $y_BR, $text_color_background);
1259
-
1260
-				// end block for background color only
1261
-
1262
-
1263
-				$y_offset = 0;
1264
-				foreach ($textlines as $dummy => $line) {
1265
-
1266
-					$TTFboxLine = imagettfbbox($size, $angle, $ttffont, $line);
1267
-					$min_x_line = min($TTFboxLine[0], $TTFboxLine[2], $TTFboxLine[4], $TTFboxLine[6]);
1268
-					$max_x_line = max($TTFboxLine[0], $TTFboxLine[2], $TTFboxLine[4], $TTFboxLine[6]);
1269
-					$text_width_line = round($max_x_line - $min_x_line);
1270
-
1271
-					switch ($alignment) {
1272
-						// $text_origin_y set above, just re-set $text_origin_x here as needed
1273
-
1274
-						case 'L':
1275
-						case 'TL':
1276
-						case 'BL':
1277
-							// no change necessary
1278
-							break;
1279
-
1280
-						case 'C':
1281
-						case 'T':
1282
-						case 'B':
1283
-							$text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width_line / 2) : round((imagesx($gdimg) - $text_width_line) / 2));
1284
-							break;
1285
-
1286
-						case 'R':
1287
-						case 'TR':
1288
-						case 'BR':
1289
-							$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width_line : imagesx($gdimg) - $text_width_line  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1290
-							break;
1291
-					}
1292
-
1293
-					//imagettftext($gdimg, $size, $angle, $text_origin_x, $text_origin_y, $letter_color_text, $ttffont, $text);
1294
-					$this->DebugMessage('WatermarkText() calling imagettftext($gdimg, '.$size.', '.$angle.', '.$text_origin_x.', '.($text_origin_y + $y_offset).', $letter_color_text, '.$ttffont.', '.$line.')', __FILE__, __LINE__);
1295
-					imagettftext($gdimg, $size, $angle, $text_origin_x, $text_origin_y + $y_offset, $letter_color_text, $ttffont, $line);
1296
-
1297
-					$y_offset += $char_height * $lineheight;
1298
-				}
1299
-
1300
-			}
1301
-			return true;
1302
-
1303
-		} else {
1304
-
1305
-			$size = min(5, max(1, $size));
1306
-			$this->DebugMessage('Using built-in font (size='.$size.') for text watermark'.($ttffont ? ' because $ttffont !is_readable('.$ttffont.')' : ''), __FILE__, __LINE__);
1307
-
1308
-			$text_width  = 0;
1309
-			$text_height = 0;
1310
-			foreach ($textlines as $dummy => $line) {
1311
-				$text_width   = max($text_width, imagefontwidth($size) * strlen($line));
1312
-				$text_height += imagefontheight($size);
1313
-			}
1314
-			if ($img_watermark = phpthumb_functions::ImageCreateFunction($text_width, $text_height)) {
1315
-				imagealphablending($img_watermark, false);
1316
-				if (phpthumb_functions::IsHexColor($bg_color)) {
1317
-					$text_background_alpha = round(127 * ((100 - min(max(0, $bg_opacity), 100)) / 100));
1318
-					$text_color_background = phpthumb_functions::ImageHexColorAllocate($img_watermark, $bg_color, false, $text_background_alpha);
1319
-				} else {
1320
-					$text_color_background = phpthumb_functions::ImageHexColorAllocate($img_watermark, 'FFFFFF', false, 127);
1321
-				}
1322
-				$this->DebugMessage('WatermarkText() calling imagefilledrectangle($img_watermark, 0, 0, '.imagesx($img_watermark).', '.imagesy($img_watermark).', $text_color_background)', __FILE__, __LINE__);
1323
-				imagefilledrectangle($img_watermark, 0, 0, imagesx($img_watermark), imagesy($img_watermark), $text_color_background);
1324
-
1325
-				$img_watermark_mask    = false;
1326
-				$mask_color_background = false;
1327
-				$mask_color_watermark  = false;
1328
-				if ($angle && function_exists('imagerotate')) {
1329
-					// using $img_watermark_mask is pointless if imagerotate function isn't available
1330
-					if ($img_watermark_mask = phpthumb_functions::ImageCreateFunction($text_width, $text_height)) {
1331
-						$mask_color_background = imagecolorallocate($img_watermark_mask, 0, 0, 0);
1332
-						imagealphablending($img_watermark_mask, false);
1333
-						imagefilledrectangle($img_watermark_mask, 0, 0, imagesx($img_watermark_mask), imagesy($img_watermark_mask), $mask_color_background);
1334
-						$mask_color_watermark = imagecolorallocate($img_watermark_mask, 255, 255, 255);
1335
-					}
1336
-				}
1337
-
1338
-				$text_color_watermark = phpthumb_functions::ImageHexColorAllocate($img_watermark, $hex_color);
1339
-				$x_offset = 0;
1340
-				foreach ($textlines as $key => $line) {
1341
-					switch ($alignment) {
1342
-						case 'C':
1343
-							$x_offset = round(($text_width - (imagefontwidth($size) * strlen($line))) / 2);
1344
-							$originOffsetX = (imagesx($gdimg) - imagesx($img_watermark)) / 2;
1345
-							$originOffsetY = (imagesy($gdimg) - imagesy($img_watermark)) / 2;
1346
-							break;
1347
-
1348
-						case 'T':
1349
-							$x_offset = round(($text_width - (imagefontwidth($size) * strlen($line))) / 2);
1350
-							$originOffsetX = (imagesx($gdimg) - imagesx($img_watermark)) / 2;
1351
-							$originOffsetY = $margin;
1352
-							break;
1353
-
1354
-						case 'B':
1355
-							$x_offset = round(($text_width - (imagefontwidth($size) * strlen($line))) / 2);
1356
-							$originOffsetX = (imagesx($gdimg) - imagesx($img_watermark)) / 2;
1357
-							$originOffsetY = imagesy($gdimg) - imagesy($img_watermark) - $margin;
1358
-							break;
1359
-
1360
-						case 'L':
1361
-							$x_offset = 0;
1362
-							$originOffsetX = $margin;
1363
-							$originOffsetY = (imagesy($gdimg) - imagesy($img_watermark)) / 2;
1364
-							break;
1365
-
1366
-						case 'TL':
1367
-							$x_offset = 0;
1368
-							$originOffsetX = $margin;
1369
-							$originOffsetY = $margin;
1370
-							break;
1371
-
1372
-						case 'BL':
1373
-							$x_offset = 0;
1374
-							$originOffsetX = $margin;
1375
-							$originOffsetY = imagesy($gdimg) - imagesy($img_watermark) - $margin;
1376
-							break;
1377
-
1378
-						case 'R':
1379
-							$x_offset = $text_width - (imagefontwidth($size) * strlen($line));
1380
-							$originOffsetX = imagesx($gdimg) - imagesx($img_watermark) - $margin;
1381
-							$originOffsetY = (imagesy($gdimg) - imagesy($img_watermark)) / 2;
1382
-							break;
1383
-
1384
-						case 'TR':
1385
-							$x_offset = $text_width - (imagefontwidth($size) * strlen($line));
1386
-							$originOffsetX = imagesx($gdimg) - imagesx($img_watermark) - $margin;
1387
-							$originOffsetY = $margin;
1388
-							break;
1389
-
1390
-						case 'BR':
1391
-						default:
1392
-							if (!empty($originOffsetX) || !empty($originOffsetY)) {
1393
-								// absolute pixel positioning
1394
-							} else {
1395
-								$x_offset = $text_width - (imagefontwidth($size) * strlen($line));
1396
-								$originOffsetX = imagesx($gdimg) - imagesx($img_watermark) - $margin;
1397
-								$originOffsetY = imagesy($gdimg) - imagesy($img_watermark) - $margin;
1398
-							}
1399
-							break;
1400
-					}
1401
-					$this->DebugMessage('WatermarkText() calling imagestring($img_watermark, '.$size.', '.$x_offset.', '.($key * imagefontheight($size)).', '.$line.', $text_color_watermark)', __FILE__, __LINE__);
1402
-					imagestring($img_watermark, $size, $x_offset, $key * imagefontheight($size), $line, $text_color_watermark);
1403
-					if ($angle && $img_watermark_mask) {
1404
-						$this->DebugMessage('WatermarkText() calling imagestring($img_watermark_mask, '.$size.', '.$x_offset.', '.($key * imagefontheight($size) * $lineheight).', '.$text.', $mask_color_watermark)', __FILE__, __LINE__);
1405
-						imagestring($img_watermark_mask, $size, $x_offset, $key * imagefontheight($size) * $lineheight, $text, $mask_color_watermark);
1406
-					}
1407
-				}
1408
-				if ($angle && $img_watermark_mask) {
1409
-					$img_watermark      = imagerotate($img_watermark,      $angle, $text_color_background);
1410
-					$img_watermark_mask = imagerotate($img_watermark_mask, $angle, $mask_color_background);
1411
-					self::ApplyMask($img_watermark_mask, $img_watermark);
1412
-				}
1413
-				//phpthumb_filters::WatermarkOverlay($gdimg, $img_watermark, $alignment, $opacity, $margin);
1414
-				$this->DebugMessage('WatermarkText() calling phpthumb_filters::WatermarkOverlay($gdimg, $img_watermark, '.($originOffsetX.'x'.$originOffsetY).', '.$opacity.', 0)', __FILE__, __LINE__);
1415
-				self::WatermarkOverlay($gdimg, $img_watermark, $originOffsetX.'x'.$originOffsetY, $opacity, 0);
1416
-				imagedestroy($img_watermark);
1417
-				return true;
1418
-			}
1419
-
1420
-		}
1421
-		return false;
1422
-	}
1423
-
1424
-
1425
-	public function WatermarkOverlay(&$gdimg_dest, &$img_watermark, $alignment='*', $opacity=50, $margin_x=5, $margin_y=null) {
1426
-
1427
-		if (is_resource($gdimg_dest) && is_resource($img_watermark)) {
1428
-			$img_source_width          = imagesx($gdimg_dest);
1429
-			$img_source_height         = imagesy($gdimg_dest);
1430
-			$watermark_source_width    = imagesx($img_watermark);
1431
-			$watermark_source_height   = imagesy($img_watermark);
1432
-			$watermark_opacity_percent = max(0, min(100, $opacity));
1433
-			$margin_y = (null === $margin_y ? $margin_x : $margin_y);
1434
-			$watermark_margin_x = ((($margin_x > 0) && ($margin_x < 1)) ? round((1 - $margin_x) * $img_source_width)  : $margin_x);
1435
-			$watermark_margin_y = ((($margin_y > 0) && ($margin_y < 1)) ? round((1 - $margin_y) * $img_source_height) : $margin_y);
1436
-			$watermark_destination_x = 0;
1437
-			$watermark_destination_y = 0;
1438
-			if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
1439
-				$watermark_destination_x = (int) $matches[ 1];
1440
-				$watermark_destination_y = (int) $matches[ 2];
1441
-			} else {
1442
-				switch ($alignment) {
1443
-					case '*':
1444
-						if ($gdimg_tiledwatermark = phpthumb_functions::ImageCreateFunction($img_source_width, $img_source_height)) {
1445
-
1446
-							imagealphablending($gdimg_tiledwatermark, false);
1447
-							imagesavealpha($gdimg_tiledwatermark, true);
1448
-							$text_color_transparent = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_tiledwatermark, 255, 0, 255, 127);
1449
-							imagefill($gdimg_tiledwatermark, 0, 0, $text_color_transparent);
1450
-
1451
-							// set the tiled image transparent color to whatever the untiled image transparency index is
1452
-	//						imagecolortransparent($gdimg_tiledwatermark, imagecolortransparent($img_watermark));
1453
-
1454
-							// a "cleaner" way of doing it, but can't handle the margin feature :(
1455
-	//						imagesettile($gdimg_tiledwatermark, $img_watermark);
1456
-	//						imagefill($gdimg_tiledwatermark, 0, 0, IMG_COLOR_TILED);
1457
-	//						break;
1458
-
1459
-	//						imagefill($gdimg_tiledwatermark, 0, 0, imagecolortransparent($gdimg_tiledwatermark));
1460
-							// tile the image as many times as can fit
1461
-							for ($x = $watermark_margin_x; $x < ($img_source_width + $watermark_source_width); $x += ($watermark_source_width + $watermark_margin_x)) {
1462
-								for ($y = $watermark_margin_y; $y < ($img_source_height + $watermark_source_height); $y += ($watermark_source_height + $watermark_margin_y)) {
1463
-									imagecopy(
1464
-										$gdimg_tiledwatermark,
1465
-										$img_watermark,
1466
-										$x,
1467
-										$y,
1468
-										0,
1469
-										0,
1470
-										min($watermark_source_width,  $img_source_width  - $x - $watermark_margin_x),
1471
-										min($watermark_source_height, $img_source_height - $y - $watermark_margin_y)
1472
-									);
1473
-								}
1474
-							}
1475
-
1476
-							$watermark_source_width  = imagesx($gdimg_tiledwatermark);
1477
-							$watermark_source_height = imagesy($gdimg_tiledwatermark);
1478
-							$watermark_destination_x = 0;
1479
-							$watermark_destination_y = 0;
1480
-
1481
-							imagedestroy($img_watermark);
1482
-							$img_watermark = $gdimg_tiledwatermark;
1483
-						}
1484
-						break;
1485
-
1486
-					case 'T':
1487
-						$watermark_destination_x = round((($img_source_width  / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1488
-						$watermark_destination_y = $watermark_margin_y;
1489
-						break;
1490
-
1491
-					case 'B':
1492
-						$watermark_destination_x = round((($img_source_width  / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1493
-						$watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1494
-						break;
1495
-
1496
-					case 'L':
1497
-						$watermark_destination_x = $watermark_margin_x;
1498
-						$watermark_destination_y = round((($img_source_height / 2) - ($watermark_source_height / 2)) + $watermark_margin_y);
1499
-						break;
1500
-
1501
-					case 'R':
1502
-						$watermark_destination_x = $img_source_width - $watermark_source_width - $watermark_margin_x;
1503
-						$watermark_destination_y = round((($img_source_height / 2) - ($watermark_source_height / 2)) + $watermark_margin_y);
1504
-						break;
1505
-
1506
-					case 'C':
1507
-						$watermark_destination_x = round(($img_source_width  / 2) - ($watermark_source_width  / 2));
1508
-						$watermark_destination_y = round(($img_source_height / 2) - ($watermark_source_height / 2));
1509
-						break;
1510
-
1511
-					case 'TL':
1512
-						$watermark_destination_x = $watermark_margin_x;
1513
-						$watermark_destination_y = $watermark_margin_y;
1514
-						break;
1515
-
1516
-					case 'TR':
1517
-						$watermark_destination_x = $img_source_width - $watermark_source_width - $watermark_margin_x;
1518
-						$watermark_destination_y = $watermark_margin_y;
1519
-						break;
1520
-
1521
-					case 'BL':
1522
-						$watermark_destination_x = $watermark_margin_x;
1523
-						$watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1524
-						break;
1525
-
1526
-					case 'BR':
1527
-					default:
1528
-						$watermark_destination_x = $img_source_width  - $watermark_source_width  - $watermark_margin_x;
1529
-						$watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1530
-						break;
1531
-				}
1532
-			}
1533
-			imagealphablending($gdimg_dest, false);
1534
-			imagesavealpha($gdimg_dest, true);
1535
-			imagesavealpha($img_watermark, true);
1536
-			phpthumb_functions::ImageCopyRespectAlpha($gdimg_dest, $img_watermark, $watermark_destination_x, $watermark_destination_y, 0, 0, $watermark_source_width, $watermark_source_height, $watermark_opacity_percent);
1537
-
1538
-			return true;
1539
-		}
1540
-		return false;
1541
-	}
98
+    public function Blur(&$gdimg, $radius=0.5) {
99
+        // Taken from Torstein Hønsi's phpUnsharpMask (see phpthumb.unsharp.php)
100
+
101
+        $radius = round(max(0, min($radius, 50)) * 2);
102
+        if (!$radius) {
103
+            return false;
104
+        }
105
+
106
+        $w = imagesx($gdimg);
107
+        $h = imagesy($gdimg);
108
+        if ($imgBlur = imagecreatetruecolor($w, $h)) {
109
+            // Gaussian blur matrix:
110
+            //	1	2	1
111
+            //	2	4	2
112
+            //	1	2	1
113
+
114
+            // Move copies of the image around one pixel at the time and merge them with weight
115
+            // according to the matrix. The same matrix is simply repeated for higher radii.
116
+            for ($i = 0; $i < $radius; $i++)	{
117
+                imagecopy     ($imgBlur, $gdimg, 0, 0, 1, 1, $w - 1, $h - 1);            // up left
118
+                imagecopymerge($imgBlur, $gdimg, 1, 1, 0, 0, $w,     $h,     50.00000);  // down right
119
+                imagecopymerge($imgBlur, $gdimg, 0, 1, 1, 0, $w - 1, $h,     33.33333);  // down left
120
+                imagecopymerge($imgBlur, $gdimg, 1, 0, 0, 1, $w,     $h - 1, 25.00000);  // up right
121
+                imagecopymerge($imgBlur, $gdimg, 0, 0, 1, 0, $w - 1, $h,     33.33333);  // left
122
+                imagecopymerge($imgBlur, $gdimg, 1, 0, 0, 0, $w,     $h,     25.00000);  // right
123
+                imagecopymerge($imgBlur, $gdimg, 0, 0, 0, 1, $w,     $h - 1, 20.00000);  // up
124
+                imagecopymerge($imgBlur, $gdimg, 0, 1, 0, 0, $w,     $h,     16.666667); // down
125
+                imagecopymerge($imgBlur, $gdimg, 0, 0, 0, 0, $w,     $h,     50.000000); // center
126
+                imagecopy     ($gdimg, $imgBlur, 0, 0, 0, 0, $w,     $h);
127
+            }
128
+            return true;
129
+        }
130
+        return false;
131
+    }
132
+
133
+
134
+    public function BlurGaussian(&$gdimg) {
135
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
136
+            if (imagefilter($gdimg, IMG_FILTER_GAUSSIAN_BLUR)) {
137
+                return true;
138
+            }
139
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_GAUSSIAN_BLUR)', __FILE__, __LINE__);
140
+            // fall through and try it the hard way
141
+        }
142
+        $this->DebugMessage('FAILED: phpthumb_filters::BlurGaussian($gdimg) [using phpthumb_filters::Blur() instead]', __FILE__, __LINE__);
143
+        return self::Blur($gdimg, 0.5);
144
+    }
145
+
146
+
147
+    public function BlurSelective(&$gdimg) {
148
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
149
+            if (imagefilter($gdimg, IMG_FILTER_SELECTIVE_BLUR)) {
150
+                return true;
151
+            }
152
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_SELECTIVE_BLUR)', __FILE__, __LINE__);
153
+            // fall through and try it the hard way
154
+        }
155
+        // currently not implemented "the hard way"
156
+        $this->DebugMessage('FAILED: phpthumb_filters::BlurSelective($gdimg) [function not implemented]', __FILE__, __LINE__);
157
+        return false;
158
+    }
159
+
160
+
161
+    public function Brightness(&$gdimg, $amount=0) {
162
+        if ($amount == 0) {
163
+            return true;
164
+        }
165
+        $amount = max(-255, min(255, $amount));
166
+
167
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
168
+            if (imagefilter($gdimg, IMG_FILTER_BRIGHTNESS, $amount)) {
169
+                return true;
170
+            }
171
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_BRIGHTNESS, '.$amount.')', __FILE__, __LINE__);
172
+            // fall through and try it the hard way
173
+        }
174
+
175
+        $scaling = (255 - abs($amount)) / 255;
176
+        $baseamount = (($amount > 0) ? $amount : 0);
177
+        for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
178
+            for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
179
+                $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
180
+                $NewPixel = array();
181
+                foreach ($OriginalPixel as $key => $value) {
182
+                    $NewPixel[$key] = round($baseamount + ($OriginalPixel[$key] * $scaling));
183
+                }
184
+                $newColor = imagecolorallocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
185
+                imagesetpixel($gdimg, $x, $y, $newColor);
186
+            }
187
+        }
188
+        return true;
189
+    }
190
+
191
+
192
+    public function Contrast(&$gdimg, $amount=0) {
193
+        if ($amount == 0) {
194
+            return true;
195
+        }
196
+        $amount = max(-255, min(255, $amount));
197
+
198
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
199
+            // imagefilter(IMG_FILTER_CONTRAST) has range +100 to -100 (positive numbers make it darker!)
200
+            $amount = ($amount / 255) * -100;
201
+            if (imagefilter($gdimg, IMG_FILTER_CONTRAST, $amount)) {
202
+                return true;
203
+            }
204
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_CONTRAST, '.$amount.')', __FILE__, __LINE__);
205
+            // fall through and try it the hard way
206
+        }
207
+
208
+        if ($amount > 0) {
209
+            $scaling = 1 + ($amount / 255);
210
+        } else {
211
+            $scaling = (255 - abs($amount)) / 255;
212
+        }
213
+        for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
214
+            for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
215
+                $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
216
+                $NewPixel = array();
217
+                foreach ($OriginalPixel as $key => $value) {
218
+                    $NewPixel[$key] = min(255, max(0, round($OriginalPixel[$key] * $scaling)));
219
+                }
220
+                $newColor = imagecolorallocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
221
+                imagesetpixel($gdimg, $x, $y, $newColor);
222
+            }
223
+        }
224
+        return true;
225
+    }
226
+
227
+
228
+    public function Colorize(&$gdimg, $amount, $targetColor) {
229
+        $amount      = (is_numeric($amount)                          ? $amount      : 25);
230
+        $amountPct   = $amount / 100;
231
+        $targetColor = (phpthumb_functions::IsHexColor($targetColor) ? $targetColor : 'gray');
232
+
233
+        if ($amount == 0) {
234
+            return true;
235
+        }
236
+
237
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
238
+            if ($targetColor == 'gray') {
239
+                $targetColor = '808080';
240
+            }
241
+            $r = round($amountPct * hexdec(substr($targetColor, 0, 2)));
242
+            $g = round($amountPct * hexdec(substr($targetColor, 2, 2)));
243
+            $b = round($amountPct * hexdec(substr($targetColor, 4, 2)));
244
+            if (imagefilter($gdimg, IMG_FILTER_COLORIZE, $r, $g, $b)) {
245
+                return true;
246
+            }
247
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_COLORIZE)', __FILE__, __LINE__);
248
+            // fall through and try it the hard way
249
+        }
250
+
251
+        // overridden below for grayscale
252
+        $TargetPixel = array();
253
+        if ($targetColor != 'gray') {
254
+            $TargetPixel['red']   = hexdec(substr($targetColor, 0, 2));
255
+            $TargetPixel['green'] = hexdec(substr($targetColor, 2, 2));
256
+            $TargetPixel['blue']  = hexdec(substr($targetColor, 4, 2));
257
+        }
258
+
259
+        for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
260
+            for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
261
+                $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
262
+                if ($targetColor == 'gray') {
263
+                    $TargetPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
264
+                }
265
+                $NewPixel = array();
266
+                foreach ($TargetPixel as $key => $value) {
267
+                    $NewPixel[$key] = round(max(0, min(255, ($OriginalPixel[$key] * ((100 - $amount) / 100)) + ($TargetPixel[$key] * $amountPct))));
268
+                }
269
+                //$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue'], $OriginalPixel['alpha']);
270
+                $newColor = imagecolorallocate($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue']);
271
+                imagesetpixel($gdimg, $x, $y, $newColor);
272
+            }
273
+        }
274
+        return true;
275
+    }
276
+
277
+
278
+    public function Crop(&$gdimg, $left=0, $right=0, $top=0, $bottom=0) {
279
+        if (!$left && !$right && !$top && !$bottom) {
280
+            return true;
281
+        }
282
+        $oldW = imagesx($gdimg);
283
+        $oldH = imagesy($gdimg);
284
+        if (($left   > 0) && ($left   < 1)) { $left   = round($left   * $oldW); }
285
+        if (($right  > 0) && ($right  < 1)) { $right  = round($right  * $oldW); }
286
+        if (($top    > 0) && ($top    < 1)) { $top    = round($top    * $oldH); }
287
+        if (($bottom > 0) && ($bottom < 1)) { $bottom = round($bottom * $oldH); }
288
+        $right  = min($oldW - $left - 1, $right);
289
+        $bottom = min($oldH - $top  - 1, $bottom);
290
+        $newW = $oldW - $left - $right;
291
+        $newH = $oldH - $top  - $bottom;
292
+
293
+        if ($imgCropped = imagecreatetruecolor($newW, $newH)) {
294
+            imagecopy($imgCropped, $gdimg, 0, 0, $left, $top, $newW, $newH);
295
+            if ($gdimg = imagecreatetruecolor($newW, $newH)) {
296
+                imagecopy($gdimg, $imgCropped, 0, 0, 0, 0, $newW, $newH);
297
+                imagedestroy($imgCropped);
298
+                return true;
299
+            }
300
+            imagedestroy($imgCropped);
301
+        }
302
+        return false;
303
+    }
304
+
305
+
306
+    public function Desaturate(&$gdimg, $amount, $color='') {
307
+        if ($amount == 0) {
308
+            return true;
309
+        }
310
+        return self::Colorize($gdimg, $amount, (phpthumb_functions::IsHexColor($color) ? $color : 'gray'));
311
+    }
312
+
313
+
314
+    public function DropShadow(&$gdimg, $distance, $width, $hexcolor, $angle, $alpha) {
315
+        if (phpthumb_functions::gd_version() < 2) {
316
+            return false;
317
+        }
318
+        $distance =                 ($distance ? $distance : 10);
319
+        $width    =                 ($width    ? $width    : 10);
320
+        $hexcolor =                 ($hexcolor ? $hexcolor : '000000');
321
+        $angle    =                 ($angle    ? $angle    : 225) % 360;
322
+        $alpha    = max(0, min(100, ($alpha    ? $alpha    : 100)));
323
+
324
+        if ($alpha <= 0) {
325
+            // invisible shadow, nothing to do
326
+            return true;
327
+        }
328
+        if ($distance <= 0) {
329
+            // shadow completely obscured by source image, nothing to do
330
+            return true;
331
+        }
332
+
333
+        //$width_shadow  = cos(deg2rad($angle)) * ($distance + $width);
334
+        //$height_shadow = sin(deg2rad($angle)) * ($distance + $width);
335
+        //$scaling = min(imagesx($gdimg) / (imagesx($gdimg) + abs($width_shadow)), imagesy($gdimg) / (imagesy($gdimg) + abs($height_shadow)));
336
+
337
+        $Offset = array();
338
+        for ($i = 0; $i < $width; $i++) {
339
+            $WidthAlpha[$i] = (abs(($width / 2) - $i) / $width);
340
+            $Offset['x'] = cos(deg2rad($angle)) * ($distance + $i);
341
+            $Offset['y'] = sin(deg2rad($angle)) * ($distance + $i);
342
+        }
343
+
344
+        $tempImageWidth  = imagesx($gdimg)  + abs($Offset['x']);
345
+        $tempImageHeight = imagesy($gdimg) + abs($Offset['y']);
346
+
347
+        if ($gdimg_dropshadow_temp = phpthumb_functions::ImageCreateFunction($tempImageWidth, $tempImageHeight)) {
348
+
349
+            imagealphablending($gdimg_dropshadow_temp, false);
350
+            imagesavealpha($gdimg_dropshadow_temp, true);
351
+            $transparent1 = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_dropshadow_temp, 0, 0, 0, 127);
352
+            imagefill($gdimg_dropshadow_temp, 0, 0, $transparent1);
353
+
354
+            $PixelMap = array();
355
+            for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
356
+                for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
357
+                    $PixelMap[$x][$y] = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
358
+                }
359
+            }
360
+            for ($x = 0; $x < $tempImageWidth; $x++) {
361
+                for ($y = 0; $y < $tempImageHeight; $y++) {
362
+                    //for ($i = 0; $i < $width; $i++) {
363
+                    for ($i = 0; $i < 1; $i++) {
364
+                        if (!isset($PixelMap[$x][$y]['alpha']) || ($PixelMap[$x][$y]['alpha'] > 0)) {
365
+                            if (isset($PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha']) && ($PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha'] < 127)) {
366
+                                $thisColor = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor, false, $PixelMap[$x + $Offset['x']][$y + $Offset['y']]['alpha']);
367
+                                imagesetpixel($gdimg_dropshadow_temp, $x, $y, $thisColor);
368
+                            }
369
+                        }
370
+                    }
371
+                }
372
+            }
373
+
374
+            imagealphablending($gdimg_dropshadow_temp, true);
375
+            for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
376
+                for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
377
+                    if ($PixelMap[$x][$y]['alpha'] < 127) {
378
+                        $thisColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_dropshadow_temp, $PixelMap[$x][$y]['red'], $PixelMap[$x][$y]['green'], $PixelMap[$x][$y]['blue'], $PixelMap[$x][$y]['alpha']);
379
+                        imagesetpixel($gdimg_dropshadow_temp, $x, $y, $thisColor);
380
+                    }
381
+                }
382
+            }
383
+
384
+            imagesavealpha($gdimg, true);
385
+            imagealphablending($gdimg, false);
386
+            //$this->is_alpha = true;
387
+            $transparent2 = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0, 0, 0, 127);
388
+            imagefilledrectangle($gdimg, 0, 0, imagesx($gdimg), imagesy($gdimg), $transparent2);
389
+            imagecopyresampled($gdimg, $gdimg_dropshadow_temp, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg), imagesx($gdimg_dropshadow_temp), imagesy($gdimg_dropshadow_temp));
390
+
391
+            imagedestroy($gdimg_dropshadow_temp);
392
+        }
393
+        return true;
394
+    }
395
+
396
+
397
+    public function EdgeDetect(&$gdimg) {
398
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
399
+            if (imagefilter($gdimg, IMG_FILTER_EDGEDETECT)) {
400
+                return true;
401
+            }
402
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_EDGEDETECT)', __FILE__, __LINE__);
403
+            // fall through and try it the hard way
404
+        }
405
+        // currently not implemented "the hard way"
406
+        $this->DebugMessage('FAILED: phpthumb_filters::EdgeDetect($gdimg) [function not implemented]', __FILE__, __LINE__);
407
+        return false;
408
+    }
409
+
410
+
411
+    public function Ellipse($gdimg) {
412
+        if (phpthumb_functions::gd_version() < 2) {
413
+            return false;
414
+        }
415
+        // generate mask at twice desired resolution and downsample afterwards for easy antialiasing
416
+        if ($gdimg_ellipsemask_double = phpthumb_functions::ImageCreateFunction(imagesx($gdimg) * 2, imagesy($gdimg) * 2)) {
417
+            if ($gdimg_ellipsemask = phpthumb_functions::ImageCreateFunction(imagesx($gdimg), imagesy($gdimg))) {
418
+
419
+                $color_transparent = imagecolorallocate($gdimg_ellipsemask_double, 255, 255, 255);
420
+                imagefilledellipse($gdimg_ellipsemask_double, imagesx($gdimg), imagesy($gdimg), (imagesx($gdimg) - 1) * 2, (imagesy($gdimg) - 1) * 2, $color_transparent);
421
+                imagecopyresampled($gdimg_ellipsemask, $gdimg_ellipsemask_double, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg), imagesx($gdimg) * 2, imagesy($gdimg) * 2);
422
+
423
+                self::ApplyMask($gdimg_ellipsemask, $gdimg);
424
+                imagedestroy($gdimg_ellipsemask);
425
+                return true;
426
+
427
+            } else {
428
+                $this->DebugMessage('$gdimg_ellipsemask = phpthumb_functions::ImageCreateFunction() failed', __FILE__, __LINE__);
429
+            }
430
+            imagedestroy($gdimg_ellipsemask_double);
431
+        } else {
432
+            $this->DebugMessage('$gdimg_ellipsemask_double = phpthumb_functions::ImageCreateFunction() failed', __FILE__, __LINE__);
433
+        }
434
+        return false;
435
+    }
436
+
437
+
438
+    public function Emboss(&$gdimg) {
439
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
440
+            if (imagefilter($gdimg, IMG_FILTER_EMBOSS)) {
441
+                return true;
442
+            }
443
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_EMBOSS)', __FILE__, __LINE__);
444
+            // fall through and try it the hard way
445
+        }
446
+        // currently not implemented "the hard way"
447
+        $this->DebugMessage('FAILED: phpthumb_filters::Emboss($gdimg) [function not implemented]', __FILE__, __LINE__);
448
+        return false;
449
+    }
450
+
451
+
452
+    public function Flip(&$gdimg, $x=false, $y=false) {
453
+        if (!$x && !$y) {
454
+            return false;
455
+        }
456
+        if ($tempImage = phpthumb_functions::ImageCreateFunction(imagesx($gdimg), imagesy($gdimg))) {
457
+            if ($x) {
458
+                imagecopy($tempImage, $gdimg, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg));
459
+                for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
460
+                    imagecopy($gdimg, $tempImage, imagesx($gdimg) - 1 - $x, 0, $x, 0, 1, imagesy($gdimg));
461
+                }
462
+            }
463
+            if ($y) {
464
+                imagecopy($tempImage, $gdimg, 0, 0, 0, 0, imagesx($gdimg), imagesy($gdimg));
465
+                for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
466
+                    imagecopy($gdimg, $tempImage, 0, imagesy($gdimg) - 1 - $y, 0, $y, imagesx($gdimg), 1);
467
+                }
468
+            }
469
+            imagedestroy($tempImage);
470
+        }
471
+        return true;
472
+    }
473
+
474
+
475
+    public function Frame(&$gdimg, $frame_width, $edge_width, $hexcolor_frame, $hexcolor1, $hexcolor2) {
476
+        $frame_width    = ($frame_width    ? $frame_width    : 5);
477
+        $edge_width     = ($edge_width     ? $edge_width     : 1);
478
+        $hexcolor_frame = ($hexcolor_frame ? $hexcolor_frame : 'CCCCCC');
479
+        $hexcolor1      = ($hexcolor1      ? $hexcolor1      : 'FFFFFF');
480
+        $hexcolor2      = ($hexcolor2      ? $hexcolor2      : '000000');
481
+
482
+        $color_frame = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor_frame);
483
+        $color1      = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor1);
484
+        $color2      = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor2);
485
+        for ($i = 0; $i < $edge_width; $i++) {
486
+            // outer bevel
487
+            imageline($gdimg,                   $i,                   $i,                   $i, imagesy($gdimg) - $i, $color1); // left
488
+            imageline($gdimg,                   $i,                   $i, imagesx($gdimg) - $i,                   $i, $color1); // top
489
+            imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i, imagesx($gdimg) - $i,                   $i, $color2); // right
490
+            imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i,                   $i, imagesy($gdimg) - $i, $color2); // bottom
491
+        }
492
+        for ($i = 0; $i < $frame_width; $i++) {
493
+            // actual frame
494
+            imagerectangle($gdimg, $edge_width + $i, $edge_width + $i, imagesx($gdimg) - $edge_width - $i, imagesy($gdimg) - $edge_width - $i, $color_frame);
495
+        }
496
+        for ($i = 0; $i < $edge_width; $i++) {
497
+            // inner bevel
498
+            imageline($gdimg,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $color2); // left
499
+            imageline($gdimg,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i, imagesx($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, $color2); // top
500
+            imageline($gdimg, imagesx($gdimg) - $frame_width - $edge_width - $i, imagesy($gdimg) - $frame_width - $edge_width - $i, imagesx($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, $color1); // right
501
+            imageline($gdimg, imagesx($gdimg) - $frame_width - $edge_width - $i, imagesy($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $color1); // bottom
502
+        }
503
+        return true;
504
+    }
505
+
506
+
507
+    public function Gamma(&$gdimg, $amount) {
508
+        if (number_format($amount, 4) == '1.0000') {
509
+            return true;
510
+        }
511
+        return imagegammacorrect($gdimg, 1.0, $amount);
512
+    }
513
+
514
+
515
+    public function Grayscale(&$gdimg) {
516
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
517
+            if (imagefilter($gdimg, IMG_FILTER_GRAYSCALE)) {
518
+                return true;
519
+            }
520
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_GRAYSCALE)', __FILE__, __LINE__);
521
+            // fall through and try it the hard way
522
+        }
523
+        return self::Colorize($gdimg, 100, 'gray');
524
+    }
525
+
526
+
527
+    public function HistogramAnalysis(&$gdimg, $calculateGray=false) {
528
+        $ImageSX = imagesx($gdimg);
529
+        $ImageSY = imagesy($gdimg);
530
+        $Analysis = array();
531
+        for ($x = 0; $x < $ImageSX; $x++) {
532
+            for ($y = 0; $y < $ImageSY; $y++) {
533
+                $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
534
+                @$Analysis['red'][$OriginalPixel['red']]++;
535
+                @$Analysis['green'][$OriginalPixel['green']]++;
536
+                @$Analysis['blue'][$OriginalPixel['blue']]++;
537
+                @$Analysis['alpha'][$OriginalPixel['alpha']]++;
538
+                if ($calculateGray) {
539
+                    $GrayPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
540
+                    @$Analysis['gray'][$GrayPixel['red']]++;
541
+                }
542
+            }
543
+        }
544
+        $keys = array('red', 'green', 'blue', 'alpha');
545
+        if ($calculateGray) {
546
+            $keys[] = 'gray';
547
+        }
548
+        foreach ($keys as $dummy => $key) {
549
+            ksort($Analysis[$key]);
550
+        }
551
+        return $Analysis;
552
+    }
553
+
554
+
555
+    public function HistogramStretch(&$gdimg, $band='*', $method=0, $threshold=0.1) {
556
+        // equivalent of "Auto Contrast" in Adobe Photoshop
557
+        // method 0 stretches according to RGB colors. Gives a more conservative stretch.
558
+        // method 1 band stretches according to grayscale which is color-biased (59% green, 30% red, 11% blue). May give a punchier / more aggressive stretch, possibly appearing over-saturated
559
+        $Analysis = self::HistogramAnalysis($gdimg, true);
560
+        $keys = array('r'=>'red', 'g'=>'green', 'b'=>'blue', 'a'=>'alpha', '*'=>(($method == 0) ? 'all' : 'gray'));
561
+        $band = $band[ 0 ];
562
+        if (!isset($keys[$band])) {
563
+            return false;
564
+        }
565
+        $key = $keys[$band];
566
+
567
+        // If the absolute brightest and darkest pixels are used then one random
568
+        // pixel in the image could throw off the whole system. Instead, count up/down
569
+        // from the limit and allow <threshold> (default = 0.1%) of brightest/darkest
570
+        // pixels to be clipped to min/max
571
+        $threshold = (float) $threshold / 100;
572
+        $clip_threshold = imagesx($gdimg) * imagesx($gdimg) * $threshold;
573
+
574
+        $countsum  = 0;
575
+        $range_min = 0;
576
+        for ($i = 0; $i <= 255; $i++) {
577
+            if ($method == 0) {
578
+                $countsum = max(@$Analysis['red'][$i], @$Analysis['green'][$i], @$Analysis['blue'][$i]);
579
+            } else {
580
+                $countsum += @$Analysis[$key][$i];
581
+            }
582
+            if ($countsum >= $clip_threshold) {
583
+                $range_min = $i - 1;
584
+                break;
585
+            }
586
+        }
587
+        $range_min = max($range_min, 0);
588
+
589
+        $countsum  =   0;
590
+        $range_max = 255;
591
+        for ($i = 255; $i >= 0; $i--) {
592
+            if ($method == 0) {
593
+                $countsum = max(@$Analysis['red'][$i], @$Analysis['green'][$i], @$Analysis['blue'][$i]);
594
+            } else {
595
+                $countsum += @$Analysis[$key][$i];
596
+            }
597
+            if ($countsum >= $clip_threshold) {
598
+                $range_max = $i + 1;
599
+                break;
600
+            }
601
+        }
602
+        $range_max = min($range_max, 255);
603
+
604
+        $range_scale = (($range_max == $range_min) ? 1 : (255 / ($range_max - $range_min)));
605
+        if (($range_min == 0) && ($range_max == 255)) {
606
+            // no adjustment necessary - don't waste CPU time!
607
+            return true;
608
+        }
609
+
610
+        $ImageSX = imagesx($gdimg);
611
+        $ImageSY = imagesy($gdimg);
612
+        for ($x = 0; $x < $ImageSX; $x++) {
613
+            for ($y = 0; $y < $ImageSY; $y++) {
614
+                $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
615
+                if ($band == '*') {
616
+                    $new['red']   = min(255, max(0, ($OriginalPixel['red']   - $range_min) * $range_scale));
617
+                    $new['green'] = min(255, max(0, ($OriginalPixel['green'] - $range_min) * $range_scale));
618
+                    $new['blue']  = min(255, max(0, ($OriginalPixel['blue']  - $range_min) * $range_scale));
619
+                    $new['alpha'] = min(255, max(0, ($OriginalPixel['alpha'] - $range_min) * $range_scale));
620
+                } else {
621
+                    $new = $OriginalPixel;
622
+                    $new[$key] = min(255, max(0, ($OriginalPixel[$key] - $range_min) * $range_scale));
623
+                }
624
+                $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $new['red'], $new['green'], $new['blue'], $new['alpha']);
625
+                imagesetpixel($gdimg, $x, $y, $newColor);
626
+            }
627
+        }
628
+
629
+        return true;
630
+    }
631
+
632
+
633
+    public function HistogramOverlay(&$gdimg, $bands='*', $colors='', $width=0.25, $height=0.25, $alignment='BR', $opacity=50, $margin_x=5, $margin_y=null) {
634
+        $margin_y = (null === $margin_y ? $margin_x : $margin_y);
635
+
636
+        $Analysis = self::HistogramAnalysis($gdimg, true);
637
+        $histW = round(($width > 1) ? min($width, imagesx($gdimg)) : imagesx($gdimg) * $width);
638
+        $histH = round(($width > 1) ? min($width, imagesx($gdimg)) : imagesx($gdimg) * $width);
639
+        if ($gdHist = imagecreatetruecolor($histW, $histH)) {
640
+            $color_back = phpthumb_functions::ImageColorAllocateAlphaSafe($gdHist, 0, 0, 0, 127);
641
+            imagefilledrectangle($gdHist, 0, 0, $histW, $histH, $color_back);
642
+            imagealphablending($gdHist, false);
643
+            imagesavealpha($gdHist, true);
644
+
645
+            $HistogramTempWidth  = 256;
646
+            $HistogramTempHeight = 100;
647
+            if ($gdHistTemp = imagecreatetruecolor($HistogramTempWidth, $HistogramTempHeight)) {
648
+                $color_back_temp = phpthumb_functions::ImageColorAllocateAlphaSafe($gdHistTemp, 255, 0, 255, 127);
649
+                imagealphablending($gdHistTemp, false);
650
+                imagesavealpha($gdHistTemp, true);
651
+                imagefilledrectangle($gdHistTemp, 0, 0, imagesx($gdHistTemp), imagesy($gdHistTemp), $color_back_temp);
652
+
653
+                $DefaultColors = array('r'=>'FF0000', 'g'=>'00FF00', 'b'=>'0000FF', 'a'=>'999999', '*'=>'FFFFFF');
654
+                $Colors = explode(';', $colors);
655
+                $BandsToGraph = array_unique(preg_split('##', $bands));
656
+                $keys = array('r'=>'red', 'g'=>'green', 'b'=>'blue', 'a'=>'alpha', '*'=>'gray');
657
+                foreach ($BandsToGraph as $key => $band) {
658
+                    if (!isset($keys[$band])) {
659
+                        continue;
660
+                    }
661
+                    $PeakValue = max($Analysis[$keys[$band]]);
662
+                    $thisColor = phpthumb_functions::ImageHexColorAllocate($gdHistTemp, phpthumb_functions::IsHexColor(@$Colors[$key]) ? $Colors[$key] : $DefaultColors[$band]);
663
+                    for ($x = 0; $x < $HistogramTempWidth; $x++) {
664
+                        imageline($gdHistTemp, $x, $HistogramTempHeight - 1, $x, $HistogramTempHeight - 1 - round(@$Analysis[$keys[$band]][$x] / $PeakValue * $HistogramTempHeight), $thisColor);
665
+                    }
666
+                    imageline($gdHistTemp, 0, $HistogramTempHeight - 1, $HistogramTempWidth - 1, $HistogramTempHeight - 1, $thisColor);
667
+                    imageline($gdHistTemp, 0, $HistogramTempHeight - 2, $HistogramTempWidth - 1, $HistogramTempHeight - 2, $thisColor);
668
+                }
669
+                imagecopyresampled($gdHist, $gdHistTemp, 0, 0, 0, 0, imagesx($gdHist), imagesy($gdHist), imagesx($gdHistTemp), imagesy($gdHistTemp));
670
+                imagedestroy($gdHistTemp);
671
+            } else {
672
+                return false;
673
+            }
674
+
675
+            self::WatermarkOverlay($gdimg, $gdHist, $alignment, $opacity, $margin_x, $margin_y);
676
+            imagedestroy($gdHist);
677
+            return true;
678
+        }
679
+        return false;
680
+    }
681
+
682
+
683
+    public function ImageBorder(&$gdimg, $border_width, $radius_x, $radius_y, $hexcolor_border) {
684
+        $border_width = ($border_width ? $border_width : 1);
685
+        $radius_x     = ($radius_x     ? $radius_x     : 0);
686
+        $radius_y     = ($radius_y     ? $radius_y     : 0);
687
+
688
+        $output_width  = imagesx($gdimg);
689
+        $output_height = imagesy($gdimg);
690
+
691
+        list($new_width, $new_height) = phpthumb_functions::ProportionalResize($output_width, $output_height, $output_width - max($border_width * 2, $radius_x), $output_height - max($border_width * 2, $radius_y));
692
+        $offset_x = ($radius_x ? $output_width  - $new_width  - $radius_x : 0);
693
+
694
+        if ($gd_border_canvas = phpthumb_functions::ImageCreateFunction($output_width, $output_height)) {
695
+
696
+            imagesavealpha($gd_border_canvas, true);
697
+            imagealphablending($gd_border_canvas, false);
698
+            $color_background = phpthumb_functions::ImageColorAllocateAlphaSafe($gd_border_canvas, 255, 255, 255, 127);
699
+            imagefilledrectangle($gd_border_canvas, 0, 0, $output_width, $output_height, $color_background);
700
+
701
+            $color_border = phpthumb_functions::ImageHexColorAllocate($gd_border_canvas, (phpthumb_functions::IsHexColor($hexcolor_border) ? $hexcolor_border : '000000'));
702
+
703
+            for ($i = 0; $i < $border_width; $i++) {
704
+                imageline($gd_border_canvas,             floor($offset_x / 2) + $radius_x,                      $i, $output_width - $radius_x - ceil($offset_x / 2),                         $i, $color_border); // top
705
+                imageline($gd_border_canvas,             floor($offset_x / 2) + $radius_x, $output_height - 1 - $i, $output_width - $radius_x - ceil($offset_x / 2),    $output_height - 1 - $i, $color_border); // bottom
706
+                imageline($gd_border_canvas,                    floor($offset_x / 2) + $i,               $radius_y,                      floor($offset_x / 2) +  $i, $output_height - $radius_y, $color_border); // left
707
+                imageline($gd_border_canvas, $output_width - 1 - $i - ceil($offset_x / 2),               $radius_y,    $output_width - 1 - $i - ceil($offset_x / 2), $output_height - $radius_y, $color_border); // right
708
+            }
709
+
710
+            if ($radius_x && $radius_y) {
711
+
712
+                // PHP bug: imagearc() with thicknesses > 1 give bad/undesirable/unpredicatable results
713
+                // Solution: Draw multiple 1px arcs side-by-side.
714
+
715
+                // Problem: parallel arcs give strange/ugly antialiasing problems
716
+                // Solution: draw non-parallel arcs, from one side of the line thickness at the start angle
717
+                //   to the opposite edge of the line thickness at the terminating angle
718
+                for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) {
719
+                    imagearc($gd_border_canvas, floor($offset_x / 2) + 1 +                 $radius_x,              $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
720
+                    imagearc($gd_border_canvas,                     $output_width - $radius_x - 1 - ceil($offset_x / 2),              $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
721
+                    imagearc($gd_border_canvas,                     $output_width - $radius_x - 1 - ceil($offset_x / 2), $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2,   0,  90, $color_border); // bottom-right
722
+                    imagearc($gd_border_canvas, floor($offset_x / 2) + 1 +                 $radius_x, $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2,  90, 180, $color_border); // bottom-left
723
+                }
724
+                if ($border_width > 1) {
725
+                    for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) {
726
+                        imagearc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x,                                      $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
727
+                        imagearc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2),                                      $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
728
+                        imagearc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2),                     $output_height - $radius_y, $radius_x * 2, $radius_y * 2,   0,  90, $color_border); // bottom-right
729
+                        imagearc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x,                     $output_height - $radius_y, $radius_x * 2, $radius_y * 2,  90, 180, $color_border); // bottom-left
730
+                    }
731
+                }
732
+
733
+            }
734
+            $this->phpThumbObject->ImageResizeFunction($gd_border_canvas, $gdimg, floor(($output_width - $new_width) / 2), round(($output_height - $new_height) / 2), 0, 0, $new_width, $new_height, $output_width, $output_height);
735
+
736
+            imagedestroy($gdimg);
737
+            $gdimg = phpthumb_functions::ImageCreateFunction($output_width, $output_height);
738
+            imagesavealpha($gdimg, true);
739
+            imagealphablending($gdimg, false);
740
+            $gdimg_color_background = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 255, 255, 255, 127);
741
+            imagefilledrectangle($gdimg, 0, 0, $output_width, $output_height, $gdimg_color_background);
742
+
743
+            imagecopy($gdimg, $gd_border_canvas, 0, 0, 0, 0, $output_width, $output_height);
744
+            imagedestroy($gd_border_canvas);
745
+            return true;
746
+
747
+
748
+        } else {
749
+            $this->DebugMessage('FAILED: $gd_border_canvas = phpthumb_functions::ImageCreateFunction('.$output_width.', '.$output_height.')', __FILE__, __LINE__);
750
+        }
751
+        return false;
752
+    }
753
+
754
+
755
+    public static function ImprovedImageRotate(&$gdimg_source, $rotate_angle=0, $config_background_hexcolor='FFFFFF', $bg=null, &$phpThumbObject) {
756
+        while ($rotate_angle < 0) {
757
+            $rotate_angle += 360;
758
+        }
759
+        $rotate_angle %= 360;
760
+        if ($rotate_angle != 0) {
761
+
762
+            $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_source, $config_background_hexcolor);
763
+
764
+            if ((phpthumb_functions::gd_version() >= 2) && !$bg && ($rotate_angle % 90)) {
765
+
766
+                //$this->DebugMessage('Using alpha rotate', __FILE__, __LINE__);
767
+                if ($gdimg_rotate_mask = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_source), imagesy($gdimg_source))) {
768
+
769
+                    $color_mask = array();
770
+                    for ($i = 0; $i <= 255; $i++) {
771
+                        $color_mask[$i] = imagecolorallocate($gdimg_rotate_mask, $i, $i, $i);
772
+                    }
773
+                    imagefilledrectangle($gdimg_rotate_mask, 0, 0, imagesx($gdimg_rotate_mask), imagesy($gdimg_rotate_mask), $color_mask[255]);
774
+                    $imageX = imagesx($gdimg_source);
775
+                    $imageY = imagesy($gdimg_source);
776
+                    for ($x = 0; $x < $imageX; $x++) {
777
+                        for ($y = 0; $y < $imageY; $y++) {
778
+                            $pixelcolor = phpthumb_functions::GetPixelColor($gdimg_source, $x, $y);
779
+                            imagesetpixel($gdimg_rotate_mask, $x, $y, $color_mask[255 - round($pixelcolor['alpha'] * 255 / 127)]);
780
+                        }
781
+                    }
782
+                    $gdimg_rotate_mask = imagerotate($gdimg_rotate_mask, $rotate_angle, $color_mask[0]);
783
+                    $gdimg_source      = imagerotate($gdimg_source,      $rotate_angle, $background_color);
784
+
785
+                    imagealphablending($gdimg_source, false);
786
+                    imagesavealpha($gdimg_source, true);
787
+                    //$this->is_alpha = true;
788
+                    $phpThumbFilters = new self();
789
+                    //$phpThumbFilters->phpThumbObject = $this;
790
+                    $phpThumbFilters->phpThumbObject = $phpThumbObject;
791
+                    $phpThumbFilters->ApplyMask($gdimg_rotate_mask, $gdimg_source);
792
+
793
+                    imagedestroy($gdimg_rotate_mask);
794
+
795
+                } else {
796
+                    //$this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
797
+                }
798
+
799
+            } else {
800
+
801
+                if (phpthumb_functions::gd_version() < 2) {
802
+                    //$this->DebugMessage('Using non-alpha rotate because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
803
+                } elseif ($bg) {
804
+                    //$this->DebugMessage('Using non-alpha rotate because $this->bg is "'.$bg.'"', __FILE__, __LINE__);
805
+                } elseif ($rotate_angle % 90) {
806
+                    //$this->DebugMessage('Using non-alpha rotate because ($rotate_angle % 90) = "'.($rotate_angle % 90).'"', __FILE__, __LINE__);
807
+                } else {
808
+                    //$this->DebugMessage('Using non-alpha rotate because $this->thumbnailFormat is "'.$this->thumbnailFormat.'"', __FILE__, __LINE__);
809
+                }
810
+
811
+                if (imagecolortransparent($gdimg_source) >= 0) {
812
+                    // imagerotate() forgets all about an image's transparency and sets the transparent color to black
813
+                    // To compensate, flood-fill the transparent color of the source image with the specified background color first
814
+                    // then rotate and the colors should match
815
+
816
+                    if (!function_exists('imageistruecolor') || !imageistruecolor($gdimg_source)) {
817
+                        // convert paletted image to true-color before rotating to prevent nasty aliasing artifacts
818
+
819
+                        //$this->source_width  = imagesx($gdimg_source);
820
+                        //$this->source_height = imagesy($gdimg_source);
821
+                        $gdimg_newsrc = phpthumb_functions::ImageCreateFunction(imagesx($gdimg_source), imagesy($gdimg_source));
822
+                        $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_newsrc, $config_background_hexcolor);
823
+                        imagefilledrectangle($gdimg_newsrc, 0, 0, imagesx($gdimg_source), imagesy($gdimg_source), phpthumb_functions::ImageHexColorAllocate($gdimg_newsrc, $config_background_hexcolor));
824
+                        imagecopy($gdimg_newsrc, $gdimg_source, 0, 0, 0, 0, imagesx($gdimg_source), imagesy($gdimg_source));
825
+                        imagedestroy($gdimg_source);
826
+                        unset($gdimg_source);
827
+                        $gdimg_source = $gdimg_newsrc;
828
+                        unset($gdimg_newsrc);
829
+
830
+                    } else {
831
+
832
+                        imagecolorset(
833
+                            $gdimg_source,
834
+                            imagecolortransparent($gdimg_source),
835
+                            hexdec(substr($config_background_hexcolor, 0, 2)),
836
+                            hexdec(substr($config_background_hexcolor, 2, 2)),
837
+                            hexdec(substr($config_background_hexcolor, 4, 2)));
838
+
839
+                        imagecolortransparent($gdimg_source, -1);
840
+
841
+                    }
842
+                }
843
+
844
+                $gdimg_source = imagerotate($gdimg_source, $rotate_angle, $background_color);
845
+
846
+            }
847
+        }
848
+        return true;
849
+    }
850
+
851
+
852
+    public function MeanRemoval(&$gdimg) {
853
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
854
+            if (imagefilter($gdimg, IMG_FILTER_MEAN_REMOVAL)) {
855
+                return true;
856
+            }
857
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_MEAN_REMOVAL)', __FILE__, __LINE__);
858
+            // fall through and try it the hard way
859
+        }
860
+        // currently not implemented "the hard way"
861
+        $this->DebugMessage('FAILED: phpthumb_filters::MeanRemoval($gdimg) [function not implemented]', __FILE__, __LINE__);
862
+        return false;
863
+    }
864
+
865
+
866
+    public function Negative(&$gdimg) {
867
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
868
+            if (imagefilter($gdimg, IMG_FILTER_NEGATE)) {
869
+                return true;
870
+            }
871
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_NEGATE)', __FILE__, __LINE__);
872
+            // fall through and try it the hard way
873
+        }
874
+        $ImageSX = imagesx($gdimg);
875
+        $ImageSY = imagesy($gdimg);
876
+        for ($x = 0; $x < $ImageSX; $x++) {
877
+            for ($y = 0; $y < $ImageSY; $y++) {
878
+                $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
879
+                $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, (~$currentPixel['red'] & 0xFF), (~$currentPixel['green'] & 0xFF), (~$currentPixel['blue'] & 0xFF), $currentPixel['alpha']);
880
+                imagesetpixel($gdimg, $x, $y, $newColor);
881
+            }
882
+        }
883
+        return true;
884
+    }
885
+
886
+
887
+    public function RoundedImageCorners(&$gdimg, $radius_x, $radius_y) {
888
+        // generate mask at twice desired resolution and downsample afterwards for easy antialiasing
889
+        // mask is generated as a white double-size ellipse on a triple-size black background and copy-paste-resampled
890
+        // onto a correct-size mask image as 4 corners due to errors when the entire mask is resampled at once (gray edges)
891
+        if ($gdimg_cornermask_triple = phpthumb_functions::ImageCreateFunction($radius_x * 6, $radius_y * 6)) {
892
+            if ($gdimg_cornermask = phpthumb_functions::ImageCreateFunction(imagesx($gdimg), imagesy($gdimg))) {
893
+
894
+                $color_transparent = imagecolorallocate($gdimg_cornermask_triple, 255, 255, 255);
895
+                imagefilledellipse($gdimg_cornermask_triple, $radius_x * 3, $radius_y * 3, $radius_x * 4, $radius_y * 4, $color_transparent);
896
+
897
+                imagefilledrectangle($gdimg_cornermask, 0, 0, imagesx($gdimg), imagesy($gdimg), $color_transparent);
898
+
899
+                imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple,                           0,                           0,     $radius_x,     $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
900
+                imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple,                           0, imagesy($gdimg) - $radius_y,     $radius_x, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
901
+                imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, imagesx($gdimg) - $radius_x, imagesy($gdimg) - $radius_y, $radius_x * 3, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
902
+                imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, imagesx($gdimg) - $radius_x,                           0, $radius_x * 3,     $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
903
+
904
+                self::ApplyMask($gdimg_cornermask, $gdimg);
905
+                imagedestroy($gdimg_cornermask);
906
+                $this->DebugMessage('RoundedImageCorners('.$radius_x.', '.$radius_y.') succeeded', __FILE__, __LINE__);
907
+                return true;
908
+
909
+            } else {
910
+                $this->DebugMessage('FAILED: $gdimg_cornermask = phpthumb_functions::ImageCreateFunction('.imagesx($gdimg).', '.imagesy($gdimg).')', __FILE__, __LINE__);
911
+            }
912
+            imagedestroy($gdimg_cornermask_triple);
913
+
914
+        } else {
915
+            $this->DebugMessage('FAILED: $gdimg_cornermask_triple = phpthumb_functions::ImageCreateFunction('.($radius_x * 6).', '.($radius_y * 6).')', __FILE__, __LINE__);
916
+        }
917
+        return false;
918
+    }
919
+
920
+
921
+    public function Saturation(&$gdimg, $amount, $color='') {
922
+        if ($amount == 0) {
923
+            return true;
924
+        } elseif ($amount > 0) {
925
+            $amount = 0 - $amount;
926
+        } else {
927
+            $amount = abs($amount);
928
+        }
929
+        return self::Desaturate($gdimg, $amount, $color);
930
+    }
931
+
932
+
933
+    public function Sepia(&$gdimg, $amount, $targetColor) {
934
+        $amount      = (is_numeric($amount) ? max(0, min(100, $amount)) : 50);
935
+        $amountPct   = $amount / 100;
936
+        $targetColor = (phpthumb_functions::IsHexColor($targetColor) ? $targetColor : 'A28065');
937
+
938
+        if ($amount == 0) {
939
+            return true;
940
+        }
941
+
942
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
943
+            if (imagefilter($gdimg, IMG_FILTER_GRAYSCALE)) {
944
+
945
+                $r = round($amountPct * hexdec(substr($targetColor, 0, 2)));
946
+                $g = round($amountPct * hexdec(substr($targetColor, 2, 2)));
947
+                $b = round($amountPct * hexdec(substr($targetColor, 4, 2)));
948
+                if (imagefilter($gdimg, IMG_FILTER_COLORIZE, $r, $g, $b)) {
949
+                    return true;
950
+                }
951
+                $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_COLORIZE)', __FILE__, __LINE__);
952
+                // fall through and try it the hard way
953
+
954
+            } else {
955
+
956
+                $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_GRAYSCALE)', __FILE__, __LINE__);
957
+                // fall through and try it the hard way
958
+
959
+            }
960
+        }
961
+
962
+        $TargetPixel['red']   = hexdec(substr($targetColor, 0, 2));
963
+        $TargetPixel['green'] = hexdec(substr($targetColor, 2, 2));
964
+        $TargetPixel['blue']  = hexdec(substr($targetColor, 4, 2));
965
+
966
+        $ImageSX = imagesx($gdimg);
967
+        $ImageSY = imagesy($gdimg);
968
+        for ($x = 0; $x < $ImageSX; $x++) {
969
+            for ($y = 0; $y < $ImageSY; $y++) {
970
+                $OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
971
+                $GrayPixel = phpthumb_functions::GrayscalePixel($OriginalPixel);
972
+
973
+                // http://www.gimpguru.org/Tutorials/SepiaToning/
974
+                // "In the traditional sepia toning process, the tinting occurs most in
975
+                // the mid-tones: the lighter and darker areas appear to be closer to B&W."
976
+                $SepiaAmount = ((128 - abs($GrayPixel['red'] - 128)) / 128) * $amountPct;
977
+
978
+                $NewPixel = array();
979
+                foreach ($TargetPixel as $key => $value) {
980
+                    $NewPixel[$key] = round(max(0, min(255, $GrayPixel[$key] * (1 - $SepiaAmount) + ($TargetPixel[$key] * $SepiaAmount))));
981
+                }
982
+                $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, $NewPixel['red'], $NewPixel['green'], $NewPixel['blue'], $OriginalPixel['alpha']);
983
+                imagesetpixel($gdimg, $x, $y, $newColor);
984
+            }
985
+        }
986
+        return true;
987
+    }
988
+
989
+
990
+    public function Smooth(&$gdimg, $amount=6) {
991
+        $amount = min(25, max(0, $amount));
992
+        if ($amount == 0) {
993
+            return true;
994
+        }
995
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
996
+            if (imagefilter($gdimg, IMG_FILTER_SMOOTH, $amount)) {
997
+                return true;
998
+            }
999
+            $this->DebugMessage('FAILED: imagefilter($gdimg, IMG_FILTER_SMOOTH, '.$amount.')', __FILE__, __LINE__);
1000
+            // fall through and try it the hard way
1001
+        }
1002
+        // currently not implemented "the hard way"
1003
+        $this->DebugMessage('FAILED: phpthumb_filters::Smooth($gdimg, '.$amount.') [function not implemented]', __FILE__, __LINE__);
1004
+        return false;
1005
+    }
1006
+
1007
+
1008
+    public function SourceTransparentColorMask(&$gdimg, $hexcolor, $min_limit=5, $max_limit=10) {
1009
+        $width  = imagesx($gdimg);
1010
+        $height = imagesy($gdimg);
1011
+        if ($gdimg_mask = imagecreatetruecolor($width, $height)) {
1012
+            $R = hexdec(substr($hexcolor, 0, 2));
1013
+            $G = hexdec(substr($hexcolor, 2, 2));
1014
+            $B = hexdec(substr($hexcolor, 4, 2));
1015
+            $targetPixel = array('red'=>$R, 'green'=>$G, 'blue'=>$B);
1016
+            $cutoffRange = $max_limit - $min_limit;
1017
+            for ($x = 0; $x < $width; $x++) {
1018
+                for ($y = 0; $y < $height; $y++) {
1019
+                    $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1020
+                    $colorDiff = phpthumb_functions::PixelColorDifferencePercent($currentPixel, $targetPixel);
1021
+                    $grayLevel = min($cutoffRange, max(0, -$min_limit + $colorDiff)) * (255 / max(1, $cutoffRange));
1022
+                    $newColor = imagecolorallocate($gdimg_mask, $grayLevel, $grayLevel, $grayLevel);
1023
+                    imagesetpixel($gdimg_mask, $x, $y, $newColor);
1024
+                }
1025
+            }
1026
+            return $gdimg_mask;
1027
+        }
1028
+        return false;
1029
+    }
1030
+
1031
+
1032
+    public function Threshold(&$gdimg, $cutoff) {
1033
+        $width  = imagesx($gdimg);
1034
+        $height = imagesy($gdimg);
1035
+        $cutoff = min(255, max(0, ($cutoff ? $cutoff : 128)));
1036
+        for ($x = 0; $x < $width; $x++) {
1037
+            for ($y = 0; $y < $height; $y++) {
1038
+                $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1039
+                $grayPixel = phpthumb_functions::GrayscalePixel($currentPixel);
1040
+                if ($grayPixel['red'] < $cutoff) {
1041
+                    $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0x00, 0x00, 0x00, $currentPixel['alpha']);
1042
+                } else {
1043
+                    $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg, 0xFF, 0xFF, 0xFF, $currentPixel['alpha']);
1044
+                }
1045
+                imagesetpixel($gdimg, $x, $y, $newColor);
1046
+            }
1047
+        }
1048
+        return true;
1049
+    }
1050
+
1051
+
1052
+    public function ImageTrueColorToPalette2(&$image, $dither, $ncolors) {
1053
+        // http://www.php.net/manual/en/function.imagetruecolortopalette.php
1054
+        // zmorris at zsculpt dot com (17-Aug-2004 06:58)
1055
+        $width  = imagesx($image);
1056
+        $height = imagesy($image);
1057
+        $image_copy = imagecreatetruecolor($width, $height);
1058
+        //imagecopymerge($image_copy, $image, 0, 0, 0, 0, $width, $height, 100);
1059
+        imagecopy($image_copy, $image, 0, 0, 0, 0, $width, $height);
1060
+        imagetruecolortopalette($image, $dither, $ncolors);
1061
+        imagecolormatch($image_copy, $image);
1062
+        imagedestroy($image_copy);
1063
+        return true;
1064
+    }
1065
+
1066
+    public function ReduceColorDepth(&$gdimg, $colors=256, $dither=true) {
1067
+        $colors = max(min($colors, 256), 2);
1068
+        // imagetruecolortopalette usually makes ugly colors, the replacement is a bit better
1069
+        //imagetruecolortopalette($gdimg, $dither, $colors);
1070
+        self::ImageTrueColorToPalette2($gdimg, $dither, $colors);
1071
+        return true;
1072
+    }
1073
+
1074
+
1075
+    public function WhiteBalance(&$gdimg, $targetColor='') {
1076
+        if (phpthumb_functions::IsHexColor($targetColor)) {
1077
+            $targetPixel = array(
1078
+                'red'   => hexdec(substr($targetColor, 0, 2)),
1079
+                'green' => hexdec(substr($targetColor, 2, 2)),
1080
+                'blue'  => hexdec(substr($targetColor, 4, 2))
1081
+            );
1082
+        } else {
1083
+            $Analysis = self::HistogramAnalysis($gdimg, false);
1084
+            $targetPixel = array(
1085
+                'red'   => max(array_keys($Analysis['red'])),
1086
+                'green' => max(array_keys($Analysis['green'])),
1087
+                'blue'  => max(array_keys($Analysis['blue']))
1088
+            );
1089
+        }
1090
+        $grayValue = phpthumb_functions::GrayscaleValue($targetPixel['red'], $targetPixel['green'], $targetPixel['blue']);
1091
+        $scaleR = $grayValue / $targetPixel['red'];
1092
+        $scaleG = $grayValue / $targetPixel['green'];
1093
+        $scaleB = $grayValue / $targetPixel['blue'];
1094
+
1095
+        for ($x = 0, $xMax = imagesx($gdimg); $x < $xMax; $x++) {
1096
+            for ($y = 0, $yMax = imagesy($gdimg); $y < $yMax; $y++) {
1097
+                $currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1098
+                $newColor = phpthumb_functions::ImageColorAllocateAlphaSafe(
1099
+                    $gdimg,
1100
+                    max(0, min(255, round($currentPixel['red']   * $scaleR))),
1101
+                    max(0, min(255, round($currentPixel['green'] * $scaleG))),
1102
+                    max(0, min(255, round($currentPixel['blue']  * $scaleB))),
1103
+                    $currentPixel['alpha']
1104
+                );
1105
+                imagesetpixel($gdimg, $x, $y, $newColor);
1106
+            }
1107
+        }
1108
+        return true;
1109
+    }
1110
+
1111
+
1112
+    public function WatermarkText(&$gdimg, $text, $size, $alignment, $hex_color='000000', $ttffont='', $opacity=100, $margin=5, $angle=0, $bg_color=false, $bg_opacity=0, $fillextend='', $lineheight=1.0) {
1113
+        // text watermark requested
1114
+        if (!$text) {
1115
+            return false;
1116
+        }
1117
+        imagealphablending($gdimg, true);
1118
+
1119
+        if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)(@[LCR])?$#i', $alignment, $matches)) {
1120
+            $originOffsetX = (int) $matches[ 1];
1121
+            $originOffsetY = (int) $matches[ 2];
1122
+            $alignment = (@$matches[4] ? $matches[4] : 'L');
1123
+            $margin = 0;
1124
+        } else {
1125
+            $originOffsetX = 0;
1126
+            $originOffsetY = 0;
1127
+        }
1128
+        $lineheight = min(100.0, max(0.01, (float) $lineheight));
1129
+
1130
+        $metaTextArray = array(
1131
+            '^Fb' =>       $this->phpThumbObject->getimagesizeinfo['filesize'],
1132
+            '^Fk' => round($this->phpThumbObject->getimagesizeinfo['filesize'] / 1024),
1133
+            '^Fm' => round($this->phpThumbObject->getimagesizeinfo['filesize'] / 1048576),
1134
+            '^X'  => $this->phpThumbObject->getimagesizeinfo[0],
1135
+            '^Y'  => $this->phpThumbObject->getimagesizeinfo[1],
1136
+            '^x'  => imagesx($gdimg),
1137
+            '^y'  => imagesy($gdimg),
1138
+            '^^'  => '^',
1139
+        );
1140
+        $text = strtr($text, $metaTextArray);
1141
+
1142
+        $text = str_replace(array(
1143
+            "\r\n",
1144
+            "\r"
1145
+        ), "\n", $text);
1146
+        $textlines = explode("\n", $text);
1147
+        $this->DebugMessage('Processing '.count($textlines).' lines of text', __FILE__, __LINE__);
1148
+
1149
+        if (@is_readable($ttffont) && is_file($ttffont)) {
1150
+
1151
+            $opacity = 100 - (int) max(min($opacity, 100), 0);
1152
+            $letter_color_text = phpthumb_functions::ImageHexColorAllocate($gdimg, $hex_color, false, $opacity * 1.27);
1153
+
1154
+            $this->DebugMessage('Using TTF font "'.$ttffont.'"', __FILE__, __LINE__);
1155
+
1156
+            $TTFbox = imagettfbbox($size, $angle, $ttffont, $text);
1157
+
1158
+            $min_x = min($TTFbox[0], $TTFbox[2], $TTFbox[4], $TTFbox[6]);
1159
+            $max_x = max($TTFbox[0], $TTFbox[2], $TTFbox[4], $TTFbox[6]);
1160
+            //$text_width = round($max_x - $min_x + ($size * 0.5));
1161
+            $text_width = round($max_x - $min_x);
1162
+
1163
+            $min_y = min($TTFbox[1], $TTFbox[3], $TTFbox[5], $TTFbox[7]);
1164
+            $max_y = max($TTFbox[1], $TTFbox[3], $TTFbox[5], $TTFbox[7]);
1165
+            //$text_height = round($max_y - $min_y + ($size * 0.5));
1166
+            $text_height = round($max_y - $min_y);
1167
+
1168
+            $TTFboxChar = imagettfbbox($size, $angle, $ttffont, 'jH');
1169
+            $char_min_y = min($TTFboxChar[1], $TTFboxChar[3], $TTFboxChar[5], $TTFboxChar[7]);
1170
+            $char_max_y = max($TTFboxChar[1], $TTFboxChar[3], $TTFboxChar[5], $TTFboxChar[7]);
1171
+            $char_height = round($char_max_y - $char_min_y);
1172
+
1173
+            if ($alignment == '*') {
1174
+
1175
+                $text_origin_y = $char_height + $margin;
1176
+                while (($text_origin_y - $text_height) < imagesy($gdimg)) {
1177
+                    $text_origin_x = $margin;
1178
+                    while ($text_origin_x < imagesx($gdimg)) {
1179
+                        imagettftext($gdimg, $size, $angle, $text_origin_x, $text_origin_y, $letter_color_text, $ttffont, $text);
1180
+                        $text_origin_x += ($text_width + $margin);
1181
+                    }
1182
+                    $text_origin_y += ($text_height + $margin) * $lineheight;
1183
+                }
1184
+
1185
+            } else {
1186
+
1187
+                // this block for background color only
1188
+
1189
+                $text_origin_x = 0;
1190
+                $text_origin_y = 0;
1191
+                switch ($alignment) {
1192
+                    case '*':
1193
+                        // handled separately
1194
+                        break;
1195
+
1196
+                    case 'T':
1197
+                        $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((imagesx($gdimg) - $text_width) / 2));
1198
+                        $text_origin_y = $char_height + $margin + $originOffsetY;
1199
+                        break;
1200
+
1201
+                    case 'B':
1202
+                        $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((imagesx($gdimg) - $text_width) / 2));
1203
+                        $text_origin_y = imagesy($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1204
+                        break;
1205
+
1206
+                    case 'L':
1207
+                        $text_origin_x = $margin + $originOffsetX;
1208
+                        $text_origin_y = ($originOffsetY ? $originOffsetY : round((imagesy($gdimg) - $text_height) / 2) + $char_height);
1209
+                        break;
1210
+
1211
+                    case 'R':
1212
+                        $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1213
+                        $text_origin_y = ($originOffsetY ? $originOffsetY : round((imagesy($gdimg) - $text_height) / 2) + $char_height);
1214
+                        break;
1215
+
1216
+                    case 'C':
1217
+                        $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width / 2) : round((imagesx($gdimg) - $text_width) / 2));
1218
+                        $text_origin_y = ($originOffsetY ? $originOffsetY : round((imagesy($gdimg) - $text_height) / 2) + $char_height);
1219
+                        break;
1220
+
1221
+                    case 'TL':
1222
+                        $text_origin_x = $margin + $originOffsetX;
1223
+                        $text_origin_y = $char_height + $margin + $originOffsetY;
1224
+                        break;
1225
+
1226
+                    case 'TR':
1227
+                        $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1228
+                        $text_origin_y = $char_height + $margin + $originOffsetY;
1229
+                        break;
1230
+
1231
+                    case 'BL':
1232
+                        $text_origin_x = $margin + $originOffsetX;
1233
+                        $text_origin_y = imagesy($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1234
+                        break;
1235
+
1236
+                    case 'BR':
1237
+                    default:
1238
+                        $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1239
+                        $text_origin_y = imagesy($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1240
+                        break;
1241
+                }
1242
+
1243
+                if (phpthumb_functions::IsHexColor($bg_color)) {
1244
+                    $text_background_alpha = round(127 * ((100 - min(max(0, $bg_opacity), 100)) / 100));
1245
+                    $text_color_background = phpthumb_functions::ImageHexColorAllocate($gdimg, $bg_color, false, $text_background_alpha);
1246
+                } else {
1247
+                    $text_color_background = phpthumb_functions::ImageHexColorAllocate($gdimg, 'FFFFFF', false, 127);
1248
+                }
1249
+                $x1 = $text_origin_x + $min_x;
1250
+                $y1 = $text_origin_y + $TTFbox[1];
1251
+                $x2 = $text_origin_x + $min_x + $text_width;
1252
+                $y2 = $text_origin_y + $TTFbox[1] - $text_height;
1253
+                $x_TL = false !== stripos($fillextend, "x") ?               0 : min($x1, $x2);
1254
+                $y_TL = false !== stripos($fillextend, "y") ?               0 : min($y1, $y2);
1255
+                $x_BR = false !== stripos($fillextend, "x") ? imagesx($gdimg) : max($x1, $x2);
1256
+                $y_BR = false !== stripos($fillextend, "y") ? imagesy($gdimg) : max($y1, $y2);
1257
+                $this->DebugMessage('WatermarkText() calling imagefilledrectangle($gdimg, '.$x_TL.', '.$y_TL.', '.$x_BR.', '.$y_BR.', $text_color_background)', __FILE__, __LINE__);
1258
+                imagefilledrectangle($gdimg, $x_TL, $y_TL, $x_BR, $y_BR, $text_color_background);
1259
+
1260
+                // end block for background color only
1261
+
1262
+
1263
+                $y_offset = 0;
1264
+                foreach ($textlines as $dummy => $line) {
1265
+
1266
+                    $TTFboxLine = imagettfbbox($size, $angle, $ttffont, $line);
1267
+                    $min_x_line = min($TTFboxLine[0], $TTFboxLine[2], $TTFboxLine[4], $TTFboxLine[6]);
1268
+                    $max_x_line = max($TTFboxLine[0], $TTFboxLine[2], $TTFboxLine[4], $TTFboxLine[6]);
1269
+                    $text_width_line = round($max_x_line - $min_x_line);
1270
+
1271
+                    switch ($alignment) {
1272
+                        // $text_origin_y set above, just re-set $text_origin_x here as needed
1273
+
1274
+                        case 'L':
1275
+                        case 'TL':
1276
+                        case 'BL':
1277
+                            // no change necessary
1278
+                            break;
1279
+
1280
+                        case 'C':
1281
+                        case 'T':
1282
+                        case 'B':
1283
+                            $text_origin_x = ($originOffsetX ? $originOffsetX - round($text_width_line / 2) : round((imagesx($gdimg) - $text_width_line) / 2));
1284
+                            break;
1285
+
1286
+                        case 'R':
1287
+                        case 'TR':
1288
+                        case 'BR':
1289
+                            $text_origin_x = ($originOffsetX ? $originOffsetX - $text_width_line : imagesx($gdimg) - $text_width_line  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1290
+                            break;
1291
+                    }
1292
+
1293
+                    //imagettftext($gdimg, $size, $angle, $text_origin_x, $text_origin_y, $letter_color_text, $ttffont, $text);
1294
+                    $this->DebugMessage('WatermarkText() calling imagettftext($gdimg, '.$size.', '.$angle.', '.$text_origin_x.', '.($text_origin_y + $y_offset).', $letter_color_text, '.$ttffont.', '.$line.')', __FILE__, __LINE__);
1295
+                    imagettftext($gdimg, $size, $angle, $text_origin_x, $text_origin_y + $y_offset, $letter_color_text, $ttffont, $line);
1296
+
1297
+                    $y_offset += $char_height * $lineheight;
1298
+                }
1299
+
1300
+            }
1301
+            return true;
1302
+
1303
+        } else {
1304
+
1305
+            $size = min(5, max(1, $size));
1306
+            $this->DebugMessage('Using built-in font (size='.$size.') for text watermark'.($ttffont ? ' because $ttffont !is_readable('.$ttffont.')' : ''), __FILE__, __LINE__);
1307
+
1308
+            $text_width  = 0;
1309
+            $text_height = 0;
1310
+            foreach ($textlines as $dummy => $line) {
1311
+                $text_width   = max($text_width, imagefontwidth($size) * strlen($line));
1312
+                $text_height += imagefontheight($size);
1313
+            }
1314
+            if ($img_watermark = phpthumb_functions::ImageCreateFunction($text_width, $text_height)) {
1315
+                imagealphablending($img_watermark, false);
1316
+                if (phpthumb_functions::IsHexColor($bg_color)) {
1317
+                    $text_background_alpha = round(127 * ((100 - min(max(0, $bg_opacity), 100)) / 100));
1318
+                    $text_color_background = phpthumb_functions::ImageHexColorAllocate($img_watermark, $bg_color, false, $text_background_alpha);
1319
+                } else {
1320
+                    $text_color_background = phpthumb_functions::ImageHexColorAllocate($img_watermark, 'FFFFFF', false, 127);
1321
+                }
1322
+                $this->DebugMessage('WatermarkText() calling imagefilledrectangle($img_watermark, 0, 0, '.imagesx($img_watermark).', '.imagesy($img_watermark).', $text_color_background)', __FILE__, __LINE__);
1323
+                imagefilledrectangle($img_watermark, 0, 0, imagesx($img_watermark), imagesy($img_watermark), $text_color_background);
1324
+
1325
+                $img_watermark_mask    = false;
1326
+                $mask_color_background = false;
1327
+                $mask_color_watermark  = false;
1328
+                if ($angle && function_exists('imagerotate')) {
1329
+                    // using $img_watermark_mask is pointless if imagerotate function isn't available
1330
+                    if ($img_watermark_mask = phpthumb_functions::ImageCreateFunction($text_width, $text_height)) {
1331
+                        $mask_color_background = imagecolorallocate($img_watermark_mask, 0, 0, 0);
1332
+                        imagealphablending($img_watermark_mask, false);
1333
+                        imagefilledrectangle($img_watermark_mask, 0, 0, imagesx($img_watermark_mask), imagesy($img_watermark_mask), $mask_color_background);
1334
+                        $mask_color_watermark = imagecolorallocate($img_watermark_mask, 255, 255, 255);
1335
+                    }
1336
+                }
1337
+
1338
+                $text_color_watermark = phpthumb_functions::ImageHexColorAllocate($img_watermark, $hex_color);
1339
+                $x_offset = 0;
1340
+                foreach ($textlines as $key => $line) {
1341
+                    switch ($alignment) {
1342
+                        case 'C':
1343
+                            $x_offset = round(($text_width - (imagefontwidth($size) * strlen($line))) / 2);
1344
+                            $originOffsetX = (imagesx($gdimg) - imagesx($img_watermark)) / 2;
1345
+                            $originOffsetY = (imagesy($gdimg) - imagesy($img_watermark)) / 2;
1346
+                            break;
1347
+
1348
+                        case 'T':
1349
+                            $x_offset = round(($text_width - (imagefontwidth($size) * strlen($line))) / 2);
1350
+                            $originOffsetX = (imagesx($gdimg) - imagesx($img_watermark)) / 2;
1351
+                            $originOffsetY = $margin;
1352
+                            break;
1353
+
1354
+                        case 'B':
1355
+                            $x_offset = round(($text_width - (imagefontwidth($size) * strlen($line))) / 2);
1356
+                            $originOffsetX = (imagesx($gdimg) - imagesx($img_watermark)) / 2;
1357
+                            $originOffsetY = imagesy($gdimg) - imagesy($img_watermark) - $margin;
1358
+                            break;
1359
+
1360
+                        case 'L':
1361
+                            $x_offset = 0;
1362
+                            $originOffsetX = $margin;
1363
+                            $originOffsetY = (imagesy($gdimg) - imagesy($img_watermark)) / 2;
1364
+                            break;
1365
+
1366
+                        case 'TL':
1367
+                            $x_offset = 0;
1368
+                            $originOffsetX = $margin;
1369
+                            $originOffsetY = $margin;
1370
+                            break;
1371
+
1372
+                        case 'BL':
1373
+                            $x_offset = 0;
1374
+                            $originOffsetX = $margin;
1375
+                            $originOffsetY = imagesy($gdimg) - imagesy($img_watermark) - $margin;
1376
+                            break;
1377
+
1378
+                        case 'R':
1379
+                            $x_offset = $text_width - (imagefontwidth($size) * strlen($line));
1380
+                            $originOffsetX = imagesx($gdimg) - imagesx($img_watermark) - $margin;
1381
+                            $originOffsetY = (imagesy($gdimg) - imagesy($img_watermark)) / 2;
1382
+                            break;
1383
+
1384
+                        case 'TR':
1385
+                            $x_offset = $text_width - (imagefontwidth($size) * strlen($line));
1386
+                            $originOffsetX = imagesx($gdimg) - imagesx($img_watermark) - $margin;
1387
+                            $originOffsetY = $margin;
1388
+                            break;
1389
+
1390
+                        case 'BR':
1391
+                        default:
1392
+                            if (!empty($originOffsetX) || !empty($originOffsetY)) {
1393
+                                // absolute pixel positioning
1394
+                            } else {
1395
+                                $x_offset = $text_width - (imagefontwidth($size) * strlen($line));
1396
+                                $originOffsetX = imagesx($gdimg) - imagesx($img_watermark) - $margin;
1397
+                                $originOffsetY = imagesy($gdimg) - imagesy($img_watermark) - $margin;
1398
+                            }
1399
+                            break;
1400
+                    }
1401
+                    $this->DebugMessage('WatermarkText() calling imagestring($img_watermark, '.$size.', '.$x_offset.', '.($key * imagefontheight($size)).', '.$line.', $text_color_watermark)', __FILE__, __LINE__);
1402
+                    imagestring($img_watermark, $size, $x_offset, $key * imagefontheight($size), $line, $text_color_watermark);
1403
+                    if ($angle && $img_watermark_mask) {
1404
+                        $this->DebugMessage('WatermarkText() calling imagestring($img_watermark_mask, '.$size.', '.$x_offset.', '.($key * imagefontheight($size) * $lineheight).', '.$text.', $mask_color_watermark)', __FILE__, __LINE__);
1405
+                        imagestring($img_watermark_mask, $size, $x_offset, $key * imagefontheight($size) * $lineheight, $text, $mask_color_watermark);
1406
+                    }
1407
+                }
1408
+                if ($angle && $img_watermark_mask) {
1409
+                    $img_watermark      = imagerotate($img_watermark,      $angle, $text_color_background);
1410
+                    $img_watermark_mask = imagerotate($img_watermark_mask, $angle, $mask_color_background);
1411
+                    self::ApplyMask($img_watermark_mask, $img_watermark);
1412
+                }
1413
+                //phpthumb_filters::WatermarkOverlay($gdimg, $img_watermark, $alignment, $opacity, $margin);
1414
+                $this->DebugMessage('WatermarkText() calling phpthumb_filters::WatermarkOverlay($gdimg, $img_watermark, '.($originOffsetX.'x'.$originOffsetY).', '.$opacity.', 0)', __FILE__, __LINE__);
1415
+                self::WatermarkOverlay($gdimg, $img_watermark, $originOffsetX.'x'.$originOffsetY, $opacity, 0);
1416
+                imagedestroy($img_watermark);
1417
+                return true;
1418
+            }
1419
+
1420
+        }
1421
+        return false;
1422
+    }
1423
+
1424
+
1425
+    public function WatermarkOverlay(&$gdimg_dest, &$img_watermark, $alignment='*', $opacity=50, $margin_x=5, $margin_y=null) {
1426
+
1427
+        if (is_resource($gdimg_dest) && is_resource($img_watermark)) {
1428
+            $img_source_width          = imagesx($gdimg_dest);
1429
+            $img_source_height         = imagesy($gdimg_dest);
1430
+            $watermark_source_width    = imagesx($img_watermark);
1431
+            $watermark_source_height   = imagesy($img_watermark);
1432
+            $watermark_opacity_percent = max(0, min(100, $opacity));
1433
+            $margin_y = (null === $margin_y ? $margin_x : $margin_y);
1434
+            $watermark_margin_x = ((($margin_x > 0) && ($margin_x < 1)) ? round((1 - $margin_x) * $img_source_width)  : $margin_x);
1435
+            $watermark_margin_y = ((($margin_y > 0) && ($margin_y < 1)) ? round((1 - $margin_y) * $img_source_height) : $margin_y);
1436
+            $watermark_destination_x = 0;
1437
+            $watermark_destination_y = 0;
1438
+            if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
1439
+                $watermark_destination_x = (int) $matches[ 1];
1440
+                $watermark_destination_y = (int) $matches[ 2];
1441
+            } else {
1442
+                switch ($alignment) {
1443
+                    case '*':
1444
+                        if ($gdimg_tiledwatermark = phpthumb_functions::ImageCreateFunction($img_source_width, $img_source_height)) {
1445
+
1446
+                            imagealphablending($gdimg_tiledwatermark, false);
1447
+                            imagesavealpha($gdimg_tiledwatermark, true);
1448
+                            $text_color_transparent = phpthumb_functions::ImageColorAllocateAlphaSafe($gdimg_tiledwatermark, 255, 0, 255, 127);
1449
+                            imagefill($gdimg_tiledwatermark, 0, 0, $text_color_transparent);
1450
+
1451
+                            // set the tiled image transparent color to whatever the untiled image transparency index is
1452
+    //						imagecolortransparent($gdimg_tiledwatermark, imagecolortransparent($img_watermark));
1453
+
1454
+                            // a "cleaner" way of doing it, but can't handle the margin feature :(
1455
+    //						imagesettile($gdimg_tiledwatermark, $img_watermark);
1456
+    //						imagefill($gdimg_tiledwatermark, 0, 0, IMG_COLOR_TILED);
1457
+    //						break;
1458
+
1459
+    //						imagefill($gdimg_tiledwatermark, 0, 0, imagecolortransparent($gdimg_tiledwatermark));
1460
+                            // tile the image as many times as can fit
1461
+                            for ($x = $watermark_margin_x; $x < ($img_source_width + $watermark_source_width); $x += ($watermark_source_width + $watermark_margin_x)) {
1462
+                                for ($y = $watermark_margin_y; $y < ($img_source_height + $watermark_source_height); $y += ($watermark_source_height + $watermark_margin_y)) {
1463
+                                    imagecopy(
1464
+                                        $gdimg_tiledwatermark,
1465
+                                        $img_watermark,
1466
+                                        $x,
1467
+                                        $y,
1468
+                                        0,
1469
+                                        0,
1470
+                                        min($watermark_source_width,  $img_source_width  - $x - $watermark_margin_x),
1471
+                                        min($watermark_source_height, $img_source_height - $y - $watermark_margin_y)
1472
+                                    );
1473
+                                }
1474
+                            }
1475
+
1476
+                            $watermark_source_width  = imagesx($gdimg_tiledwatermark);
1477
+                            $watermark_source_height = imagesy($gdimg_tiledwatermark);
1478
+                            $watermark_destination_x = 0;
1479
+                            $watermark_destination_y = 0;
1480
+
1481
+                            imagedestroy($img_watermark);
1482
+                            $img_watermark = $gdimg_tiledwatermark;
1483
+                        }
1484
+                        break;
1485
+
1486
+                    case 'T':
1487
+                        $watermark_destination_x = round((($img_source_width  / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1488
+                        $watermark_destination_y = $watermark_margin_y;
1489
+                        break;
1490
+
1491
+                    case 'B':
1492
+                        $watermark_destination_x = round((($img_source_width  / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1493
+                        $watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1494
+                        break;
1495
+
1496
+                    case 'L':
1497
+                        $watermark_destination_x = $watermark_margin_x;
1498
+                        $watermark_destination_y = round((($img_source_height / 2) - ($watermark_source_height / 2)) + $watermark_margin_y);
1499
+                        break;
1500
+
1501
+                    case 'R':
1502
+                        $watermark_destination_x = $img_source_width - $watermark_source_width - $watermark_margin_x;
1503
+                        $watermark_destination_y = round((($img_source_height / 2) - ($watermark_source_height / 2)) + $watermark_margin_y);
1504
+                        break;
1505
+
1506
+                    case 'C':
1507
+                        $watermark_destination_x = round(($img_source_width  / 2) - ($watermark_source_width  / 2));
1508
+                        $watermark_destination_y = round(($img_source_height / 2) - ($watermark_source_height / 2));
1509
+                        break;
1510
+
1511
+                    case 'TL':
1512
+                        $watermark_destination_x = $watermark_margin_x;
1513
+                        $watermark_destination_y = $watermark_margin_y;
1514
+                        break;
1515
+
1516
+                    case 'TR':
1517
+                        $watermark_destination_x = $img_source_width - $watermark_source_width - $watermark_margin_x;
1518
+                        $watermark_destination_y = $watermark_margin_y;
1519
+                        break;
1520
+
1521
+                    case 'BL':
1522
+                        $watermark_destination_x = $watermark_margin_x;
1523
+                        $watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1524
+                        break;
1525
+
1526
+                    case 'BR':
1527
+                    default:
1528
+                        $watermark_destination_x = $img_source_width  - $watermark_source_width  - $watermark_margin_x;
1529
+                        $watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1530
+                        break;
1531
+                }
1532
+            }
1533
+            imagealphablending($gdimg_dest, false);
1534
+            imagesavealpha($gdimg_dest, true);
1535
+            imagesavealpha($img_watermark, true);
1536
+            phpthumb_functions::ImageCopyRespectAlpha($gdimg_dest, $img_watermark, $watermark_destination_x, $watermark_destination_y, 0, 0, $watermark_source_width, $watermark_source_height, $watermark_opacity_percent);
1537
+
1538
+            return true;
1539
+        }
1540
+        return false;
1541
+    }
1542 1542
 
1543 1543
 }
Please login to merge, or discard this patch.
Spacing   +104 added lines, -104 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@  discard block
 block discarded – undo
18 18
 	public $phpThumbObject = null;
19 19
 
20 20
 
21
-	public function DebugMessage($message, $file='', $line='') {
21
+	public function DebugMessage($message, $file = '', $line = '') {
22 22
 		if (is_object($this->phpThumbObject)) {
23 23
 			return $this->phpThumbObject->DebugMessage($message, $file, $line);
24 24
 		}
@@ -69,14 +69,14 @@  discard block
 block discarded – undo
69 69
 
70 70
 		} else {
71 71
 			// alpha merging requires PHP v4.3.2+
72
-			$this->DebugMessage('Skipping ApplyMask() technique because PHP is v"'. PHP_VERSION .'"', __FILE__, __LINE__);
72
+			$this->DebugMessage('Skipping ApplyMask() technique because PHP is v"'.PHP_VERSION.'"', __FILE__, __LINE__);
73 73
 		}
74 74
 		return true;
75 75
 	}
76 76
 
77 77
 
78 78
     public function Bevel(&$gdimg, $width, $hexcolor1, $hexcolor2) {
79
-        $width     = ($width     ? $width     : 5);
79
+        $width     = ($width ? $width : 5);
80 80
         $hexcolor1 = ($hexcolor1 ? $hexcolor1 : 'FFFFFF');
81 81
         $hexcolor2 = ($hexcolor2 ? $hexcolor2 : '000000');
82 82
 
@@ -86,16 +86,16 @@  discard block
 block discarded – undo
86 86
             $color1 = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor1, false, $alpha);
87 87
             $color2 = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor2, false, $alpha);
88 88
 
89
-            imageline($gdimg,                   $i,                   $i + 1,                   $i, imagesy($gdimg) - $i - 1, $color1); // left
90
-            imageline($gdimg,                   $i,                   $i    , imagesx($gdimg) - $i,                   $i    , $color1); // top
91
-            imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i - 1, imagesx($gdimg) - $i,                   $i + 1, $color2); // right
92
-            imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i    ,                   $i, imagesy($gdimg) - $i    , $color2); // bottom
89
+            imageline($gdimg, $i, $i + 1, $i, imagesy($gdimg) - $i - 1, $color1); // left
90
+            imageline($gdimg, $i, $i, imagesx($gdimg) - $i, $i, $color1); // top
91
+            imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i - 1, imagesx($gdimg) - $i, $i + 1, $color2); // right
92
+            imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i, $i, imagesy($gdimg) - $i, $color2); // bottom
93 93
         }
94 94
         return true;
95 95
     }
96 96
 
97 97
 
98
-	public function Blur(&$gdimg, $radius=0.5) {
98
+	public function Blur(&$gdimg, $radius = 0.5) {
99 99
 		// Taken from Torstein Hønsi's phpUnsharpMask (see phpthumb.unsharp.php)
100 100
 
101 101
 		$radius = round(max(0, min($radius, 50)) * 2);
@@ -113,17 +113,17 @@  discard block
 block discarded – undo
113 113
 
114 114
 			// Move copies of the image around one pixel at the time and merge them with weight
115 115
 			// according to the matrix. The same matrix is simply repeated for higher radii.
116
-			for ($i = 0; $i < $radius; $i++)	{
117
-				imagecopy     ($imgBlur, $gdimg, 0, 0, 1, 1, $w - 1, $h - 1);            // up left
118
-				imagecopymerge($imgBlur, $gdimg, 1, 1, 0, 0, $w,     $h,     50.00000);  // down right
119
-				imagecopymerge($imgBlur, $gdimg, 0, 1, 1, 0, $w - 1, $h,     33.33333);  // down left
120
-				imagecopymerge($imgBlur, $gdimg, 1, 0, 0, 1, $w,     $h - 1, 25.00000);  // up right
121
-				imagecopymerge($imgBlur, $gdimg, 0, 0, 1, 0, $w - 1, $h,     33.33333);  // left
122
-				imagecopymerge($imgBlur, $gdimg, 1, 0, 0, 0, $w,     $h,     25.00000);  // right
123
-				imagecopymerge($imgBlur, $gdimg, 0, 0, 0, 1, $w,     $h - 1, 20.00000);  // up
124
-				imagecopymerge($imgBlur, $gdimg, 0, 1, 0, 0, $w,     $h,     16.666667); // down
125
-				imagecopymerge($imgBlur, $gdimg, 0, 0, 0, 0, $w,     $h,     50.000000); // center
126
-				imagecopy     ($gdimg, $imgBlur, 0, 0, 0, 0, $w,     $h);
116
+			for ($i = 0; $i < $radius; $i++) {
117
+				imagecopy($imgBlur, $gdimg, 0, 0, 1, 1, $w - 1, $h - 1); // up left
118
+				imagecopymerge($imgBlur, $gdimg, 1, 1, 0, 0, $w, $h, 50.00000); // down right
119
+				imagecopymerge($imgBlur, $gdimg, 0, 1, 1, 0, $w - 1, $h, 33.33333); // down left
120
+				imagecopymerge($imgBlur, $gdimg, 1, 0, 0, 1, $w, $h - 1, 25.00000); // up right
121
+				imagecopymerge($imgBlur, $gdimg, 0, 0, 1, 0, $w - 1, $h, 33.33333); // left
122
+				imagecopymerge($imgBlur, $gdimg, 1, 0, 0, 0, $w, $h, 25.00000); // right
123
+				imagecopymerge($imgBlur, $gdimg, 0, 0, 0, 1, $w, $h - 1, 20.00000); // up
124
+				imagecopymerge($imgBlur, $gdimg, 0, 1, 0, 0, $w, $h, 16.666667); // down
125
+				imagecopymerge($imgBlur, $gdimg, 0, 0, 0, 0, $w, $h, 50.000000); // center
126
+				imagecopy($gdimg, $imgBlur, 0, 0, 0, 0, $w, $h);
127 127
 			}
128 128
 			return true;
129 129
 		}
@@ -158,7 +158,7 @@  discard block
 block discarded – undo
158 158
 	}
159 159
 
160 160
 
161
-	public function Brightness(&$gdimg, $amount=0) {
161
+	public function Brightness(&$gdimg, $amount = 0) {
162 162
 		if ($amount == 0) {
163 163
 			return true;
164 164
 		}
@@ -189,7 +189,7 @@  discard block
 block discarded – undo
189 189
 	}
190 190
 
191 191
 
192
-	public function Contrast(&$gdimg, $amount=0) {
192
+	public function Contrast(&$gdimg, $amount = 0) {
193 193
 		if ($amount == 0) {
194 194
 			return true;
195 195
 		}
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
 
227 227
 
228 228
 	public function Colorize(&$gdimg, $amount, $targetColor) {
229
-		$amount      = (is_numeric($amount)                          ? $amount      : 25);
229
+		$amount      = (is_numeric($amount) ? $amount : 25);
230 230
 		$amountPct   = $amount / 100;
231 231
 		$targetColor = (phpthumb_functions::IsHexColor($targetColor) ? $targetColor : 'gray');
232 232
 
@@ -275,20 +275,20 @@  discard block
 block discarded – undo
275 275
 	}
276 276
 
277 277
 
278
-	public function Crop(&$gdimg, $left=0, $right=0, $top=0, $bottom=0) {
278
+	public function Crop(&$gdimg, $left = 0, $right = 0, $top = 0, $bottom = 0) {
279 279
 		if (!$left && !$right && !$top && !$bottom) {
280 280
 			return true;
281 281
 		}
282 282
 		$oldW = imagesx($gdimg);
283 283
 		$oldH = imagesy($gdimg);
284
-		if (($left   > 0) && ($left   < 1)) { $left   = round($left   * $oldW); }
285
-		if (($right  > 0) && ($right  < 1)) { $right  = round($right  * $oldW); }
286
-		if (($top    > 0) && ($top    < 1)) { $top    = round($top    * $oldH); }
284
+		if (($left > 0) && ($left < 1)) { $left   = round($left * $oldW); }
285
+		if (($right > 0) && ($right < 1)) { $right  = round($right * $oldW); }
286
+		if (($top > 0) && ($top < 1)) { $top    = round($top * $oldH); }
287 287
 		if (($bottom > 0) && ($bottom < 1)) { $bottom = round($bottom * $oldH); }
288 288
 		$right  = min($oldW - $left - 1, $right);
289
-		$bottom = min($oldH - $top  - 1, $bottom);
289
+		$bottom = min($oldH - $top - 1, $bottom);
290 290
 		$newW = $oldW - $left - $right;
291
-		$newH = $oldH - $top  - $bottom;
291
+		$newH = $oldH - $top - $bottom;
292 292
 
293 293
 		if ($imgCropped = imagecreatetruecolor($newW, $newH)) {
294 294
 			imagecopy($imgCropped, $gdimg, 0, 0, $left, $top, $newW, $newH);
@@ -303,7 +303,7 @@  discard block
 block discarded – undo
303 303
 	}
304 304
 
305 305
 
306
-	public function Desaturate(&$gdimg, $amount, $color='') {
306
+	public function Desaturate(&$gdimg, $amount, $color = '') {
307 307
 		if ($amount == 0) {
308 308
 			return true;
309 309
 		}
@@ -315,11 +315,11 @@  discard block
 block discarded – undo
315 315
 		if (phpthumb_functions::gd_version() < 2) {
316 316
 			return false;
317 317
 		}
318
-		$distance =                 ($distance ? $distance : 10);
319
-		$width    =                 ($width    ? $width    : 10);
320
-		$hexcolor =                 ($hexcolor ? $hexcolor : '000000');
321
-		$angle    =                 ($angle    ? $angle    : 225) % 360;
322
-		$alpha    = max(0, min(100, ($alpha    ? $alpha    : 100)));
318
+		$distance = ($distance ? $distance : 10);
319
+		$width    = ($width ? $width : 10);
320
+		$hexcolor = ($hexcolor ? $hexcolor : '000000');
321
+		$angle    = ($angle ? $angle : 225) % 360;
322
+		$alpha    = max(0, min(100, ($alpha ? $alpha : 100)));
323 323
 
324 324
 		if ($alpha <= 0) {
325 325
 			// invisible shadow, nothing to do
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
 			$Offset['y'] = sin(deg2rad($angle)) * ($distance + $i);
342 342
 		}
343 343
 
344
-		$tempImageWidth  = imagesx($gdimg)  + abs($Offset['x']);
344
+		$tempImageWidth  = imagesx($gdimg) + abs($Offset['x']);
345 345
 		$tempImageHeight = imagesy($gdimg) + abs($Offset['y']);
346 346
 
347 347
 		if ($gdimg_dropshadow_temp = phpthumb_functions::ImageCreateFunction($tempImageWidth, $tempImageHeight)) {
@@ -449,7 +449,7 @@  discard block
 block discarded – undo
449 449
 	}
450 450
 
451 451
 
452
-	public function Flip(&$gdimg, $x=false, $y=false) {
452
+	public function Flip(&$gdimg, $x = false, $y = false) {
453 453
 		if (!$x && !$y) {
454 454
 			return false;
455 455
 		}
@@ -473,21 +473,21 @@  discard block
 block discarded – undo
473 473
 
474 474
 
475 475
 	public function Frame(&$gdimg, $frame_width, $edge_width, $hexcolor_frame, $hexcolor1, $hexcolor2) {
476
-		$frame_width    = ($frame_width    ? $frame_width    : 5);
477
-		$edge_width     = ($edge_width     ? $edge_width     : 1);
476
+		$frame_width    = ($frame_width ? $frame_width : 5);
477
+		$edge_width     = ($edge_width ? $edge_width : 1);
478 478
 		$hexcolor_frame = ($hexcolor_frame ? $hexcolor_frame : 'CCCCCC');
479
-		$hexcolor1      = ($hexcolor1      ? $hexcolor1      : 'FFFFFF');
480
-		$hexcolor2      = ($hexcolor2      ? $hexcolor2      : '000000');
479
+		$hexcolor1      = ($hexcolor1 ? $hexcolor1 : 'FFFFFF');
480
+		$hexcolor2      = ($hexcolor2 ? $hexcolor2 : '000000');
481 481
 
482 482
 		$color_frame = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor_frame);
483 483
 		$color1      = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor1);
484 484
 		$color2      = phpthumb_functions::ImageHexColorAllocate($gdimg, $hexcolor2);
485 485
 		for ($i = 0; $i < $edge_width; $i++) {
486 486
 			// outer bevel
487
-			imageline($gdimg,                   $i,                   $i,                   $i, imagesy($gdimg) - $i, $color1); // left
488
-			imageline($gdimg,                   $i,                   $i, imagesx($gdimg) - $i,                   $i, $color1); // top
489
-			imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i, imagesx($gdimg) - $i,                   $i, $color2); // right
490
-			imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i,                   $i, imagesy($gdimg) - $i, $color2); // bottom
487
+			imageline($gdimg, $i, $i, $i, imagesy($gdimg) - $i, $color1); // left
488
+			imageline($gdimg, $i, $i, imagesx($gdimg) - $i, $i, $color1); // top
489
+			imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i, imagesx($gdimg) - $i, $i, $color2); // right
490
+			imageline($gdimg, imagesx($gdimg) - $i, imagesy($gdimg) - $i, $i, imagesy($gdimg) - $i, $color2); // bottom
491 491
 		}
492 492
 		for ($i = 0; $i < $frame_width; $i++) {
493 493
 			// actual frame
@@ -495,10 +495,10 @@  discard block
 block discarded – undo
495 495
 		}
496 496
 		for ($i = 0; $i < $edge_width; $i++) {
497 497
 			// inner bevel
498
-			imageline($gdimg,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $color2); // left
499
-			imageline($gdimg,                   $frame_width + $edge_width + $i,                   $frame_width + $edge_width + $i, imagesx($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, $color2); // top
500
-			imageline($gdimg, imagesx($gdimg) - $frame_width - $edge_width - $i, imagesy($gdimg) - $frame_width - $edge_width - $i, imagesx($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, $color1); // right
501
-			imageline($gdimg, imagesx($gdimg) - $frame_width - $edge_width - $i, imagesy($gdimg) - $frame_width - $edge_width - $i,                   $frame_width + $edge_width + $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $color1); // bottom
498
+			imageline($gdimg, $frame_width + $edge_width + $i, $frame_width + $edge_width + $i, $frame_width + $edge_width + $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $color2); // left
499
+			imageline($gdimg, $frame_width + $edge_width + $i, $frame_width + $edge_width + $i, imagesx($gdimg) - $frame_width - $edge_width - $i, $frame_width + $edge_width + $i, $color2); // top
500
+			imageline($gdimg, imagesx($gdimg) - $frame_width - $edge_width - $i, imagesy($gdimg) - $frame_width - $edge_width - $i, imagesx($gdimg) - $frame_width - $edge_width - $i, $frame_width + $edge_width + $i, $color1); // right
501
+			imageline($gdimg, imagesx($gdimg) - $frame_width - $edge_width - $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $frame_width + $edge_width + $i, imagesy($gdimg) - $frame_width - $edge_width - $i, $color1); // bottom
502 502
 		}
503 503
 		return true;
504 504
 	}
@@ -524,7 +524,7 @@  discard block
 block discarded – undo
524 524
 	}
525 525
 
526 526
 
527
-	public function HistogramAnalysis(&$gdimg, $calculateGray=false) {
527
+	public function HistogramAnalysis(&$gdimg, $calculateGray = false) {
528 528
 		$ImageSX = imagesx($gdimg);
529 529
 		$ImageSY = imagesy($gdimg);
530 530
 		$Analysis = array();
@@ -552,13 +552,13 @@  discard block
 block discarded – undo
552 552
 	}
553 553
 
554 554
 
555
-	public function HistogramStretch(&$gdimg, $band='*', $method=0, $threshold=0.1) {
555
+	public function HistogramStretch(&$gdimg, $band = '*', $method = 0, $threshold = 0.1) {
556 556
 		// equivalent of "Auto Contrast" in Adobe Photoshop
557 557
 		// method 0 stretches according to RGB colors. Gives a more conservative stretch.
558 558
 		// method 1 band stretches according to grayscale which is color-biased (59% green, 30% red, 11% blue). May give a punchier / more aggressive stretch, possibly appearing over-saturated
559 559
 		$Analysis = self::HistogramAnalysis($gdimg, true);
560 560
 		$keys = array('r'=>'red', 'g'=>'green', 'b'=>'blue', 'a'=>'alpha', '*'=>(($method == 0) ? 'all' : 'gray'));
561
-		$band = $band[ 0 ];
561
+		$band = $band[0];
562 562
 		if (!isset($keys[$band])) {
563 563
 			return false;
564 564
 		}
@@ -568,7 +568,7 @@  discard block
 block discarded – undo
568 568
 		// pixel in the image could throw off the whole system. Instead, count up/down
569 569
 		// from the limit and allow <threshold> (default = 0.1%) of brightest/darkest
570 570
 		// pixels to be clipped to min/max
571
-		$threshold = (float) $threshold / 100;
571
+		$threshold = (float)$threshold / 100;
572 572
 		$clip_threshold = imagesx($gdimg) * imagesx($gdimg) * $threshold;
573 573
 
574 574
 		$countsum  = 0;
@@ -586,7 +586,7 @@  discard block
 block discarded – undo
586 586
 		}
587 587
 		$range_min = max($range_min, 0);
588 588
 
589
-		$countsum  =   0;
589
+		$countsum  = 0;
590 590
 		$range_max = 255;
591 591
 		for ($i = 255; $i >= 0; $i--) {
592 592
 			if ($method == 0) {
@@ -613,9 +613,9 @@  discard block
 block discarded – undo
613 613
 			for ($y = 0; $y < $ImageSY; $y++) {
614 614
 				$OriginalPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
615 615
 				if ($band == '*') {
616
-					$new['red']   = min(255, max(0, ($OriginalPixel['red']   - $range_min) * $range_scale));
616
+					$new['red']   = min(255, max(0, ($OriginalPixel['red'] - $range_min) * $range_scale));
617 617
 					$new['green'] = min(255, max(0, ($OriginalPixel['green'] - $range_min) * $range_scale));
618
-					$new['blue']  = min(255, max(0, ($OriginalPixel['blue']  - $range_min) * $range_scale));
618
+					$new['blue']  = min(255, max(0, ($OriginalPixel['blue'] - $range_min) * $range_scale));
619 619
 					$new['alpha'] = min(255, max(0, ($OriginalPixel['alpha'] - $range_min) * $range_scale));
620 620
 				} else {
621 621
 					$new = $OriginalPixel;
@@ -630,7 +630,7 @@  discard block
 block discarded – undo
630 630
 	}
631 631
 
632 632
 
633
-	public function HistogramOverlay(&$gdimg, $bands='*', $colors='', $width=0.25, $height=0.25, $alignment='BR', $opacity=50, $margin_x=5, $margin_y=null) {
633
+	public function HistogramOverlay(&$gdimg, $bands = '*', $colors = '', $width = 0.25, $height = 0.25, $alignment = 'BR', $opacity = 50, $margin_x = 5, $margin_y = null) {
634 634
 		$margin_y = (null === $margin_y ? $margin_x : $margin_y);
635 635
 
636 636
 		$Analysis = self::HistogramAnalysis($gdimg, true);
@@ -682,14 +682,14 @@  discard block
 block discarded – undo
682 682
 
683 683
 	public function ImageBorder(&$gdimg, $border_width, $radius_x, $radius_y, $hexcolor_border) {
684 684
 		$border_width = ($border_width ? $border_width : 1);
685
-		$radius_x     = ($radius_x     ? $radius_x     : 0);
686
-		$radius_y     = ($radius_y     ? $radius_y     : 0);
685
+		$radius_x     = ($radius_x ? $radius_x : 0);
686
+		$radius_y     = ($radius_y ? $radius_y : 0);
687 687
 
688 688
 		$output_width  = imagesx($gdimg);
689 689
 		$output_height = imagesy($gdimg);
690 690
 
691 691
 		list($new_width, $new_height) = phpthumb_functions::ProportionalResize($output_width, $output_height, $output_width - max($border_width * 2, $radius_x), $output_height - max($border_width * 2, $radius_y));
692
-		$offset_x = ($radius_x ? $output_width  - $new_width  - $radius_x : 0);
692
+		$offset_x = ($radius_x ? $output_width - $new_width - $radius_x : 0);
693 693
 
694 694
 		if ($gd_border_canvas = phpthumb_functions::ImageCreateFunction($output_width, $output_height)) {
695 695
 
@@ -701,10 +701,10 @@  discard block
 block discarded – undo
701 701
 			$color_border = phpthumb_functions::ImageHexColorAllocate($gd_border_canvas, (phpthumb_functions::IsHexColor($hexcolor_border) ? $hexcolor_border : '000000'));
702 702
 
703 703
 			for ($i = 0; $i < $border_width; $i++) {
704
-				imageline($gd_border_canvas,             floor($offset_x / 2) + $radius_x,                      $i, $output_width - $radius_x - ceil($offset_x / 2),                         $i, $color_border); // top
705
-				imageline($gd_border_canvas,             floor($offset_x / 2) + $radius_x, $output_height - 1 - $i, $output_width - $radius_x - ceil($offset_x / 2),    $output_height - 1 - $i, $color_border); // bottom
706
-				imageline($gd_border_canvas,                    floor($offset_x / 2) + $i,               $radius_y,                      floor($offset_x / 2) +  $i, $output_height - $radius_y, $color_border); // left
707
-				imageline($gd_border_canvas, $output_width - 1 - $i - ceil($offset_x / 2),               $radius_y,    $output_width - 1 - $i - ceil($offset_x / 2), $output_height - $radius_y, $color_border); // right
704
+				imageline($gd_border_canvas, floor($offset_x / 2) + $radius_x, $i, $output_width - $radius_x - ceil($offset_x / 2), $i, $color_border); // top
705
+				imageline($gd_border_canvas, floor($offset_x / 2) + $radius_x, $output_height - 1 - $i, $output_width - $radius_x - ceil($offset_x / 2), $output_height - 1 - $i, $color_border); // bottom
706
+				imageline($gd_border_canvas, floor($offset_x / 2) + $i, $radius_y, floor($offset_x / 2) + $i, $output_height - $radius_y, $color_border); // left
707
+				imageline($gd_border_canvas, $output_width - 1 - $i - ceil($offset_x / 2), $radius_y, $output_width - 1 - $i - ceil($offset_x / 2), $output_height - $radius_y, $color_border); // right
708 708
 			}
709 709
 
710 710
 			if ($radius_x && $radius_y) {
@@ -716,17 +716,17 @@  discard block
 block discarded – undo
716 716
 				// Solution: draw non-parallel arcs, from one side of the line thickness at the start angle
717 717
 				//   to the opposite edge of the line thickness at the terminating angle
718 718
 				for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) {
719
-					imagearc($gd_border_canvas, floor($offset_x / 2) + 1 +                 $radius_x,              $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
720
-					imagearc($gd_border_canvas,                     $output_width - $radius_x - 1 - ceil($offset_x / 2),              $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
721
-					imagearc($gd_border_canvas,                     $output_width - $radius_x - 1 - ceil($offset_x / 2), $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2,   0,  90, $color_border); // bottom-right
722
-					imagearc($gd_border_canvas, floor($offset_x / 2) + 1 +                 $radius_x, $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2,  90, 180, $color_border); // bottom-left
719
+					imagearc($gd_border_canvas, floor($offset_x / 2) + 1 + $radius_x, $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
720
+					imagearc($gd_border_canvas, $output_width - $radius_x - 1 - ceil($offset_x / 2), $thickness_offset - 1 + $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
721
+					imagearc($gd_border_canvas, $output_width - $radius_x - 1 - ceil($offset_x / 2), $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2, 0, 90, $color_border); // bottom-right
722
+					imagearc($gd_border_canvas, floor($offset_x / 2) + 1 + $radius_x, $output_height - $thickness_offset - $radius_y, $radius_x * 2, $radius_y * 2, 90, 180, $color_border); // bottom-left
723 723
 				}
724 724
 				if ($border_width > 1) {
725 725
 					for ($thickness_offset = 0; $thickness_offset < $border_width; $thickness_offset++) {
726
-						imagearc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x,                                      $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
727
-						imagearc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2),                                      $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
728
-						imagearc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2),                     $output_height - $radius_y, $radius_x * 2, $radius_y * 2,   0,  90, $color_border); // bottom-right
729
-						imagearc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x,                     $output_height - $radius_y, $radius_x * 2, $radius_y * 2,  90, 180, $color_border); // bottom-left
726
+						imagearc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x, $radius_y, $radius_x * 2, $radius_y * 2, 180, 270, $color_border); // top-left
727
+						imagearc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2), $radius_y, $radius_x * 2, $radius_y * 2, 270, 360, $color_border); // top-right
728
+						imagearc($gd_border_canvas, $output_width - $thickness_offset - $radius_x - 1 - ceil($offset_x / 2), $output_height - $radius_y, $radius_x * 2, $radius_y * 2, 0, 90, $color_border); // bottom-right
729
+						imagearc($gd_border_canvas, floor($offset_x / 2) + $thickness_offset + $radius_x, $output_height - $radius_y, $radius_x * 2, $radius_y * 2, 90, 180, $color_border); // bottom-left
730 730
 					}
731 731
 				}
732 732
 
@@ -752,7 +752,7 @@  discard block
 block discarded – undo
752 752
 	}
753 753
 
754 754
 
755
-	public static function ImprovedImageRotate(&$gdimg_source, $rotate_angle=0, $config_background_hexcolor='FFFFFF', $bg=null, &$phpThumbObject) {
755
+	public static function ImprovedImageRotate(&$gdimg_source, $rotate_angle = 0, $config_background_hexcolor = 'FFFFFF', $bg = null, &$phpThumbObject) {
756 756
 		while ($rotate_angle < 0) {
757 757
 			$rotate_angle += 360;
758 758
 		}
@@ -780,7 +780,7 @@  discard block
 block discarded – undo
780 780
 						}
781 781
 					}
782 782
 					$gdimg_rotate_mask = imagerotate($gdimg_rotate_mask, $rotate_angle, $color_mask[0]);
783
-					$gdimg_source      = imagerotate($gdimg_source,      $rotate_angle, $background_color);
783
+					$gdimg_source      = imagerotate($gdimg_source, $rotate_angle, $background_color);
784 784
 
785 785
 					imagealphablending($gdimg_source, false);
786 786
 					imagesavealpha($gdimg_source, true);
@@ -896,10 +896,10 @@  discard block
 block discarded – undo
896 896
 
897 897
 				imagefilledrectangle($gdimg_cornermask, 0, 0, imagesx($gdimg), imagesy($gdimg), $color_transparent);
898 898
 
899
-				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple,                           0,                           0,     $radius_x,     $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
900
-				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple,                           0, imagesy($gdimg) - $radius_y,     $radius_x, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
899
+				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, 0, 0, $radius_x, $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
900
+				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, 0, imagesy($gdimg) - $radius_y, $radius_x, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
901 901
 				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, imagesx($gdimg) - $radius_x, imagesy($gdimg) - $radius_y, $radius_x * 3, $radius_y * 3, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
902
-				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, imagesx($gdimg) - $radius_x,                           0, $radius_x * 3,     $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
902
+				imagecopyresampled($gdimg_cornermask, $gdimg_cornermask_triple, imagesx($gdimg) - $radius_x, 0, $radius_x * 3, $radius_y, $radius_x, $radius_y, $radius_x * 2, $radius_y * 2);
903 903
 
904 904
 				self::ApplyMask($gdimg_cornermask, $gdimg);
905 905
 				imagedestroy($gdimg_cornermask);
@@ -918,7 +918,7 @@  discard block
 block discarded – undo
918 918
 	}
919 919
 
920 920
 
921
-	public function Saturation(&$gdimg, $amount, $color='') {
921
+	public function Saturation(&$gdimg, $amount, $color = '') {
922 922
 		if ($amount == 0) {
923 923
 			return true;
924 924
 		} elseif ($amount > 0) {
@@ -987,7 +987,7 @@  discard block
 block discarded – undo
987 987
 	}
988 988
 
989 989
 
990
-	public function Smooth(&$gdimg, $amount=6) {
990
+	public function Smooth(&$gdimg, $amount = 6) {
991 991
 		$amount = min(25, max(0, $amount));
992 992
 		if ($amount == 0) {
993 993
 			return true;
@@ -1005,7 +1005,7 @@  discard block
 block discarded – undo
1005 1005
 	}
1006 1006
 
1007 1007
 
1008
-	public function SourceTransparentColorMask(&$gdimg, $hexcolor, $min_limit=5, $max_limit=10) {
1008
+	public function SourceTransparentColorMask(&$gdimg, $hexcolor, $min_limit = 5, $max_limit = 10) {
1009 1009
 		$width  = imagesx($gdimg);
1010 1010
 		$height = imagesy($gdimg);
1011 1011
 		if ($gdimg_mask = imagecreatetruecolor($width, $height)) {
@@ -1063,7 +1063,7 @@  discard block
 block discarded – undo
1063 1063
 		return true;
1064 1064
 	}
1065 1065
 
1066
-	public function ReduceColorDepth(&$gdimg, $colors=256, $dither=true) {
1066
+	public function ReduceColorDepth(&$gdimg, $colors = 256, $dither = true) {
1067 1067
 		$colors = max(min($colors, 256), 2);
1068 1068
 		// imagetruecolortopalette usually makes ugly colors, the replacement is a bit better
1069 1069
 		//imagetruecolortopalette($gdimg, $dither, $colors);
@@ -1072,7 +1072,7 @@  discard block
 block discarded – undo
1072 1072
 	}
1073 1073
 
1074 1074
 
1075
-	public function WhiteBalance(&$gdimg, $targetColor='') {
1075
+	public function WhiteBalance(&$gdimg, $targetColor = '') {
1076 1076
 		if (phpthumb_functions::IsHexColor($targetColor)) {
1077 1077
 			$targetPixel = array(
1078 1078
 				'red'   => hexdec(substr($targetColor, 0, 2)),
@@ -1097,9 +1097,9 @@  discard block
 block discarded – undo
1097 1097
 				$currentPixel = phpthumb_functions::GetPixelColor($gdimg, $x, $y);
1098 1098
 				$newColor = phpthumb_functions::ImageColorAllocateAlphaSafe(
1099 1099
 					$gdimg,
1100
-					max(0, min(255, round($currentPixel['red']   * $scaleR))),
1100
+					max(0, min(255, round($currentPixel['red'] * $scaleR))),
1101 1101
 					max(0, min(255, round($currentPixel['green'] * $scaleG))),
1102
-					max(0, min(255, round($currentPixel['blue']  * $scaleB))),
1102
+					max(0, min(255, round($currentPixel['blue'] * $scaleB))),
1103 1103
 					$currentPixel['alpha']
1104 1104
 				);
1105 1105
 				imagesetpixel($gdimg, $x, $y, $newColor);
@@ -1109,7 +1109,7 @@  discard block
 block discarded – undo
1109 1109
 	}
1110 1110
 
1111 1111
 
1112
-	public function WatermarkText(&$gdimg, $text, $size, $alignment, $hex_color='000000', $ttffont='', $opacity=100, $margin=5, $angle=0, $bg_color=false, $bg_opacity=0, $fillextend='', $lineheight=1.0) {
1112
+	public function WatermarkText(&$gdimg, $text, $size, $alignment, $hex_color = '000000', $ttffont = '', $opacity = 100, $margin = 5, $angle = 0, $bg_color = false, $bg_opacity = 0, $fillextend = '', $lineheight = 1.0) {
1113 1113
 		// text watermark requested
1114 1114
 		if (!$text) {
1115 1115
 			return false;
@@ -1117,15 +1117,15 @@  discard block
 block discarded – undo
1117 1117
 		imagealphablending($gdimg, true);
1118 1118
 
1119 1119
 		if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)(@[LCR])?$#i', $alignment, $matches)) {
1120
-			$originOffsetX = (int) $matches[ 1];
1121
-			$originOffsetY = (int) $matches[ 2];
1120
+			$originOffsetX = (int)$matches[1];
1121
+			$originOffsetY = (int)$matches[2];
1122 1122
 			$alignment = (@$matches[4] ? $matches[4] : 'L');
1123 1123
 			$margin = 0;
1124 1124
 		} else {
1125 1125
 			$originOffsetX = 0;
1126 1126
 			$originOffsetY = 0;
1127 1127
 		}
1128
-		$lineheight = min(100.0, max(0.01, (float) $lineheight));
1128
+		$lineheight = min(100.0, max(0.01, (float)$lineheight));
1129 1129
 
1130 1130
 		$metaTextArray = array(
1131 1131
 			'^Fb' =>       $this->phpThumbObject->getimagesizeinfo['filesize'],
@@ -1148,7 +1148,7 @@  discard block
 block discarded – undo
1148 1148
 
1149 1149
 		if (@is_readable($ttffont) && is_file($ttffont)) {
1150 1150
 
1151
-			$opacity = 100 - (int) max(min($opacity, 100), 0);
1151
+			$opacity = 100 - (int)max(min($opacity, 100), 0);
1152 1152
 			$letter_color_text = phpthumb_functions::ImageHexColorAllocate($gdimg, $hex_color, false, $opacity * 1.27);
1153 1153
 
1154 1154
 			$this->DebugMessage('Using TTF font "'.$ttffont.'"', __FILE__, __LINE__);
@@ -1209,7 +1209,7 @@  discard block
 block discarded – undo
1209 1209
 						break;
1210 1210
 
1211 1211
 					case 'R':
1212
-						$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1212
+						$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1213 1213
 						$text_origin_y = ($originOffsetY ? $originOffsetY : round((imagesy($gdimg) - $text_height) / 2) + $char_height);
1214 1214
 						break;
1215 1215
 
@@ -1224,7 +1224,7 @@  discard block
 block discarded – undo
1224 1224
 						break;
1225 1225
 
1226 1226
 					case 'TR':
1227
-						$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1227
+						$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1228 1228
 						$text_origin_y = $char_height + $margin + $originOffsetY;
1229 1229
 						break;
1230 1230
 
@@ -1235,7 +1235,7 @@  discard block
 block discarded – undo
1235 1235
 
1236 1236
 					case 'BR':
1237 1237
 					default:
1238
-						$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1238
+						$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width : imagesx($gdimg) - $text_width + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1239 1239
 						$text_origin_y = imagesy($gdimg) + $TTFbox[1] - $margin + $originOffsetY;
1240 1240
 						break;
1241 1241
 				}
@@ -1250,8 +1250,8 @@  discard block
 block discarded – undo
1250 1250
 				$y1 = $text_origin_y + $TTFbox[1];
1251 1251
 				$x2 = $text_origin_x + $min_x + $text_width;
1252 1252
 				$y2 = $text_origin_y + $TTFbox[1] - $text_height;
1253
-				$x_TL = false !== stripos($fillextend, "x") ?               0 : min($x1, $x2);
1254
-				$y_TL = false !== stripos($fillextend, "y") ?               0 : min($y1, $y2);
1253
+				$x_TL = false !== stripos($fillextend, "x") ? 0 : min($x1, $x2);
1254
+				$y_TL = false !== stripos($fillextend, "y") ? 0 : min($y1, $y2);
1255 1255
 				$x_BR = false !== stripos($fillextend, "x") ? imagesx($gdimg) : max($x1, $x2);
1256 1256
 				$y_BR = false !== stripos($fillextend, "y") ? imagesy($gdimg) : max($y1, $y2);
1257 1257
 				$this->DebugMessage('WatermarkText() calling imagefilledrectangle($gdimg, '.$x_TL.', '.$y_TL.', '.$x_BR.', '.$y_BR.', $text_color_background)', __FILE__, __LINE__);
@@ -1286,7 +1286,7 @@  discard block
 block discarded – undo
1286 1286
 						case 'R':
1287 1287
 						case 'TR':
1288 1288
 						case 'BR':
1289
-							$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width_line : imagesx($gdimg) - $text_width_line  + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1289
+							$text_origin_x = ($originOffsetX ? $originOffsetX - $text_width_line : imagesx($gdimg) - $text_width_line + $TTFbox[0] - $min_x + round($size * 0.25) - $margin);
1290 1290
 							break;
1291 1291
 					}
1292 1292
 
@@ -1406,7 +1406,7 @@  discard block
 block discarded – undo
1406 1406
 					}
1407 1407
 				}
1408 1408
 				if ($angle && $img_watermark_mask) {
1409
-					$img_watermark      = imagerotate($img_watermark,      $angle, $text_color_background);
1409
+					$img_watermark      = imagerotate($img_watermark, $angle, $text_color_background);
1410 1410
 					$img_watermark_mask = imagerotate($img_watermark_mask, $angle, $mask_color_background);
1411 1411
 					self::ApplyMask($img_watermark_mask, $img_watermark);
1412 1412
 				}
@@ -1422,7 +1422,7 @@  discard block
 block discarded – undo
1422 1422
 	}
1423 1423
 
1424 1424
 
1425
-	public function WatermarkOverlay(&$gdimg_dest, &$img_watermark, $alignment='*', $opacity=50, $margin_x=5, $margin_y=null) {
1425
+	public function WatermarkOverlay(&$gdimg_dest, &$img_watermark, $alignment = '*', $opacity = 50, $margin_x = 5, $margin_y = null) {
1426 1426
 
1427 1427
 		if (is_resource($gdimg_dest) && is_resource($img_watermark)) {
1428 1428
 			$img_source_width          = imagesx($gdimg_dest);
@@ -1431,13 +1431,13 @@  discard block
 block discarded – undo
1431 1431
 			$watermark_source_height   = imagesy($img_watermark);
1432 1432
 			$watermark_opacity_percent = max(0, min(100, $opacity));
1433 1433
 			$margin_y = (null === $margin_y ? $margin_x : $margin_y);
1434
-			$watermark_margin_x = ((($margin_x > 0) && ($margin_x < 1)) ? round((1 - $margin_x) * $img_source_width)  : $margin_x);
1434
+			$watermark_margin_x = ((($margin_x > 0) && ($margin_x < 1)) ? round((1 - $margin_x) * $img_source_width) : $margin_x);
1435 1435
 			$watermark_margin_y = ((($margin_y > 0) && ($margin_y < 1)) ? round((1 - $margin_y) * $img_source_height) : $margin_y);
1436 1436
 			$watermark_destination_x = 0;
1437 1437
 			$watermark_destination_y = 0;
1438 1438
 			if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
1439
-				$watermark_destination_x = (int) $matches[ 1];
1440
-				$watermark_destination_y = (int) $matches[ 2];
1439
+				$watermark_destination_x = (int)$matches[1];
1440
+				$watermark_destination_y = (int)$matches[2];
1441 1441
 			} else {
1442 1442
 				switch ($alignment) {
1443 1443
 					case '*':
@@ -1467,7 +1467,7 @@  discard block
 block discarded – undo
1467 1467
 										$y,
1468 1468
 										0,
1469 1469
 										0,
1470
-										min($watermark_source_width,  $img_source_width  - $x - $watermark_margin_x),
1470
+										min($watermark_source_width, $img_source_width - $x - $watermark_margin_x),
1471 1471
 										min($watermark_source_height, $img_source_height - $y - $watermark_margin_y)
1472 1472
 									);
1473 1473
 								}
@@ -1484,12 +1484,12 @@  discard block
 block discarded – undo
1484 1484
 						break;
1485 1485
 
1486 1486
 					case 'T':
1487
-						$watermark_destination_x = round((($img_source_width  / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1487
+						$watermark_destination_x = round((($img_source_width / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1488 1488
 						$watermark_destination_y = $watermark_margin_y;
1489 1489
 						break;
1490 1490
 
1491 1491
 					case 'B':
1492
-						$watermark_destination_x = round((($img_source_width  / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1492
+						$watermark_destination_x = round((($img_source_width / 2) - ($watermark_source_width / 2)) + $watermark_margin_x);
1493 1493
 						$watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1494 1494
 						break;
1495 1495
 
@@ -1504,7 +1504,7 @@  discard block
 block discarded – undo
1504 1504
 						break;
1505 1505
 
1506 1506
 					case 'C':
1507
-						$watermark_destination_x = round(($img_source_width  / 2) - ($watermark_source_width  / 2));
1507
+						$watermark_destination_x = round(($img_source_width / 2) - ($watermark_source_width / 2));
1508 1508
 						$watermark_destination_y = round(($img_source_height / 2) - ($watermark_source_height / 2));
1509 1509
 						break;
1510 1510
 
@@ -1525,7 +1525,7 @@  discard block
 block discarded – undo
1525 1525
 
1526 1526
 					case 'BR':
1527 1527
 					default:
1528
-						$watermark_destination_x = $img_source_width  - $watermark_source_width  - $watermark_margin_x;
1528
+						$watermark_destination_x = $img_source_width - $watermark_source_width - $watermark_margin_x;
1529 1529
 						$watermark_destination_y = $img_source_height - $watermark_source_height - $watermark_margin_y;
1530 1530
 						break;
1531 1531
 				}
Please login to merge, or discard this patch.
htdocs/modules/system/class/thumbs/index.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -1,10 +1,10 @@
 block discarded – undo
1 1
 <?php
2 2
 if (!file_exists('phpThumb.config.php')) {
3
-	if (file_exists('phpThumb.config.php.default')) {
4
-		echo 'WARNING! "phpThumb.config.php.default" MUST be renamed to "phpThumb.config.php"';
5
-	} else {
6
-		echo 'WARNING! "phpThumb.config.php" should exist but does not';
7
-	}
8
-	exit;
3
+    if (file_exists('phpThumb.config.php.default')) {
4
+        echo 'WARNING! "phpThumb.config.php.default" MUST be renamed to "phpThumb.config.php"';
5
+    } else {
6
+        echo 'WARNING! "phpThumb.config.php" should exist but does not';
7
+    }
8
+    exit;
9 9
 }
10 10
 header('Location: ./demo/');
Please login to merge, or discard this patch.
htdocs/modules/system/class/thumbs/phpthumb.ico.php 2 patches
Indentation   +104 added lines, -104 removed lines patch added patch discarded remove patch
@@ -12,109 +12,109 @@
 block discarded – undo
12 12
 
13 13
 class phpthumb_ico {
14 14
 
15
-	public function GD2ICOstring(&$gd_image_array) {
16
-		$ImageWidths  = array();
17
-		$ImageHeights = array();
18
-		$bpp          = array();
19
-		$totalcolors  = array();
20
-		$icXOR        = array();
21
-		$icAND        = array();
22
-		$icANDmask    = array();
23
-		foreach ($gd_image_array as $key => $gd_image) {
24
-
25
-			$ImageWidths[$key]  = imagesx($gd_image);
26
-			$ImageHeights[$key] = imagesy($gd_image);
27
-			$bpp[$key]          = imageistruecolor($gd_image) ? 32 : 24;
28
-			$totalcolors[$key]  = imagecolorstotal($gd_image);
29
-
30
-			$icXOR[$key] = '';
31
-			for ($y = $ImageHeights[$key] - 1; $y >= 0; $y--) {
32
-				for ($x = 0; $x < $ImageWidths[$key]; $x++) {
33
-					$argb = phpthumb_functions::GetPixelColor($gd_image, $x, $y);
34
-					$a = round(255 * ((127 - $argb['alpha']) / 127));
35
-					$r = $argb['red'];
36
-					$g = $argb['green'];
37
-					$b = $argb['blue'];
38
-
39
-					if ($bpp[$key] == 32) {
40
-						$icXOR[$key] .= chr($b).chr($g).chr($r).chr($a);
41
-					} elseif ($bpp[$key] == 24) {
42
-						$icXOR[$key] .= chr($b).chr($g).chr($r);
43
-					}
44
-
45
-					if ($a < 128) {
46
-						@$icANDmask[$key][$y] .= '1';
47
-					} else {
48
-						@$icANDmask[$key][$y] .= '0';
49
-					}
50
-				}
51
-				// mask bits are 32-bit aligned per scanline
52
-				while (strlen($icANDmask[$key][$y]) % 32) {
53
-					$icANDmask[$key][$y] .= '0';
54
-				}
55
-			}
56
-			$icAND[$key] = '';
57
-			foreach ($icANDmask[$key] as $y => $scanlinemaskbits) {
58
-				for ($i = 0, $iMax = strlen($scanlinemaskbits); $i < $iMax; $i += 8) {
59
-					$icAND[$key] .= chr(bindec(str_pad(substr($scanlinemaskbits, $i, 8), 8, '0', STR_PAD_LEFT)));
60
-				}
61
-			}
62
-
63
-		}
64
-
65
-		foreach ($gd_image_array as $key => $gd_image) {
66
-			$biSizeImage = $ImageWidths[$key] * $ImageHeights[$key] * ($bpp[$key] / 8);
67
-
68
-			// BITMAPINFOHEADER - 40 bytes
69
-			$BitmapInfoHeader[$key]  = '';
70
-			$BitmapInfoHeader[$key] .= "\x28\x00\x00\x00";                              // DWORD  biSize;
71
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4);      // LONG   biWidth;
72
-			// The biHeight member specifies the combined
73
-			// height of the XOR and AND masks.
74
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG   biHeight;
75
-			$BitmapInfoHeader[$key] .= "\x01\x00";                                      // WORD   biPlanes;
76
-			$BitmapInfoHeader[$key] .= chr($bpp[$key])."\x00";                          // wBitCount;
77
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // DWORD  biCompression;
78
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4);            // DWORD  biSizeImage;
79
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // LONG   biXPelsPerMeter;
80
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // LONG   biYPelsPerMeter;
81
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // DWORD  biClrUsed;
82
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // DWORD  biClrImportant;
83
-		}
84
-
85
-
86
-		$icondata  = "\x00\x00";                                      // idReserved;   // Reserved (must be 0)
87
-		$icondata .= "\x01\x00";                                      // idType;       // Resource Type (1 for icons)
88
-		$icondata .= phpthumb_functions::LittleEndian2String(count($gd_image_array), 2);  // idCount;      // How many images?
89
-
90
-		$dwImageOffset = 6 + (count($gd_image_array) * 16);
91
-		foreach ($gd_image_array as $key => $gd_image) {
92
-			// ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
93
-
94
-			$icondata .= chr($ImageWidths[$key]);                     // bWidth;          // Width, in pixels, of the image
95
-			$icondata .= chr($ImageHeights[$key]);                    // bHeight;         // Height, in pixels, of the image
96
-			$icondata .= chr($totalcolors[$key]);                     // bColorCount;     // Number of colors in image (0 if >=8bpp)
97
-			$icondata .= "\x00";                                      // bReserved;       // Reserved ( must be 0)
98
-
99
-			$icondata .= "\x01\x00";                                  // wPlanes;         // Color Planes
100
-			$icondata .= chr($bpp[$key])."\x00";                      // wBitCount;       // Bits per pixel
101
-
102
-			$dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);
103
-			$icondata .= phpthumb_functions::LittleEndian2String($dwBytesInRes, 4);       // dwBytesInRes;    // How many bytes in this resource?
104
-
105
-			$icondata .= phpthumb_functions::LittleEndian2String($dwImageOffset, 4);      // dwImageOffset;   // Where in the file is this image?
106
-			$dwImageOffset += strlen($BitmapInfoHeader[$key]);
107
-			$dwImageOffset += strlen($icXOR[$key]);
108
-			$dwImageOffset += strlen($icAND[$key]);
109
-		}
110
-
111
-		foreach ($gd_image_array as $key => $gd_image) {
112
-			$icondata .= $BitmapInfoHeader[$key];
113
-			$icondata .= $icXOR[$key];
114
-			$icondata .= $icAND[$key];
115
-		}
116
-
117
-		return $icondata;
118
-	}
15
+    public function GD2ICOstring(&$gd_image_array) {
16
+        $ImageWidths  = array();
17
+        $ImageHeights = array();
18
+        $bpp          = array();
19
+        $totalcolors  = array();
20
+        $icXOR        = array();
21
+        $icAND        = array();
22
+        $icANDmask    = array();
23
+        foreach ($gd_image_array as $key => $gd_image) {
24
+
25
+            $ImageWidths[$key]  = imagesx($gd_image);
26
+            $ImageHeights[$key] = imagesy($gd_image);
27
+            $bpp[$key]          = imageistruecolor($gd_image) ? 32 : 24;
28
+            $totalcolors[$key]  = imagecolorstotal($gd_image);
29
+
30
+            $icXOR[$key] = '';
31
+            for ($y = $ImageHeights[$key] - 1; $y >= 0; $y--) {
32
+                for ($x = 0; $x < $ImageWidths[$key]; $x++) {
33
+                    $argb = phpthumb_functions::GetPixelColor($gd_image, $x, $y);
34
+                    $a = round(255 * ((127 - $argb['alpha']) / 127));
35
+                    $r = $argb['red'];
36
+                    $g = $argb['green'];
37
+                    $b = $argb['blue'];
38
+
39
+                    if ($bpp[$key] == 32) {
40
+                        $icXOR[$key] .= chr($b).chr($g).chr($r).chr($a);
41
+                    } elseif ($bpp[$key] == 24) {
42
+                        $icXOR[$key] .= chr($b).chr($g).chr($r);
43
+                    }
44
+
45
+                    if ($a < 128) {
46
+                        @$icANDmask[$key][$y] .= '1';
47
+                    } else {
48
+                        @$icANDmask[$key][$y] .= '0';
49
+                    }
50
+                }
51
+                // mask bits are 32-bit aligned per scanline
52
+                while (strlen($icANDmask[$key][$y]) % 32) {
53
+                    $icANDmask[$key][$y] .= '0';
54
+                }
55
+            }
56
+            $icAND[$key] = '';
57
+            foreach ($icANDmask[$key] as $y => $scanlinemaskbits) {
58
+                for ($i = 0, $iMax = strlen($scanlinemaskbits); $i < $iMax; $i += 8) {
59
+                    $icAND[$key] .= chr(bindec(str_pad(substr($scanlinemaskbits, $i, 8), 8, '0', STR_PAD_LEFT)));
60
+                }
61
+            }
62
+
63
+        }
64
+
65
+        foreach ($gd_image_array as $key => $gd_image) {
66
+            $biSizeImage = $ImageWidths[$key] * $ImageHeights[$key] * ($bpp[$key] / 8);
67
+
68
+            // BITMAPINFOHEADER - 40 bytes
69
+            $BitmapInfoHeader[$key]  = '';
70
+            $BitmapInfoHeader[$key] .= "\x28\x00\x00\x00";                              // DWORD  biSize;
71
+            $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4);      // LONG   biWidth;
72
+            // The biHeight member specifies the combined
73
+            // height of the XOR and AND masks.
74
+            $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG   biHeight;
75
+            $BitmapInfoHeader[$key] .= "\x01\x00";                                      // WORD   biPlanes;
76
+            $BitmapInfoHeader[$key] .= chr($bpp[$key])."\x00";                          // wBitCount;
77
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // DWORD  biCompression;
78
+            $BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4);            // DWORD  biSizeImage;
79
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // LONG   biXPelsPerMeter;
80
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // LONG   biYPelsPerMeter;
81
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // DWORD  biClrUsed;
82
+            $BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // DWORD  biClrImportant;
83
+        }
84
+
85
+
86
+        $icondata  = "\x00\x00";                                      // idReserved;   // Reserved (must be 0)
87
+        $icondata .= "\x01\x00";                                      // idType;       // Resource Type (1 for icons)
88
+        $icondata .= phpthumb_functions::LittleEndian2String(count($gd_image_array), 2);  // idCount;      // How many images?
89
+
90
+        $dwImageOffset = 6 + (count($gd_image_array) * 16);
91
+        foreach ($gd_image_array as $key => $gd_image) {
92
+            // ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
93
+
94
+            $icondata .= chr($ImageWidths[$key]);                     // bWidth;          // Width, in pixels, of the image
95
+            $icondata .= chr($ImageHeights[$key]);                    // bHeight;         // Height, in pixels, of the image
96
+            $icondata .= chr($totalcolors[$key]);                     // bColorCount;     // Number of colors in image (0 if >=8bpp)
97
+            $icondata .= "\x00";                                      // bReserved;       // Reserved ( must be 0)
98
+
99
+            $icondata .= "\x01\x00";                                  // wPlanes;         // Color Planes
100
+            $icondata .= chr($bpp[$key])."\x00";                      // wBitCount;       // Bits per pixel
101
+
102
+            $dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);
103
+            $icondata .= phpthumb_functions::LittleEndian2String($dwBytesInRes, 4);       // dwBytesInRes;    // How many bytes in this resource?
104
+
105
+            $icondata .= phpthumb_functions::LittleEndian2String($dwImageOffset, 4);      // dwImageOffset;   // Where in the file is this image?
106
+            $dwImageOffset += strlen($BitmapInfoHeader[$key]);
107
+            $dwImageOffset += strlen($icXOR[$key]);
108
+            $dwImageOffset += strlen($icAND[$key]);
109
+        }
110
+
111
+        foreach ($gd_image_array as $key => $gd_image) {
112
+            $icondata .= $BitmapInfoHeader[$key];
113
+            $icondata .= $icXOR[$key];
114
+            $icondata .= $icAND[$key];
115
+        }
116
+
117
+        return $icondata;
118
+    }
119 119
 
120 120
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -67,42 +67,42 @@
 block discarded – undo
67 67
 
68 68
 			// BITMAPINFOHEADER - 40 bytes
69 69
 			$BitmapInfoHeader[$key]  = '';
70
-			$BitmapInfoHeader[$key] .= "\x28\x00\x00\x00";                              // DWORD  biSize;
71
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4);      // LONG   biWidth;
70
+			$BitmapInfoHeader[$key] .= "\x28\x00\x00\x00"; // DWORD  biSize;
71
+			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageWidths[$key], 4); // LONG   biWidth;
72 72
 			// The biHeight member specifies the combined
73 73
 			// height of the XOR and AND masks.
74 74
 			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG   biHeight;
75
-			$BitmapInfoHeader[$key] .= "\x01\x00";                                      // WORD   biPlanes;
76
-			$BitmapInfoHeader[$key] .= chr($bpp[$key])."\x00";                          // wBitCount;
77
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // DWORD  biCompression;
78
-			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4);            // DWORD  biSizeImage;
79
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // LONG   biXPelsPerMeter;
80
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // LONG   biYPelsPerMeter;
81
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // DWORD  biClrUsed;
82
-			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00";                              // DWORD  biClrImportant;
75
+			$BitmapInfoHeader[$key] .= "\x01\x00"; // WORD   biPlanes;
76
+			$BitmapInfoHeader[$key] .= chr($bpp[$key])."\x00"; // wBitCount;
77
+			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00"; // DWORD  biCompression;
78
+			$BitmapInfoHeader[$key] .= phpthumb_functions::LittleEndian2String($biSizeImage, 4); // DWORD  biSizeImage;
79
+			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00"; // LONG   biXPelsPerMeter;
80
+			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00"; // LONG   biYPelsPerMeter;
81
+			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00"; // DWORD  biClrUsed;
82
+			$BitmapInfoHeader[$key] .= "\x00\x00\x00\x00"; // DWORD  biClrImportant;
83 83
 		}
84 84
 
85 85
 
86
-		$icondata  = "\x00\x00";                                      // idReserved;   // Reserved (must be 0)
87
-		$icondata .= "\x01\x00";                                      // idType;       // Resource Type (1 for icons)
88
-		$icondata .= phpthumb_functions::LittleEndian2String(count($gd_image_array), 2);  // idCount;      // How many images?
86
+		$icondata  = "\x00\x00"; // idReserved;   // Reserved (must be 0)
87
+		$icondata .= "\x01\x00"; // idType;       // Resource Type (1 for icons)
88
+		$icondata .= phpthumb_functions::LittleEndian2String(count($gd_image_array), 2); // idCount;      // How many images?
89 89
 
90 90
 		$dwImageOffset = 6 + (count($gd_image_array) * 16);
91 91
 		foreach ($gd_image_array as $key => $gd_image) {
92 92
 			// ICONDIRENTRY   idEntries[1]; // An entry for each image (idCount of 'em)
93 93
 
94
-			$icondata .= chr($ImageWidths[$key]);                     // bWidth;          // Width, in pixels, of the image
95
-			$icondata .= chr($ImageHeights[$key]);                    // bHeight;         // Height, in pixels, of the image
96
-			$icondata .= chr($totalcolors[$key]);                     // bColorCount;     // Number of colors in image (0 if >=8bpp)
97
-			$icondata .= "\x00";                                      // bReserved;       // Reserved ( must be 0)
94
+			$icondata .= chr($ImageWidths[$key]); // bWidth;          // Width, in pixels, of the image
95
+			$icondata .= chr($ImageHeights[$key]); // bHeight;         // Height, in pixels, of the image
96
+			$icondata .= chr($totalcolors[$key]); // bColorCount;     // Number of colors in image (0 if >=8bpp)
97
+			$icondata .= "\x00"; // bReserved;       // Reserved ( must be 0)
98 98
 
99
-			$icondata .= "\x01\x00";                                  // wPlanes;         // Color Planes
100
-			$icondata .= chr($bpp[$key])."\x00";                      // wBitCount;       // Bits per pixel
99
+			$icondata .= "\x01\x00"; // wPlanes;         // Color Planes
100
+			$icondata .= chr($bpp[$key])."\x00"; // wBitCount;       // Bits per pixel
101 101
 
102 102
 			$dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);
103
-			$icondata .= phpthumb_functions::LittleEndian2String($dwBytesInRes, 4);       // dwBytesInRes;    // How many bytes in this resource?
103
+			$icondata .= phpthumb_functions::LittleEndian2String($dwBytesInRes, 4); // dwBytesInRes;    // How many bytes in this resource?
104 104
 
105
-			$icondata .= phpthumb_functions::LittleEndian2String($dwImageOffset, 4);      // dwImageOffset;   // Where in the file is this image?
105
+			$icondata .= phpthumb_functions::LittleEndian2String($dwImageOffset, 4); // dwImageOffset;   // Where in the file is this image?
106 106
 			$dwImageOffset += strlen($BitmapInfoHeader[$key]);
107 107
 			$dwImageOffset += strlen($icXOR[$key]);
108 108
 			$dwImageOffset += strlen($icAND[$key]);
Please login to merge, or discard this patch.
htdocs/modules/system/class/thumbs/phpthumb.class.php 2 patches
Indentation   +4302 added lines, -4302 removed lines patch added patch discarded remove patch
@@ -11,390 +11,390 @@  discard block
 block discarded – undo
11 11
 
12 12
 ob_start();
13 13
 if (!include_once( __DIR__ .'/phpthumb.functions.php')) {
14
-	ob_end_flush();
15
-	die('failed to include_once("'. __DIR__ .'/phpthumb.functions.php")');
14
+    ob_end_flush();
15
+    die('failed to include_once("'. __DIR__ .'/phpthumb.functions.php")');
16 16
 }
17 17
 ob_end_clean();
18 18
 
19 19
 class phpthumb {
20 20
 
21
-	// public:
22
-	// START PARAMETERS (for object mode and phpThumb.php)
23
-	// See phpthumb.readme.txt for descriptions of what each of these values are
24
-	public $src  = null;     // SouRCe filename
25
-	public $new  = null;     // NEW image (phpThumb.php only)
26
-	public $w    = null;     // Width
27
-	public $h    = null;     // Height
28
-	public $wp   = null;     // Width  (Portrait Images Only)
29
-	public $hp   = null;     // Height (Portrait Images Only)
30
-	public $wl   = null;     // Width  (Landscape Images Only)
31
-	public $hl   = null;     // Height (Landscape Images Only)
32
-	public $ws   = null;     // Width  (Square Images Only)
33
-	public $hs   = null;     // Height (Square Images Only)
34
-	public $f    = null;     // output image Format
35
-	public $q    = 75;       // jpeg output Quality
36
-	public $sx   = null;     // Source crop top-left X position
37
-	public $sy   = null;     // Source crop top-left Y position
38
-	public $sw   = null;     // Source crop Width
39
-	public $sh   = null;     // Source crop Height
40
-	public $zc   = null;     // Zoom Crop
41
-	public $bc   = null;     // Border Color
42
-	public $bg   = null;     // BackGround color
43
-	public $fltr = array();  // FiLTeRs
44
-	public $goto = null;     // GO TO url after processing
45
-	public $err  = null;     // default ERRor image filename
46
-	public $xto  = null;     // extract eXif Thumbnail Only
47
-	public $ra   = null;     // Rotate by Angle
48
-	public $ar   = null;     // Auto Rotate
49
-	public $aoe  = null;     // Allow Output Enlargement
50
-	public $far  = null;     // Fixed Aspect Ratio
51
-	public $iar  = null;     // Ignore Aspect Ratio
52
-	public $maxb = null;     // MAXimum Bytes
53
-	public $down = null;     // DOWNload thumbnail filename
54
-	public $md5s = null;     // MD5 hash of Source image
55
-	public $sfn  = 0;        // Source Frame Number
56
-	public $dpi  = 150;      // Dots Per Inch for vector source formats
57
-	public $sia  = null;     // Save Image As filename
58
-
59
-	public $file = null;     // >>>deprecated, DO NOT USE, will be removed in future versions<<<
60
-
61
-	public $phpThumbDebug = null;
62
-	// END PARAMETERS
63
-
64
-
65
-	// public:
66
-	// START CONFIGURATION OPTIONS (for object mode only)
67
-	// See phpThumb.config.php for descriptions of what each of these settings do
68
-
69
-	// * Directory Configuration
70
-	public $config_cache_directory                      = null;
71
-	public $config_cache_directory_depth                = 0;
72
-	public $config_cache_disable_warning                = true;
73
-	public $config_cache_source_enabled                 = false;
74
-	public $config_cache_source_directory               = null;
75
-	public $config_temp_directory                       = null;
76
-	public $config_document_root                        = null;
77
-
78
-	// * Default output configuration:
79
-	public $config_output_format                        = 'jpeg';
80
-	public $config_output_maxwidth                      = 0;
81
-	public $config_output_maxheight                     = 0;
82
-	public $config_output_interlace                     = true;
83
-
84
-	// * Error message configuration
85
-	public $config_error_image_width                    = 400;
86
-	public $config_error_image_height                   = 100;
87
-	public $config_error_message_image_default          = '';
88
-	public $config_error_bgcolor                        = 'CCCCFF';
89
-	public $config_error_textcolor                      = 'FF0000';
90
-	public $config_error_fontsize                       = 1;
91
-	public $config_error_die_on_error                   = false;
92
-	public $config_error_silent_die_on_error            = false;
93
-	public $config_error_die_on_source_failure          = true;
94
-
95
-	// * Anti-Hotlink Configuration:
96
-	public $config_nohotlink_enabled                    = true;
97
-	public $config_nohotlink_valid_domains              = array();
98
-	public $config_nohotlink_erase_image                = true;
99
-	public $config_nohotlink_text_message               = 'Off-server thumbnailing is not allowed';
100
-	// * Off-server Linking Configuration:
101
-	public $config_nooffsitelink_enabled                = false;
102
-	public $config_nooffsitelink_valid_domains          = array();
103
-	public $config_nooffsitelink_require_refer          = false;
104
-	public $config_nooffsitelink_erase_image            = true;
105
-	public $config_nooffsitelink_watermark_src          = '';
106
-	public $config_nooffsitelink_text_message           = 'Off-server linking is not allowed';
107
-
108
-	// * Border & Background default colors
109
-	public $config_border_hexcolor                      = '000000';
110
-	public $config_background_hexcolor                  = 'FFFFFF';
111
-
112
-	// * TrueType Fonts
113
-	public $config_ttf_directory                        = './fonts';
114
-
115
-	public $config_max_source_pixels                    = null;
116
-	public $config_use_exif_thumbnail_for_speed         = false;
117
-	public $config_allow_local_http_src                 = false;
118
-
119
-	public $config_imagemagick_path                     = null;
120
-	public $config_prefer_imagemagick                   = true;
121
-	public $config_imagemagick_use_thumbnail            = true;
122
-
123
-	public $config_cache_maxage                         = null;
124
-	public $config_cache_maxsize                        = null;
125
-	public $config_cache_maxfiles                       = null;
126
-	public $config_cache_source_filemtime_ignore_local  = false;
127
-	public $config_cache_source_filemtime_ignore_remote = true;
128
-	public $config_cache_default_only_suffix            = false;
129
-	public $config_cache_force_passthru                 = true;
130
-	public $config_cache_prefix                         = '';    // default value set in the constructor below
131
-
132
-	// * MySQL
133
-	public $config_mysql_extension                      = null;
134
-	public $config_mysql_query                          = null;
135
-	public $config_mysql_hostname                       = null;
136
-	public $config_mysql_username                       = null;
137
-	public $config_mysql_password                       = null;
138
-	public $config_mysql_database                       = null;
139
-
140
-	// * Security
141
-	public $config_high_security_enabled                = true;
142
-	public $config_high_security_password               = null;
143
-	public $config_high_security_url_separator          = '&';
144
-	public $config_disable_debug                        = true;
145
-	public $config_allow_src_above_docroot              = false;
146
-	public $config_allow_src_above_phpthumb             = true;
147
-	public $config_auto_allow_symlinks                  = true;    // allow symlink target directories without explicitly whitelisting them
148
-	public $config_additional_allowed_dirs              = array(); // additional directories to allow source images to be read from
149
-	public $config_file_create_mask                     = 0755;
150
-	public $config_dir_create_mask                      = 0755;
151
-
152
-	// * HTTP fopen
153
-	public $config_http_fopen_timeout                   = 10;
154
-	public $config_http_follow_redirect                 = true;
155
-
156
-	// * Compatability
157
-	public $config_disable_pathinfo_parsing             = false;
158
-	public $config_disable_imagecopyresampled           = false;
159
-	public $config_disable_onlycreateable_passthru      = false;
160
-	public $config_disable_realpath                     = false;
161
-
162
-	public $config_http_user_agent                      = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7';
163
-
164
-	// END CONFIGURATION OPTIONS
165
-
166
-
167
-	// public: error messages (read-only; persistant)
168
-	public $debugmessages = array();
169
-	public $debugtiming   = array();
170
-	public $fatalerror    = null;
171
-
172
-
173
-	// private: (should not be modified directly)
174
-	public $thumbnailQuality = 75;
175
-	public $thumbnailFormat  = null;
176
-
177
-	public $sourceFilename   = null;
178
-	public $rawImageData     = null;
179
-	public $IMresizedData    = null;
180
-	public $outputImageData  = null;
181
-
182
-	public $useRawIMoutput   = false;
183
-
184
-	public $gdimg_output     = null;
185
-	public $gdimg_source     = null;
186
-
187
-	public $getimagesizeinfo = null;
188
-
189
-	public $source_width  = null;
190
-	public $source_height = null;
191
-
192
-	public $thumbnailCropX = null;
193
-	public $thumbnailCropY = null;
194
-	public $thumbnailCropW = null;
195
-	public $thumbnailCropH = null;
196
-
197
-	public $exif_thumbnail_width  = null;
198
-	public $exif_thumbnail_height = null;
199
-	public $exif_thumbnail_type   = null;
200
-	public $exif_thumbnail_data   = null;
201
-	public $exif_raw_data         = null;
202
-
203
-	public $thumbnail_width        = null;
204
-	public $thumbnail_height       = null;
205
-	public $thumbnail_image_width  = null;
206
-	public $thumbnail_image_height = null;
207
-
208
-	public $tempFilesToDelete = array();
209
-	public $cache_filename    = null;
210
-
211
-	public $AlphaCapableFormats = array( 'png', 'ico', 'gif');
212
-	public $is_alpha = false;
213
-
214
-	public $iswindows        = null;
215
-	public $issafemode       = null;
216
-	public $php_memory_limit = null;
217
-
218
-	public $phpthumb_version = '1.7.15-201802181529';
219
-
220
-	//////////////////////////////////////////////////////////////////////
221
-
222
-	// public: constructor
223
-	public function __construct() {
224
-		$this->phpThumb();
225
-	}
226
-
227
-	public function phpThumb() {
228
-		$this->DebugTimingMessage('phpThumb() constructor', __FILE__, __LINE__);
229
-		$this->DebugMessage('phpThumb() v'.$this->phpthumb_version, __FILE__, __LINE__);
230
-
231
-		foreach (array(ini_get('memory_limit'), get_cfg_var('memory_limit')) as $php_config_memory_limit) {
232
-			if ('' !== $php_config_memory_limit) {
233
-				if (strtoupper($php_config_memory_limit[ strlen($php_config_memory_limit) - 1 ]) == 'G') { // PHP memory limit expressed in Gigabytes
234
-					$php_config_memory_limit = (int) substr($php_config_memory_limit, 0, -1) * 1073741824;
235
-				} elseif (strtoupper($php_config_memory_limit[ strlen($php_config_memory_limit) - 1 ]) == 'M') { // PHP memory limit expressed in Megabytes
236
-					$php_config_memory_limit = (int) substr($php_config_memory_limit, 0, -1) * 1048576;
237
-				}
238
-				$this->php_memory_limit = max($this->php_memory_limit, $php_config_memory_limit);
239
-			}
240
-		}
241
-		if ($this->php_memory_limit > 0) { // could be "-1" for "no limit"
242
-			$this->config_max_source_pixels = round($this->php_memory_limit * 0.20); // 20% of memory_limit
243
-		}
244
-
245
-		$this->iswindows  = (bool) (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN');
246
-		$this->issafemode = (bool) preg_match('#(1|ON)#i', ini_get('safe_mode'));
247
-		$this->config_document_root = (!empty($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT']   : $this->config_document_root);
248
-		$this->config_cache_prefix  = ( isset($_SERVER['SERVER_NAME'])   ? $_SERVER['SERVER_NAME'].'_' : '');
249
-
250
-		$this->purgeTempFiles(); // purge existing temp files if re-initializing object
251
-
252
-		$php_sapi_name = strtolower(function_exists('php_sapi_name') ? PHP_SAPI : '');
253
-		if ($php_sapi_name == 'cli') {
254
-			$this->config_allow_src_above_docroot = true;
255
-		}
256
-
257
-		if (!$this->config_disable_debug) {
258
-			// if debug mode is enabled, force phpThumbDebug output, do not allow normal thumbnails to be generated
259
-			$this->phpThumbDebug = (null === $this->phpThumbDebug ? 9 : max(1, (int) $this->phpThumbDebug));
260
-		}
261
-	}
262
-
263
-	public function __destruct() {
264
-		$this->purgeTempFiles();
265
-	}
266
-
267
-	// public:
268
-	public function purgeTempFiles() {
269
-		foreach ($this->tempFilesToDelete as $tempFileToDelete) {
270
-			if (file_exists($tempFileToDelete)) {
271
-				$this->DebugMessage('Deleting temp file "'.$tempFileToDelete.'"', __FILE__, __LINE__);
272
-				@unlink($tempFileToDelete);
273
-			}
274
-		}
275
-		$this->tempFilesToDelete = array();
276
-		return true;
277
-	}
278
-
279
-	// public:
280
-	public function setSourceFilename($sourceFilename) {
281
-		//$this->resetObject();
282
-		//$this->rawImageData   = null;
283
-		$this->sourceFilename = $sourceFilename;
284
-		$this->src            = $sourceFilename;
285
-		if (null === $this->config_output_format) {
286
-			$sourceFileExtension = strtolower(substr(strrchr($sourceFilename, '.'), 1));
287
-			if (preg_match('#^[a-z]{3,4}$#', $sourceFileExtension)) {
288
-				$this->config_output_format = $sourceFileExtension;
289
-				$this->DebugMessage('setSourceFilename('.$sourceFilename.') set $this->config_output_format to "'.$sourceFileExtension.'"', __FILE__, __LINE__);
290
-			} else {
291
-				$this->DebugMessage('setSourceFilename('.$sourceFilename.') did NOT set $this->config_output_format to "'.$sourceFileExtension.'" because it did not seem like an appropriate image format', __FILE__, __LINE__);
292
-			}
293
-		}
294
-		$this->DebugMessage('setSourceFilename('.$sourceFilename.') set $this->sourceFilename to "'.$this->sourceFilename.'"', __FILE__, __LINE__);
295
-		return true;
296
-	}
297
-
298
-	// public:
299
-	public function setSourceData($rawImageData, $sourceFilename='') {
300
-		//$this->resetObject();
301
-		//$this->sourceFilename = null;
302
-		$this->rawImageData   = $rawImageData;
303
-		$this->DebugMessage('setSourceData() setting $this->rawImageData ('.strlen($this->rawImageData).' bytes; magic="'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).'))', __FILE__, __LINE__);
304
-		if ($this->config_cache_source_enabled) {
305
-			$sourceFilename = ($sourceFilename ? $sourceFilename : md5($rawImageData));
306
-			if (!is_dir($this->config_cache_source_directory)) {
307
-				$this->ErrorImage('$this->config_cache_source_directory ('.$this->config_cache_source_directory.') is not a directory');
308
-			} elseif (!@is_writable($this->config_cache_source_directory)) {
309
-				$this->ErrorImage('$this->config_cache_source_directory ('.$this->config_cache_source_directory.') is not writable');
310
-			}
311
-			$this->DebugMessage('setSourceData() attempting to save source image to "'.$this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename).'"', __FILE__, __LINE__);
312
-			if ($fp = @fopen($this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename), 'wb')) {
313
-				fwrite($fp, $rawImageData);
314
-				fclose($fp);
315
-			} elseif (!$this->phpThumbDebug) {
316
-				$this->ErrorImage('setSourceData() failed to write to source cache ('.$this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename).')');
317
-			}
318
-		}
319
-		return true;
320
-	}
321
-
322
-	// public:
323
-	public function setSourceImageResource($gdimg) {
324
-		//$this->resetObject();
325
-		$this->gdimg_source = $gdimg;
326
-		return true;
327
-	}
328
-
329
-	// public:
330
-	public function setParameter($param, $value) {
331
-		if ($param == 'src') {
332
-			$this->setSourceFilename($this->ResolveFilenameToAbsolute($value));
333
-		} elseif (@is_array($this->$param)) {
334
-			if (is_array($value)) {
335
-				foreach ($value as $arraykey => $arrayvalue) {
336
-					array_push($this->$param, $arrayvalue);
337
-				}
338
-			} else {
339
-				array_push($this->$param, $value);
340
-			}
341
-		} else {
342
-			$this->$param = $value;
343
-		}
344
-		return true;
345
-	}
346
-
347
-	// public:
348
-	public function getParameter($param) {
349
-		//if (property_exists('phpThumb', $param)) {
350
-			return $this->$param;
351
-		//}
352
-		//$this->DebugMessage('setParameter() attempting to get non-existant parameter "'.$param.'"', __FILE__, __LINE__);
353
-		//return false;
354
-	}
355
-
356
-
357
-	// public:
358
-	public function GenerateThumbnail() {
359
-
360
-		$this->setOutputFormat();
361
-			$this->phpThumbDebug('8a');
362
-		$this->ResolveSource();
363
-			$this->phpThumbDebug('8b');
364
-		$this->SetCacheFilename();
365
-			$this->phpThumbDebug('8c');
366
-		$this->ExtractEXIFgetImageSize();
367
-			$this->phpThumbDebug('8d');
368
-		if ($this->useRawIMoutput) {
369
-			$this->DebugMessage('Skipping rest of GenerateThumbnail() because ($this->useRawIMoutput == true)', __FILE__, __LINE__);
370
-			return true;
371
-		}
372
-			$this->phpThumbDebug('8e');
373
-		if (!$this->SourceImageToGD()) {
374
-			$this->DebugMessage('SourceImageToGD() failed', __FILE__, __LINE__);
375
-			return false;
376
-		}
377
-			$this->phpThumbDebug('8f');
378
-		$this->Rotate();
379
-			$this->phpThumbDebug('8g');
380
-		$this->CreateGDoutput();
381
-			$this->phpThumbDebug('8h');
382
-
383
-		// default values, also applicable for far="C"
384
-		$destination_offset_x = round(($this->thumbnail_width  - $this->thumbnail_image_width)  / 2);
385
-		$destination_offset_y = round(($this->thumbnail_height - $this->thumbnail_image_height) / 2);
386
-		if (($this->far == 'L') || ($this->far == 'TL') || ($this->far == 'BL')) {
387
-			$destination_offset_x = 0;
388
-		}
389
-		if (($this->far == 'R') || ($this->far == 'TR') || ($this->far == 'BR')) {
390
-			$destination_offset_x =  round($this->thumbnail_width  - $this->thumbnail_image_width);
391
-		}
392
-		if (($this->far == 'T') || ($this->far == 'TL') || ($this->far == 'TR')) {
393
-			$destination_offset_y = 0;
394
-		}
395
-		if (($this->far == 'B') || ($this->far == 'BL') || ($this->far == 'BR')) {
396
-			$destination_offset_y =  round($this->thumbnail_height - $this->thumbnail_image_height);
397
-		}
21
+    // public:
22
+    // START PARAMETERS (for object mode and phpThumb.php)
23
+    // See phpthumb.readme.txt for descriptions of what each of these values are
24
+    public $src  = null;     // SouRCe filename
25
+    public $new  = null;     // NEW image (phpThumb.php only)
26
+    public $w    = null;     // Width
27
+    public $h    = null;     // Height
28
+    public $wp   = null;     // Width  (Portrait Images Only)
29
+    public $hp   = null;     // Height (Portrait Images Only)
30
+    public $wl   = null;     // Width  (Landscape Images Only)
31
+    public $hl   = null;     // Height (Landscape Images Only)
32
+    public $ws   = null;     // Width  (Square Images Only)
33
+    public $hs   = null;     // Height (Square Images Only)
34
+    public $f    = null;     // output image Format
35
+    public $q    = 75;       // jpeg output Quality
36
+    public $sx   = null;     // Source crop top-left X position
37
+    public $sy   = null;     // Source crop top-left Y position
38
+    public $sw   = null;     // Source crop Width
39
+    public $sh   = null;     // Source crop Height
40
+    public $zc   = null;     // Zoom Crop
41
+    public $bc   = null;     // Border Color
42
+    public $bg   = null;     // BackGround color
43
+    public $fltr = array();  // FiLTeRs
44
+    public $goto = null;     // GO TO url after processing
45
+    public $err  = null;     // default ERRor image filename
46
+    public $xto  = null;     // extract eXif Thumbnail Only
47
+    public $ra   = null;     // Rotate by Angle
48
+    public $ar   = null;     // Auto Rotate
49
+    public $aoe  = null;     // Allow Output Enlargement
50
+    public $far  = null;     // Fixed Aspect Ratio
51
+    public $iar  = null;     // Ignore Aspect Ratio
52
+    public $maxb = null;     // MAXimum Bytes
53
+    public $down = null;     // DOWNload thumbnail filename
54
+    public $md5s = null;     // MD5 hash of Source image
55
+    public $sfn  = 0;        // Source Frame Number
56
+    public $dpi  = 150;      // Dots Per Inch for vector source formats
57
+    public $sia  = null;     // Save Image As filename
58
+
59
+    public $file = null;     // >>>deprecated, DO NOT USE, will be removed in future versions<<<
60
+
61
+    public $phpThumbDebug = null;
62
+    // END PARAMETERS
63
+
64
+
65
+    // public:
66
+    // START CONFIGURATION OPTIONS (for object mode only)
67
+    // See phpThumb.config.php for descriptions of what each of these settings do
68
+
69
+    // * Directory Configuration
70
+    public $config_cache_directory                      = null;
71
+    public $config_cache_directory_depth                = 0;
72
+    public $config_cache_disable_warning                = true;
73
+    public $config_cache_source_enabled                 = false;
74
+    public $config_cache_source_directory               = null;
75
+    public $config_temp_directory                       = null;
76
+    public $config_document_root                        = null;
77
+
78
+    // * Default output configuration:
79
+    public $config_output_format                        = 'jpeg';
80
+    public $config_output_maxwidth                      = 0;
81
+    public $config_output_maxheight                     = 0;
82
+    public $config_output_interlace                     = true;
83
+
84
+    // * Error message configuration
85
+    public $config_error_image_width                    = 400;
86
+    public $config_error_image_height                   = 100;
87
+    public $config_error_message_image_default          = '';
88
+    public $config_error_bgcolor                        = 'CCCCFF';
89
+    public $config_error_textcolor                      = 'FF0000';
90
+    public $config_error_fontsize                       = 1;
91
+    public $config_error_die_on_error                   = false;
92
+    public $config_error_silent_die_on_error            = false;
93
+    public $config_error_die_on_source_failure          = true;
94
+
95
+    // * Anti-Hotlink Configuration:
96
+    public $config_nohotlink_enabled                    = true;
97
+    public $config_nohotlink_valid_domains              = array();
98
+    public $config_nohotlink_erase_image                = true;
99
+    public $config_nohotlink_text_message               = 'Off-server thumbnailing is not allowed';
100
+    // * Off-server Linking Configuration:
101
+    public $config_nooffsitelink_enabled                = false;
102
+    public $config_nooffsitelink_valid_domains          = array();
103
+    public $config_nooffsitelink_require_refer          = false;
104
+    public $config_nooffsitelink_erase_image            = true;
105
+    public $config_nooffsitelink_watermark_src          = '';
106
+    public $config_nooffsitelink_text_message           = 'Off-server linking is not allowed';
107
+
108
+    // * Border & Background default colors
109
+    public $config_border_hexcolor                      = '000000';
110
+    public $config_background_hexcolor                  = 'FFFFFF';
111
+
112
+    // * TrueType Fonts
113
+    public $config_ttf_directory                        = './fonts';
114
+
115
+    public $config_max_source_pixels                    = null;
116
+    public $config_use_exif_thumbnail_for_speed         = false;
117
+    public $config_allow_local_http_src                 = false;
118
+
119
+    public $config_imagemagick_path                     = null;
120
+    public $config_prefer_imagemagick                   = true;
121
+    public $config_imagemagick_use_thumbnail            = true;
122
+
123
+    public $config_cache_maxage                         = null;
124
+    public $config_cache_maxsize                        = null;
125
+    public $config_cache_maxfiles                       = null;
126
+    public $config_cache_source_filemtime_ignore_local  = false;
127
+    public $config_cache_source_filemtime_ignore_remote = true;
128
+    public $config_cache_default_only_suffix            = false;
129
+    public $config_cache_force_passthru                 = true;
130
+    public $config_cache_prefix                         = '';    // default value set in the constructor below
131
+
132
+    // * MySQL
133
+    public $config_mysql_extension                      = null;
134
+    public $config_mysql_query                          = null;
135
+    public $config_mysql_hostname                       = null;
136
+    public $config_mysql_username                       = null;
137
+    public $config_mysql_password                       = null;
138
+    public $config_mysql_database                       = null;
139
+
140
+    // * Security
141
+    public $config_high_security_enabled                = true;
142
+    public $config_high_security_password               = null;
143
+    public $config_high_security_url_separator          = '&';
144
+    public $config_disable_debug                        = true;
145
+    public $config_allow_src_above_docroot              = false;
146
+    public $config_allow_src_above_phpthumb             = true;
147
+    public $config_auto_allow_symlinks                  = true;    // allow symlink target directories without explicitly whitelisting them
148
+    public $config_additional_allowed_dirs              = array(); // additional directories to allow source images to be read from
149
+    public $config_file_create_mask                     = 0755;
150
+    public $config_dir_create_mask                      = 0755;
151
+
152
+    // * HTTP fopen
153
+    public $config_http_fopen_timeout                   = 10;
154
+    public $config_http_follow_redirect                 = true;
155
+
156
+    // * Compatability
157
+    public $config_disable_pathinfo_parsing             = false;
158
+    public $config_disable_imagecopyresampled           = false;
159
+    public $config_disable_onlycreateable_passthru      = false;
160
+    public $config_disable_realpath                     = false;
161
+
162
+    public $config_http_user_agent                      = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915 Firefox/1.0.7';
163
+
164
+    // END CONFIGURATION OPTIONS
165
+
166
+
167
+    // public: error messages (read-only; persistant)
168
+    public $debugmessages = array();
169
+    public $debugtiming   = array();
170
+    public $fatalerror    = null;
171
+
172
+
173
+    // private: (should not be modified directly)
174
+    public $thumbnailQuality = 75;
175
+    public $thumbnailFormat  = null;
176
+
177
+    public $sourceFilename   = null;
178
+    public $rawImageData     = null;
179
+    public $IMresizedData    = null;
180
+    public $outputImageData  = null;
181
+
182
+    public $useRawIMoutput   = false;
183
+
184
+    public $gdimg_output     = null;
185
+    public $gdimg_source     = null;
186
+
187
+    public $getimagesizeinfo = null;
188
+
189
+    public $source_width  = null;
190
+    public $source_height = null;
191
+
192
+    public $thumbnailCropX = null;
193
+    public $thumbnailCropY = null;
194
+    public $thumbnailCropW = null;
195
+    public $thumbnailCropH = null;
196
+
197
+    public $exif_thumbnail_width  = null;
198
+    public $exif_thumbnail_height = null;
199
+    public $exif_thumbnail_type   = null;
200
+    public $exif_thumbnail_data   = null;
201
+    public $exif_raw_data         = null;
202
+
203
+    public $thumbnail_width        = null;
204
+    public $thumbnail_height       = null;
205
+    public $thumbnail_image_width  = null;
206
+    public $thumbnail_image_height = null;
207
+
208
+    public $tempFilesToDelete = array();
209
+    public $cache_filename    = null;
210
+
211
+    public $AlphaCapableFormats = array( 'png', 'ico', 'gif');
212
+    public $is_alpha = false;
213
+
214
+    public $iswindows        = null;
215
+    public $issafemode       = null;
216
+    public $php_memory_limit = null;
217
+
218
+    public $phpthumb_version = '1.7.15-201802181529';
219
+
220
+    //////////////////////////////////////////////////////////////////////
221
+
222
+    // public: constructor
223
+    public function __construct() {
224
+        $this->phpThumb();
225
+    }
226
+
227
+    public function phpThumb() {
228
+        $this->DebugTimingMessage('phpThumb() constructor', __FILE__, __LINE__);
229
+        $this->DebugMessage('phpThumb() v'.$this->phpthumb_version, __FILE__, __LINE__);
230
+
231
+        foreach (array(ini_get('memory_limit'), get_cfg_var('memory_limit')) as $php_config_memory_limit) {
232
+            if ('' !== $php_config_memory_limit) {
233
+                if (strtoupper($php_config_memory_limit[ strlen($php_config_memory_limit) - 1 ]) == 'G') { // PHP memory limit expressed in Gigabytes
234
+                    $php_config_memory_limit = (int) substr($php_config_memory_limit, 0, -1) * 1073741824;
235
+                } elseif (strtoupper($php_config_memory_limit[ strlen($php_config_memory_limit) - 1 ]) == 'M') { // PHP memory limit expressed in Megabytes
236
+                    $php_config_memory_limit = (int) substr($php_config_memory_limit, 0, -1) * 1048576;
237
+                }
238
+                $this->php_memory_limit = max($this->php_memory_limit, $php_config_memory_limit);
239
+            }
240
+        }
241
+        if ($this->php_memory_limit > 0) { // could be "-1" for "no limit"
242
+            $this->config_max_source_pixels = round($this->php_memory_limit * 0.20); // 20% of memory_limit
243
+        }
244
+
245
+        $this->iswindows  = (bool) (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN');
246
+        $this->issafemode = (bool) preg_match('#(1|ON)#i', ini_get('safe_mode'));
247
+        $this->config_document_root = (!empty($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT']   : $this->config_document_root);
248
+        $this->config_cache_prefix  = ( isset($_SERVER['SERVER_NAME'])   ? $_SERVER['SERVER_NAME'].'_' : '');
249
+
250
+        $this->purgeTempFiles(); // purge existing temp files if re-initializing object
251
+
252
+        $php_sapi_name = strtolower(function_exists('php_sapi_name') ? PHP_SAPI : '');
253
+        if ($php_sapi_name == 'cli') {
254
+            $this->config_allow_src_above_docroot = true;
255
+        }
256
+
257
+        if (!$this->config_disable_debug) {
258
+            // if debug mode is enabled, force phpThumbDebug output, do not allow normal thumbnails to be generated
259
+            $this->phpThumbDebug = (null === $this->phpThumbDebug ? 9 : max(1, (int) $this->phpThumbDebug));
260
+        }
261
+    }
262
+
263
+    public function __destruct() {
264
+        $this->purgeTempFiles();
265
+    }
266
+
267
+    // public:
268
+    public function purgeTempFiles() {
269
+        foreach ($this->tempFilesToDelete as $tempFileToDelete) {
270
+            if (file_exists($tempFileToDelete)) {
271
+                $this->DebugMessage('Deleting temp file "'.$tempFileToDelete.'"', __FILE__, __LINE__);
272
+                @unlink($tempFileToDelete);
273
+            }
274
+        }
275
+        $this->tempFilesToDelete = array();
276
+        return true;
277
+    }
278
+
279
+    // public:
280
+    public function setSourceFilename($sourceFilename) {
281
+        //$this->resetObject();
282
+        //$this->rawImageData   = null;
283
+        $this->sourceFilename = $sourceFilename;
284
+        $this->src            = $sourceFilename;
285
+        if (null === $this->config_output_format) {
286
+            $sourceFileExtension = strtolower(substr(strrchr($sourceFilename, '.'), 1));
287
+            if (preg_match('#^[a-z]{3,4}$#', $sourceFileExtension)) {
288
+                $this->config_output_format = $sourceFileExtension;
289
+                $this->DebugMessage('setSourceFilename('.$sourceFilename.') set $this->config_output_format to "'.$sourceFileExtension.'"', __FILE__, __LINE__);
290
+            } else {
291
+                $this->DebugMessage('setSourceFilename('.$sourceFilename.') did NOT set $this->config_output_format to "'.$sourceFileExtension.'" because it did not seem like an appropriate image format', __FILE__, __LINE__);
292
+            }
293
+        }
294
+        $this->DebugMessage('setSourceFilename('.$sourceFilename.') set $this->sourceFilename to "'.$this->sourceFilename.'"', __FILE__, __LINE__);
295
+        return true;
296
+    }
297
+
298
+    // public:
299
+    public function setSourceData($rawImageData, $sourceFilename='') {
300
+        //$this->resetObject();
301
+        //$this->sourceFilename = null;
302
+        $this->rawImageData   = $rawImageData;
303
+        $this->DebugMessage('setSourceData() setting $this->rawImageData ('.strlen($this->rawImageData).' bytes; magic="'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).'))', __FILE__, __LINE__);
304
+        if ($this->config_cache_source_enabled) {
305
+            $sourceFilename = ($sourceFilename ? $sourceFilename : md5($rawImageData));
306
+            if (!is_dir($this->config_cache_source_directory)) {
307
+                $this->ErrorImage('$this->config_cache_source_directory ('.$this->config_cache_source_directory.') is not a directory');
308
+            } elseif (!@is_writable($this->config_cache_source_directory)) {
309
+                $this->ErrorImage('$this->config_cache_source_directory ('.$this->config_cache_source_directory.') is not writable');
310
+            }
311
+            $this->DebugMessage('setSourceData() attempting to save source image to "'.$this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename).'"', __FILE__, __LINE__);
312
+            if ($fp = @fopen($this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename), 'wb')) {
313
+                fwrite($fp, $rawImageData);
314
+                fclose($fp);
315
+            } elseif (!$this->phpThumbDebug) {
316
+                $this->ErrorImage('setSourceData() failed to write to source cache ('.$this->config_cache_source_directory.DIRECTORY_SEPARATOR.urlencode($sourceFilename).')');
317
+            }
318
+        }
319
+        return true;
320
+    }
321
+
322
+    // public:
323
+    public function setSourceImageResource($gdimg) {
324
+        //$this->resetObject();
325
+        $this->gdimg_source = $gdimg;
326
+        return true;
327
+    }
328
+
329
+    // public:
330
+    public function setParameter($param, $value) {
331
+        if ($param == 'src') {
332
+            $this->setSourceFilename($this->ResolveFilenameToAbsolute($value));
333
+        } elseif (@is_array($this->$param)) {
334
+            if (is_array($value)) {
335
+                foreach ($value as $arraykey => $arrayvalue) {
336
+                    array_push($this->$param, $arrayvalue);
337
+                }
338
+            } else {
339
+                array_push($this->$param, $value);
340
+            }
341
+        } else {
342
+            $this->$param = $value;
343
+        }
344
+        return true;
345
+    }
346
+
347
+    // public:
348
+    public function getParameter($param) {
349
+        //if (property_exists('phpThumb', $param)) {
350
+            return $this->$param;
351
+        //}
352
+        //$this->DebugMessage('setParameter() attempting to get non-existant parameter "'.$param.'"', __FILE__, __LINE__);
353
+        //return false;
354
+    }
355
+
356
+
357
+    // public:
358
+    public function GenerateThumbnail() {
359
+
360
+        $this->setOutputFormat();
361
+            $this->phpThumbDebug('8a');
362
+        $this->ResolveSource();
363
+            $this->phpThumbDebug('8b');
364
+        $this->SetCacheFilename();
365
+            $this->phpThumbDebug('8c');
366
+        $this->ExtractEXIFgetImageSize();
367
+            $this->phpThumbDebug('8d');
368
+        if ($this->useRawIMoutput) {
369
+            $this->DebugMessage('Skipping rest of GenerateThumbnail() because ($this->useRawIMoutput == true)', __FILE__, __LINE__);
370
+            return true;
371
+        }
372
+            $this->phpThumbDebug('8e');
373
+        if (!$this->SourceImageToGD()) {
374
+            $this->DebugMessage('SourceImageToGD() failed', __FILE__, __LINE__);
375
+            return false;
376
+        }
377
+            $this->phpThumbDebug('8f');
378
+        $this->Rotate();
379
+            $this->phpThumbDebug('8g');
380
+        $this->CreateGDoutput();
381
+            $this->phpThumbDebug('8h');
382
+
383
+        // default values, also applicable for far="C"
384
+        $destination_offset_x = round(($this->thumbnail_width  - $this->thumbnail_image_width)  / 2);
385
+        $destination_offset_y = round(($this->thumbnail_height - $this->thumbnail_image_height) / 2);
386
+        if (($this->far == 'L') || ($this->far == 'TL') || ($this->far == 'BL')) {
387
+            $destination_offset_x = 0;
388
+        }
389
+        if (($this->far == 'R') || ($this->far == 'TR') || ($this->far == 'BR')) {
390
+            $destination_offset_x =  round($this->thumbnail_width  - $this->thumbnail_image_width);
391
+        }
392
+        if (($this->far == 'T') || ($this->far == 'TL') || ($this->far == 'TR')) {
393
+            $destination_offset_y = 0;
394
+        }
395
+        if (($this->far == 'B') || ($this->far == 'BL') || ($this->far == 'BR')) {
396
+            $destination_offset_y =  round($this->thumbnail_height - $this->thumbnail_image_height);
397
+        }
398 398
 
399 399
 //		// copy/resize image to appropriate dimensions
400 400
 //		$borderThickness = 0;
@@ -410,100 +410,100 @@  discard block
 block discarded – undo
410 410
 //			//$this->DebugMessage('Skipping ImageResizeFunction() because BorderThickness="'.$borderThickness.'"', __FILE__, __LINE__);
411 411
 //			$this->thumbnail_image_height /= 2;
412 412
 //		}
413
-		$this->ImageResizeFunction(
414
-			$this->gdimg_output,
415
-			$this->gdimg_source,
416
-			$destination_offset_x,
417
-			$destination_offset_y,
418
-			$this->thumbnailCropX,
419
-			$this->thumbnailCropY,
420
-			$this->thumbnail_image_width,
421
-			$this->thumbnail_image_height,
422
-			$this->thumbnailCropW,
423
-			$this->thumbnailCropH
424
-		);
425
-
426
-		$this->DebugMessage('memory_get_usage() after copy-resize = '.(function_exists('memory_get_usage') ? @memory_get_usage() : 'n/a'), __FILE__, __LINE__);
427
-		imagedestroy($this->gdimg_source);
428
-		$this->DebugMessage('memory_get_usage() after imagedestroy = '.(function_exists('memory_get_usage') ? @memory_get_usage() : 'n/a'), __FILE__, __LINE__);
429
-
430
-			$this->phpThumbDebug('8i');
431
-		$this->AntiOffsiteLinking();
432
-			$this->phpThumbDebug('8j');
433
-		$this->ApplyFilters();
434
-			$this->phpThumbDebug('8k');
435
-		$this->AlphaChannelFlatten();
436
-			$this->phpThumbDebug('8l');
437
-		$this->MaxFileSize();
438
-			$this->phpThumbDebug('8m');
439
-
440
-		$this->DebugMessage('GenerateThumbnail() completed successfully', __FILE__, __LINE__);
441
-		return true;
442
-	}
443
-
444
-
445
-	// public:
446
-	public function RenderOutput() {
447
-		if (!$this->useRawIMoutput && !is_resource($this->gdimg_output)) {
448
-			$this->DebugMessage('RenderOutput() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__);
449
-			return false;
450
-		}
451
-		if (!$this->thumbnailFormat) {
452
-			$this->DebugMessage('RenderOutput() failed because $this->thumbnailFormat is empty', __FILE__, __LINE__);
453
-			return false;
454
-		}
455
-		if ($this->useRawIMoutput) {
456
-			$this->DebugMessage('RenderOutput copying $this->IMresizedData ('.strlen($this->IMresizedData).' bytes) to $this->outputImage', __FILE__, __LINE__);
457
-			$this->outputImageData = $this->IMresizedData;
458
-			return true;
459
-		}
460
-
461
-		$builtin_formats = array();
462
-		if (function_exists('imagetypes')) {
463
-			$imagetypes = imagetypes();
464
-			$builtin_formats['wbmp'] = (bool) ($imagetypes & IMG_WBMP);
465
-			$builtin_formats['jpg']  = (bool) ($imagetypes & IMG_JPG);
466
-			$builtin_formats['gif']  = (bool) ($imagetypes & IMG_GIF);
467
-			$builtin_formats['png']  = (bool) ($imagetypes & IMG_PNG);
468
-		}
469
-
470
-		$this->DebugMessage('imageinterlace($this->gdimg_output, '. (int) $this->config_output_interlace .')', __FILE__, __LINE__);
471
-		imageinterlace($this->gdimg_output, (int) $this->config_output_interlace);
472
-
473
-		$this->DebugMessage('RenderOutput() attempting image'.strtolower(@$this->thumbnailFormat).'($this->gdimg_output)', __FILE__, __LINE__);
474
-		ob_start();
475
-		switch ($this->thumbnailFormat) {
476
-			case 'wbmp':
477
-				if (empty($builtin_formats['wbmp'])) {
478
-					$this->DebugMessage('GD does not have required built-in support for WBMP output', __FILE__, __LINE__);
479
-					ob_end_clean();
480
-					return false;
481
-				}
482
-				imagejpeg($this->gdimg_output, null, $this->thumbnailQuality);
483
-				$this->outputImageData = ob_get_contents();
484
-				break;
485
-
486
-			case 'jpeg':
487
-			case 'jpg':  // should be "jpeg" not "jpg" but just in case...
488
-				if (empty($builtin_formats['jpg'])) {
489
-					$this->DebugMessage('GD does not have required built-in support for JPEG output', __FILE__, __LINE__);
490
-					ob_end_clean();
491
-					return false;
492
-				}
493
-				imagejpeg($this->gdimg_output, null, $this->thumbnailQuality);
494
-				$this->outputImageData = ob_get_contents();
495
-				break;
496
-
497
-			case 'png':
498
-				if (empty($builtin_formats['png'])) {
499
-					$this->DebugMessage('GD does not have required built-in support for PNG output', __FILE__, __LINE__);
500
-					ob_end_clean();
501
-					return false;
502
-				}
503
-				if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.1.2', '>=')) {
504
-					// https://github.com/JamesHeinrich/phpThumb/issues/24
505
-
506
-					/* http://php.net/manual/en/function.imagepng.php:
413
+        $this->ImageResizeFunction(
414
+            $this->gdimg_output,
415
+            $this->gdimg_source,
416
+            $destination_offset_x,
417
+            $destination_offset_y,
418
+            $this->thumbnailCropX,
419
+            $this->thumbnailCropY,
420
+            $this->thumbnail_image_width,
421
+            $this->thumbnail_image_height,
422
+            $this->thumbnailCropW,
423
+            $this->thumbnailCropH
424
+        );
425
+
426
+        $this->DebugMessage('memory_get_usage() after copy-resize = '.(function_exists('memory_get_usage') ? @memory_get_usage() : 'n/a'), __FILE__, __LINE__);
427
+        imagedestroy($this->gdimg_source);
428
+        $this->DebugMessage('memory_get_usage() after imagedestroy = '.(function_exists('memory_get_usage') ? @memory_get_usage() : 'n/a'), __FILE__, __LINE__);
429
+
430
+            $this->phpThumbDebug('8i');
431
+        $this->AntiOffsiteLinking();
432
+            $this->phpThumbDebug('8j');
433
+        $this->ApplyFilters();
434
+            $this->phpThumbDebug('8k');
435
+        $this->AlphaChannelFlatten();
436
+            $this->phpThumbDebug('8l');
437
+        $this->MaxFileSize();
438
+            $this->phpThumbDebug('8m');
439
+
440
+        $this->DebugMessage('GenerateThumbnail() completed successfully', __FILE__, __LINE__);
441
+        return true;
442
+    }
443
+
444
+
445
+    // public:
446
+    public function RenderOutput() {
447
+        if (!$this->useRawIMoutput && !is_resource($this->gdimg_output)) {
448
+            $this->DebugMessage('RenderOutput() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__);
449
+            return false;
450
+        }
451
+        if (!$this->thumbnailFormat) {
452
+            $this->DebugMessage('RenderOutput() failed because $this->thumbnailFormat is empty', __FILE__, __LINE__);
453
+            return false;
454
+        }
455
+        if ($this->useRawIMoutput) {
456
+            $this->DebugMessage('RenderOutput copying $this->IMresizedData ('.strlen($this->IMresizedData).' bytes) to $this->outputImage', __FILE__, __LINE__);
457
+            $this->outputImageData = $this->IMresizedData;
458
+            return true;
459
+        }
460
+
461
+        $builtin_formats = array();
462
+        if (function_exists('imagetypes')) {
463
+            $imagetypes = imagetypes();
464
+            $builtin_formats['wbmp'] = (bool) ($imagetypes & IMG_WBMP);
465
+            $builtin_formats['jpg']  = (bool) ($imagetypes & IMG_JPG);
466
+            $builtin_formats['gif']  = (bool) ($imagetypes & IMG_GIF);
467
+            $builtin_formats['png']  = (bool) ($imagetypes & IMG_PNG);
468
+        }
469
+
470
+        $this->DebugMessage('imageinterlace($this->gdimg_output, '. (int) $this->config_output_interlace .')', __FILE__, __LINE__);
471
+        imageinterlace($this->gdimg_output, (int) $this->config_output_interlace);
472
+
473
+        $this->DebugMessage('RenderOutput() attempting image'.strtolower(@$this->thumbnailFormat).'($this->gdimg_output)', __FILE__, __LINE__);
474
+        ob_start();
475
+        switch ($this->thumbnailFormat) {
476
+            case 'wbmp':
477
+                if (empty($builtin_formats['wbmp'])) {
478
+                    $this->DebugMessage('GD does not have required built-in support for WBMP output', __FILE__, __LINE__);
479
+                    ob_end_clean();
480
+                    return false;
481
+                }
482
+                imagejpeg($this->gdimg_output, null, $this->thumbnailQuality);
483
+                $this->outputImageData = ob_get_contents();
484
+                break;
485
+
486
+            case 'jpeg':
487
+            case 'jpg':  // should be "jpeg" not "jpg" but just in case...
488
+                if (empty($builtin_formats['jpg'])) {
489
+                    $this->DebugMessage('GD does not have required built-in support for JPEG output', __FILE__, __LINE__);
490
+                    ob_end_clean();
491
+                    return false;
492
+                }
493
+                imagejpeg($this->gdimg_output, null, $this->thumbnailQuality);
494
+                $this->outputImageData = ob_get_contents();
495
+                break;
496
+
497
+            case 'png':
498
+                if (empty($builtin_formats['png'])) {
499
+                    $this->DebugMessage('GD does not have required built-in support for PNG output', __FILE__, __LINE__);
500
+                    ob_end_clean();
501
+                    return false;
502
+                }
503
+                if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.1.2', '>=')) {
504
+                    // https://github.com/JamesHeinrich/phpThumb/issues/24
505
+
506
+                    /* http://php.net/manual/en/function.imagepng.php:
507 507
 					from php source (gd.h):
508 508
 					2.0.12: Compression level: 0-9 or -1, where 0 is NO COMPRESSION at all,
509 509
 					:: 1 is FASTEST but produces larger files, 9 provides the best
@@ -511,684 +511,684 @@  discard block
 block discarded – undo
511 511
 					:: -1 selects the default compiled into the zlib library.
512 512
 					Conclusion: Based on the Zlib manual (http://www.zlib.net/manual.html) the default compression level is set to 6.
513 513
 					*/
514
-					if (($this->thumbnailQuality >= -1) && ($this->thumbnailQuality <= 9)) {
515
-						$PNGquality = $this->thumbnailQuality;
516
-					} else {
517
-						$this->DebugMessage('Specified thumbnailQuality "'.$this->thumbnailQuality.'" is outside the accepted range (0-9, or -1). Using 6 as default value.', __FILE__, __LINE__);
518
-						$PNGquality = 6;
519
-					}
520
-					imagepng($this->gdimg_output, null, $PNGquality);
521
-				} else {
522
-					imagepng($this->gdimg_output);
523
-				}
524
-				$this->outputImageData = ob_get_contents();
525
-				break;
526
-
527
-			case 'gif':
528
-				if (empty($builtin_formats['gif'])) {
529
-					$this->DebugMessage('GD does not have required built-in support for GIF output', __FILE__, __LINE__);
530
-					ob_end_clean();
531
-					return false;
532
-				}
533
-				imagegif($this->gdimg_output);
534
-				$this->outputImageData = ob_get_contents();
535
-				break;
536
-
537
-			case 'bmp':
538
-				if (!@include_once( __DIR__ .'/phpthumb.bmp.php')) {
539
-					$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
540
-					ob_end_clean();
541
-					return false;
542
-				}
543
-				$phpthumb_bmp = new phpthumb_bmp();
544
-				$this->outputImageData = $phpthumb_bmp->GD2BMPstring($this->gdimg_output);
545
-				unset($phpthumb_bmp);
546
-				break;
547
-
548
-			case 'ico':
549
-				if (!@include_once( __DIR__ .'/phpthumb.ico.php')) {
550
-					$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
551
-					ob_end_clean();
552
-					return false;
553
-				}
554
-				$phpthumb_ico = new phpthumb_ico();
555
-				$arrayOfOutputImages = array($this->gdimg_output);
556
-				$this->outputImageData = $phpthumb_ico->GD2ICOstring($arrayOfOutputImages);
557
-				unset($phpthumb_ico);
558
-				break;
559
-
560
-			default:
561
-				$this->DebugMessage('RenderOutput failed because $this->thumbnailFormat "'.$this->thumbnailFormat.'" is not valid', __FILE__, __LINE__);
562
-				ob_end_clean();
563
-				return false;
564
-		}
565
-		ob_end_clean();
566
-		if (!$this->outputImageData) {
567
-			$this->DebugMessage('RenderOutput() for "'.$this->thumbnailFormat.'" failed', __FILE__, __LINE__);
568
-			ob_end_clean();
569
-			return false;
570
-		}
571
-		$this->DebugMessage('RenderOutput() completing with $this->outputImageData = '.strlen($this->outputImageData).' bytes', __FILE__, __LINE__);
572
-		return true;
573
-	}
574
-
575
-
576
-	// public:
577
-	public function RenderToFile($filename) {
578
-		if (preg_match('#^[a-z0-9]+://#i', $filename)) {
579
-			$this->DebugMessage('RenderToFile() failed because $filename ('.$filename.') is a URL', __FILE__, __LINE__);
580
-			return false;
581
-		}
582
-		// render thumbnail to this file only, do not cache, do not output to browser
583
-		//$renderfilename = $this->ResolveFilenameToAbsolute(dirname($filename)).DIRECTORY_SEPARATOR.basename($filename);
584
-		$renderfilename = $filename;
585
-		if (($filename{0} != '/') && ($filename{0} != '\\') && ($filename{1} != ':')) {
586
-			$renderfilename = $this->ResolveFilenameToAbsolute($renderfilename);
587
-		}
588
-		if (!@is_writable(dirname($renderfilename))) {
589
-			$this->DebugMessage('RenderToFile() failed because "'.dirname($renderfilename).'/" is not writable', __FILE__, __LINE__);
590
-			return false;
591
-		}
592
-		if (@is_file($renderfilename) && !@is_writable($renderfilename)) {
593
-			$this->DebugMessage('RenderToFile() failed because "'.$renderfilename.'" is not writable', __FILE__, __LINE__);
594
-			return false;
595
-		}
596
-
597
-		if ($this->RenderOutput()) {
598
-			if (file_put_contents($renderfilename, $this->outputImageData)) {
599
-				@chmod($renderfilename, $this->getParameter('config_file_create_mask'));
600
-				$this->DebugMessage('RenderToFile('.$renderfilename.') succeeded', __FILE__, __LINE__);
601
-				return true;
602
-			}
603
-			if (!@file_exists($renderfilename)) {
604
-				$this->DebugMessage('RenderOutput ['.$this->thumbnailFormat.'('.$renderfilename.')] did not appear to fail, but the output image does not exist either...', __FILE__, __LINE__);
605
-			}
606
-		} else {
607
-			$this->DebugMessage('RenderOutput ['.$this->thumbnailFormat.'('.$renderfilename.')] failed', __FILE__, __LINE__);
608
-		}
609
-		return false;
610
-	}
611
-
612
-
613
-	// public:
614
-	public function OutputThumbnail() {
615
-		$this->purgeTempFiles();
616
-
617
-		if (!$this->useRawIMoutput && !is_resource($this->gdimg_output)) {
618
-			$this->DebugMessage('OutputThumbnail() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__);
619
-			return false;
620
-		}
621
-		if (headers_sent()) {
622
-			return $this->ErrorImage('OutputThumbnail() failed - headers already sent');
623
-		}
624
-
625
-		$downloadfilename = phpthumb_functions::SanitizeFilename(is_string($this->sia) ? $this->sia : ($this->down ? $this->down : 'phpThumb_generated_thumbnail'.'.'.$this->thumbnailFormat));
626
-		$this->DebugMessage('Content-Disposition header filename set to "'.$downloadfilename.'"', __FILE__, __LINE__);
627
-		if ($downloadfilename) {
628
-			header('Content-Disposition: '.($this->down ? 'attachment' : 'inline').'; filename="'.$downloadfilename.'"');
629
-		} else {
630
-			$this->DebugMessage('failed to send Content-Disposition header because $downloadfilename is empty', __FILE__, __LINE__);
631
-		}
632
-
633
-		if ($this->useRawIMoutput) {
634
-
635
-			header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
636
-			echo $this->IMresizedData;
637
-
638
-		} else {
639
-
640
-			$this->DebugMessage('imageinterlace($this->gdimg_output, '. (int) $this->config_output_interlace .')', __FILE__, __LINE__);
641
-			imageinterlace($this->gdimg_output, (int) $this->config_output_interlace);
642
-			switch ($this->thumbnailFormat) {
643
-				case 'jpeg':
644
-					header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
645
-					$ImageOutFunction = 'image'.$this->thumbnailFormat;
646
-					@$ImageOutFunction($this->gdimg_output, null, $this->thumbnailQuality);
647
-					break;
648
-
649
-				case 'png':
650
-				case 'gif':
651
-					header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
652
-					$ImageOutFunction = 'image'.$this->thumbnailFormat;
653
-					@$ImageOutFunction($this->gdimg_output);
654
-					break;
655
-
656
-				case 'bmp':
657
-					if (!@include_once( __DIR__ .'/phpthumb.bmp.php')) {
658
-						$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
659
-						return false;
660
-					}
661
-					$phpthumb_bmp = new phpthumb_bmp();
662
-					if (is_object($phpthumb_bmp)) {
663
-						$bmp_data = $phpthumb_bmp->GD2BMPstring($this->gdimg_output);
664
-						unset($phpthumb_bmp);
665
-						if (!$bmp_data) {
666
-							$this->DebugMessage('$phpthumb_bmp->GD2BMPstring() failed', __FILE__, __LINE__);
667
-							return false;
668
-						}
669
-						header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
670
-						echo $bmp_data;
671
-					} else {
672
-						$this->DebugMessage('new phpthumb_bmp() failed', __FILE__, __LINE__);
673
-						return false;
674
-					}
675
-					break;
676
-
677
-				case 'ico':
678
-					if (!@include_once( __DIR__ .'/phpthumb.ico.php')) {
679
-						$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
680
-						return false;
681
-					}
682
-					$phpthumb_ico = new phpthumb_ico();
683
-					if (is_object($phpthumb_ico)) {
684
-						$arrayOfOutputImages = array($this->gdimg_output);
685
-						$ico_data = $phpthumb_ico->GD2ICOstring($arrayOfOutputImages);
686
-						unset($phpthumb_ico);
687
-						if (!$ico_data) {
688
-							$this->DebugMessage('$phpthumb_ico->GD2ICOstring() failed', __FILE__, __LINE__);
689
-							return false;
690
-						}
691
-						header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
692
-						echo $ico_data;
693
-					} else {
694
-						$this->DebugMessage('new phpthumb_ico() failed', __FILE__, __LINE__);
695
-						return false;
696
-					}
697
-					break;
698
-
699
-				default:
700
-					$this->DebugMessage('OutputThumbnail failed because $this->thumbnailFormat "'.$this->thumbnailFormat.'" is not valid', __FILE__, __LINE__);
701
-					return false;
702
-					break;
703
-			}
704
-
705
-		}
706
-		return true;
707
-	}
708
-
709
-
710
-	// public:
711
-	public function CleanUpCacheDirectory() {
712
-		$this->DebugMessage('CleanUpCacheDirectory() set to purge ('.(null === $this->config_cache_maxage ? 'NULL' : number_format($this->config_cache_maxage / 86400, 1)).' days; '.(null === $this->config_cache_maxsize ? 'NULL' : number_format($this->config_cache_maxsize / 1048576, 2)).' MB; '.(null === $this->config_cache_maxfiles ? 'NULL' : number_format($this->config_cache_maxfiles)).' files)', __FILE__, __LINE__);
713
-
714
-		if (!is_writable($this->config_cache_directory)) {
715
-			$this->DebugMessage('CleanUpCacheDirectory() skipped because "'.$this->config_cache_directory.'" is not writable', __FILE__, __LINE__);
716
-			return true;
717
-		}
718
-
719
-		// cache status of cache directory for 1 hour to avoid hammering the filesystem functions
720
-		$phpThumbCacheStats_filename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheStats.txt';
721
-		if (file_exists($phpThumbCacheStats_filename) && is_readable($phpThumbCacheStats_filename) && (filemtime($phpThumbCacheStats_filename) >= (time() - 3600))) {
722
-			$this->DebugMessage('CleanUpCacheDirectory() skipped because "'.$phpThumbCacheStats_filename.'" is recently modified', __FILE__, __LINE__);
723
-			return true;
724
-		}
725
-		if (!@touch($phpThumbCacheStats_filename)) {
726
-			$this->DebugMessage('touch('.$phpThumbCacheStats_filename.') failed', __FILE__, __LINE__);
727
-		}
728
-
729
-		$DeletedKeys = array();
730
-		$AllFilesInCacheDirectory = array();
731
-		if (($this->config_cache_maxage > 0) || ($this->config_cache_maxsize > 0) || ($this->config_cache_maxfiles > 0)) {
732
-			$CacheDirOldFilesAge  = array();
733
-			$CacheDirOldFilesSize = array();
734
-			$AllFilesInCacheDirectory = phpthumb_functions::GetAllFilesInSubfolders($this->config_cache_directory);
735
-			foreach ($AllFilesInCacheDirectory as $fullfilename) {
736
-				if (preg_match('#'.preg_quote($this->config_cache_prefix).'#i', $fullfilename) && file_exists($fullfilename)) {
737
-					$CacheDirOldFilesAge[$fullfilename] = @fileatime($fullfilename);
738
-					if ($CacheDirOldFilesAge[$fullfilename] == 0) {
739
-						$CacheDirOldFilesAge[$fullfilename] = @filemtime($fullfilename);
740
-					}
741
-					$CacheDirOldFilesSize[$fullfilename] = @filesize($fullfilename);
742
-				}
743
-			}
744
-			if (empty($CacheDirOldFilesSize)) {
745
-				$this->DebugMessage('CleanUpCacheDirectory() skipped because $CacheDirOldFilesSize is empty (phpthumb_functions::GetAllFilesInSubfolders('.$this->config_cache_directory.') found no files)', __FILE__, __LINE__);
746
-				return true;
747
-			}
748
-			$DeletedKeys['zerobyte'] = array();
749
-			foreach ($CacheDirOldFilesSize as $fullfilename => $filesize) {
750
-				// purge all zero-size files more than an hour old (to prevent trying to delete just-created and/or in-use files)
751
-				$cutofftime = time() - 3600;
752
-				if (($filesize == 0) && ($CacheDirOldFilesAge[$fullfilename] < $cutofftime)) {
753
-					$this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
754
-					if (@unlink($fullfilename)) {
755
-						$DeletedKeys['zerobyte'][] = $fullfilename;
756
-						unset($CacheDirOldFilesSize[$fullfilename]);
757
-						unset($CacheDirOldFilesAge[$fullfilename]);
758
-					}
759
-				}
760
-			}
761
-			$this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['zerobyte']).' zero-byte files', __FILE__, __LINE__);
762
-			asort($CacheDirOldFilesAge);
763
-
764
-			if ($this->config_cache_maxfiles > 0) {
765
-				$TotalCachedFiles = count($CacheDirOldFilesAge);
766
-				$DeletedKeys['maxfiles'] = array();
767
-				foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
768
-					if ($TotalCachedFiles > $this->config_cache_maxfiles) {
769
-						$this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
770
-						if (@unlink($fullfilename)) {
771
-							$TotalCachedFiles--;
772
-							$DeletedKeys['maxfiles'][] = $fullfilename;
773
-						}
774
-					} else {
775
-						// there are few enough files to keep the rest
776
-						break;
777
-					}
778
-				}
779
-				$this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxfiles']).' files based on (config_cache_maxfiles='.$this->config_cache_maxfiles.')', __FILE__, __LINE__);
780
-				foreach ($DeletedKeys['maxfiles'] as $fullfilename) {
781
-					unset($CacheDirOldFilesAge[$fullfilename]);
782
-					unset($CacheDirOldFilesSize[$fullfilename]);
783
-				}
784
-			}
785
-
786
-			if ($this->config_cache_maxage > 0) {
787
-				$mindate = time() - $this->config_cache_maxage;
788
-				$DeletedKeys['maxage'] = array();
789
-				foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
790
-					if ($filedate > 0) {
791
-						if ($filedate < $mindate) {
792
-							$this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
793
-							if (@unlink($fullfilename)) {
794
-								$DeletedKeys['maxage'][] = $fullfilename;
795
-							}
796
-						} else {
797
-							// the rest of the files are new enough to keep
798
-							break;
799
-						}
800
-					}
801
-				}
802
-				$this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxage']).' files based on (config_cache_maxage='.$this->config_cache_maxage.')', __FILE__, __LINE__);
803
-				foreach ($DeletedKeys['maxage'] as $fullfilename) {
804
-					unset($CacheDirOldFilesAge[$fullfilename]);
805
-					unset($CacheDirOldFilesSize[$fullfilename]);
806
-				}
807
-			}
808
-
809
-			if ($this->config_cache_maxsize > 0) {
810
-				$TotalCachedFileSize = array_sum($CacheDirOldFilesSize);
811
-				$DeletedKeys['maxsize'] = array();
812
-				foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
813
-					if ($TotalCachedFileSize > $this->config_cache_maxsize) {
814
-						$this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
815
-						if (@unlink($fullfilename)) {
816
-							$TotalCachedFileSize -= $CacheDirOldFilesSize[$fullfilename];
817
-							$DeletedKeys['maxsize'][] = $fullfilename;
818
-						}
819
-					} else {
820
-						// the total filesizes are small enough to keep the rest of the files
821
-						break;
822
-					}
823
-				}
824
-				$this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxsize']).' files based on (config_cache_maxsize='.$this->config_cache_maxsize.')', __FILE__, __LINE__);
825
-				foreach ($DeletedKeys['maxsize'] as $fullfilename) {
826
-					unset($CacheDirOldFilesAge[$fullfilename]);
827
-					unset($CacheDirOldFilesSize[$fullfilename]);
828
-				}
829
-			}
830
-
831
-		} else {
832
-			$this->DebugMessage('skipping CleanUpCacheDirectory() because config set to not use it', __FILE__, __LINE__);
833
-		}
834
-		$totalpurged = 0;
835
-		foreach ($DeletedKeys as $key => $value) {
836
-			$totalpurged += count($value);
837
-		}
838
-		$this->DebugMessage('CleanUpCacheDirectory() purged '.$totalpurged.' files (from '.count($AllFilesInCacheDirectory).') based on config settings', __FILE__, __LINE__);
839
-		if ($totalpurged > 0) {
840
-			$empty_dirs = array();
841
-			foreach ($AllFilesInCacheDirectory as $fullfilename) {
842
-				if (is_dir($fullfilename)) {
843
-					$empty_dirs[$this->realPathSafe($fullfilename)] = 1;
844
-				} else {
845
-					unset($empty_dirs[$this->realPathSafe(dirname($fullfilename))]);
846
-				}
847
-			}
848
-			krsort($empty_dirs);
849
-			$totalpurgeddirs = 0;
850
-			foreach ($empty_dirs as $empty_dir => $dummy) {
851
-				if ($empty_dir == $this->config_cache_directory) {
852
-					// shouldn't happen, but just in case, don't let it delete actual cache directory
853
-					continue;
854
-				} elseif (@rmdir($empty_dir)) {
855
-					$totalpurgeddirs++;
856
-				} else {
857
-					$this->DebugMessage('failed to rmdir('.$empty_dir.')', __FILE__, __LINE__);
858
-				}
859
-			}
860
-			$this->DebugMessage('purged '.$totalpurgeddirs.' empty directories', __FILE__, __LINE__);
861
-		}
862
-		return true;
863
-	}
864
-
865
-	//////////////////////////////////////////////////////////////////////
866
-
867
-	// private: re-initializator (call between rendering multiple images with one object)
868
-	public function resetObject() {
869
-		$class_vars = get_class_vars(get_class($this));
870
-		foreach ($class_vars as $key => $value) {
871
-			// do not clobber debug or config info
872
-			if (!preg_match('#^(config_|debug|fatalerror)#i', $key)) {
873
-				$this->$key = $value;
874
-			}
875
-		}
876
-		$this->phpThumb(); // re-initialize some class variables
877
-		return true;
878
-	}
879
-
880
-	//////////////////////////////////////////////////////////////////////
881
-
882
-	public function ResolveSource() {
883
-		if (is_resource($this->gdimg_source)) {
884
-			$this->DebugMessage('ResolveSource() exiting because is_resource($this->gdimg_source)', __FILE__, __LINE__);
885
-			return true;
886
-		}
887
-		if ($this->rawImageData) {
888
-			$this->sourceFilename = null;
889
-			$this->DebugMessage('ResolveSource() exiting because $this->rawImageData is set ('.number_format(strlen($this->rawImageData)).' bytes)', __FILE__, __LINE__);
890
-			return true;
891
-		}
892
-		if ($this->sourceFilename) {
893
-			$this->sourceFilename = $this->ResolveFilenameToAbsolute($this->sourceFilename);
894
-			$this->DebugMessage('$this->sourceFilename set to "'.$this->sourceFilename.'"', __FILE__, __LINE__);
895
-		} elseif ($this->src) {
896
-			$this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src);
897
-			$this->DebugMessage('$this->sourceFilename set to "'.$this->sourceFilename.'" from $this->src ('.$this->src.')', __FILE__, __LINE__);
898
-		} else {
899
-			return $this->ErrorImage('$this->sourceFilename and $this->src are both empty');
900
-		}
901
-		if ($this->iswindows && ((substr($this->sourceFilename, 0, 2) == '//') || (substr($this->sourceFilename, 0, 2) == '\\\\'))) {
902
-			// Windows \\share\filename.ext
903
-		} elseif (preg_match('#^[a-z0-9]+://#i', $this->sourceFilename, $protocol_matches)) {
904
-			if (preg_match('#^(f|ht)tps?\://#i', $this->sourceFilename)) {
905
-				// URL
906
-				if ($this->config_http_user_agent) {
907
-					ini_set('user_agent', $this->config_http_user_agent);
908
-				}
909
-			} else {
910
-				return $this->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "'.$protocol_matches[1].'" is not');
911
-		}
912
-		} elseif (!@file_exists($this->sourceFilename)) {
913
-			return $this->ErrorImage('"'.$this->sourceFilename.'" does not exist');
914
-		} elseif (!@is_file($this->sourceFilename)) {
915
-			return $this->ErrorImage('"'.$this->sourceFilename.'" is not a file');
916
-		}
917
-		return true;
918
-	}
919
-
920
-
921
-	public function setOutputFormat() {
922
-		static $alreadyCalled = false;
923
-		if ($this->thumbnailFormat && $alreadyCalled) {
924
-			return true;
925
-		}
926
-		$alreadyCalled = true;
927
-
928
-		$AvailableImageOutputFormats = array();
929
-		$AvailableImageOutputFormats[] = 'text';
930
-		if (@is_readable( __DIR__ .'/phpthumb.ico.php')) {
931
-			$AvailableImageOutputFormats[] = 'ico';
932
-		}
933
-		if (@is_readable( __DIR__ .'/phpthumb.bmp.php')) {
934
-			$AvailableImageOutputFormats[] = 'bmp';
935
-		}
936
-
937
-		$this->thumbnailFormat = 'ico';
938
-
939
-		// Set default output format based on what image types are available
940
-		if (function_exists('imagetypes')) {
941
-			$imagetypes = imagetypes();
942
-			if ($imagetypes & IMG_WBMP) {
943
-				$this->thumbnailFormat         = 'wbmp';
944
-				$AvailableImageOutputFormats[] = 'wbmp';
945
-			}
946
-			if ($imagetypes & IMG_GIF) {
947
-				$this->thumbnailFormat         = 'gif';
948
-				$AvailableImageOutputFormats[] = 'gif';
949
-			}
950
-			if ($imagetypes & IMG_PNG) {
951
-				$this->thumbnailFormat         = 'png';
952
-				$AvailableImageOutputFormats[] = 'png';
953
-			}
954
-			if ($imagetypes & IMG_JPG) {
955
-				$this->thumbnailFormat         = 'jpeg';
956
-				$AvailableImageOutputFormats[] = 'jpeg';
957
-			}
958
-		} else {
959
-			$this->DebugMessage('imagetypes() does not exist - GD support might not be enabled?',  __FILE__, __LINE__);
960
-		}
961
-		if ($this->ImageMagickVersion()) {
962
-			$IMformats = array('jpeg', 'png', 'gif', 'bmp', 'ico', 'wbmp');
963
-			$this->DebugMessage('Addding ImageMagick formats to $AvailableImageOutputFormats ('.implode(';', $AvailableImageOutputFormats).')', __FILE__, __LINE__);
964
-			foreach ($IMformats as $key => $format) {
965
-				$AvailableImageOutputFormats[] = $format;
966
-			}
967
-		}
968
-		$AvailableImageOutputFormats = array_unique($AvailableImageOutputFormats);
969
-		$this->DebugMessage('$AvailableImageOutputFormats = array('.implode(';', $AvailableImageOutputFormats).')', __FILE__, __LINE__);
970
-
971
-		$this->f = preg_replace('#[^a-z]#', '', strtolower($this->f));
972
-		if (strtolower($this->config_output_format) == 'jpg') {
973
-			$this->config_output_format = 'jpeg';
974
-		}
975
-		if (strtolower($this->f) == 'jpg') {
976
-			$this->f = 'jpeg';
977
-		}
978
-		if (phpthumb_functions::CaseInsensitiveInArray($this->config_output_format, $AvailableImageOutputFormats)) {
979
-			// set output format to config default if that format is available
980
-			$this->DebugMessage('$this->thumbnailFormat set to $this->config_output_format "'.strtolower($this->config_output_format).'"', __FILE__, __LINE__);
981
-			$this->thumbnailFormat = strtolower($this->config_output_format);
982
-		} elseif ($this->config_output_format) {
983
-			$this->DebugMessage('$this->thumbnailFormat staying as "'.$this->thumbnailFormat.'" because $this->config_output_format ('.strtolower($this->config_output_format).') is not in $AvailableImageOutputFormats', __FILE__, __LINE__);
984
-		}
985
-		if ($this->f && (phpthumb_functions::CaseInsensitiveInArray($this->f, $AvailableImageOutputFormats))) {
986
-			// override output format if $this->f is set and that format is available
987
-			$this->DebugMessage('$this->thumbnailFormat set to $this->f "'.strtolower($this->f).'"', __FILE__, __LINE__);
988
-			$this->thumbnailFormat = strtolower($this->f);
989
-		} elseif ($this->f) {
990
-			$this->DebugMessage('$this->thumbnailFormat staying as "'.$this->thumbnailFormat.'" because $this->f ('.strtolower($this->f).') is not in $AvailableImageOutputFormats', __FILE__, __LINE__);
991
-		}
992
-
993
-		// for JPEG images, quality 1 (worst) to 99 (best)
994
-		// quality < 25 is nasty, with not much size savings - not recommended
995
-		// problems with 100 - invalid JPEG?
996
-		$this->thumbnailQuality = max(1, min(99, ($this->q ? (int) $this->q : 75)));
997
-		$this->DebugMessage('$this->thumbnailQuality set to "'.$this->thumbnailQuality.'"', __FILE__, __LINE__);
998
-
999
-		return true;
1000
-	}
1001
-
1002
-
1003
-	public function setCacheDirectory() {
1004
-		// resolve cache directory to absolute pathname
1005
-		$this->DebugMessage('setCacheDirectory() starting with config_cache_directory = "'.$this->config_cache_directory.'"', __FILE__, __LINE__);
1006
-		if ($this->config_cache_directory[ 0 ] == '.') {
1007
-			if (preg_match('#^(f|ht)tps?\://#i', $this->src)) {
1008
-				if (!$this->config_cache_disable_warning) {
1009
-					$this->ErrorImage('$this->config_cache_directory ('.$this->config_cache_directory.') cannot be used for remote images. Adjust "cache_directory" or "cache_disable_warning" in phpThumb.config.php');
1010
-				}
1011
-			} elseif ($this->src) {
1012
-				// resolve relative cache directory to source image
1013
-				$this->config_cache_directory = dirname($this->ResolveFilenameToAbsolute($this->src)).DIRECTORY_SEPARATOR.$this->config_cache_directory;
1014
-			} else {
1015
-				// $this->new is probably set
1016
-			}
1017
-		}
1018
-		if (substr($this->config_cache_directory, -1) == '/') {
1019
-			$this->config_cache_directory = substr($this->config_cache_directory, 0, -1);
1020
-		}
1021
-		if ($this->iswindows) {
1022
-			$this->config_cache_directory = str_replace('/', DIRECTORY_SEPARATOR, $this->config_cache_directory);
1023
-		}
1024
-		if ($this->config_cache_directory) {
1025
-			$real_cache_path = $this->realPathSafe($this->config_cache_directory);
1026
-			if (!$real_cache_path) {
1027
-				$this->DebugMessage('$this->realPathSafe($this->config_cache_directory) failed for "'.$this->config_cache_directory.'"', __FILE__, __LINE__);
1028
-				if (!is_dir($this->config_cache_directory)) {
1029
-					$this->DebugMessage('!is_dir('.$this->config_cache_directory.')', __FILE__, __LINE__);
1030
-				}
1031
-			}
1032
-			if ($real_cache_path) {
1033
-				$this->DebugMessage('setting config_cache_directory to $this->realPathSafe('.$this->config_cache_directory.') = "'.$real_cache_path.'"', __FILE__, __LINE__);
1034
-				$this->config_cache_directory = $real_cache_path;
1035
-			}
1036
-		}
1037
-		if (!is_dir($this->config_cache_directory)) {
1038
-			if (!$this->config_cache_disable_warning) {
1039
-				$this->ErrorImage('$this->config_cache_directory ('.$this->config_cache_directory.') does not exist. Adjust "cache_directory" or "cache_disable_warning" in phpThumb.config.php');
1040
-			}
1041
-			$this->DebugMessage('$this->config_cache_directory ('.$this->config_cache_directory.') is not a directory', __FILE__, __LINE__);
1042
-			$this->config_cache_directory = null;
1043
-		} elseif (!@is_writable($this->config_cache_directory)) {
1044
-			$this->DebugMessage('$this->config_cache_directory is not writable ('.$this->config_cache_directory.')', __FILE__, __LINE__);
1045
-		}
1046
-
1047
-		$this->InitializeTempDirSetting();
1048
-		if (!@is_dir($this->config_temp_directory) && !@is_writable($this->config_temp_directory) && @is_dir($this->config_cache_directory) && @is_writable($this->config_cache_directory)) {
1049
-			$this->DebugMessage('setting $this->config_temp_directory = $this->config_cache_directory ('.$this->config_cache_directory.')', __FILE__, __LINE__);
1050
-			$this->config_temp_directory = $this->config_cache_directory;
1051
-		}
1052
-		return true;
1053
-	}
1054
-
1055
-	/* Takes the array of path segments up to now, and the next segment (maybe a modifier: empty, . or ..)
514
+                    if (($this->thumbnailQuality >= -1) && ($this->thumbnailQuality <= 9)) {
515
+                        $PNGquality = $this->thumbnailQuality;
516
+                    } else {
517
+                        $this->DebugMessage('Specified thumbnailQuality "'.$this->thumbnailQuality.'" is outside the accepted range (0-9, or -1). Using 6 as default value.', __FILE__, __LINE__);
518
+                        $PNGquality = 6;
519
+                    }
520
+                    imagepng($this->gdimg_output, null, $PNGquality);
521
+                } else {
522
+                    imagepng($this->gdimg_output);
523
+                }
524
+                $this->outputImageData = ob_get_contents();
525
+                break;
526
+
527
+            case 'gif':
528
+                if (empty($builtin_formats['gif'])) {
529
+                    $this->DebugMessage('GD does not have required built-in support for GIF output', __FILE__, __LINE__);
530
+                    ob_end_clean();
531
+                    return false;
532
+                }
533
+                imagegif($this->gdimg_output);
534
+                $this->outputImageData = ob_get_contents();
535
+                break;
536
+
537
+            case 'bmp':
538
+                if (!@include_once( __DIR__ .'/phpthumb.bmp.php')) {
539
+                    $this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
540
+                    ob_end_clean();
541
+                    return false;
542
+                }
543
+                $phpthumb_bmp = new phpthumb_bmp();
544
+                $this->outputImageData = $phpthumb_bmp->GD2BMPstring($this->gdimg_output);
545
+                unset($phpthumb_bmp);
546
+                break;
547
+
548
+            case 'ico':
549
+                if (!@include_once( __DIR__ .'/phpthumb.ico.php')) {
550
+                    $this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
551
+                    ob_end_clean();
552
+                    return false;
553
+                }
554
+                $phpthumb_ico = new phpthumb_ico();
555
+                $arrayOfOutputImages = array($this->gdimg_output);
556
+                $this->outputImageData = $phpthumb_ico->GD2ICOstring($arrayOfOutputImages);
557
+                unset($phpthumb_ico);
558
+                break;
559
+
560
+            default:
561
+                $this->DebugMessage('RenderOutput failed because $this->thumbnailFormat "'.$this->thumbnailFormat.'" is not valid', __FILE__, __LINE__);
562
+                ob_end_clean();
563
+                return false;
564
+        }
565
+        ob_end_clean();
566
+        if (!$this->outputImageData) {
567
+            $this->DebugMessage('RenderOutput() for "'.$this->thumbnailFormat.'" failed', __FILE__, __LINE__);
568
+            ob_end_clean();
569
+            return false;
570
+        }
571
+        $this->DebugMessage('RenderOutput() completing with $this->outputImageData = '.strlen($this->outputImageData).' bytes', __FILE__, __LINE__);
572
+        return true;
573
+    }
574
+
575
+
576
+    // public:
577
+    public function RenderToFile($filename) {
578
+        if (preg_match('#^[a-z0-9]+://#i', $filename)) {
579
+            $this->DebugMessage('RenderToFile() failed because $filename ('.$filename.') is a URL', __FILE__, __LINE__);
580
+            return false;
581
+        }
582
+        // render thumbnail to this file only, do not cache, do not output to browser
583
+        //$renderfilename = $this->ResolveFilenameToAbsolute(dirname($filename)).DIRECTORY_SEPARATOR.basename($filename);
584
+        $renderfilename = $filename;
585
+        if (($filename{0} != '/') && ($filename{0} != '\\') && ($filename{1} != ':')) {
586
+            $renderfilename = $this->ResolveFilenameToAbsolute($renderfilename);
587
+        }
588
+        if (!@is_writable(dirname($renderfilename))) {
589
+            $this->DebugMessage('RenderToFile() failed because "'.dirname($renderfilename).'/" is not writable', __FILE__, __LINE__);
590
+            return false;
591
+        }
592
+        if (@is_file($renderfilename) && !@is_writable($renderfilename)) {
593
+            $this->DebugMessage('RenderToFile() failed because "'.$renderfilename.'" is not writable', __FILE__, __LINE__);
594
+            return false;
595
+        }
596
+
597
+        if ($this->RenderOutput()) {
598
+            if (file_put_contents($renderfilename, $this->outputImageData)) {
599
+                @chmod($renderfilename, $this->getParameter('config_file_create_mask'));
600
+                $this->DebugMessage('RenderToFile('.$renderfilename.') succeeded', __FILE__, __LINE__);
601
+                return true;
602
+            }
603
+            if (!@file_exists($renderfilename)) {
604
+                $this->DebugMessage('RenderOutput ['.$this->thumbnailFormat.'('.$renderfilename.')] did not appear to fail, but the output image does not exist either...', __FILE__, __LINE__);
605
+            }
606
+        } else {
607
+            $this->DebugMessage('RenderOutput ['.$this->thumbnailFormat.'('.$renderfilename.')] failed', __FILE__, __LINE__);
608
+        }
609
+        return false;
610
+    }
611
+
612
+
613
+    // public:
614
+    public function OutputThumbnail() {
615
+        $this->purgeTempFiles();
616
+
617
+        if (!$this->useRawIMoutput && !is_resource($this->gdimg_output)) {
618
+            $this->DebugMessage('OutputThumbnail() failed because !is_resource($this->gdimg_output)', __FILE__, __LINE__);
619
+            return false;
620
+        }
621
+        if (headers_sent()) {
622
+            return $this->ErrorImage('OutputThumbnail() failed - headers already sent');
623
+        }
624
+
625
+        $downloadfilename = phpthumb_functions::SanitizeFilename(is_string($this->sia) ? $this->sia : ($this->down ? $this->down : 'phpThumb_generated_thumbnail'.'.'.$this->thumbnailFormat));
626
+        $this->DebugMessage('Content-Disposition header filename set to "'.$downloadfilename.'"', __FILE__, __LINE__);
627
+        if ($downloadfilename) {
628
+            header('Content-Disposition: '.($this->down ? 'attachment' : 'inline').'; filename="'.$downloadfilename.'"');
629
+        } else {
630
+            $this->DebugMessage('failed to send Content-Disposition header because $downloadfilename is empty', __FILE__, __LINE__);
631
+        }
632
+
633
+        if ($this->useRawIMoutput) {
634
+
635
+            header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
636
+            echo $this->IMresizedData;
637
+
638
+        } else {
639
+
640
+            $this->DebugMessage('imageinterlace($this->gdimg_output, '. (int) $this->config_output_interlace .')', __FILE__, __LINE__);
641
+            imageinterlace($this->gdimg_output, (int) $this->config_output_interlace);
642
+            switch ($this->thumbnailFormat) {
643
+                case 'jpeg':
644
+                    header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
645
+                    $ImageOutFunction = 'image'.$this->thumbnailFormat;
646
+                    @$ImageOutFunction($this->gdimg_output, null, $this->thumbnailQuality);
647
+                    break;
648
+
649
+                case 'png':
650
+                case 'gif':
651
+                    header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
652
+                    $ImageOutFunction = 'image'.$this->thumbnailFormat;
653
+                    @$ImageOutFunction($this->gdimg_output);
654
+                    break;
655
+
656
+                case 'bmp':
657
+                    if (!@include_once( __DIR__ .'/phpthumb.bmp.php')) {
658
+                        $this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
659
+                        return false;
660
+                    }
661
+                    $phpthumb_bmp = new phpthumb_bmp();
662
+                    if (is_object($phpthumb_bmp)) {
663
+                        $bmp_data = $phpthumb_bmp->GD2BMPstring($this->gdimg_output);
664
+                        unset($phpthumb_bmp);
665
+                        if (!$bmp_data) {
666
+                            $this->DebugMessage('$phpthumb_bmp->GD2BMPstring() failed', __FILE__, __LINE__);
667
+                            return false;
668
+                        }
669
+                        header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
670
+                        echo $bmp_data;
671
+                    } else {
672
+                        $this->DebugMessage('new phpthumb_bmp() failed', __FILE__, __LINE__);
673
+                        return false;
674
+                    }
675
+                    break;
676
+
677
+                case 'ico':
678
+                    if (!@include_once( __DIR__ .'/phpthumb.ico.php')) {
679
+                        $this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
680
+                        return false;
681
+                    }
682
+                    $phpthumb_ico = new phpthumb_ico();
683
+                    if (is_object($phpthumb_ico)) {
684
+                        $arrayOfOutputImages = array($this->gdimg_output);
685
+                        $ico_data = $phpthumb_ico->GD2ICOstring($arrayOfOutputImages);
686
+                        unset($phpthumb_ico);
687
+                        if (!$ico_data) {
688
+                            $this->DebugMessage('$phpthumb_ico->GD2ICOstring() failed', __FILE__, __LINE__);
689
+                            return false;
690
+                        }
691
+                        header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
692
+                        echo $ico_data;
693
+                    } else {
694
+                        $this->DebugMessage('new phpthumb_ico() failed', __FILE__, __LINE__);
695
+                        return false;
696
+                    }
697
+                    break;
698
+
699
+                default:
700
+                    $this->DebugMessage('OutputThumbnail failed because $this->thumbnailFormat "'.$this->thumbnailFormat.'" is not valid', __FILE__, __LINE__);
701
+                    return false;
702
+                    break;
703
+            }
704
+
705
+        }
706
+        return true;
707
+    }
708
+
709
+
710
+    // public:
711
+    public function CleanUpCacheDirectory() {
712
+        $this->DebugMessage('CleanUpCacheDirectory() set to purge ('.(null === $this->config_cache_maxage ? 'NULL' : number_format($this->config_cache_maxage / 86400, 1)).' days; '.(null === $this->config_cache_maxsize ? 'NULL' : number_format($this->config_cache_maxsize / 1048576, 2)).' MB; '.(null === $this->config_cache_maxfiles ? 'NULL' : number_format($this->config_cache_maxfiles)).' files)', __FILE__, __LINE__);
713
+
714
+        if (!is_writable($this->config_cache_directory)) {
715
+            $this->DebugMessage('CleanUpCacheDirectory() skipped because "'.$this->config_cache_directory.'" is not writable', __FILE__, __LINE__);
716
+            return true;
717
+        }
718
+
719
+        // cache status of cache directory for 1 hour to avoid hammering the filesystem functions
720
+        $phpThumbCacheStats_filename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheStats.txt';
721
+        if (file_exists($phpThumbCacheStats_filename) && is_readable($phpThumbCacheStats_filename) && (filemtime($phpThumbCacheStats_filename) >= (time() - 3600))) {
722
+            $this->DebugMessage('CleanUpCacheDirectory() skipped because "'.$phpThumbCacheStats_filename.'" is recently modified', __FILE__, __LINE__);
723
+            return true;
724
+        }
725
+        if (!@touch($phpThumbCacheStats_filename)) {
726
+            $this->DebugMessage('touch('.$phpThumbCacheStats_filename.') failed', __FILE__, __LINE__);
727
+        }
728
+
729
+        $DeletedKeys = array();
730
+        $AllFilesInCacheDirectory = array();
731
+        if (($this->config_cache_maxage > 0) || ($this->config_cache_maxsize > 0) || ($this->config_cache_maxfiles > 0)) {
732
+            $CacheDirOldFilesAge  = array();
733
+            $CacheDirOldFilesSize = array();
734
+            $AllFilesInCacheDirectory = phpthumb_functions::GetAllFilesInSubfolders($this->config_cache_directory);
735
+            foreach ($AllFilesInCacheDirectory as $fullfilename) {
736
+                if (preg_match('#'.preg_quote($this->config_cache_prefix).'#i', $fullfilename) && file_exists($fullfilename)) {
737
+                    $CacheDirOldFilesAge[$fullfilename] = @fileatime($fullfilename);
738
+                    if ($CacheDirOldFilesAge[$fullfilename] == 0) {
739
+                        $CacheDirOldFilesAge[$fullfilename] = @filemtime($fullfilename);
740
+                    }
741
+                    $CacheDirOldFilesSize[$fullfilename] = @filesize($fullfilename);
742
+                }
743
+            }
744
+            if (empty($CacheDirOldFilesSize)) {
745
+                $this->DebugMessage('CleanUpCacheDirectory() skipped because $CacheDirOldFilesSize is empty (phpthumb_functions::GetAllFilesInSubfolders('.$this->config_cache_directory.') found no files)', __FILE__, __LINE__);
746
+                return true;
747
+            }
748
+            $DeletedKeys['zerobyte'] = array();
749
+            foreach ($CacheDirOldFilesSize as $fullfilename => $filesize) {
750
+                // purge all zero-size files more than an hour old (to prevent trying to delete just-created and/or in-use files)
751
+                $cutofftime = time() - 3600;
752
+                if (($filesize == 0) && ($CacheDirOldFilesAge[$fullfilename] < $cutofftime)) {
753
+                    $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
754
+                    if (@unlink($fullfilename)) {
755
+                        $DeletedKeys['zerobyte'][] = $fullfilename;
756
+                        unset($CacheDirOldFilesSize[$fullfilename]);
757
+                        unset($CacheDirOldFilesAge[$fullfilename]);
758
+                    }
759
+                }
760
+            }
761
+            $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['zerobyte']).' zero-byte files', __FILE__, __LINE__);
762
+            asort($CacheDirOldFilesAge);
763
+
764
+            if ($this->config_cache_maxfiles > 0) {
765
+                $TotalCachedFiles = count($CacheDirOldFilesAge);
766
+                $DeletedKeys['maxfiles'] = array();
767
+                foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
768
+                    if ($TotalCachedFiles > $this->config_cache_maxfiles) {
769
+                        $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
770
+                        if (@unlink($fullfilename)) {
771
+                            $TotalCachedFiles--;
772
+                            $DeletedKeys['maxfiles'][] = $fullfilename;
773
+                        }
774
+                    } else {
775
+                        // there are few enough files to keep the rest
776
+                        break;
777
+                    }
778
+                }
779
+                $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxfiles']).' files based on (config_cache_maxfiles='.$this->config_cache_maxfiles.')', __FILE__, __LINE__);
780
+                foreach ($DeletedKeys['maxfiles'] as $fullfilename) {
781
+                    unset($CacheDirOldFilesAge[$fullfilename]);
782
+                    unset($CacheDirOldFilesSize[$fullfilename]);
783
+                }
784
+            }
785
+
786
+            if ($this->config_cache_maxage > 0) {
787
+                $mindate = time() - $this->config_cache_maxage;
788
+                $DeletedKeys['maxage'] = array();
789
+                foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
790
+                    if ($filedate > 0) {
791
+                        if ($filedate < $mindate) {
792
+                            $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
793
+                            if (@unlink($fullfilename)) {
794
+                                $DeletedKeys['maxage'][] = $fullfilename;
795
+                            }
796
+                        } else {
797
+                            // the rest of the files are new enough to keep
798
+                            break;
799
+                        }
800
+                    }
801
+                }
802
+                $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxage']).' files based on (config_cache_maxage='.$this->config_cache_maxage.')', __FILE__, __LINE__);
803
+                foreach ($DeletedKeys['maxage'] as $fullfilename) {
804
+                    unset($CacheDirOldFilesAge[$fullfilename]);
805
+                    unset($CacheDirOldFilesSize[$fullfilename]);
806
+                }
807
+            }
808
+
809
+            if ($this->config_cache_maxsize > 0) {
810
+                $TotalCachedFileSize = array_sum($CacheDirOldFilesSize);
811
+                $DeletedKeys['maxsize'] = array();
812
+                foreach ($CacheDirOldFilesAge as $fullfilename => $filedate) {
813
+                    if ($TotalCachedFileSize > $this->config_cache_maxsize) {
814
+                        $this->DebugMessage('deleting "'.$fullfilename.'"', __FILE__, __LINE__);
815
+                        if (@unlink($fullfilename)) {
816
+                            $TotalCachedFileSize -= $CacheDirOldFilesSize[$fullfilename];
817
+                            $DeletedKeys['maxsize'][] = $fullfilename;
818
+                        }
819
+                    } else {
820
+                        // the total filesizes are small enough to keep the rest of the files
821
+                        break;
822
+                    }
823
+                }
824
+                $this->DebugMessage('CleanUpCacheDirectory() purged '.count($DeletedKeys['maxsize']).' files based on (config_cache_maxsize='.$this->config_cache_maxsize.')', __FILE__, __LINE__);
825
+                foreach ($DeletedKeys['maxsize'] as $fullfilename) {
826
+                    unset($CacheDirOldFilesAge[$fullfilename]);
827
+                    unset($CacheDirOldFilesSize[$fullfilename]);
828
+                }
829
+            }
830
+
831
+        } else {
832
+            $this->DebugMessage('skipping CleanUpCacheDirectory() because config set to not use it', __FILE__, __LINE__);
833
+        }
834
+        $totalpurged = 0;
835
+        foreach ($DeletedKeys as $key => $value) {
836
+            $totalpurged += count($value);
837
+        }
838
+        $this->DebugMessage('CleanUpCacheDirectory() purged '.$totalpurged.' files (from '.count($AllFilesInCacheDirectory).') based on config settings', __FILE__, __LINE__);
839
+        if ($totalpurged > 0) {
840
+            $empty_dirs = array();
841
+            foreach ($AllFilesInCacheDirectory as $fullfilename) {
842
+                if (is_dir($fullfilename)) {
843
+                    $empty_dirs[$this->realPathSafe($fullfilename)] = 1;
844
+                } else {
845
+                    unset($empty_dirs[$this->realPathSafe(dirname($fullfilename))]);
846
+                }
847
+            }
848
+            krsort($empty_dirs);
849
+            $totalpurgeddirs = 0;
850
+            foreach ($empty_dirs as $empty_dir => $dummy) {
851
+                if ($empty_dir == $this->config_cache_directory) {
852
+                    // shouldn't happen, but just in case, don't let it delete actual cache directory
853
+                    continue;
854
+                } elseif (@rmdir($empty_dir)) {
855
+                    $totalpurgeddirs++;
856
+                } else {
857
+                    $this->DebugMessage('failed to rmdir('.$empty_dir.')', __FILE__, __LINE__);
858
+                }
859
+            }
860
+            $this->DebugMessage('purged '.$totalpurgeddirs.' empty directories', __FILE__, __LINE__);
861
+        }
862
+        return true;
863
+    }
864
+
865
+    //////////////////////////////////////////////////////////////////////
866
+
867
+    // private: re-initializator (call between rendering multiple images with one object)
868
+    public function resetObject() {
869
+        $class_vars = get_class_vars(get_class($this));
870
+        foreach ($class_vars as $key => $value) {
871
+            // do not clobber debug or config info
872
+            if (!preg_match('#^(config_|debug|fatalerror)#i', $key)) {
873
+                $this->$key = $value;
874
+            }
875
+        }
876
+        $this->phpThumb(); // re-initialize some class variables
877
+        return true;
878
+    }
879
+
880
+    //////////////////////////////////////////////////////////////////////
881
+
882
+    public function ResolveSource() {
883
+        if (is_resource($this->gdimg_source)) {
884
+            $this->DebugMessage('ResolveSource() exiting because is_resource($this->gdimg_source)', __FILE__, __LINE__);
885
+            return true;
886
+        }
887
+        if ($this->rawImageData) {
888
+            $this->sourceFilename = null;
889
+            $this->DebugMessage('ResolveSource() exiting because $this->rawImageData is set ('.number_format(strlen($this->rawImageData)).' bytes)', __FILE__, __LINE__);
890
+            return true;
891
+        }
892
+        if ($this->sourceFilename) {
893
+            $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->sourceFilename);
894
+            $this->DebugMessage('$this->sourceFilename set to "'.$this->sourceFilename.'"', __FILE__, __LINE__);
895
+        } elseif ($this->src) {
896
+            $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src);
897
+            $this->DebugMessage('$this->sourceFilename set to "'.$this->sourceFilename.'" from $this->src ('.$this->src.')', __FILE__, __LINE__);
898
+        } else {
899
+            return $this->ErrorImage('$this->sourceFilename and $this->src are both empty');
900
+        }
901
+        if ($this->iswindows && ((substr($this->sourceFilename, 0, 2) == '//') || (substr($this->sourceFilename, 0, 2) == '\\\\'))) {
902
+            // Windows \\share\filename.ext
903
+        } elseif (preg_match('#^[a-z0-9]+://#i', $this->sourceFilename, $protocol_matches)) {
904
+            if (preg_match('#^(f|ht)tps?\://#i', $this->sourceFilename)) {
905
+                // URL
906
+                if ($this->config_http_user_agent) {
907
+                    ini_set('user_agent', $this->config_http_user_agent);
908
+                }
909
+            } else {
910
+                return $this->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "'.$protocol_matches[1].'" is not');
911
+        }
912
+        } elseif (!@file_exists($this->sourceFilename)) {
913
+            return $this->ErrorImage('"'.$this->sourceFilename.'" does not exist');
914
+        } elseif (!@is_file($this->sourceFilename)) {
915
+            return $this->ErrorImage('"'.$this->sourceFilename.'" is not a file');
916
+        }
917
+        return true;
918
+    }
919
+
920
+
921
+    public function setOutputFormat() {
922
+        static $alreadyCalled = false;
923
+        if ($this->thumbnailFormat && $alreadyCalled) {
924
+            return true;
925
+        }
926
+        $alreadyCalled = true;
927
+
928
+        $AvailableImageOutputFormats = array();
929
+        $AvailableImageOutputFormats[] = 'text';
930
+        if (@is_readable( __DIR__ .'/phpthumb.ico.php')) {
931
+            $AvailableImageOutputFormats[] = 'ico';
932
+        }
933
+        if (@is_readable( __DIR__ .'/phpthumb.bmp.php')) {
934
+            $AvailableImageOutputFormats[] = 'bmp';
935
+        }
936
+
937
+        $this->thumbnailFormat = 'ico';
938
+
939
+        // Set default output format based on what image types are available
940
+        if (function_exists('imagetypes')) {
941
+            $imagetypes = imagetypes();
942
+            if ($imagetypes & IMG_WBMP) {
943
+                $this->thumbnailFormat         = 'wbmp';
944
+                $AvailableImageOutputFormats[] = 'wbmp';
945
+            }
946
+            if ($imagetypes & IMG_GIF) {
947
+                $this->thumbnailFormat         = 'gif';
948
+                $AvailableImageOutputFormats[] = 'gif';
949
+            }
950
+            if ($imagetypes & IMG_PNG) {
951
+                $this->thumbnailFormat         = 'png';
952
+                $AvailableImageOutputFormats[] = 'png';
953
+            }
954
+            if ($imagetypes & IMG_JPG) {
955
+                $this->thumbnailFormat         = 'jpeg';
956
+                $AvailableImageOutputFormats[] = 'jpeg';
957
+            }
958
+        } else {
959
+            $this->DebugMessage('imagetypes() does not exist - GD support might not be enabled?',  __FILE__, __LINE__);
960
+        }
961
+        if ($this->ImageMagickVersion()) {
962
+            $IMformats = array('jpeg', 'png', 'gif', 'bmp', 'ico', 'wbmp');
963
+            $this->DebugMessage('Addding ImageMagick formats to $AvailableImageOutputFormats ('.implode(';', $AvailableImageOutputFormats).')', __FILE__, __LINE__);
964
+            foreach ($IMformats as $key => $format) {
965
+                $AvailableImageOutputFormats[] = $format;
966
+            }
967
+        }
968
+        $AvailableImageOutputFormats = array_unique($AvailableImageOutputFormats);
969
+        $this->DebugMessage('$AvailableImageOutputFormats = array('.implode(';', $AvailableImageOutputFormats).')', __FILE__, __LINE__);
970
+
971
+        $this->f = preg_replace('#[^a-z]#', '', strtolower($this->f));
972
+        if (strtolower($this->config_output_format) == 'jpg') {
973
+            $this->config_output_format = 'jpeg';
974
+        }
975
+        if (strtolower($this->f) == 'jpg') {
976
+            $this->f = 'jpeg';
977
+        }
978
+        if (phpthumb_functions::CaseInsensitiveInArray($this->config_output_format, $AvailableImageOutputFormats)) {
979
+            // set output format to config default if that format is available
980
+            $this->DebugMessage('$this->thumbnailFormat set to $this->config_output_format "'.strtolower($this->config_output_format).'"', __FILE__, __LINE__);
981
+            $this->thumbnailFormat = strtolower($this->config_output_format);
982
+        } elseif ($this->config_output_format) {
983
+            $this->DebugMessage('$this->thumbnailFormat staying as "'.$this->thumbnailFormat.'" because $this->config_output_format ('.strtolower($this->config_output_format).') is not in $AvailableImageOutputFormats', __FILE__, __LINE__);
984
+        }
985
+        if ($this->f && (phpthumb_functions::CaseInsensitiveInArray($this->f, $AvailableImageOutputFormats))) {
986
+            // override output format if $this->f is set and that format is available
987
+            $this->DebugMessage('$this->thumbnailFormat set to $this->f "'.strtolower($this->f).'"', __FILE__, __LINE__);
988
+            $this->thumbnailFormat = strtolower($this->f);
989
+        } elseif ($this->f) {
990
+            $this->DebugMessage('$this->thumbnailFormat staying as "'.$this->thumbnailFormat.'" because $this->f ('.strtolower($this->f).') is not in $AvailableImageOutputFormats', __FILE__, __LINE__);
991
+        }
992
+
993
+        // for JPEG images, quality 1 (worst) to 99 (best)
994
+        // quality < 25 is nasty, with not much size savings - not recommended
995
+        // problems with 100 - invalid JPEG?
996
+        $this->thumbnailQuality = max(1, min(99, ($this->q ? (int) $this->q : 75)));
997
+        $this->DebugMessage('$this->thumbnailQuality set to "'.$this->thumbnailQuality.'"', __FILE__, __LINE__);
998
+
999
+        return true;
1000
+    }
1001
+
1002
+
1003
+    public function setCacheDirectory() {
1004
+        // resolve cache directory to absolute pathname
1005
+        $this->DebugMessage('setCacheDirectory() starting with config_cache_directory = "'.$this->config_cache_directory.'"', __FILE__, __LINE__);
1006
+        if ($this->config_cache_directory[ 0 ] == '.') {
1007
+            if (preg_match('#^(f|ht)tps?\://#i', $this->src)) {
1008
+                if (!$this->config_cache_disable_warning) {
1009
+                    $this->ErrorImage('$this->config_cache_directory ('.$this->config_cache_directory.') cannot be used for remote images. Adjust "cache_directory" or "cache_disable_warning" in phpThumb.config.php');
1010
+                }
1011
+            } elseif ($this->src) {
1012
+                // resolve relative cache directory to source image
1013
+                $this->config_cache_directory = dirname($this->ResolveFilenameToAbsolute($this->src)).DIRECTORY_SEPARATOR.$this->config_cache_directory;
1014
+            } else {
1015
+                // $this->new is probably set
1016
+            }
1017
+        }
1018
+        if (substr($this->config_cache_directory, -1) == '/') {
1019
+            $this->config_cache_directory = substr($this->config_cache_directory, 0, -1);
1020
+        }
1021
+        if ($this->iswindows) {
1022
+            $this->config_cache_directory = str_replace('/', DIRECTORY_SEPARATOR, $this->config_cache_directory);
1023
+        }
1024
+        if ($this->config_cache_directory) {
1025
+            $real_cache_path = $this->realPathSafe($this->config_cache_directory);
1026
+            if (!$real_cache_path) {
1027
+                $this->DebugMessage('$this->realPathSafe($this->config_cache_directory) failed for "'.$this->config_cache_directory.'"', __FILE__, __LINE__);
1028
+                if (!is_dir($this->config_cache_directory)) {
1029
+                    $this->DebugMessage('!is_dir('.$this->config_cache_directory.')', __FILE__, __LINE__);
1030
+                }
1031
+            }
1032
+            if ($real_cache_path) {
1033
+                $this->DebugMessage('setting config_cache_directory to $this->realPathSafe('.$this->config_cache_directory.') = "'.$real_cache_path.'"', __FILE__, __LINE__);
1034
+                $this->config_cache_directory = $real_cache_path;
1035
+            }
1036
+        }
1037
+        if (!is_dir($this->config_cache_directory)) {
1038
+            if (!$this->config_cache_disable_warning) {
1039
+                $this->ErrorImage('$this->config_cache_directory ('.$this->config_cache_directory.') does not exist. Adjust "cache_directory" or "cache_disable_warning" in phpThumb.config.php');
1040
+            }
1041
+            $this->DebugMessage('$this->config_cache_directory ('.$this->config_cache_directory.') is not a directory', __FILE__, __LINE__);
1042
+            $this->config_cache_directory = null;
1043
+        } elseif (!@is_writable($this->config_cache_directory)) {
1044
+            $this->DebugMessage('$this->config_cache_directory is not writable ('.$this->config_cache_directory.')', __FILE__, __LINE__);
1045
+        }
1046
+
1047
+        $this->InitializeTempDirSetting();
1048
+        if (!@is_dir($this->config_temp_directory) && !@is_writable($this->config_temp_directory) && @is_dir($this->config_cache_directory) && @is_writable($this->config_cache_directory)) {
1049
+            $this->DebugMessage('setting $this->config_temp_directory = $this->config_cache_directory ('.$this->config_cache_directory.')', __FILE__, __LINE__);
1050
+            $this->config_temp_directory = $this->config_cache_directory;
1051
+        }
1052
+        return true;
1053
+    }
1054
+
1055
+    /* Takes the array of path segments up to now, and the next segment (maybe a modifier: empty, . or ..)
1056 1056
 	   Applies it, adding or removing from $segments as a result. Returns nothing. */
1057
-	// http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1058
-	public function applyPathSegment(&$segments, $segment) {
1059
-		if ($segment == '.') {
1060
-			return; // always remove
1061
-		}
1062
-		if ($segment == '') {
1063
-			$test = array_pop($segments);
1064
-			if (null === $test) {
1065
-				$segments[] = $segment; // keep the first empty block
1066
-			} elseif ($test == '') {
1067
-				$test = array_pop($segments);
1068
-				if (null === $test) {
1069
-					$segments[] = $test;
1070
-					$segments[] = $segment; // keep the second one too
1071
-				} else { // put both back and ignore segment
1072
-					$segments[] = $test;
1073
-					$segments[] = $test;
1074
-				}
1075
-			} else {
1076
-				$segments[] = $test; // ignore empty blocks
1077
-			}
1078
-		} else {
1079
-			if ($segment == '..') {
1080
-				$test = array_pop($segments);
1081
-				if (null === $test) {
1082
-					$segments[] = $segment;
1083
-				} elseif ($test == '..') {
1084
-					$segments[] = $test;
1085
-					$segments[] = $segment;
1086
-				} else {
1087
-					if ($test == '') {
1088
-						$segments[] = $test;
1089
-					} // else nothing, remove both
1090
-				}
1091
-			} else {
1092
-				$segments[] = $segment;
1093
-			}
1094
-		}
1095
-	}
1096
-
1097
-	/* Takes array of path components, normalizes it: removes empty slots and '.', collapses '..' and folder names.  Returns array. */
1098
-	// http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1099
-	public function normalizePath($segments) {
1100
-		$parts = array();
1101
-		foreach ($segments as $segment) {
1102
-			$this->applyPathSegment($parts, $segment);
1103
-		}
1104
-		return $parts;
1105
-	}
1106
-
1107
-	/* True if the provided path points (without resolving symbolic links) into one of the allowed directories. */
1108
-	// http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1109
-	public function matchPath($path, $allowed_dirs) {
1110
-		if (!empty($allowed_dirs)) {
1111
-			foreach ($allowed_dirs as $one_dir) {
1112
-				if (preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', $this->realPathSafe($one_dir))).'#', $path)) {
1113
-					return true;
1114
-				}
1115
-			}
1116
-		}
1117
-		return false;
1118
-	}
1119
-
1120
-	/* True if the provided path points inside one of open_basedirs (or if open_basedirs are disabled) */
1121
-	// http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1122
-	public function isInOpenBasedir($path) {
1123
-		static $open_basedirs = null;
1124
-		if (null === $open_basedirs) {
1125
-			$ini_text = ini_get('open_basedir');
1126
-			$this->DebugMessage('open_basedir: "'.$ini_text.'"', __FILE__, __LINE__);
1127
-			$open_basedirs = array();
1128
-			if (strlen($ini_text) > 0) {
1129
-				foreach (preg_split('#[;:]#', $ini_text) as $key => $value) {
1130
-					$open_basedirs[$key] = $this->realPathSafe($value);
1131
-				}
1132
-			}
1133
-		}
1134
-		return (empty($open_basedirs) || $this->matchPath($path, $open_basedirs));
1135
-	}
1136
-
1137
-	/* Resolves all symlinks in $path, checking that each continuous part ends in an allowed zone. Returns null, if any component leads outside of allowed zone. */
1138
-	// http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1139
-	public function resolvePath($path, $allowed_dirs) {
1140
-		$this->DebugMessage('resolvePath: '.$path.' (allowed_dirs: '.print_r($allowed_dirs, true).')', __FILE__, __LINE__);
1141
-
1142
-		// add base path to the top of the list
1143
-		if (!$this->config_allow_src_above_docroot) {
1144
-			array_unshift($allowed_dirs, $this->realPathSafe($this->config_document_root));
1145
-		} else {
1146
-			if (!$this->config_allow_src_above_phpthumb) {
1147
-				array_unshift($allowed_dirs, $this->realPathSafe( __DIR__ ));
1148
-			} else {
1149
-				// no checks are needed, offload the work to realpath and forget about it
1150
-				$this->DebugMessage('resolvePath: checks disabled, returning '.$this->realPathSafe($path), __FILE__, __LINE__);
1151
-				return $this->realPathSafe($path);
1152
-			}
1153
-		}
1154
-		if ($path == '') {
1155
-			return null; // save us trouble
1156
-		}
1157
-
1158
-		do {
1159
-			$this->DebugMessage('resolvePath: iteration, path='.$path.', base path = '.$allowed_dirs[0], __FILE__, __LINE__);
1160
-
1161
-			$parts = array();
1162
-			// do not use "cleaner" foreach version of this loop as later code relies on both $segments and $i
1163
-			// http://support.silisoftware.com/phpBB3/viewtopic.php?t=964
1164
-			$segments = explode(DIRECTORY_SEPARATOR, $path);
1165
-			for ($i = 0, $iMax = count($segments); $i < $iMax; $i++) {
1166
-				$this->applyPathSegment($parts, $segments[$i]);
1167
-				$thispart = implode(DIRECTORY_SEPARATOR, $parts);
1168
-				if ($this->isInOpenBasedir($thispart)) {
1169
-					if (is_link($thispart)) {
1170
-						break;
1171
-					}
1172
-				}
1173
-			}
1174
-
1175
-			$this->DebugMessage('resolvePath: stop at component '.$i, __FILE__, __LINE__);
1176
-			// test the part up to here
1177
-			$path = implode(DIRECTORY_SEPARATOR, $parts);
1178
-			$this->DebugMessage('resolvePath: stop at path='.$path, __FILE__, __LINE__);
1179
-			if (!$this->matchPath($path, $allowed_dirs)) {
1180
-				$this->DebugMessage('resolvePath: no match, returning null', __FILE__, __LINE__);
1181
-				return null;
1182
-			}
1183
-			if ($i >= count($segments)) { // reached end
1184
-				$this->DebugMessage('resolvePath: path parsed, over', __FILE__, __LINE__);
1185
-				break;
1186
-			}
1187
-			// else it's symlink, rewrite path
1188
-			$path = readlink($path);
1189
-			$this->DebugMessage('resolvePath: symlink matched, target='.$path, __FILE__, __LINE__);
1190
-
1191
-			/*
1057
+    // http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1058
+    public function applyPathSegment(&$segments, $segment) {
1059
+        if ($segment == '.') {
1060
+            return; // always remove
1061
+        }
1062
+        if ($segment == '') {
1063
+            $test = array_pop($segments);
1064
+            if (null === $test) {
1065
+                $segments[] = $segment; // keep the first empty block
1066
+            } elseif ($test == '') {
1067
+                $test = array_pop($segments);
1068
+                if (null === $test) {
1069
+                    $segments[] = $test;
1070
+                    $segments[] = $segment; // keep the second one too
1071
+                } else { // put both back and ignore segment
1072
+                    $segments[] = $test;
1073
+                    $segments[] = $test;
1074
+                }
1075
+            } else {
1076
+                $segments[] = $test; // ignore empty blocks
1077
+            }
1078
+        } else {
1079
+            if ($segment == '..') {
1080
+                $test = array_pop($segments);
1081
+                if (null === $test) {
1082
+                    $segments[] = $segment;
1083
+                } elseif ($test == '..') {
1084
+                    $segments[] = $test;
1085
+                    $segments[] = $segment;
1086
+                } else {
1087
+                    if ($test == '') {
1088
+                        $segments[] = $test;
1089
+                    } // else nothing, remove both
1090
+                }
1091
+            } else {
1092
+                $segments[] = $segment;
1093
+            }
1094
+        }
1095
+    }
1096
+
1097
+    /* Takes array of path components, normalizes it: removes empty slots and '.', collapses '..' and folder names.  Returns array. */
1098
+    // http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1099
+    public function normalizePath($segments) {
1100
+        $parts = array();
1101
+        foreach ($segments as $segment) {
1102
+            $this->applyPathSegment($parts, $segment);
1103
+        }
1104
+        return $parts;
1105
+    }
1106
+
1107
+    /* True if the provided path points (without resolving symbolic links) into one of the allowed directories. */
1108
+    // http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1109
+    public function matchPath($path, $allowed_dirs) {
1110
+        if (!empty($allowed_dirs)) {
1111
+            foreach ($allowed_dirs as $one_dir) {
1112
+                if (preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', $this->realPathSafe($one_dir))).'#', $path)) {
1113
+                    return true;
1114
+                }
1115
+            }
1116
+        }
1117
+        return false;
1118
+    }
1119
+
1120
+    /* True if the provided path points inside one of open_basedirs (or if open_basedirs are disabled) */
1121
+    // http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1122
+    public function isInOpenBasedir($path) {
1123
+        static $open_basedirs = null;
1124
+        if (null === $open_basedirs) {
1125
+            $ini_text = ini_get('open_basedir');
1126
+            $this->DebugMessage('open_basedir: "'.$ini_text.'"', __FILE__, __LINE__);
1127
+            $open_basedirs = array();
1128
+            if (strlen($ini_text) > 0) {
1129
+                foreach (preg_split('#[;:]#', $ini_text) as $key => $value) {
1130
+                    $open_basedirs[$key] = $this->realPathSafe($value);
1131
+                }
1132
+            }
1133
+        }
1134
+        return (empty($open_basedirs) || $this->matchPath($path, $open_basedirs));
1135
+    }
1136
+
1137
+    /* Resolves all symlinks in $path, checking that each continuous part ends in an allowed zone. Returns null, if any component leads outside of allowed zone. */
1138
+    // http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1139
+    public function resolvePath($path, $allowed_dirs) {
1140
+        $this->DebugMessage('resolvePath: '.$path.' (allowed_dirs: '.print_r($allowed_dirs, true).')', __FILE__, __LINE__);
1141
+
1142
+        // add base path to the top of the list
1143
+        if (!$this->config_allow_src_above_docroot) {
1144
+            array_unshift($allowed_dirs, $this->realPathSafe($this->config_document_root));
1145
+        } else {
1146
+            if (!$this->config_allow_src_above_phpthumb) {
1147
+                array_unshift($allowed_dirs, $this->realPathSafe( __DIR__ ));
1148
+            } else {
1149
+                // no checks are needed, offload the work to realpath and forget about it
1150
+                $this->DebugMessage('resolvePath: checks disabled, returning '.$this->realPathSafe($path), __FILE__, __LINE__);
1151
+                return $this->realPathSafe($path);
1152
+            }
1153
+        }
1154
+        if ($path == '') {
1155
+            return null; // save us trouble
1156
+        }
1157
+
1158
+        do {
1159
+            $this->DebugMessage('resolvePath: iteration, path='.$path.', base path = '.$allowed_dirs[0], __FILE__, __LINE__);
1160
+
1161
+            $parts = array();
1162
+            // do not use "cleaner" foreach version of this loop as later code relies on both $segments and $i
1163
+            // http://support.silisoftware.com/phpBB3/viewtopic.php?t=964
1164
+            $segments = explode(DIRECTORY_SEPARATOR, $path);
1165
+            for ($i = 0, $iMax = count($segments); $i < $iMax; $i++) {
1166
+                $this->applyPathSegment($parts, $segments[$i]);
1167
+                $thispart = implode(DIRECTORY_SEPARATOR, $parts);
1168
+                if ($this->isInOpenBasedir($thispart)) {
1169
+                    if (is_link($thispart)) {
1170
+                        break;
1171
+                    }
1172
+                }
1173
+            }
1174
+
1175
+            $this->DebugMessage('resolvePath: stop at component '.$i, __FILE__, __LINE__);
1176
+            // test the part up to here
1177
+            $path = implode(DIRECTORY_SEPARATOR, $parts);
1178
+            $this->DebugMessage('resolvePath: stop at path='.$path, __FILE__, __LINE__);
1179
+            if (!$this->matchPath($path, $allowed_dirs)) {
1180
+                $this->DebugMessage('resolvePath: no match, returning null', __FILE__, __LINE__);
1181
+                return null;
1182
+            }
1183
+            if ($i >= count($segments)) { // reached end
1184
+                $this->DebugMessage('resolvePath: path parsed, over', __FILE__, __LINE__);
1185
+                break;
1186
+            }
1187
+            // else it's symlink, rewrite path
1188
+            $path = readlink($path);
1189
+            $this->DebugMessage('resolvePath: symlink matched, target='.$path, __FILE__, __LINE__);
1190
+
1191
+            /*
1192 1192
 			Replace base path with symlink target.
1193 1193
 			Assuming:
1194 1194
 			  /www/img/external -> /external
@@ -1198,134 +1198,134 @@  discard block
 block discarded – undo
1198 1198
 			  GET /www/img/external/../www/img/pic.jpg
1199 1199
 			So there's only one base path which is the last symlink target, but any number of stable whitelisted paths.
1200 1200
 			*/
1201
-			if ($this->config_auto_allow_symlinks) {
1202
-				$allowed_dirs[0] = $path;
1203
-			}
1204
-			$path = $path.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, array_slice($segments,$i + 1));
1205
-		} while (true);
1206
-		return $path;
1207
-	}
1208
-
1209
-
1210
-	public function realPathSafe($filename) {
1211
-		// http://php.net/manual/en/function.realpath.php -- "Note: The running script must have executable permissions on all directories in the hierarchy, otherwise realpath() will return FALSE"
1212
-		// realPathSafe() provides a reasonable facsimile of realpath() but does not resolve symbolic links, nor does it check that the file/path actually exists
1213
-		if (!$this->config_disable_realpath) {
1214
-			return realpath($filename);
1215
-		}
1216
-
1217
-		// http://stackoverflow.com/questions/21421569
1218
-		$newfilename = preg_replace('#[\\/]+#', DIRECTORY_SEPARATOR, $filename);
1219
-		if (!preg_match('#^'.DIRECTORY_SEPARATOR.'#', $newfilename)) {
1220
-			$newfilename =  __DIR__ .DIRECTORY_SEPARATOR.$newfilename;
1221
-		}
1222
-		do {
1223
-			$beforeloop = $newfilename;
1224
-
1225
-			// Replace all sequences of more than one / with a single one [[ If you're working on a system that treats // at the start of a path as special, make sure you replace multiple / characters at the start with two of them. This is the only place where POSIX allows (but does not mandate) special handling for multiples, in all other cases, multiple / characters are equivalent to a single one.]]
1226
-			$newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'+#', DIRECTORY_SEPARATOR, $newfilename);
1227
-
1228
-			// Replace all occurrences of /./ with /
1229
-			$newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'\\.'.DIRECTORY_SEPARATOR.'#', DIRECTORY_SEPARATOR, $newfilename);
1230
-
1231
-			// Remove ./ if at the start
1232
-			$newfilename = preg_replace('#^\\.'.DIRECTORY_SEPARATOR.'#', '', $newfilename);
1233
-
1234
-			// Remove /. if at the end
1235
-			$newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'\\.$#', '', $newfilename);
1236
-
1237
-			// Replace /anything/../ with /
1238
-			$newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'[^'.DIRECTORY_SEPARATOR.']+'.DIRECTORY_SEPARATOR.'\\.\\.'.DIRECTORY_SEPARATOR.'#', DIRECTORY_SEPARATOR, $newfilename);
1239
-
1240
-			// Remove /anything/.. if at the end
1241
-			$newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'[^'.DIRECTORY_SEPARATOR.']+'.DIRECTORY_SEPARATOR.'\\.\\.$#', '', $newfilename);
1242
-
1243
-		} while ($newfilename != $beforeloop);
1244
-		return $newfilename;
1245
-	}
1246
-
1247
-
1248
-	public function ResolveFilenameToAbsolute($filename) {
1249
-		if (empty($filename)) {
1250
-			return false;
1251
-		}
1252
-
1253
-		if (preg_match('#^[a-z0-9]+\:/{1,2}#i', $filename)) {
1254
-			// eg: http://host/path/file.jpg (HTTP URL)
1255
-			// eg: ftp://host/path/file.jpg  (FTP URL)
1256
-			// eg: data1:/path/file.jpg      (Netware path)
1257
-
1258
-			//$AbsoluteFilename = $filename;
1259
-			return $filename;
1260
-
1261
-		} elseif ($this->iswindows && isset($filename{1}) && ($filename{1} == ':')) {
1262
-
1263
-			// absolute pathname (Windows)
1264
-			$AbsoluteFilename = $filename;
1265
-
1266
-		} elseif ($this->iswindows && ((substr($filename, 0, 2) == '//') || (substr($filename, 0, 2) == '\\\\'))) {
1267
-
1268
-			// absolute pathname (Windows)
1269
-			$AbsoluteFilename = $filename;
1270
-
1271
-		} elseif ($filename{0} == '/') {
1272
-
1273
-			if (@is_readable($filename) && !@is_readable($this->config_document_root.$filename)) {
1274
-
1275
-				// absolute filename (*nix)
1276
-				$AbsoluteFilename = $filename;
1277
-
1278
-			} elseif (isset($filename{1}) && ($filename{1} == '~')) {
1201
+            if ($this->config_auto_allow_symlinks) {
1202
+                $allowed_dirs[0] = $path;
1203
+            }
1204
+            $path = $path.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, array_slice($segments,$i + 1));
1205
+        } while (true);
1206
+        return $path;
1207
+    }
1279 1208
 
1280
-				// /~user/path
1281
-				if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray($filename)) {
1282
-					$AbsoluteFilename = $ApacheLookupURIarray['filename'];
1283
-				} else {
1284
-					$AbsoluteFilename = $this->realPathSafe($filename);
1285
-					if (@is_readable($AbsoluteFilename)) {
1286
-						$this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.$filename.'", but the correct filename ('.$AbsoluteFilename.') seems to have been resolved with $this->realPathSafe($filename)', __FILE__, __LINE__);
1287
-					} elseif (is_dir(dirname($AbsoluteFilename))) {
1288
-						$this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname($filename).'", but the correct directory ('.dirname($AbsoluteFilename).') seems to have been resolved with $this->realPathSafe(.)', __FILE__, __LINE__);
1289
-					} else {
1290
-						return $this->ErrorImage('phpthumb_functions::ApacheLookupURIarray() failed for "'.$filename.'". This has been known to fail on Apache2 - try using the absolute filename for the source image (ex: "/home/user/httpdocs/image.jpg" instead of "/~user/image.jpg")');
1291
-					}
1292
-				}
1293 1209
 
1294
-			} else {
1210
+    public function realPathSafe($filename) {
1211
+        // http://php.net/manual/en/function.realpath.php -- "Note: The running script must have executable permissions on all directories in the hierarchy, otherwise realpath() will return FALSE"
1212
+        // realPathSafe() provides a reasonable facsimile of realpath() but does not resolve symbolic links, nor does it check that the file/path actually exists
1213
+        if (!$this->config_disable_realpath) {
1214
+            return realpath($filename);
1215
+        }
1295 1216
 
1296
-				// relative filename (any OS)
1297
-				if (preg_match('#^'.preg_quote($this->config_document_root).'#', $filename)) {
1298
-					$AbsoluteFilename = $filename;
1299
-					$this->DebugMessage('ResolveFilenameToAbsolute() NOT prepending $this->config_document_root ('.$this->config_document_root.') to $filename ('.$filename.') resulting in ($AbsoluteFilename = "'.$AbsoluteFilename.'")', __FILE__, __LINE__);
1300
-				} else {
1301
-					$AbsoluteFilename = $this->config_document_root.$filename;
1302
-					$this->DebugMessage('ResolveFilenameToAbsolute() prepending $this->config_document_root ('.$this->config_document_root.') to $filename ('.$filename.') resulting in ($AbsoluteFilename = "'.$AbsoluteFilename.'")', __FILE__, __LINE__);
1303
-				}
1217
+        // http://stackoverflow.com/questions/21421569
1218
+        $newfilename = preg_replace('#[\\/]+#', DIRECTORY_SEPARATOR, $filename);
1219
+        if (!preg_match('#^'.DIRECTORY_SEPARATOR.'#', $newfilename)) {
1220
+            $newfilename =  __DIR__ .DIRECTORY_SEPARATOR.$newfilename;
1221
+        }
1222
+        do {
1223
+            $beforeloop = $newfilename;
1224
+
1225
+            // Replace all sequences of more than one / with a single one [[ If you're working on a system that treats // at the start of a path as special, make sure you replace multiple / characters at the start with two of them. This is the only place where POSIX allows (but does not mandate) special handling for multiples, in all other cases, multiple / characters are equivalent to a single one.]]
1226
+            $newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'+#', DIRECTORY_SEPARATOR, $newfilename);
1227
+
1228
+            // Replace all occurrences of /./ with /
1229
+            $newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'\\.'.DIRECTORY_SEPARATOR.'#', DIRECTORY_SEPARATOR, $newfilename);
1230
+
1231
+            // Remove ./ if at the start
1232
+            $newfilename = preg_replace('#^\\.'.DIRECTORY_SEPARATOR.'#', '', $newfilename);
1233
+
1234
+            // Remove /. if at the end
1235
+            $newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'\\.$#', '', $newfilename);
1236
+
1237
+            // Replace /anything/../ with /
1238
+            $newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'[^'.DIRECTORY_SEPARATOR.']+'.DIRECTORY_SEPARATOR.'\\.\\.'.DIRECTORY_SEPARATOR.'#', DIRECTORY_SEPARATOR, $newfilename);
1239
+
1240
+            // Remove /anything/.. if at the end
1241
+            $newfilename = preg_replace('#'.DIRECTORY_SEPARATOR.'[^'.DIRECTORY_SEPARATOR.']+'.DIRECTORY_SEPARATOR.'\\.\\.$#', '', $newfilename);
1242
+
1243
+        } while ($newfilename != $beforeloop);
1244
+        return $newfilename;
1245
+    }
1246
+
1247
+
1248
+    public function ResolveFilenameToAbsolute($filename) {
1249
+        if (empty($filename)) {
1250
+            return false;
1251
+        }
1252
+
1253
+        if (preg_match('#^[a-z0-9]+\:/{1,2}#i', $filename)) {
1254
+            // eg: http://host/path/file.jpg (HTTP URL)
1255
+            // eg: ftp://host/path/file.jpg  (FTP URL)
1256
+            // eg: data1:/path/file.jpg      (Netware path)
1257
+
1258
+            //$AbsoluteFilename = $filename;
1259
+            return $filename;
1260
+
1261
+        } elseif ($this->iswindows && isset($filename{1}) && ($filename{1} == ':')) {
1262
+
1263
+            // absolute pathname (Windows)
1264
+            $AbsoluteFilename = $filename;
1265
+
1266
+        } elseif ($this->iswindows && ((substr($filename, 0, 2) == '//') || (substr($filename, 0, 2) == '\\\\'))) {
1267
+
1268
+            // absolute pathname (Windows)
1269
+            $AbsoluteFilename = $filename;
1270
+
1271
+        } elseif ($filename{0} == '/') {
1272
+
1273
+            if (@is_readable($filename) && !@is_readable($this->config_document_root.$filename)) {
1274
+
1275
+                // absolute filename (*nix)
1276
+                $AbsoluteFilename = $filename;
1277
+
1278
+            } elseif (isset($filename{1}) && ($filename{1} == '~')) {
1279
+
1280
+                // /~user/path
1281
+                if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray($filename)) {
1282
+                    $AbsoluteFilename = $ApacheLookupURIarray['filename'];
1283
+                } else {
1284
+                    $AbsoluteFilename = $this->realPathSafe($filename);
1285
+                    if (@is_readable($AbsoluteFilename)) {
1286
+                        $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.$filename.'", but the correct filename ('.$AbsoluteFilename.') seems to have been resolved with $this->realPathSafe($filename)', __FILE__, __LINE__);
1287
+                    } elseif (is_dir(dirname($AbsoluteFilename))) {
1288
+                        $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname($filename).'", but the correct directory ('.dirname($AbsoluteFilename).') seems to have been resolved with $this->realPathSafe(.)', __FILE__, __LINE__);
1289
+                    } else {
1290
+                        return $this->ErrorImage('phpthumb_functions::ApacheLookupURIarray() failed for "'.$filename.'". This has been known to fail on Apache2 - try using the absolute filename for the source image (ex: "/home/user/httpdocs/image.jpg" instead of "/~user/image.jpg")');
1291
+                    }
1292
+                }
1293
+
1294
+            } else {
1295
+
1296
+                // relative filename (any OS)
1297
+                if (preg_match('#^'.preg_quote($this->config_document_root).'#', $filename)) {
1298
+                    $AbsoluteFilename = $filename;
1299
+                    $this->DebugMessage('ResolveFilenameToAbsolute() NOT prepending $this->config_document_root ('.$this->config_document_root.') to $filename ('.$filename.') resulting in ($AbsoluteFilename = "'.$AbsoluteFilename.'")', __FILE__, __LINE__);
1300
+                } else {
1301
+                    $AbsoluteFilename = $this->config_document_root.$filename;
1302
+                    $this->DebugMessage('ResolveFilenameToAbsolute() prepending $this->config_document_root ('.$this->config_document_root.') to $filename ('.$filename.') resulting in ($AbsoluteFilename = "'.$AbsoluteFilename.'")', __FILE__, __LINE__);
1303
+                }
1304
+
1305
+            }
1304 1306
 
1305
-			}
1307
+        } else {
1306 1308
 
1307
-		} else {
1309
+            // relative to current directory (any OS)
1310
+            $AbsoluteFilename =  __DIR__ .DIRECTORY_SEPARATOR.preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $filename);
1311
+
1312
+            if (substr(dirname(@$_SERVER['PHP_SELF']), 0, 2) == '/~') {
1313
+                if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) {
1314
+                    $AbsoluteFilename = $ApacheLookupURIarray['filename'].DIRECTORY_SEPARATOR.$filename;
1315
+                } else {
1316
+                    $AbsoluteFilename = $this->realPathSafe('.').DIRECTORY_SEPARATOR.$filename;
1317
+                    if (@is_readable($AbsoluteFilename)) {
1318
+                        $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'", but the correct filename ('.$AbsoluteFilename.') seems to have been resolved with $this->realPathSafe(.)/$filename', __FILE__, __LINE__);
1319
+                    } elseif (is_dir(dirname($AbsoluteFilename))) {
1320
+                        $this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'", but the correct directory ('.dirname($AbsoluteFilename).') seems to have been resolved with $this->realPathSafe(.)', __FILE__, __LINE__);
1321
+                    } else {
1322
+                        return $this->ErrorImage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'". This has been known to fail on Apache2 - try using the absolute filename for the source image');
1323
+                    }
1324
+                }
1325
+            }
1308 1326
 
1309
-			// relative to current directory (any OS)
1310
-			$AbsoluteFilename =  __DIR__ .DIRECTORY_SEPARATOR.preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $filename);
1311
-
1312
-			if (substr(dirname(@$_SERVER['PHP_SELF']), 0, 2) == '/~') {
1313
-				if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) {
1314
-					$AbsoluteFilename = $ApacheLookupURIarray['filename'].DIRECTORY_SEPARATOR.$filename;
1315
-				} else {
1316
-					$AbsoluteFilename = $this->realPathSafe('.').DIRECTORY_SEPARATOR.$filename;
1317
-					if (@is_readable($AbsoluteFilename)) {
1318
-						$this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'", but the correct filename ('.$AbsoluteFilename.') seems to have been resolved with $this->realPathSafe(.)/$filename', __FILE__, __LINE__);
1319
-					} elseif (is_dir(dirname($AbsoluteFilename))) {
1320
-						$this->DebugMessage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'", but the correct directory ('.dirname($AbsoluteFilename).') seems to have been resolved with $this->realPathSafe(.)', __FILE__, __LINE__);
1321
-					} else {
1322
-						return $this->ErrorImage('phpthumb_functions::ApacheLookupURIarray() failed for "'.dirname(@$_SERVER['PHP_SELF']).'". This has been known to fail on Apache2 - try using the absolute filename for the source image');
1323
-					}
1324
-				}
1325
-			}
1326
-
1327
-		}
1328
-		/*
1327
+        }
1328
+        /*
1329 1329
 		// removed 2014-May-30: http://support.silisoftware.com/phpBB3/viewtopic.php?t=961
1330 1330
 		if (is_link($AbsoluteFilename)) {
1331 1331
 			$this->DebugMessage('is_link()==true, changing "'.$AbsoluteFilename.'" to "'.readlink($AbsoluteFilename).'"', __FILE__, __LINE__);
@@ -1335,317 +1335,317 @@  discard block
 block discarded – undo
1335 1335
 			$AbsoluteFilename = $this->realPathSafe($AbsoluteFilename);
1336 1336
 		}
1337 1337
 		*/
1338
-		if ($this->iswindows) {
1339
-			$AbsoluteFilename = preg_replace('#^'.preg_quote($this->realPathSafe($this->config_document_root)).'#i', str_replace('\\', '\\\\', $this->realPathSafe($this->config_document_root)), $AbsoluteFilename);
1340
-			$AbsoluteFilename = str_replace(DIRECTORY_SEPARATOR, '/', $AbsoluteFilename);
1341
-		}
1342
-		$resolvedAbsoluteFilename = $this->resolvePath($AbsoluteFilename, $this->config_additional_allowed_dirs);
1343
-		if (!$this->config_allow_src_above_docroot && !preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', $this->realPathSafe($this->config_document_root))).'#', $resolvedAbsoluteFilename)) {
1344
-			$this->DebugMessage('!$this->config_allow_src_above_docroot therefore setting "'.$AbsoluteFilename.'" (outside "'.$this->realPathSafe($this->config_document_root).'") to null', __FILE__, __LINE__);
1345
-			return false;
1346
-		}
1347
-		if (!$this->config_allow_src_above_phpthumb && !preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/',  __DIR__ )).'#', $resolvedAbsoluteFilename)) {
1348
-			$this->DebugMessage('!$this->config_allow_src_above_phpthumb therefore setting "'.$AbsoluteFilename.'" (outside "'. __DIR__ .'") to null', __FILE__, __LINE__);
1349
-			return false;
1350
-		}
1351
-		return $resolvedAbsoluteFilename;
1352
-	}
1353
-
1354
-
1355
-	public function file_exists_ignoreopenbasedir($filename, $cached=true) {
1356
-		static $open_basedirs = null;
1357
-		static $file_exists_cache = array();
1358
-		if (!$cached || !isset($file_exists_cache[$filename])) {
1359
-			if (null === $open_basedirs) {
1360
-				$open_basedirs = preg_split('#[;:]#', ini_get('open_basedir'));
1361
-			}
1362
-			if (empty($open_basedirs) || in_array(dirname($filename), $open_basedirs)) {
1363
-				$file_exists_cache[$filename] = file_exists($filename);
1364
-			} elseif ($this->iswindows) {
1365
-				$ls_filename = trim(phpthumb_functions::SafeExec('dir /b '.phpthumb_functions::escapeshellarg_replacement($filename)));
1366
-				$file_exists_cache[$filename] = ($ls_filename == basename($filename));  // command dir /b return only filename without path
1367
-			} else {
1368
-				$ls_filename = trim(phpthumb_functions::SafeExec('ls '.phpthumb_functions::escapeshellarg_replacement($filename)));
1369
-				$file_exists_cache[$filename] = ($ls_filename == $filename);
1370
-			}
1371
-		}
1372
-		return $file_exists_cache[$filename];
1373
-	}
1374
-
1375
-
1376
-	public function ImageMagickWhichConvert() {
1377
-		static $WhichConvert = null;
1378
-		if (null === $WhichConvert) {
1379
-			if ($this->iswindows) {
1380
-				$WhichConvert = false;
1381
-			} else {
1382
-				$IMwhichConvertCacheFilename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheIMwhichConvert.txt';
1383
-				if (($cachedwhichconvertstring = @file_get_contents($IMwhichConvertCacheFilename)) !== false) {
1384
-					$WhichConvert = $cachedwhichconvertstring;
1385
-				} else {
1386
-					$WhichConvert = trim(phpthumb_functions::SafeExec('which convert'));
1387
-					@file_put_contents($IMwhichConvertCacheFilename, $WhichConvert);
1388
-					@chmod($IMwhichConvertCacheFilename, $this->getParameter('config_file_create_mask'));
1389
-				}
1390
-			}
1391
-		}
1392
-		return $WhichConvert;
1393
-	}
1394
-
1395
-
1396
-	public function ImageMagickCommandlineBase() {
1397
-		static $commandline = null;
1398
-		if (null === $commandline) {
1399
-			if ($this->issafemode) {
1400
-				$commandline = '';
1401
-				return $commandline;
1402
-			}
1403
-
1404
-			$IMcommandlineBaseCacheFilename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheIMcommandlineBase.txt';
1405
-			if (($commandline = @file_get_contents($IMcommandlineBaseCacheFilename)) !== false) {
1406
-				return $commandline;
1407
-			}
1408
-
1409
-			$commandline = (null !== $this->config_imagemagick_path ? $this->config_imagemagick_path : '');
1410
-
1411
-			if ($this->config_imagemagick_path && ($this->config_imagemagick_path != $this->realPathSafe($this->config_imagemagick_path))) {
1412
-				if (@is_executable($this->realPathSafe($this->config_imagemagick_path))) {
1413
-					$this->DebugMessage('Changing $this->config_imagemagick_path ('.$this->config_imagemagick_path.') to $this->realPathSafe($this->config_imagemagick_path) ('.$this->realPathSafe($this->config_imagemagick_path).')', __FILE__, __LINE__);
1414
-					$this->config_imagemagick_path = $this->realPathSafe($this->config_imagemagick_path);
1415
-				} else {
1416
-					$this->DebugMessage('Leaving $this->config_imagemagick_path as ('.$this->config_imagemagick_path.') because !is_execuatable($this->realPathSafe($this->config_imagemagick_path)) ('.$this->realPathSafe($this->config_imagemagick_path).')', __FILE__, __LINE__);
1417
-				}
1418
-			}
1419
-			$this->DebugMessage('                  file_exists('.$this->config_imagemagick_path.') = '. (int) (@file_exists($this->config_imagemagick_path)), __FILE__, __LINE__);
1420
-			$this->DebugMessage('file_exists_ignoreopenbasedir('.$this->config_imagemagick_path.') = '. (int) $this->file_exists_ignoreopenbasedir($this->config_imagemagick_path), __FILE__, __LINE__);
1421
-			$this->DebugMessage('                      is_file('.$this->config_imagemagick_path.') = '. (int) (@is_file($this->config_imagemagick_path)), __FILE__, __LINE__);
1422
-			$this->DebugMessage('                is_executable('.$this->config_imagemagick_path.') = '. (int) (@is_executable($this->config_imagemagick_path)), __FILE__, __LINE__);
1423
-
1424
-			if ($this->file_exists_ignoreopenbasedir($this->config_imagemagick_path)) {
1425
-
1426
-				$this->DebugMessage('using ImageMagick path from $this->config_imagemagick_path ('.$this->config_imagemagick_path.')', __FILE__, __LINE__);
1427
-				if ($this->iswindows) {
1428
-					$commandline = substr($this->config_imagemagick_path, 0, 2).' && cd '.phpthumb_functions::escapeshellarg_replacement(str_replace('/', DIRECTORY_SEPARATOR, substr(dirname($this->config_imagemagick_path), 2))).' && '.phpthumb_functions::escapeshellarg_replacement(basename($this->config_imagemagick_path));
1429
-				} else {
1430
-					$commandline = phpthumb_functions::escapeshellarg_replacement($this->config_imagemagick_path);
1431
-				}
1432
-
1433
-			} else {
1434
-
1435
-				$which_convert = $this->ImageMagickWhichConvert();
1436
-				$IMversion     = $this->ImageMagickVersion();
1437
-
1438
-				if ($which_convert && ($which_convert{0} == '/') && $this->file_exists_ignoreopenbasedir($which_convert)) {
1439
-
1440
-					// `which convert` *should* return the path if "convert" exist, or nothing if it doesn't
1441
-					// other things *may* get returned, like "sh: convert: not found" or "no convert in /usr/local/bin /usr/sbin /usr/bin /usr/ccs/bin"
1442
-					// so only do this if the value returned exists as a file
1443
-					$this->DebugMessage('using ImageMagick path from `which convert` ('.$which_convert.')', __FILE__, __LINE__);
1444
-					$commandline = 'convert';
1445
-
1446
-				} elseif ($IMversion) {
1447
-
1448
-					$this->DebugMessage('setting ImageMagick path to $this->config_imagemagick_path ('.$this->config_imagemagick_path.') ['.$IMversion.']', __FILE__, __LINE__);
1449
-					$commandline = $this->config_imagemagick_path;
1450
-
1451
-				} else {
1452
-
1453
-					$this->DebugMessage('ImageMagickThumbnailToGD() aborting because cannot find convert in $this->config_imagemagick_path ('.$this->config_imagemagick_path.'), and `which convert` returned ('.$which_convert.')', __FILE__, __LINE__);
1454
-					$commandline = '';
1455
-
1456
-				}
1457
-
1458
-			}
1459
-
1460
-			@file_put_contents($IMcommandlineBaseCacheFilename, $commandline);
1461
-			@chmod($IMcommandlineBaseCacheFilename, $this->getParameter('config_file_create_mask'));
1462
-		}
1463
-		return $commandline;
1464
-	}
1465
-
1466
-
1467
-	public function ImageMagickVersion($returnRAW=false) {
1468
-		static $versionstring = null;
1469
-		if (null === $versionstring) {
1470
-			$versionstring = array(0=>false, 1=>false);
1471
-
1472
-			$IMversionCacheFilename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheIMversion.txt';
1473
-			if ($cachedversionstring = @file_get_contents($IMversionCacheFilename)) {
1474
-
1475
-				$versionstring = explode("\n", $cachedversionstring, 2);
1476
-				$versionstring[0] = ($versionstring[0] ? $versionstring[0] : false); // "false" is stored as an empty string in the cache file
1477
-				$versionstring[1] = ($versionstring[1] ? $versionstring[1] : false); // "false" is stored as an empty string in the cache file
1478
-
1479
-			} else {
1480
-
1481
-				$commandline = $this->ImageMagickCommandlineBase();
1482
-				$commandline = (null !== $commandline ? $commandline : '');
1483
-				if ($commandline) {
1484
-					$commandline .= ' --version';
1485
-					$this->DebugMessage('ImageMagick version checked with "'.$commandline.'"', __FILE__, __LINE__);
1486
-					$versionstring[1] = trim(phpthumb_functions::SafeExec($commandline));
1487
-					if (preg_match('#^Version: [^0-9]*([ 0-9\\.\\:Q/\\-]+)#i', $versionstring[1], $matches)) {
1488
-						$versionstring[0] = trim($matches[1]);
1489
-					} else {
1490
-						$versionstring[0] = false;
1491
-						$this->DebugMessage('ImageMagick did not return recognized version string ('.$versionstring[1].')', __FILE__, __LINE__);
1492
-					}
1493
-					$this->DebugMessage('ImageMagick convert --version says "'.@$matches[0].'"', __FILE__, __LINE__);
1494
-				}
1495
-
1496
-				@file_put_contents($IMversionCacheFilename, $versionstring[0]."\n".$versionstring[1]);
1497
-				@chmod($IMversionCacheFilename, $this->getParameter('config_file_create_mask'));
1498
-
1499
-			}
1500
-		}
1501
-		return $versionstring[ (int) $returnRAW ];
1502
-	}
1503
-
1504
-
1505
-	public function ImageMagickSwitchAvailable($switchname) {
1506
-		static $IMoptions = null;
1507
-		if (null === $IMoptions) {
1508
-			$IMoptions = array();
1509
-			$commandline = $this->ImageMagickCommandlineBase();
1510
-			if (null !== $commandline) {
1511
-				$commandline .= ' -help';
1512
-				$IMhelp_lines = explode("\n", phpthumb_functions::SafeExec($commandline));
1513
-				foreach ($IMhelp_lines as $line) {
1514
-					if (preg_match('#^[\\+\\-]([a-z\\-]+) #', trim($line), $matches)) {
1515
-						$IMoptions[$matches[1]] = true;
1516
-					}
1517
-				}
1518
-			}
1519
-		}
1520
-		if (is_array($switchname)) {
1521
-			$allOK = true;
1522
-			foreach ($switchname as $key => $value) {
1523
-				if (!isset($IMoptions[$value])) {
1524
-					$allOK = false;
1525
-					break;
1526
-				}
1527
-			}
1528
-			$this->DebugMessage('ImageMagickSwitchAvailable('.implode(';', $switchname).') = '. (int) $allOK .'', __FILE__, __LINE__);
1529
-		} else {
1530
-			$allOK = isset($IMoptions[$switchname]);
1531
-			$this->DebugMessage('ImageMagickSwitchAvailable('.$switchname.') = '. (int) $allOK .'', __FILE__, __LINE__);
1532
-		}
1533
-		return $allOK;
1534
-	}
1535
-
1536
-
1537
-	public function ImageMagickFormatsList() {
1538
-		static $IMformatsList = null;
1539
-		if (null === $IMformatsList) {
1540
-			$IMformatsList = '';
1541
-			$commandline = $this->ImageMagickCommandlineBase();
1542
-			if (null !== $commandline) {
1543
-				$commandline = dirname($commandline).DIRECTORY_SEPARATOR.str_replace('convert', 'identify', basename($commandline));
1544
-				$commandline .= ' -list format';
1545
-				$IMformatsList = phpthumb_functions::SafeExec($commandline);
1546
-			}
1547
-		}
1548
-		return $IMformatsList;
1549
-	}
1550
-
1551
-
1552
-	public function SourceDataToTempFile() {
1553
-		if ($IMtempSourceFilename = $this->phpThumb_tempnam()) {
1554
-			$IMtempSourceFilename = $this->realPathSafe($IMtempSourceFilename);
1555
-			ob_start();
1556
-			$fp_tempfile = fopen($IMtempSourceFilename, 'wb');
1557
-			$tempfile_open_error  = ob_get_contents();
1558
-			ob_end_clean();
1559
-			if ($fp_tempfile) {
1560
-				fwrite($fp_tempfile, $this->rawImageData);
1561
-				fclose($fp_tempfile);
1562
-				@chmod($IMtempSourceFilename, $this->getParameter('config_file_create_mask'));
1563
-				$this->sourceFilename = $IMtempSourceFilename;
1564
-				$this->DebugMessage('ImageMagickThumbnailToGD() setting $this->sourceFilename to "'.$IMtempSourceFilename.'" from $this->rawImageData ('.strlen($this->rawImageData).' bytes)', __FILE__, __LINE__);
1565
-			} else {
1566
-				$this->DebugMessage('ImageMagickThumbnailToGD() FAILED setting $this->sourceFilename to "'.$IMtempSourceFilename.'" (failed to open for writing: "'.$tempfile_open_error.'")', __FILE__, __LINE__);
1567
-			}
1568
-			unset($tempfile_open_error, $IMtempSourceFilename);
1569
-			return true;
1570
-		}
1571
-		$this->DebugMessage('SourceDataToTempFile() FAILED because $this->phpThumb_tempnam() failed', __FILE__, __LINE__);
1572
-		return false;
1573
-	}
1574
-
1575
-
1576
-	public function ImageMagickThumbnailToGD() {
1577
-		// http://www.imagemagick.org/script/command-line-options.php
1578
-
1579
-		$this->useRawIMoutput = true;
1580
-		if (phpthumb_functions::gd_version()) {
1581
-			// if GD is not available, must use whatever ImageMagick can output
1582
-
1583
-			// $UnAllowedParameters contains options that can only be processed in GD, not ImageMagick
1584
-			// note: 'fltr' *may* need to be processed by GD, but we'll check that in more detail below
1585
-			$UnAllowedParameters = array('xto', 'ar', 'bg', 'bc');
1586
-			// 'ra' may be part of this list, if not a multiple of 90 degrees
1587
-			foreach ($UnAllowedParameters as $parameter) {
1588
-				if (isset($this->$parameter)) {
1589
-					$this->DebugMessage('$this->useRawIMoutput=false because "'.$parameter.'" is set', __FILE__, __LINE__);
1590
-					$this->useRawIMoutput = false;
1591
-					break;
1592
-				}
1593
-			}
1594
-		}
1595
-		$this->DebugMessage('$this->useRawIMoutput='.($this->useRawIMoutput ? 'true' : 'false').' after checking $UnAllowedParameters', __FILE__, __LINE__);
1596
-		$ImageCreateFunction = '';
1597
-		$outputFormat = $this->thumbnailFormat;
1598
-		if (phpthumb_functions::gd_version()) {
1599
-			if ($this->useRawIMoutput) {
1600
-				switch ($this->thumbnailFormat) {
1601
-					case 'gif':
1602
-						$ImageCreateFunction = 'imagecreatefromgif';
1603
-						$this->is_alpha = true;
1604
-						break;
1605
-					case 'png':
1606
-						$ImageCreateFunction = 'imagecreatefrompng';
1607
-						$this->is_alpha = true;
1608
-						break;
1609
-					case 'jpg':
1610
-					case 'jpeg':
1611
-						$ImageCreateFunction = 'imagecreatefromjpeg';
1612
-						break;
1613
-					default:
1614
-						$this->DebugMessage('Forcing output to PNG because $this->thumbnailFormat ('.$this->thumbnailFormat.' is not a GD-supported format)', __FILE__, __LINE__);
1615
-						$outputFormat = 'png';
1616
-						$ImageCreateFunction = 'imagecreatefrompng';
1617
-						$this->is_alpha = true;
1618
-						$this->useRawIMoutput = false;
1619
-						break;
1620
-				}
1621
-				if (!function_exists(@$ImageCreateFunction)) {
1622
-					// ImageMagickThumbnailToGD() depends on imagecreatefrompng/imagecreatefromgif
1623
-					//$this->DebugMessage('ImageMagickThumbnailToGD() aborting because '.@$ImageCreateFunction.'() is not available', __FILE__, __LINE__);
1624
-					$this->useRawIMoutput = true;
1625
-					//return false;
1626
-				}
1627
-			} else {
1628
-				$outputFormat = 'png';
1629
-				$ImageCreateFunction = 'imagecreatefrompng';
1630
-				$this->is_alpha = true;
1631
-				$this->useRawIMoutput = false;
1632
-			}
1633
-		}
1634
-
1635
-		// http://freealter.org/doc_distrib/ImageMagick-5.1.1/www/convert.html
1636
-		if (!$this->sourceFilename && $this->rawImageData) {
1637
-			$this->SourceDataToTempFile();
1638
-		}
1639
-		if (!$this->sourceFilename) {
1640
-			$this->DebugMessage('ImageMagickThumbnailToGD() aborting because $this->sourceFilename is empty', __FILE__, __LINE__);
1641
-			$this->useRawIMoutput = false;
1642
-			return false;
1643
-		}
1644
-		if ($this->issafemode) {
1645
-			$this->DebugMessage('ImageMagickThumbnailToGD() aborting because safe_mode is enabled', __FILE__, __LINE__);
1646
-			$this->useRawIMoutput = false;
1647
-			return false;
1648
-		}
1338
+        if ($this->iswindows) {
1339
+            $AbsoluteFilename = preg_replace('#^'.preg_quote($this->realPathSafe($this->config_document_root)).'#i', str_replace('\\', '\\\\', $this->realPathSafe($this->config_document_root)), $AbsoluteFilename);
1340
+            $AbsoluteFilename = str_replace(DIRECTORY_SEPARATOR, '/', $AbsoluteFilename);
1341
+        }
1342
+        $resolvedAbsoluteFilename = $this->resolvePath($AbsoluteFilename, $this->config_additional_allowed_dirs);
1343
+        if (!$this->config_allow_src_above_docroot && !preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', $this->realPathSafe($this->config_document_root))).'#', $resolvedAbsoluteFilename)) {
1344
+            $this->DebugMessage('!$this->config_allow_src_above_docroot therefore setting "'.$AbsoluteFilename.'" (outside "'.$this->realPathSafe($this->config_document_root).'") to null', __FILE__, __LINE__);
1345
+            return false;
1346
+        }
1347
+        if (!$this->config_allow_src_above_phpthumb && !preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/',  __DIR__ )).'#', $resolvedAbsoluteFilename)) {
1348
+            $this->DebugMessage('!$this->config_allow_src_above_phpthumb therefore setting "'.$AbsoluteFilename.'" (outside "'. __DIR__ .'") to null', __FILE__, __LINE__);
1349
+            return false;
1350
+        }
1351
+        return $resolvedAbsoluteFilename;
1352
+    }
1353
+
1354
+
1355
+    public function file_exists_ignoreopenbasedir($filename, $cached=true) {
1356
+        static $open_basedirs = null;
1357
+        static $file_exists_cache = array();
1358
+        if (!$cached || !isset($file_exists_cache[$filename])) {
1359
+            if (null === $open_basedirs) {
1360
+                $open_basedirs = preg_split('#[;:]#', ini_get('open_basedir'));
1361
+            }
1362
+            if (empty($open_basedirs) || in_array(dirname($filename), $open_basedirs)) {
1363
+                $file_exists_cache[$filename] = file_exists($filename);
1364
+            } elseif ($this->iswindows) {
1365
+                $ls_filename = trim(phpthumb_functions::SafeExec('dir /b '.phpthumb_functions::escapeshellarg_replacement($filename)));
1366
+                $file_exists_cache[$filename] = ($ls_filename == basename($filename));  // command dir /b return only filename without path
1367
+            } else {
1368
+                $ls_filename = trim(phpthumb_functions::SafeExec('ls '.phpthumb_functions::escapeshellarg_replacement($filename)));
1369
+                $file_exists_cache[$filename] = ($ls_filename == $filename);
1370
+            }
1371
+        }
1372
+        return $file_exists_cache[$filename];
1373
+    }
1374
+
1375
+
1376
+    public function ImageMagickWhichConvert() {
1377
+        static $WhichConvert = null;
1378
+        if (null === $WhichConvert) {
1379
+            if ($this->iswindows) {
1380
+                $WhichConvert = false;
1381
+            } else {
1382
+                $IMwhichConvertCacheFilename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheIMwhichConvert.txt';
1383
+                if (($cachedwhichconvertstring = @file_get_contents($IMwhichConvertCacheFilename)) !== false) {
1384
+                    $WhichConvert = $cachedwhichconvertstring;
1385
+                } else {
1386
+                    $WhichConvert = trim(phpthumb_functions::SafeExec('which convert'));
1387
+                    @file_put_contents($IMwhichConvertCacheFilename, $WhichConvert);
1388
+                    @chmod($IMwhichConvertCacheFilename, $this->getParameter('config_file_create_mask'));
1389
+                }
1390
+            }
1391
+        }
1392
+        return $WhichConvert;
1393
+    }
1394
+
1395
+
1396
+    public function ImageMagickCommandlineBase() {
1397
+        static $commandline = null;
1398
+        if (null === $commandline) {
1399
+            if ($this->issafemode) {
1400
+                $commandline = '';
1401
+                return $commandline;
1402
+            }
1403
+
1404
+            $IMcommandlineBaseCacheFilename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheIMcommandlineBase.txt';
1405
+            if (($commandline = @file_get_contents($IMcommandlineBaseCacheFilename)) !== false) {
1406
+                return $commandline;
1407
+            }
1408
+
1409
+            $commandline = (null !== $this->config_imagemagick_path ? $this->config_imagemagick_path : '');
1410
+
1411
+            if ($this->config_imagemagick_path && ($this->config_imagemagick_path != $this->realPathSafe($this->config_imagemagick_path))) {
1412
+                if (@is_executable($this->realPathSafe($this->config_imagemagick_path))) {
1413
+                    $this->DebugMessage('Changing $this->config_imagemagick_path ('.$this->config_imagemagick_path.') to $this->realPathSafe($this->config_imagemagick_path) ('.$this->realPathSafe($this->config_imagemagick_path).')', __FILE__, __LINE__);
1414
+                    $this->config_imagemagick_path = $this->realPathSafe($this->config_imagemagick_path);
1415
+                } else {
1416
+                    $this->DebugMessage('Leaving $this->config_imagemagick_path as ('.$this->config_imagemagick_path.') because !is_execuatable($this->realPathSafe($this->config_imagemagick_path)) ('.$this->realPathSafe($this->config_imagemagick_path).')', __FILE__, __LINE__);
1417
+                }
1418
+            }
1419
+            $this->DebugMessage('                  file_exists('.$this->config_imagemagick_path.') = '. (int) (@file_exists($this->config_imagemagick_path)), __FILE__, __LINE__);
1420
+            $this->DebugMessage('file_exists_ignoreopenbasedir('.$this->config_imagemagick_path.') = '. (int) $this->file_exists_ignoreopenbasedir($this->config_imagemagick_path), __FILE__, __LINE__);
1421
+            $this->DebugMessage('                      is_file('.$this->config_imagemagick_path.') = '. (int) (@is_file($this->config_imagemagick_path)), __FILE__, __LINE__);
1422
+            $this->DebugMessage('                is_executable('.$this->config_imagemagick_path.') = '. (int) (@is_executable($this->config_imagemagick_path)), __FILE__, __LINE__);
1423
+
1424
+            if ($this->file_exists_ignoreopenbasedir($this->config_imagemagick_path)) {
1425
+
1426
+                $this->DebugMessage('using ImageMagick path from $this->config_imagemagick_path ('.$this->config_imagemagick_path.')', __FILE__, __LINE__);
1427
+                if ($this->iswindows) {
1428
+                    $commandline = substr($this->config_imagemagick_path, 0, 2).' && cd '.phpthumb_functions::escapeshellarg_replacement(str_replace('/', DIRECTORY_SEPARATOR, substr(dirname($this->config_imagemagick_path), 2))).' && '.phpthumb_functions::escapeshellarg_replacement(basename($this->config_imagemagick_path));
1429
+                } else {
1430
+                    $commandline = phpthumb_functions::escapeshellarg_replacement($this->config_imagemagick_path);
1431
+                }
1432
+
1433
+            } else {
1434
+
1435
+                $which_convert = $this->ImageMagickWhichConvert();
1436
+                $IMversion     = $this->ImageMagickVersion();
1437
+
1438
+                if ($which_convert && ($which_convert{0} == '/') && $this->file_exists_ignoreopenbasedir($which_convert)) {
1439
+
1440
+                    // `which convert` *should* return the path if "convert" exist, or nothing if it doesn't
1441
+                    // other things *may* get returned, like "sh: convert: not found" or "no convert in /usr/local/bin /usr/sbin /usr/bin /usr/ccs/bin"
1442
+                    // so only do this if the value returned exists as a file
1443
+                    $this->DebugMessage('using ImageMagick path from `which convert` ('.$which_convert.')', __FILE__, __LINE__);
1444
+                    $commandline = 'convert';
1445
+
1446
+                } elseif ($IMversion) {
1447
+
1448
+                    $this->DebugMessage('setting ImageMagick path to $this->config_imagemagick_path ('.$this->config_imagemagick_path.') ['.$IMversion.']', __FILE__, __LINE__);
1449
+                    $commandline = $this->config_imagemagick_path;
1450
+
1451
+                } else {
1452
+
1453
+                    $this->DebugMessage('ImageMagickThumbnailToGD() aborting because cannot find convert in $this->config_imagemagick_path ('.$this->config_imagemagick_path.'), and `which convert` returned ('.$which_convert.')', __FILE__, __LINE__);
1454
+                    $commandline = '';
1455
+
1456
+                }
1457
+
1458
+            }
1459
+
1460
+            @file_put_contents($IMcommandlineBaseCacheFilename, $commandline);
1461
+            @chmod($IMcommandlineBaseCacheFilename, $this->getParameter('config_file_create_mask'));
1462
+        }
1463
+        return $commandline;
1464
+    }
1465
+
1466
+
1467
+    public function ImageMagickVersion($returnRAW=false) {
1468
+        static $versionstring = null;
1469
+        if (null === $versionstring) {
1470
+            $versionstring = array(0=>false, 1=>false);
1471
+
1472
+            $IMversionCacheFilename = $this->config_cache_directory.DIRECTORY_SEPARATOR.'phpThumbCacheIMversion.txt';
1473
+            if ($cachedversionstring = @file_get_contents($IMversionCacheFilename)) {
1474
+
1475
+                $versionstring = explode("\n", $cachedversionstring, 2);
1476
+                $versionstring[0] = ($versionstring[0] ? $versionstring[0] : false); // "false" is stored as an empty string in the cache file
1477
+                $versionstring[1] = ($versionstring[1] ? $versionstring[1] : false); // "false" is stored as an empty string in the cache file
1478
+
1479
+            } else {
1480
+
1481
+                $commandline = $this->ImageMagickCommandlineBase();
1482
+                $commandline = (null !== $commandline ? $commandline : '');
1483
+                if ($commandline) {
1484
+                    $commandline .= ' --version';
1485
+                    $this->DebugMessage('ImageMagick version checked with "'.$commandline.'"', __FILE__, __LINE__);
1486
+                    $versionstring[1] = trim(phpthumb_functions::SafeExec($commandline));
1487
+                    if (preg_match('#^Version: [^0-9]*([ 0-9\\.\\:Q/\\-]+)#i', $versionstring[1], $matches)) {
1488
+                        $versionstring[0] = trim($matches[1]);
1489
+                    } else {
1490
+                        $versionstring[0] = false;
1491
+                        $this->DebugMessage('ImageMagick did not return recognized version string ('.$versionstring[1].')', __FILE__, __LINE__);
1492
+                    }
1493
+                    $this->DebugMessage('ImageMagick convert --version says "'.@$matches[0].'"', __FILE__, __LINE__);
1494
+                }
1495
+
1496
+                @file_put_contents($IMversionCacheFilename, $versionstring[0]."\n".$versionstring[1]);
1497
+                @chmod($IMversionCacheFilename, $this->getParameter('config_file_create_mask'));
1498
+
1499
+            }
1500
+        }
1501
+        return $versionstring[ (int) $returnRAW ];
1502
+    }
1503
+
1504
+
1505
+    public function ImageMagickSwitchAvailable($switchname) {
1506
+        static $IMoptions = null;
1507
+        if (null === $IMoptions) {
1508
+            $IMoptions = array();
1509
+            $commandline = $this->ImageMagickCommandlineBase();
1510
+            if (null !== $commandline) {
1511
+                $commandline .= ' -help';
1512
+                $IMhelp_lines = explode("\n", phpthumb_functions::SafeExec($commandline));
1513
+                foreach ($IMhelp_lines as $line) {
1514
+                    if (preg_match('#^[\\+\\-]([a-z\\-]+) #', trim($line), $matches)) {
1515
+                        $IMoptions[$matches[1]] = true;
1516
+                    }
1517
+                }
1518
+            }
1519
+        }
1520
+        if (is_array($switchname)) {
1521
+            $allOK = true;
1522
+            foreach ($switchname as $key => $value) {
1523
+                if (!isset($IMoptions[$value])) {
1524
+                    $allOK = false;
1525
+                    break;
1526
+                }
1527
+            }
1528
+            $this->DebugMessage('ImageMagickSwitchAvailable('.implode(';', $switchname).') = '. (int) $allOK .'', __FILE__, __LINE__);
1529
+        } else {
1530
+            $allOK = isset($IMoptions[$switchname]);
1531
+            $this->DebugMessage('ImageMagickSwitchAvailable('.$switchname.') = '. (int) $allOK .'', __FILE__, __LINE__);
1532
+        }
1533
+        return $allOK;
1534
+    }
1535
+
1536
+
1537
+    public function ImageMagickFormatsList() {
1538
+        static $IMformatsList = null;
1539
+        if (null === $IMformatsList) {
1540
+            $IMformatsList = '';
1541
+            $commandline = $this->ImageMagickCommandlineBase();
1542
+            if (null !== $commandline) {
1543
+                $commandline = dirname($commandline).DIRECTORY_SEPARATOR.str_replace('convert', 'identify', basename($commandline));
1544
+                $commandline .= ' -list format';
1545
+                $IMformatsList = phpthumb_functions::SafeExec($commandline);
1546
+            }
1547
+        }
1548
+        return $IMformatsList;
1549
+    }
1550
+
1551
+
1552
+    public function SourceDataToTempFile() {
1553
+        if ($IMtempSourceFilename = $this->phpThumb_tempnam()) {
1554
+            $IMtempSourceFilename = $this->realPathSafe($IMtempSourceFilename);
1555
+            ob_start();
1556
+            $fp_tempfile = fopen($IMtempSourceFilename, 'wb');
1557
+            $tempfile_open_error  = ob_get_contents();
1558
+            ob_end_clean();
1559
+            if ($fp_tempfile) {
1560
+                fwrite($fp_tempfile, $this->rawImageData);
1561
+                fclose($fp_tempfile);
1562
+                @chmod($IMtempSourceFilename, $this->getParameter('config_file_create_mask'));
1563
+                $this->sourceFilename = $IMtempSourceFilename;
1564
+                $this->DebugMessage('ImageMagickThumbnailToGD() setting $this->sourceFilename to "'.$IMtempSourceFilename.'" from $this->rawImageData ('.strlen($this->rawImageData).' bytes)', __FILE__, __LINE__);
1565
+            } else {
1566
+                $this->DebugMessage('ImageMagickThumbnailToGD() FAILED setting $this->sourceFilename to "'.$IMtempSourceFilename.'" (failed to open for writing: "'.$tempfile_open_error.'")', __FILE__, __LINE__);
1567
+            }
1568
+            unset($tempfile_open_error, $IMtempSourceFilename);
1569
+            return true;
1570
+        }
1571
+        $this->DebugMessage('SourceDataToTempFile() FAILED because $this->phpThumb_tempnam() failed', __FILE__, __LINE__);
1572
+        return false;
1573
+    }
1574
+
1575
+
1576
+    public function ImageMagickThumbnailToGD() {
1577
+        // http://www.imagemagick.org/script/command-line-options.php
1578
+
1579
+        $this->useRawIMoutput = true;
1580
+        if (phpthumb_functions::gd_version()) {
1581
+            // if GD is not available, must use whatever ImageMagick can output
1582
+
1583
+            // $UnAllowedParameters contains options that can only be processed in GD, not ImageMagick
1584
+            // note: 'fltr' *may* need to be processed by GD, but we'll check that in more detail below
1585
+            $UnAllowedParameters = array('xto', 'ar', 'bg', 'bc');
1586
+            // 'ra' may be part of this list, if not a multiple of 90 degrees
1587
+            foreach ($UnAllowedParameters as $parameter) {
1588
+                if (isset($this->$parameter)) {
1589
+                    $this->DebugMessage('$this->useRawIMoutput=false because "'.$parameter.'" is set', __FILE__, __LINE__);
1590
+                    $this->useRawIMoutput = false;
1591
+                    break;
1592
+                }
1593
+            }
1594
+        }
1595
+        $this->DebugMessage('$this->useRawIMoutput='.($this->useRawIMoutput ? 'true' : 'false').' after checking $UnAllowedParameters', __FILE__, __LINE__);
1596
+        $ImageCreateFunction = '';
1597
+        $outputFormat = $this->thumbnailFormat;
1598
+        if (phpthumb_functions::gd_version()) {
1599
+            if ($this->useRawIMoutput) {
1600
+                switch ($this->thumbnailFormat) {
1601
+                    case 'gif':
1602
+                        $ImageCreateFunction = 'imagecreatefromgif';
1603
+                        $this->is_alpha = true;
1604
+                        break;
1605
+                    case 'png':
1606
+                        $ImageCreateFunction = 'imagecreatefrompng';
1607
+                        $this->is_alpha = true;
1608
+                        break;
1609
+                    case 'jpg':
1610
+                    case 'jpeg':
1611
+                        $ImageCreateFunction = 'imagecreatefromjpeg';
1612
+                        break;
1613
+                    default:
1614
+                        $this->DebugMessage('Forcing output to PNG because $this->thumbnailFormat ('.$this->thumbnailFormat.' is not a GD-supported format)', __FILE__, __LINE__);
1615
+                        $outputFormat = 'png';
1616
+                        $ImageCreateFunction = 'imagecreatefrompng';
1617
+                        $this->is_alpha = true;
1618
+                        $this->useRawIMoutput = false;
1619
+                        break;
1620
+                }
1621
+                if (!function_exists(@$ImageCreateFunction)) {
1622
+                    // ImageMagickThumbnailToGD() depends on imagecreatefrompng/imagecreatefromgif
1623
+                    //$this->DebugMessage('ImageMagickThumbnailToGD() aborting because '.@$ImageCreateFunction.'() is not available', __FILE__, __LINE__);
1624
+                    $this->useRawIMoutput = true;
1625
+                    //return false;
1626
+                }
1627
+            } else {
1628
+                $outputFormat = 'png';
1629
+                $ImageCreateFunction = 'imagecreatefrompng';
1630
+                $this->is_alpha = true;
1631
+                $this->useRawIMoutput = false;
1632
+            }
1633
+        }
1634
+
1635
+        // http://freealter.org/doc_distrib/ImageMagick-5.1.1/www/convert.html
1636
+        if (!$this->sourceFilename && $this->rawImageData) {
1637
+            $this->SourceDataToTempFile();
1638
+        }
1639
+        if (!$this->sourceFilename) {
1640
+            $this->DebugMessage('ImageMagickThumbnailToGD() aborting because $this->sourceFilename is empty', __FILE__, __LINE__);
1641
+            $this->useRawIMoutput = false;
1642
+            return false;
1643
+        }
1644
+        if ($this->issafemode) {
1645
+            $this->DebugMessage('ImageMagickThumbnailToGD() aborting because safe_mode is enabled', __FILE__, __LINE__);
1646
+            $this->useRawIMoutput = false;
1647
+            return false;
1648
+        }
1649 1649
 // TO BE FIXED
1650 1650
 //if (true) {
1651 1651
 //	$this->DebugMessage('ImageMagickThumbnailToGD() aborting it is broken right now', __FILE__, __LINE__);
@@ -1653,2741 +1653,2741 @@  discard block
 block discarded – undo
1653 1653
 //	return false;
1654 1654
 //}
1655 1655
 
1656
-		$commandline = $this->ImageMagickCommandlineBase();
1657
-		if ($commandline) {
1658
-			$commandline .= ' '.phpthumb_functions::escapeshellarg_replacement(preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $this->sourceFilename).(($outputFormat == 'gif') ? '' : '['. (int) $this->sfn .']')); // [0] means first frame of (GIF) animation, can be ignored
1659
-			if ($IMtempfilename = $this->phpThumb_tempnam()) {
1660
-				$IMtempfilename = $this->realPathSafe($IMtempfilename);
1661
-
1662
-				$IMuseExplicitImageOutputDimensions = false;
1663
-				if ($this->ImageMagickSwitchAvailable('thumbnail') && $this->config_imagemagick_use_thumbnail) {
1664
-					$IMresizeParameter = 'thumbnail';
1665
-				} else {
1666
-					$IMresizeParameter = 'resize';
1667
-
1668
-					// some (older? around 2002) versions of IM won't accept "-resize 100x" but require "-resize 100x100"
1669
-					$commandline_test = $this->ImageMagickCommandlineBase().' logo: -resize 1x '.phpthumb_functions::escapeshellarg_replacement($IMtempfilename).' 2>&1';
1670
-					$IMresult_test = phpthumb_functions::SafeExec($commandline_test);
1671
-					$IMuseExplicitImageOutputDimensions = preg_match('#image dimensions are zero#i', $IMresult_test);
1672
-					$this->DebugMessage('IMuseExplicitImageOutputDimensions = '. (int) $IMuseExplicitImageOutputDimensions, __FILE__, __LINE__);
1673
-					if ($fp_im_temp = @fopen($IMtempfilename, 'wb')) {
1674
-						// erase temp image so ImageMagick logo doesn't get output if other processing fails
1675
-						fclose($fp_im_temp);
1676
-						@chmod($IMtempfilename, $this->getParameter('config_file_create_mask'));
1677
-					}
1678
-				}
1679
-
1680
-
1681
-				ob_start();
1682
-				$getimagesize = getimagesize($this->sourceFilename);
1683
-				$GetImageSizeError = ob_get_contents();
1684
-				ob_end_clean();
1685
-				if (is_array($getimagesize)) {
1686
-					$this->DebugMessage('getimagesize('.$this->sourceFilename.') SUCCEEDED: '.print_r($getimagesize, true), __FILE__, __LINE__);
1687
-				} else {
1688
-					$this->DebugMessage('getimagesize('.$this->sourceFilename.') FAILED with error "'.$GetImageSizeError.'"', __FILE__, __LINE__);
1689
-				}
1690
-				if (null !== $this->dpi && $this->ImageMagickSwitchAvailable('density')) {
1691
-					// for vector source formats only (WMF, PDF, etc)
1692
-					if (is_array($getimagesize) && isset($getimagesize[2]) && ($getimagesize[2] == IMAGETYPE_PNG)) {
1693
-						// explicitly exclude PNG from "-flatten" to make sure transparency is preserved
1694
-						// https://github.com/JamesHeinrich/phpThumb/issues/65
1695
-					} else {
1696
-						$commandline .= ' -flatten';
1697
-						$commandline .= ' -density '.phpthumb_functions::escapeshellarg_replacement($this->dpi);
1698
-					}
1699
-				}
1700
-				if (is_array($getimagesize)) {
1701
-					$this->DebugMessage('getimagesize('.$this->sourceFilename.') returned [w='.$getimagesize[0].';h='.$getimagesize[1].';f='.$getimagesize[2].']', __FILE__, __LINE__);
1702
-					$this->source_width  = $getimagesize[0];
1703
-					$this->source_height = $getimagesize[1];
1704
-					$this->DebugMessage('source dimensions set to '.$this->source_width.'x'.$this->source_height, __FILE__, __LINE__);
1705
-					$this->SetOrientationDependantWidthHeight();
1706
-
1707
-					if (!preg_match('#('.implode('|', $this->AlphaCapableFormats).')#i', $outputFormat)) {
1708
-						// not a transparency-capable format
1709
-						$commandline .= ' -background '.phpthumb_functions::escapeshellarg_replacement('#'.($this->bg ? $this->bg : 'FFFFFF'));
1710
-						if ($getimagesize[2] == IMAGETYPE_GIF) {
1711
-							$commandline .= ' -flatten';
1712
-						}
1713
-					} else {
1714
-						if ($getimagesize[2] == IMAGETYPE_PNG && !$this->bg) {
1715
-							$commandline .= ' -background none';
1716
-						}
1717
-					}
1718
-					if ($getimagesize[2] == IMAGETYPE_GIF) {
1719
-						$commandline .= ' -coalesce'; // may be needed for animated GIFs
1720
-					}
1721
-					if ($this->source_width || $this->source_height) {
1722
-						if ($this->zc) {
1723
-
1724
-							$borderThickness = 0;
1725
-							if (!empty($this->fltr)) {
1726
-								foreach ($this->fltr as $key => $value) {
1727
-									if (preg_match('#^bord\|([0-9]+)#', $value, $matches)) {
1728
-										$borderThickness = $matches[1];
1729
-										break;
1730
-									}
1731
-								}
1732
-							}
1733
-							$wAll = (int) max($this->w, $this->wp, $this->wl, $this->ws) - (2 * $borderThickness);
1734
-							$hAll = (int) max($this->h, $this->hp, $this->hl, $this->hs) - (2 * $borderThickness);
1735
-							$imAR = $this->source_width / $this->source_height;
1736
-							$zcAR = (($wAll && $hAll) ? $wAll / $hAll : 1);
1737
-							$side  = phpthumb_functions::nonempty_min($this->source_width, $this->source_height, max($wAll, $hAll));
1738
-							$sideX = phpthumb_functions::nonempty_min($this->source_width,                       $wAll, round($hAll * $zcAR));
1739
-							$sideY = phpthumb_functions::nonempty_min(                     $this->source_height, $hAll, round($wAll / $zcAR));
1740
-
1741
-							$thumbnailH = round(max($sideY, ($sideY * $zcAR) / $imAR));
1742
-							if ($this->aoe == 1) {
1743
-								$commandline .= ' -'.$IMresizeParameter.' "'.$wAll.'x'.$hAll.'^"';
1744
-							} else {
1745
-								$commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(($IMuseExplicitImageOutputDimensions ? $thumbnailH : '').'x'.$thumbnailH);
1746
-							}
1747
-
1748
-							switch (strtoupper($this->zc)) {
1749
-								case 'T':
1750
-									$commandline .= ' -gravity north';
1751
-									break;
1752
-								case 'B':
1753
-									$commandline .= ' -gravity south';
1754
-									break;
1755
-								case 'L':
1756
-									$commandline .= ' -gravity west';
1757
-									break;
1758
-								case 'R':
1759
-									$commandline .= ' -gravity east';
1760
-									break;
1761
-								case 'TL':
1762
-									$commandline .= ' -gravity northwest';
1763
-									break;
1764
-								case 'TR':
1765
-									$commandline .= ' -gravity northeast';
1766
-									break;
1767
-								case 'BL':
1768
-									$commandline .= ' -gravity southwest';
1769
-									break;
1770
-								case 'BR':
1771
-									$commandline .= ' -gravity southeast';
1772
-									break;
1773
-								case '1':
1774
-								case 'C':
1775
-								default:
1776
-									$commandline .= ' -gravity center';
1777
-									break;
1778
-							}
1779
-
1780
-							if (($wAll > 0) && ($hAll > 0)) {
1781
-								$commandline .= ' -crop '.phpthumb_functions::escapeshellarg_replacement($wAll.'x'.$hAll.'+0+0');
1782
-							} else {
1783
-								$commandline .= ' -crop '.phpthumb_functions::escapeshellarg_replacement($side.'x'.$side.'+0+0');
1784
-							}
1785
-							if ($this->ImageMagickSwitchAvailable('repage')) {
1786
-								$commandline .= ' +repage';
1787
-							} else {
1788
-								$this->DebugMessage('Skipping "+repage" because ImageMagick (v'.$this->ImageMagickVersion().') does not support it', __FILE__, __LINE__);
1789
-							}
1790
-
1791
-						} elseif ($this->sw || $this->sh || $this->sx || $this->sy) {
1792
-
1793
-							$crop_param   = '';
1794
-							$crop_param  .=     ($this->sw ? (($this->sw < 2) ? round($this->sw * $this->source_width)  : $this->sw) : $this->source_width);
1795
-							$crop_param  .= 'x'.($this->sh ? (($this->sh < 2) ? round($this->sh * $this->source_height) : $this->sh) : $this->source_height);
1796
-							$crop_param  .= '+'.(($this->sx < 2) ? round($this->sx * $this->source_width)  : $this->sx);
1797
-							$crop_param  .= '+'.(($this->sy < 2) ? round($this->sy * $this->source_height) : $this->sy);
1656
+        $commandline = $this->ImageMagickCommandlineBase();
1657
+        if ($commandline) {
1658
+            $commandline .= ' '.phpthumb_functions::escapeshellarg_replacement(preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $this->sourceFilename).(($outputFormat == 'gif') ? '' : '['. (int) $this->sfn .']')); // [0] means first frame of (GIF) animation, can be ignored
1659
+            if ($IMtempfilename = $this->phpThumb_tempnam()) {
1660
+                $IMtempfilename = $this->realPathSafe($IMtempfilename);
1661
+
1662
+                $IMuseExplicitImageOutputDimensions = false;
1663
+                if ($this->ImageMagickSwitchAvailable('thumbnail') && $this->config_imagemagick_use_thumbnail) {
1664
+                    $IMresizeParameter = 'thumbnail';
1665
+                } else {
1666
+                    $IMresizeParameter = 'resize';
1667
+
1668
+                    // some (older? around 2002) versions of IM won't accept "-resize 100x" but require "-resize 100x100"
1669
+                    $commandline_test = $this->ImageMagickCommandlineBase().' logo: -resize 1x '.phpthumb_functions::escapeshellarg_replacement($IMtempfilename).' 2>&1';
1670
+                    $IMresult_test = phpthumb_functions::SafeExec($commandline_test);
1671
+                    $IMuseExplicitImageOutputDimensions = preg_match('#image dimensions are zero#i', $IMresult_test);
1672
+                    $this->DebugMessage('IMuseExplicitImageOutputDimensions = '. (int) $IMuseExplicitImageOutputDimensions, __FILE__, __LINE__);
1673
+                    if ($fp_im_temp = @fopen($IMtempfilename, 'wb')) {
1674
+                        // erase temp image so ImageMagick logo doesn't get output if other processing fails
1675
+                        fclose($fp_im_temp);
1676
+                        @chmod($IMtempfilename, $this->getParameter('config_file_create_mask'));
1677
+                    }
1678
+                }
1679
+
1680
+
1681
+                ob_start();
1682
+                $getimagesize = getimagesize($this->sourceFilename);
1683
+                $GetImageSizeError = ob_get_contents();
1684
+                ob_end_clean();
1685
+                if (is_array($getimagesize)) {
1686
+                    $this->DebugMessage('getimagesize('.$this->sourceFilename.') SUCCEEDED: '.print_r($getimagesize, true), __FILE__, __LINE__);
1687
+                } else {
1688
+                    $this->DebugMessage('getimagesize('.$this->sourceFilename.') FAILED with error "'.$GetImageSizeError.'"', __FILE__, __LINE__);
1689
+                }
1690
+                if (null !== $this->dpi && $this->ImageMagickSwitchAvailable('density')) {
1691
+                    // for vector source formats only (WMF, PDF, etc)
1692
+                    if (is_array($getimagesize) && isset($getimagesize[2]) && ($getimagesize[2] == IMAGETYPE_PNG)) {
1693
+                        // explicitly exclude PNG from "-flatten" to make sure transparency is preserved
1694
+                        // https://github.com/JamesHeinrich/phpThumb/issues/65
1695
+                    } else {
1696
+                        $commandline .= ' -flatten';
1697
+                        $commandline .= ' -density '.phpthumb_functions::escapeshellarg_replacement($this->dpi);
1698
+                    }
1699
+                }
1700
+                if (is_array($getimagesize)) {
1701
+                    $this->DebugMessage('getimagesize('.$this->sourceFilename.') returned [w='.$getimagesize[0].';h='.$getimagesize[1].';f='.$getimagesize[2].']', __FILE__, __LINE__);
1702
+                    $this->source_width  = $getimagesize[0];
1703
+                    $this->source_height = $getimagesize[1];
1704
+                    $this->DebugMessage('source dimensions set to '.$this->source_width.'x'.$this->source_height, __FILE__, __LINE__);
1705
+                    $this->SetOrientationDependantWidthHeight();
1706
+
1707
+                    if (!preg_match('#('.implode('|', $this->AlphaCapableFormats).')#i', $outputFormat)) {
1708
+                        // not a transparency-capable format
1709
+                        $commandline .= ' -background '.phpthumb_functions::escapeshellarg_replacement('#'.($this->bg ? $this->bg : 'FFFFFF'));
1710
+                        if ($getimagesize[2] == IMAGETYPE_GIF) {
1711
+                            $commandline .= ' -flatten';
1712
+                        }
1713
+                    } else {
1714
+                        if ($getimagesize[2] == IMAGETYPE_PNG && !$this->bg) {
1715
+                            $commandline .= ' -background none';
1716
+                        }
1717
+                    }
1718
+                    if ($getimagesize[2] == IMAGETYPE_GIF) {
1719
+                        $commandline .= ' -coalesce'; // may be needed for animated GIFs
1720
+                    }
1721
+                    if ($this->source_width || $this->source_height) {
1722
+                        if ($this->zc) {
1723
+
1724
+                            $borderThickness = 0;
1725
+                            if (!empty($this->fltr)) {
1726
+                                foreach ($this->fltr as $key => $value) {
1727
+                                    if (preg_match('#^bord\|([0-9]+)#', $value, $matches)) {
1728
+                                        $borderThickness = $matches[1];
1729
+                                        break;
1730
+                                    }
1731
+                                }
1732
+                            }
1733
+                            $wAll = (int) max($this->w, $this->wp, $this->wl, $this->ws) - (2 * $borderThickness);
1734
+                            $hAll = (int) max($this->h, $this->hp, $this->hl, $this->hs) - (2 * $borderThickness);
1735
+                            $imAR = $this->source_width / $this->source_height;
1736
+                            $zcAR = (($wAll && $hAll) ? $wAll / $hAll : 1);
1737
+                            $side  = phpthumb_functions::nonempty_min($this->source_width, $this->source_height, max($wAll, $hAll));
1738
+                            $sideX = phpthumb_functions::nonempty_min($this->source_width,                       $wAll, round($hAll * $zcAR));
1739
+                            $sideY = phpthumb_functions::nonempty_min(                     $this->source_height, $hAll, round($wAll / $zcAR));
1740
+
1741
+                            $thumbnailH = round(max($sideY, ($sideY * $zcAR) / $imAR));
1742
+                            if ($this->aoe == 1) {
1743
+                                $commandline .= ' -'.$IMresizeParameter.' "'.$wAll.'x'.$hAll.'^"';
1744
+                            } else {
1745
+                                $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(($IMuseExplicitImageOutputDimensions ? $thumbnailH : '').'x'.$thumbnailH);
1746
+                            }
1747
+
1748
+                            switch (strtoupper($this->zc)) {
1749
+                                case 'T':
1750
+                                    $commandline .= ' -gravity north';
1751
+                                    break;
1752
+                                case 'B':
1753
+                                    $commandline .= ' -gravity south';
1754
+                                    break;
1755
+                                case 'L':
1756
+                                    $commandline .= ' -gravity west';
1757
+                                    break;
1758
+                                case 'R':
1759
+                                    $commandline .= ' -gravity east';
1760
+                                    break;
1761
+                                case 'TL':
1762
+                                    $commandline .= ' -gravity northwest';
1763
+                                    break;
1764
+                                case 'TR':
1765
+                                    $commandline .= ' -gravity northeast';
1766
+                                    break;
1767
+                                case 'BL':
1768
+                                    $commandline .= ' -gravity southwest';
1769
+                                    break;
1770
+                                case 'BR':
1771
+                                    $commandline .= ' -gravity southeast';
1772
+                                    break;
1773
+                                case '1':
1774
+                                case 'C':
1775
+                                default:
1776
+                                    $commandline .= ' -gravity center';
1777
+                                    break;
1778
+                            }
1779
+
1780
+                            if (($wAll > 0) && ($hAll > 0)) {
1781
+                                $commandline .= ' -crop '.phpthumb_functions::escapeshellarg_replacement($wAll.'x'.$hAll.'+0+0');
1782
+                            } else {
1783
+                                $commandline .= ' -crop '.phpthumb_functions::escapeshellarg_replacement($side.'x'.$side.'+0+0');
1784
+                            }
1785
+                            if ($this->ImageMagickSwitchAvailable('repage')) {
1786
+                                $commandline .= ' +repage';
1787
+                            } else {
1788
+                                $this->DebugMessage('Skipping "+repage" because ImageMagick (v'.$this->ImageMagickVersion().') does not support it', __FILE__, __LINE__);
1789
+                            }
1790
+
1791
+                        } elseif ($this->sw || $this->sh || $this->sx || $this->sy) {
1792
+
1793
+                            $crop_param   = '';
1794
+                            $crop_param  .=     ($this->sw ? (($this->sw < 2) ? round($this->sw * $this->source_width)  : $this->sw) : $this->source_width);
1795
+                            $crop_param  .= 'x'.($this->sh ? (($this->sh < 2) ? round($this->sh * $this->source_height) : $this->sh) : $this->source_height);
1796
+                            $crop_param  .= '+'.(($this->sx < 2) ? round($this->sx * $this->source_width)  : $this->sx);
1797
+                            $crop_param  .= '+'.(($this->sy < 2) ? round($this->sy * $this->source_height) : $this->sy);
1798 1798
 // TO BE FIXED
1799 1799
 // makes 1x1 output
1800 1800
 // http://trainspotted.com/phpThumb/phpThumb.php?src=/content/CNR/47/CNR-4728-LD-L-20110723-898.jpg&w=100&h=100&far=1&f=png&fltr[]=lvl&sx=0.05&sy=0.25&sw=0.92&sh=0.42
1801 1801
 // '/usr/bin/convert' -density 150 -thumbnail 100x100 -contrast-stretch '0.1%' '/var/www/vhosts/trainspotted.com/httpdocs/content/CNR/47/CNR-4728-LD-L-20110723-898.jpg[0]' png:'/var/www/vhosts/trainspotted.com/httpdocs/phpThumb/_cache/pThumbIIUlvj'
1802
-							$commandline .= ' -crop '.phpthumb_functions::escapeshellarg_replacement($crop_param);
1802
+                            $commandline .= ' -crop '.phpthumb_functions::escapeshellarg_replacement($crop_param);
1803 1803
 
1804
-							// this is broken for aoe=1, but unsure how to fix. Send advice to [email protected]
1805
-							if ($this->w || $this->h) {
1806
-								//if ($this->ImageMagickSwitchAvailable('repage')) {
1804
+                            // this is broken for aoe=1, but unsure how to fix. Send advice to [email protected]
1805
+                            if ($this->w || $this->h) {
1806
+                                //if ($this->ImageMagickSwitchAvailable('repage')) {
1807 1807
 if (false) {
1808 1808
 // TO BE FIXED
1809 1809
 // newer versions of ImageMagick require -repage <geometry>
1810
-									$commandline .= ' -repage';
1811
-								} else {
1812
-									$this->DebugMessage('Skipping "-repage" because ImageMagick (v'.$this->ImageMagickVersion().') does not support it', __FILE__, __LINE__);
1813
-								}
1814
-								if ($IMuseExplicitImageOutputDimensions) {
1815
-									if ($this->w && !$this->h) {
1816
-										$this->h = ceil($this->w / ($this->source_width / $this->source_height));
1817
-									} elseif ($this->h && !$this->w) {
1818
-										$this->w = ceil($this->h * ($this->source_width / $this->source_height));
1819
-									}
1820
-								}
1821
-								$commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($this->w.'x'.$this->h);
1822
-							}
1823
-
1824
-						} else {
1825
-
1826
-							if ($this->iar && ((int) $this->w > 0) && ((int) $this->h > 0)) {
1827
-
1828
-								list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra);
1829
-								$nw = ((round($nw) != 0) ? round($nw) : '');
1830
-								$nh = ((round($nh) != 0) ? round($nh) : '');
1831
-								$commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($nw.'x'.$nh.'!');
1832
-
1833
-							} elseif ($this->far && ((int) $this->w > 0) && ((int) $this->h > 0)) {
1834
-
1835
-								$commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(phpthumb_functions::nonempty_min($this->w, $getimagesize[0]).'x'.phpthumb_functions::nonempty_min($this->h, $getimagesize[1]));
1836
-								$commandline .= ' -gravity center';
1837
-								$commandline .= ' -background '.phpthumb_functions::escapeshellarg_replacement('#'.$this->bg);
1838
-								$commandline .= ' -extent '.phpthumb_functions::escapeshellarg_replacement($this->w.'x'.$this->h);
1839
-
1840
-							} else {
1841
-
1842
-								$this->w = (($this->aoe && $this->w) ? $this->w : ($this->w ? phpthumb_functions::nonempty_min($this->w, $getimagesize[0]) : ''));
1843
-								$this->h = (($this->aoe && $this->h) ? $this->h : ($this->h ? phpthumb_functions::nonempty_min($this->h, $getimagesize[1]) : ''));
1844
-								if ($this->w || $this->h) {
1845
-									if ($IMuseExplicitImageOutputDimensions) {
1846
-										if ($this->w && !$this->h) {
1847
-											$this->h = ceil($this->w / ($this->source_width / $this->source_height));
1848
-										} elseif ($this->h && !$this->w) {
1849
-											$this->w = ceil($this->h * ($this->source_width / $this->source_height));
1850
-										}
1851
-									}
1852
-									list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra);
1853
-									$nw = ((round($nw) != 0) ? round($nw) : '');
1854
-									$nh = ((round($nh) != 0) ? round($nh) : '');
1855
-									$commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($nw.'x'.$nh);
1856
-								}
1857
-
1858
-							}
1859
-						}
1860
-					}
1861
-
1862
-				} else {
1863
-
1864
-					$this->DebugMessage('getimagesize('.$this->sourceFilename.') failed', __FILE__, __LINE__);
1865
-					if ($this->w || $this->h) {
1866
-						$exactDimensionsBang = (($this->iar && ((int) $this->w > 0) && ((int) $this->h > 0)) ? '!' : '');
1867
-						if ($IMuseExplicitImageOutputDimensions) {
1868
-							// unknown source aspect ratio, just put large number and hope IM figures it out
1869
-							$commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(($this->w ? $this->w : '9999').'x'.($this->h ? $this->h : '9999').$exactDimensionsBang);
1870
-						} else {
1871
-							$commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($this->w.'x'.$this->h.$exactDimensionsBang);
1872
-						}
1873
-					}
1874
-
1875
-				}
1876
-
1877
-				if ($this->ra) {
1878
-					$this->ra = (int) $this->ra;
1879
-					if ($this->ImageMagickSwitchAvailable('rotate')) {
1880
-						if (!preg_match('#('.implode('|', $this->AlphaCapableFormats).')#i', $outputFormat) || phpthumb_functions::version_compare_replacement($this->ImageMagickVersion(), '6.3.7', '>=')) {
1881
-							$this->DebugMessage('Using ImageMagick rotate', __FILE__, __LINE__);
1882
-							$commandline .= ' -rotate '.phpthumb_functions::escapeshellarg_replacement($this->ra);
1883
-							if (($this->ra % 90) != 0) {
1884
-								if (preg_match('#('.implode('|', $this->AlphaCapableFormats).')#i', $outputFormat)) {
1885
-									// alpha-capable format
1886
-									$commandline .= ' -background rgba(255,255,255,0)';
1887
-								} else {
1888
-									$commandline .= ' -background '.phpthumb_functions::escapeshellarg_replacement('#'.($this->bg ? $this->bg : 'FFFFFF'));
1889
-								}
1890
-							}
1891
-							$this->ra = 0;
1892
-						} else {
1893
-							$this->DebugMessage('Not using ImageMagick rotate because alpha background buggy before v6.3.7', __FILE__, __LINE__);
1894
-						}
1895
-					} else {
1896
-						$this->DebugMessage('Not using ImageMagick rotate because not supported', __FILE__, __LINE__);
1897
-					}
1898
-				}
1899
-
1900
-				$successfullyProcessedFilters = array();
1901
-				foreach ($this->fltr as $filterkey => $filtercommand) {
1902
-					@list($command, $parameter) = explode('|', $filtercommand, 2);
1903
-					switch ($command) {
1904
-						case 'brit':
1905
-							if ($this->ImageMagickSwitchAvailable('modulate')) {
1906
-								$commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement((100 + (int) $parameter).',100,100');
1907
-								$successfullyProcessedFilters[] = $filterkey;
1908
-							}
1909
-							break;
1910
-
1911
-						case 'cont':
1912
-							if ($this->ImageMagickSwitchAvailable('contrast')) {
1913
-								$contDiv10 = round((int) $parameter / 10);
1914
-								if ($contDiv10 > 0) {
1915
-									$contDiv10 = min($contDiv10, 100);
1916
-									for ($i = 0; $i < $contDiv10; $i++) {
1917
-										$commandline .= ' -contrast'; // increase contrast by 10%
1918
-									}
1919
-								} elseif ($contDiv10 < 0) {
1920
-									$contDiv10 = max($contDiv10, -100);
1921
-									for ($i = $contDiv10; $i < 0; $i++) {
1922
-										$commandline .= ' +contrast'; // decrease contrast by 10%
1923
-									}
1924
-								} else {
1925
-									// do nothing
1926
-								}
1927
-								$successfullyProcessedFilters[] = $filterkey;
1928
-							}
1929
-							break;
1930
-
1931
-						case 'ds':
1932
-							if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) {
1933
-								if ($parameter == 100) {
1934
-									$commandline .= ' -colorspace GRAY';
1935
-									$commandline .= ' -modulate 100,0,100';
1936
-								} else {
1937
-									$commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement('100,'.(100 - (int) $parameter).',100');
1938
-								}
1939
-								$successfullyProcessedFilters[] = $filterkey;
1940
-							}
1941
-							break;
1942
-
1943
-						case 'sat':
1944
-							if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) {
1945
-								if ($parameter == -100) {
1946
-									$commandline .= ' -colorspace GRAY';
1947
-									$commandline .= ' -modulate 100,0,100';
1948
-								} else {
1949
-									$commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement('100,'.(100 + (int) $parameter).',100');
1950
-								}
1951
-								$successfullyProcessedFilters[] = $filterkey;
1952
-							}
1953
-							break;
1954
-
1955
-						case 'gray':
1956
-							if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) {
1957
-								$commandline .= ' -colorspace GRAY';
1958
-								$commandline .= ' -modulate 100,0,100';
1959
-								$successfullyProcessedFilters[] = $filterkey;
1960
-							}
1961
-							break;
1962
-
1963
-						case 'clr':
1964
-							if ($this->ImageMagickSwitchAvailable(array('fill', 'colorize'))) {
1965
-								@list($amount, $color) = explode('|', $parameter);
1966
-								$commandline .= ' -fill '.phpthumb_functions::escapeshellarg_replacement('#'.preg_replace('#[^0-9A-F]#i', '', $color));
1967
-								$commandline .= ' -colorize '.phpthumb_functions::escapeshellarg_replacement(min(max((int) $amount, 0), 100));
1968
-							}
1969
-							break;
1970
-
1971
-						case 'sep':
1972
-							if ($this->ImageMagickSwitchAvailable('sepia-tone')) {
1973
-								@list($amount, $color) = explode('|', $parameter);
1974
-								$amount = ($amount ? $amount : 80);
1975
-								if (!$color) {
1976
-									$commandline .= ' -sepia-tone '.phpthumb_functions::escapeshellarg_replacement(min(max((int) $amount, 0), 100).'%');
1977
-									$successfullyProcessedFilters[] = $filterkey;
1978
-								}
1979
-							}
1980
-							break;
1981
-
1982
-						case 'gam':
1983
-							@list($amount) = explode('|', $parameter);
1984
-							$amount = min(max((float) $amount, 0.001), 10);
1985
-							if (number_format($amount, 3) != '1.000') {
1986
-								if ($this->ImageMagickSwitchAvailable('gamma')) {
1987
-									$commandline .= ' -gamma '.phpthumb_functions::escapeshellarg_replacement($amount);
1988
-									$successfullyProcessedFilters[] = $filterkey;
1989
-								}
1990
-							}
1991
-							break;
1992
-
1993
-						case 'neg':
1994
-							if ($this->ImageMagickSwitchAvailable('negate')) {
1995
-								$commandline .= ' -negate';
1996
-								$successfullyProcessedFilters[] = $filterkey;
1997
-							}
1998
-							break;
1999
-
2000
-						case 'th':
2001
-							@list($amount) = explode('|', $parameter);
2002
-							if ($this->ImageMagickSwitchAvailable(array('threshold', 'dither', 'monochrome'))) {
2003
-								$commandline .= ' -threshold '.phpthumb_functions::escapeshellarg_replacement(round(min(max((int) $amount, 0), 255) / 2.55).'%');
2004
-								$commandline .= ' -dither';
2005
-								$commandline .= ' -monochrome';
2006
-								$successfullyProcessedFilters[] = $filterkey;
2007
-							}
2008
-							break;
2009
-
2010
-						case 'rcd':
2011
-							if ($this->ImageMagickSwitchAvailable(array('colors', 'dither'))) {
2012
-								@list($colors, $dither) = explode('|', $parameter);
2013
-								$colors = ($colors                ?  (int) $colors : 256);
2014
-								$dither  = ((strlen($dither) > 0) ? (bool) $dither : true);
2015
-								$commandline .= ' -colors '.phpthumb_functions::escapeshellarg_replacement(max($colors, 8)); // ImageMagick will otherwise fail with "cannot quantize to fewer than 8 colors"
2016
-								$commandline .= ($dither ? ' -dither' : ' +dither');
2017
-								$successfullyProcessedFilters[] = $filterkey;
2018
-							}
2019
-							break;
2020
-
2021
-						case 'flip':
2022
-							if ($this->ImageMagickSwitchAvailable(array('flip', 'flop'))) {
2023
-								if (strpos(strtolower($parameter), 'x') !== false) {
2024
-									$commandline .= ' -flop';
2025
-								}
2026
-								if (strpos(strtolower($parameter), 'y') !== false) {
2027
-									$commandline .= ' -flip';
2028
-								}
2029
-								$successfullyProcessedFilters[] = $filterkey;
2030
-							}
2031
-							break;
2032
-
2033
-						case 'edge':
2034
-							if ($this->ImageMagickSwitchAvailable('edge')) {
2035
-								$parameter = (!empty($parameter) ? $parameter : 2);
2036
-								$commandline .= ' -edge '.phpthumb_functions::escapeshellarg_replacement(!empty($parameter) ? (int) $parameter : 1);
2037
-								$successfullyProcessedFilters[] = $filterkey;
2038
-							}
2039
-							break;
2040
-
2041
-						case 'emb':
2042
-							if ($this->ImageMagickSwitchAvailable(array('emboss', 'negate'))) {
2043
-								$parameter = (!empty($parameter) ? $parameter : 2);
2044
-								$commandline .= ' -emboss '.phpthumb_functions::escapeshellarg_replacement((int) $parameter);
2045
-								if ($parameter < 2) {
2046
-									$commandline .= ' -negate'; // ImageMagick negates the image for some reason with '-emboss 1';
2047
-								}
2048
-								$successfullyProcessedFilters[] = $filterkey;
2049
-							}
2050
-							break;
2051
-
2052
-						case 'lvl':
2053
-							@list($band, $method, $threshold) = explode('|', $parameter);
2054
-							$band      = ($band ? preg_replace('#[^RGBA\\*]#', '', strtoupper($band))       : '*');
2055
-							$method    = ((strlen($method) > 0)    ? (int) $method :   2);
2056
-							$threshold = ((strlen($threshold) > 0) ? min(max((float) $threshold, 0), 100) : 0.1);
2057
-
2058
-							$band = preg_replace('#[^RGBA\\*]#', '', strtoupper($band));
2059
-
2060
-							if (($method > 1) && !$this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) {
2061
-								// Because ImageMagick processing happens before PHP-GD filters, and because some
2062
-								// clipping is involved in the "lvl" filter, if "lvl" happens before "wb" then the
2063
-								// "wb" filter will have (almost) no effect. Therefore, if "wb" is enabled then
2064
-								// force the "lvl" filter to be processed by GD, not ImageMagick.
2065
-								foreach ($this->fltr as $fltr_key => $fltr_value) {
2066
-									list($fltr_cmd) = explode('|', $fltr_value);
2067
-									if ($fltr_cmd == 'wb') {
2068
-										$this->DebugMessage('Setting "lvl" filter method to "0" (from "'.$method.'") because white-balance filter also enabled', __FILE__, __LINE__);
2069
-										$method = 0;
2070
-									}
2071
-								}
2072
-							}
2073
-
2074
-							switch ($method) {
2075
-								case 0: // internal RGB
2076
-								case 1: // internal grayscale
2077
-									break;
2078
-								case 2: // ImageMagick "contrast-stretch"
2079
-									if ($this->ImageMagickSwitchAvailable('contrast-stretch')) {
2080
-										if ($band != '*') {
2081
-											$commandline .= ' -channel '.phpthumb_functions::escapeshellarg_replacement(strtoupper($band));
2082
-										}
2083
-										$threshold = preg_replace('#[^0-9\\.]#', '', $threshold); // should be unneccesary, but just to be double-sure
2084
-										//$commandline .= ' -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%');
2085
-										$commandline .= ' -contrast-stretch \''.$threshold.'%\'';
2086
-										if ($band != '*') {
2087
-											$commandline .= ' +channel';
2088
-										}
2089
-										$successfullyProcessedFilters[] = $filterkey;
2090
-									}
2091
-									break;
2092
-								case 3: // ImageMagick "normalize"
2093
-									if ($this->ImageMagickSwitchAvailable('normalize')) {
2094
-										if ($band != '*') {
2095
-											$commandline .= ' -channel '.phpthumb_functions::escapeshellarg_replacement(strtoupper($band));
2096
-										}
2097
-										$commandline .= ' -normalize';
2098
-										if ($band != '*') {
2099
-											$commandline .= ' +channel';
2100
-										}
2101
-										$successfullyProcessedFilters[] = $filterkey;
2102
-									}
2103
-									break;
2104
-								default:
2105
-									$this->DebugMessage('unsupported method ('.$method.') for "lvl" filter', __FILE__, __LINE__);
2106
-									break;
2107
-							}
2108
-							if (isset($this->fltr[$filterkey]) && ($method > 1)) {
2109
-								$this->fltr[$filterkey] = $command.'|'.$band.'|0|'.$threshold;
2110
-								$this->DebugMessage('filter "lvl" remapped from method "'.$method.'" to method "0" because ImageMagick support is missing', __FILE__, __LINE__);
2111
-							}
2112
-							break;
2113
-
2114
-						case 'wb':
2115
-							if ($this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) {
2116
-								@list($threshold) = explode('|', $parameter);
2117
-								$threshold = (!empty($threshold) ? min(max((float) $threshold, 0), 100) : 0.1);
2118
-								$threshold = preg_replace('#[^0-9\\.]#', '', $threshold); // should be unneccesary, but just to be double-sure
2119
-								//$commandline .= ' -channel R -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // doesn't work on Windows because most versions of PHP do not properly
2120
-								//$commandline .= ' -channel G -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // escape special characters (such as %) and just replace them with spaces
2121
-								//$commandline .= ' -channel B -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // https://bugs.php.net/bug.php?id=43261
2122
-								$commandline .= ' -channel R -contrast-stretch \''.$threshold.'%\'';
2123
-								$commandline .= ' -channel G -contrast-stretch \''.$threshold.'%\'';
2124
-								$commandline .= ' -channel B -contrast-stretch \''.$threshold.'%\'';
2125
-								$commandline .= ' +channel';
2126
-								$successfullyProcessedFilters[] = $filterkey;
2127
-							}
2128
-							break;
2129
-
2130
-						case 'blur':
2131
-							if ($this->ImageMagickSwitchAvailable('blur')) {
2132
-								@list($radius) = explode('|', $parameter);
2133
-								$radius = (!empty($radius) ? min(max((int) $radius, 0), 25) : 1);
2134
-								$commandline .= ' -blur '.phpthumb_functions::escapeshellarg_replacement($radius);
2135
-								$successfullyProcessedFilters[] = $filterkey;
2136
-							}
2137
-							break;
2138
-
2139
-						case 'gblr':
2140
-							@list($radius) = explode('|', $parameter);
2141
-							$radius = (!empty($radius) ? min(max((int) $radius, 0), 25) : 1);
2142
-							// "-gaussian" changed to "-gaussian-blur" sometime around 2009
2143
-							if ($this->ImageMagickSwitchAvailable('gaussian-blur')) {
2144
-								$commandline .= ' -gaussian-blur '.phpthumb_functions::escapeshellarg_replacement($radius);
2145
-								$successfullyProcessedFilters[] = $filterkey;
2146
-							} elseif ($this->ImageMagickSwitchAvailable('gaussian')) {
2147
-								$commandline .= ' -gaussian '.phpthumb_functions::escapeshellarg_replacement($radius);
2148
-								$successfullyProcessedFilters[] = $filterkey;
2149
-							}
2150
-							break;
2151
-
2152
-						case 'usm':
2153
-							if ($this->ImageMagickSwitchAvailable('unsharp')) {
2154
-								@list($amount, $radius, $threshold) = explode('|', $parameter);
2155
-								$amount    = ($amount            ? min(max((int) $amount,    0), 255) : 80);
2156
-								$radius    = ($radius            ? min(max((int) $radius,    0),  10) : 0.5);
2157
-								$threshold = (strlen($threshold) ? min(max((int) $threshold, 0),  50) : 3);
2158
-								$commandline .= ' -unsharp '.phpthumb_functions::escapeshellarg_replacement(number_format(($radius * 2) - 1, 2, '.', '').'x1+'.number_format($amount / 100, 2, '.', '').'+'.number_format($threshold / 100, 2, '.', ''));
2159
-								$successfullyProcessedFilters[] = $filterkey;
2160
-							}
2161
-							break;
2162
-
2163
-						case 'bord':
2164
-							if ($this->ImageMagickSwitchAvailable(array('border', 'bordercolor', 'thumbnail', 'crop'))) {
2165
-								if (!$this->zc) {
2166
-									@list($width, $rX, $rY, $color) = explode('|', $parameter);
2167
-									$width = (int) $width;
2168
-									$rX    = (int) $rX;
2169
-									$rY    = (int) $rY;
2170
-									if ($width && !$rX && !$rY) {
2171
-										if (!phpthumb_functions::IsHexColor($color)) {
2172
-											$color = ((!empty($this->bc) && phpthumb_functions::IsHexColor($this->bc)) ? $this->bc : '000000');
2173
-										}
2174
-										$commandline .= ' -border '.phpthumb_functions::escapeshellarg_replacement((int) $width);
2175
-										$commandline .= ' -bordercolor '.phpthumb_functions::escapeshellarg_replacement('#'.$color);
2176
-
2177
-										if (preg_match('# \\-crop "([0-9]+)x([0-9]+)\\+0\\+0" #', $commandline, $matches)) {
2178
-											$commandline = str_replace(' -crop "'.$matches[1].'x'.$matches[2].'+0+0" ', ' -crop '.phpthumb_functions::escapeshellarg_replacement(($matches[1] - (2 * $width)).'x'.($matches[2] - (2 * $width)).'+0+0').' ', $commandline);
2179
-										} elseif (preg_match('# \\-'.$IMresizeParameter.' "([0-9]+)x([0-9]+)" #', $commandline, $matches)) {
2180
-											$commandline = str_replace(' -'.$IMresizeParameter.' "'.$matches[1].'x'.$matches[2].'" ', ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(($matches[1] - (2 * $width)).'x'.($matches[2] - (2 * $width))).' ', $commandline);
2181
-										}
2182
-										$successfullyProcessedFilters[] = $filterkey;
2183
-									}
2184
-								}
2185
-							}
2186
-							break;
2187
-
2188
-						case 'crop':
2189
-							break;
2190
-
2191
-						case 'sblr':
2192
-							break;
2193
-
2194
-						case 'mean':
2195
-							break;
2196
-
2197
-						case 'smth':
2198
-							break;
2199
-
2200
-						case 'bvl':
2201
-							break;
2202
-
2203
-						case 'wmi':
2204
-							break;
2205
-
2206
-						case 'wmt':
2207
-							break;
2208
-
2209
-						case 'over':
2210
-							break;
2211
-
2212
-						case 'hist':
2213
-							break;
2214
-
2215
-						case 'fram':
2216
-							break;
2217
-
2218
-						case 'drop':
2219
-							break;
2220
-
2221
-						case 'mask':
2222
-							break;
2223
-
2224
-						case 'elip':
2225
-							break;
2226
-
2227
-						case 'ric':
2228
-							break;
2229
-
2230
-						case 'stc':
2231
-							break;
2232
-
2233
-						case 'size':
2234
-							break;
2235
-
2236
-						default:
2237
-							$this->DebugMessage('Unknown $this->fltr['.$filterkey.'] ('.$filtercommand.') -- deleting filter command', __FILE__, __LINE__);
2238
-							$successfullyProcessedFilters[] = $filterkey;
2239
-							break;
2240
-					}
2241
-					if (!isset($this->fltr[$filterkey])) {
2242
-						$this->DebugMessage('Processed $this->fltr['.$filterkey.'] ('.$filtercommand.') with ImageMagick', __FILE__, __LINE__);
2243
-					} else {
2244
-						$this->DebugMessage('Skipping $this->fltr['.$filterkey.'] ('.$filtercommand.') with ImageMagick', __FILE__, __LINE__);
2245
-					}
2246
-				}
2247
-				$this->DebugMessage('Remaining $this->fltr after ImageMagick: ('.$this->phpThumbDebugVarDump($this->fltr).')', __FILE__, __LINE__);
2248
-				if (count($this->fltr) > 0) {
2249
-					$this->useRawIMoutput = false;
2250
-				}
2251
-
2252
-				if (preg_match('#jpe?g#i', $outputFormat) && $this->q) {
2253
-					if ($this->ImageMagickSwitchAvailable(array('quality', 'interlace'))) {
2254
-						$commandline .= ' -quality '.phpthumb_functions::escapeshellarg_replacement($this->thumbnailQuality);
2255
-						if ($this->config_output_interlace) {
2256
-							// causes weird things with animated GIF... leave for JPEG only
2257
-							$commandline .= ' -interlace line '; // Use Line or Plane to create an interlaced PNG or GIF or progressive JPEG image
2258
-						}
2259
-					}
2260
-				}
2261
-				$commandline .= ' '.$outputFormat.':'.phpthumb_functions::escapeshellarg_replacement($IMtempfilename);
2262
-				if (!$this->iswindows) {
2263
-					$commandline .= ' 2>&1';
2264
-				}
2265
-				$this->DebugMessage('ImageMagick called as ('.$commandline.')', __FILE__, __LINE__);
2266
-				$IMresult = phpthumb_functions::SafeExec($commandline);
2267
-				clearstatcache();
2268
-				if (!@file_exists($IMtempfilename) || !@filesize($IMtempfilename)) {
2269
-					$this->FatalError('ImageMagick failed with message ('.trim($IMresult).')');
2270
-					$this->DebugMessage('ImageMagick failed with message ('.trim($IMresult).')', __FILE__, __LINE__);
2271
-					if ($this->iswindows && !$IMresult) {
2272
-						$this->DebugMessage('Check to make sure that PHP has read+write permissions to "'.dirname($IMtempfilename).'"', __FILE__, __LINE__);
2273
-					}
2274
-
2275
-				} else {
2276
-
2277
-					foreach ($successfullyProcessedFilters as $dummy => $filterkey) {
2278
-						unset($this->fltr[$filterkey]);
2279
-					}
2280
-					$this->IMresizedData = file_get_contents($IMtempfilename);
2281
-					$getimagesize_imresized = @getimagesize($IMtempfilename);
2282
-					$this->DebugMessage('getimagesize('.$IMtempfilename.') returned [w='.$getimagesize_imresized[0].';h='.$getimagesize_imresized[1].';f='.$getimagesize_imresized[2].']', __FILE__, __LINE__);
2283
-					if (($this->config_max_source_pixels > 0) && (($getimagesize_imresized[0] * $getimagesize_imresized[1]) > $this->config_max_source_pixels)) {
2284
-						$this->DebugMessage('skipping ImageMagickThumbnailToGD::'.$ImageCreateFunction.'() because IM output is too large ('.$getimagesize_imresized[0].'x'.$getimagesize_imresized[0].' = '.($getimagesize_imresized[0] * $getimagesize_imresized[1]).' > '.$this->config_max_source_pixels.')', __FILE__, __LINE__);
2285
-					} elseif (function_exists(@$ImageCreateFunction) && ($this->gdimg_source = @$ImageCreateFunction($IMtempfilename))) {
2286
-						$this->source_width  = imagesx($this->gdimg_source);
2287
-						$this->source_height = imagesy($this->gdimg_source);
2288
-						$this->DebugMessage('ImageMagickThumbnailToGD::'.$ImageCreateFunction.'() succeeded, $this->gdimg_source is now ('.$this->source_width.'x'.$this->source_height.')', __FILE__, __LINE__);
2289
-						$this->DebugMessage('ImageMagickThumbnailToGD() returning $this->IMresizedData ('.strlen($this->IMresizedData).' bytes)', __FILE__, __LINE__);
2290
-					} else {
2291
-						$this->useRawIMoutput = true;
2292
-						$this->DebugMessage('$this->useRawIMoutput set to TRUE because '.@$ImageCreateFunction.'('.$IMtempfilename.') failed', __FILE__, __LINE__);
2293
-					}
2294
-					if (file_exists($IMtempfilename)) {
2295
-						$this->DebugMessage('deleting "'.$IMtempfilename.'"', __FILE__, __LINE__);
2296
-						@unlink($IMtempfilename);
2297
-					}
2298
-					return true;
2299
-
2300
-				}
2301
-				if (file_exists($IMtempfilename)) {
2302
-					$this->DebugMessage('deleting "'.$IMtempfilename.'"', __FILE__, __LINE__);
2303
-					@unlink($IMtempfilename);
2304
-				}
2305
-
2306
-			} elseif ($this->issafemode) {
2307
-				$this->DebugMessage('ImageMagickThumbnailToGD() aborting because PHP safe_mode is enabled and phpThumb_tempnam() failed', __FILE__, __LINE__);
2308
-				$this->useRawIMoutput = false;
2309
-			} else {
2310
-				if (file_exists($IMtempfilename)) {
2311
-					$this->DebugMessage('deleting "'.$IMtempfilename.'"', __FILE__, __LINE__);
2312
-					@unlink($IMtempfilename);
2313
-				}
2314
-				$this->DebugMessage('ImageMagickThumbnailToGD() aborting, phpThumb_tempnam() failed', __FILE__, __LINE__);
2315
-			}
2316
-		} else {
2317
-			$this->DebugMessage('ImageMagickThumbnailToGD() aborting because ImageMagickCommandlineBase() failed', __FILE__, __LINE__);
2318
-		}
2319
-		$this->useRawIMoutput = false;
2320
-		return false;
2321
-	}
2322
-
2323
-
2324
-	public function Rotate() {
2325
-		if ($this->ra || $this->ar) {
2326
-			if (!function_exists('imagerotate')) {
2327
-				$this->DebugMessage('!function_exists(imagerotate)', __FILE__, __LINE__);
2328
-				return false;
2329
-			}
2330
-			if (!include_once( __DIR__ .'/phpthumb.filters.php')) {
2331
-				$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
2332
-				return false;
2333
-			}
2334
-
2335
-			$this->config_background_hexcolor = ($this->bg ? $this->bg : $this->config_background_hexcolor);
2336
-			if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
2337
-				return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
2338
-			}
2339
-
2340
-			$rotate_angle = 0;
2341
-			if ($this->ra) {
2342
-
2343
-				$rotate_angle = (float) $this->ra;
2344
-
2345
-			} else {
2346
-
2347
-				if ($this->ar == 'x') {
2348
-					if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.2.0', '>=')) {
2349
-						if ($this->sourceFilename) {
2350
-							if (function_exists('exif_read_data')) {
2351
-								if ($exif_data = @exif_read_data($this->sourceFilename, 'IFD0')) {
2352
-									// http://sylvana.net/jpegcrop/exif_orientation.html
2353
-									switch (@$exif_data['Orientation']) {
2354
-										case 1:
2355
-											$rotate_angle = 0;
2356
-											break;
2357
-										case 3:
2358
-											$rotate_angle = 180;
2359
-											break;
2360
-										case 6:
2361
-											$rotate_angle = 270;
2362
-											break;
2363
-										case 8:
2364
-											$rotate_angle = 90;
2365
-											break;
2366
-
2367
-										default:
2368
-											$this->DebugMessage('EXIF auto-rotate failed because unknown $exif_data[Orientation] "'.@$exif_data['Orientation'].'"', __FILE__, __LINE__);
2369
-											return false;
2370
-											break;
2371
-									}
2372
-									$this->DebugMessage('EXIF auto-rotate set to '.$rotate_angle.' degrees ($exif_data[Orientation] = "'.@$exif_data['Orientation'].'")', __FILE__, __LINE__);
2373
-								} else {
2374
-									$this->DebugMessage('failed: exif_read_data('.$this->sourceFilename.')', __FILE__, __LINE__);
2375
-									return false;
2376
-								}
2377
-							} else {
2378
-								$this->DebugMessage('!function_exists(exif_read_data)', __FILE__, __LINE__);
2379
-								return false;
2380
-							}
2381
-						} else {
2382
-							$this->DebugMessage('Cannot auto-rotate from EXIF data because $this->sourceFilename is empty', __FILE__, __LINE__);
2383
-							return false;
2384
-						}
2385
-					} else {
2386
-						$this->DebugMessage('Cannot auto-rotate from EXIF data because PHP is less than v4.2.0 ('. PHP_VERSION .')', __FILE__, __LINE__);
2387
-						return false;
2388
-					}
2389
-				} elseif (($this->ar == 'l') && ($this->source_height > $this->source_width)) {
2390
-					$rotate_angle = 270;
2391
-				} elseif (($this->ar == 'L') && ($this->source_height > $this->source_width)) {
2392
-					$rotate_angle = 90;
2393
-				} elseif (($this->ar == 'p') && ($this->source_width > $this->source_height)) {
2394
-					$rotate_angle = 90;
2395
-				} elseif (($this->ar == 'P') && ($this->source_width > $this->source_height)) {
2396
-					$rotate_angle = 270;
2397
-				}
2398
-
2399
-			}
2400
-			if ($rotate_angle % 90) {
2401
-				$this->is_alpha = true;
2402
-			}
2403
-			phpthumb_filters::ImprovedImageRotate($this->gdimg_source, $rotate_angle, $this->config_background_hexcolor, $this->bg, $this);
2404
-			$this->source_width  = imagesx($this->gdimg_source);
2405
-			$this->source_height = imagesy($this->gdimg_source);
2406
-		}
2407
-		return true;
2408
-	}
2409
-
2410
-
2411
-	public function FixedAspectRatio() {
2412
-		// optional fixed-dimension images (regardless of aspect ratio)
2413
-
2414
-		if (!$this->far) {
2415
-			// do nothing
2416
-			return true;
2417
-		}
2418
-
2419
-		if (!$this->w || !$this->h) {
2420
-			return false;
2421
-		}
2422
-		$this->thumbnail_width  = $this->w;
2423
-		$this->thumbnail_height = $this->h;
2424
-		$this->is_alpha = true;
2425
-		if ($this->thumbnail_image_width >= $this->thumbnail_width) {
2426
-
2427
-			$aspectratio = $this->thumbnail_image_height / $this->thumbnail_image_width;
2428
-			if ($this->w) {
2429
-				$this->thumbnail_image_height = round($this->thumbnail_image_width * $aspectratio);
2430
-				$this->thumbnail_height = ($this->h ? $this->h : $this->thumbnail_image_height);
2431
-			} elseif ($this->thumbnail_image_height < $this->thumbnail_height) {
2432
-				$this->thumbnail_image_height = $this->thumbnail_height;
2433
-				$this->thumbnail_image_width  = round($this->thumbnail_image_height / $aspectratio);
2434
-			}
2435
-
2436
-		} else {
2437
-
2438
-			$aspectratio = $this->thumbnail_image_width / $this->thumbnail_image_height;
2439
-			if ($this->h) {
2440
-				$this->thumbnail_image_width = round($this->thumbnail_image_height * $aspectratio);
2441
-			} elseif ($this->thumbnail_image_width < $this->thumbnail_width) {
2442
-				$this->thumbnail_image_width = $this->thumbnail_width;
2443
-				$this->thumbnail_image_height  = round($this->thumbnail_image_width / $aspectratio);
2444
-			}
2445
-
2446
-		}
2447
-		return true;
2448
-	}
2449
-
2450
-
2451
-	public function OffsiteDomainIsAllowed($hostname, $allowed_domains) {
2452
-		static $domain_is_allowed = array();
2453
-		$hostname = strtolower($hostname);
2454
-		if (!isset($domain_is_allowed[$hostname])) {
2455
-			$domain_is_allowed[$hostname] = false;
2456
-			foreach ($allowed_domains as $valid_domain) {
2457
-				$starpos = strpos($valid_domain, '*');
2458
-				if ($starpos !== false) {
2459
-					$valid_domain = substr($valid_domain, $starpos + 1);
2460
-					if (preg_match('#'.preg_quote($valid_domain).'$#', $hostname)) {
2461
-						$domain_is_allowed[$hostname] = true;
2462
-						break;
2463
-					}
2464
-				} else {
2465
-					if (strtolower($valid_domain) === $hostname) {
2466
-						$domain_is_allowed[$hostname] = true;
2467
-						break;
2468
-					}
2469
-				}
2470
-			}
2471
-		}
2472
-		return $domain_is_allowed[$hostname];
2473
-	}
2474
-
2475
-
2476
-	public function AntiOffsiteLinking() {
2477
-		// Optional anti-offsite hijacking of the thumbnail script
2478
-		$allow   = true;
2479
-		if ($allow && $this->config_nooffsitelink_enabled && (@$_SERVER['HTTP_REFERER'] || $this->config_nooffsitelink_require_refer)) {
2480
-			$this->DebugMessage('AntiOffsiteLinking() checking $_SERVER[HTTP_REFERER] "'.@$_SERVER['HTTP_REFERER'].'"', __FILE__, __LINE__);
2481
-			foreach ($this->config_nooffsitelink_valid_domains as $key => $valid_domain) {
2482
-				// $_SERVER['HTTP_HOST'] contains the port number, so strip it out here to make default configuration work
2483
-				list($clean_domain) = explode(':', $valid_domain);
2484
-				$this->config_nooffsitelink_valid_domains[$key] = $clean_domain;
2485
-			}
2486
-			$parsed_url = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
2487
-			if (!$this->OffsiteDomainIsAllowed(@$parsed_url['host'], $this->config_nooffsitelink_valid_domains)) {
2488
-				$allow   = false;
2489
-				//$this->DebugMessage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is NOT in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
2490
-				$this->ErrorImage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is NOT in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')');
2491
-			} else {
2492
-				$this->DebugMessage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
2493
-			}
2494
-		}
2495
-
2496
-		if ($allow && $this->config_nohotlink_enabled && preg_match('#^(f|ht)tps?\://#i', $this->src)) {
2497
-			$parsed_url = phpthumb_functions::ParseURLbetter($this->src);
2498
-			//if (!phpthumb_functions::CaseInsensitiveInArray(@$parsed_url['host'], $this->config_nohotlink_valid_domains)) {
2499
-			if (!$this->OffsiteDomainIsAllowed(@$parsed_url['host'], $this->config_nohotlink_valid_domains)) {
2500
-				// This domain is not allowed
2501
-				$allow = false;
2502
-				$this->DebugMessage('AntiOffsiteLinking() - "'.$parsed_url['host'].'" is NOT in $this->config_nohotlink_valid_domains ('.implode(';', $this->config_nohotlink_valid_domains).')', __FILE__, __LINE__);
2503
-			} else {
2504
-				$this->DebugMessage('AntiOffsiteLinking() - "'.$parsed_url['host'].'" is in $this->config_nohotlink_valid_domains ('.implode(';', $this->config_nohotlink_valid_domains).')', __FILE__, __LINE__);
2505
-			}
2506
-		}
2507
-
2508
-		if ($allow) {
2509
-			$this->DebugMessage('AntiOffsiteLinking() says this is allowed', __FILE__, __LINE__);
2510
-			return true;
2511
-		}
2512
-
2513
-		if (!phpthumb_functions::IsHexColor($this->config_error_bgcolor)) {
2514
-			return $this->ErrorImage('Invalid hex color string "'.$this->config_error_bgcolor.'" for $this->config_error_bgcolor');
2515
-		}
2516
-		if (!phpthumb_functions::IsHexColor($this->config_error_textcolor)) {
2517
-			return $this->ErrorImage('Invalid hex color string "'.$this->config_error_textcolor.'" for $this->config_error_textcolor');
2518
-		}
2519
-		if ($this->config_nooffsitelink_erase_image) {
2520
-
2521
-			return $this->ErrorImage($this->config_nooffsitelink_text_message, $this->thumbnail_width, $this->thumbnail_height);
2522
-
2523
-		} else {
2524
-
2525
-			$this->config_nooffsitelink_watermark_src = $this->ResolveFilenameToAbsolute($this->config_nooffsitelink_watermark_src);
2526
-			if (is_file($this->config_nooffsitelink_watermark_src)) {
2527
-
2528
-				if (!include_once( __DIR__ .'/phpthumb.filters.php')) {
2529
-					$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.filters.php" which is required for applying watermark', __FILE__, __LINE__);
2530
-					return false;
2531
-				}
2532
-				$watermark_img = $this->ImageCreateFromStringReplacement(file_get_contents($this->config_nooffsitelink_watermark_src));
2533
-				$phpthumbFilters = new phpthumb_filters();
2534
-				$phpthumbFilters->phpThumbObject = &$this;
2535
-				$opacity = 50;
2536
-				$margin  = 5;
2537
-				$phpthumbFilters->WatermarkOverlay($this->gdimg_output, $watermark_img, '*', $opacity, $margin);
2538
-				imagedestroy($watermark_img);
2539
-				unset($phpthumbFilters);
2540
-
2541
-			} else {
2542
-
2543
-				$nohotlink_text_array = explode("\n", wordwrap($this->config_nooffsitelink_text_message, floor($this->thumbnail_width / imagefontwidth($this->config_error_fontsize)), "\n"));
2544
-				$nohotlink_text_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_error_textcolor);
2545
-
2546
-				$topoffset = round(($this->thumbnail_height - (count($nohotlink_text_array) * imagefontheight($this->config_error_fontsize))) / 2);
2547
-
2548
-				$rowcounter = 0;
2549
-				$this->DebugMessage('AntiOffsiteLinking() writing '.count($nohotlink_text_array).' lines of text "'.$this->config_nooffsitelink_text_message.'" (in #'.$this->config_error_textcolor.') on top of image', __FILE__, __LINE__);
2550
-				foreach ($nohotlink_text_array as $textline) {
2551
-					$leftoffset = max(0, round(($this->thumbnail_width - (strlen($textline) * imagefontwidth($this->config_error_fontsize))) / 2));
2552
-					imagestring($this->gdimg_output, $this->config_error_fontsize, $leftoffset, $topoffset + ($rowcounter++ * imagefontheight($this->config_error_fontsize)), $textline, $nohotlink_text_color);
2553
-				}
2554
-
2555
-			}
2556
-
2557
-		}
2558
-		return true;
2559
-	}
2560
-
2561
-
2562
-	public function AlphaChannelFlatten() {
2563
-		if (!$this->is_alpha) {
2564
-			// image doesn't have alpha transparency, no need to flatten
2565
-			$this->DebugMessage('skipping AlphaChannelFlatten() because !$this->is_alpha', __FILE__, __LINE__);
2566
-			return false;
2567
-		}
2568
-		switch ($this->thumbnailFormat) {
2569
-			case 'png':
2570
-			case 'ico':
2571
-				// image has alpha transparency, but output as PNG or ICO which can handle it
2572
-				$this->DebugMessage('skipping AlphaChannelFlatten() because ($this->thumbnailFormat == "'.$this->thumbnailFormat.'")', __FILE__, __LINE__);
2573
-				return false;
2574
-				break;
2575
-
2576
-			case 'gif':
2577
-				// image has alpha transparency, but output as GIF which can handle only single-color transparency
2578
-				$CurrentImageColorTransparent = imagecolortransparent($this->gdimg_output);
2579
-				if ($CurrentImageColorTransparent == -1) {
2580
-					// no transparent color defined
2581
-
2582
-					if (phpthumb_functions::gd_version() < 2.0) {
2583
-						$this->DebugMessage('AlphaChannelFlatten() failed because GD version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2584
-						return false;
2585
-					}
2586
-
2587
-					if ($img_alpha_mixdown_dither = @imagecreatetruecolor(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) {
2588
-
2589
-						$dither_color = array();
2590
-						for ($i = 0; $i <= 255; $i++) {
2591
-							$dither_color[$i] = imagecolorallocate($img_alpha_mixdown_dither, $i, $i, $i);
2592
-						}
2593
-
2594
-						// scan through current truecolor image copy alpha channel to temp image as grayscale
2595
-						for ($x = 0; $x < $this->thumbnail_width; $x++) {
2596
-							for ($y = 0; $y < $this->thumbnail_height; $y++) {
2597
-								$PixelColor = phpthumb_functions::GetPixelColor($this->gdimg_output, $x, $y);
2598
-								imagesetpixel($img_alpha_mixdown_dither, $x, $y, $dither_color[($PixelColor['alpha'] * 2)]);
2599
-							}
2600
-						}
2601
-
2602
-						// dither alpha channel grayscale version down to 2 colors
2603
-						imagetruecolortopalette($img_alpha_mixdown_dither, true, 2);
2604
-
2605
-						// reduce color palette to 256-1 colors (leave one palette position for transparent color)
2606
-						imagetruecolortopalette($this->gdimg_output, true, 255);
2607
-
2608
-						// allocate a new color for transparent color index
2609
-						$TransparentColor = imagecolorallocate($this->gdimg_output, 1, 254, 253);
2610
-						imagecolortransparent($this->gdimg_output, $TransparentColor);
2611
-
2612
-						// scan through alpha channel image and note pixels with >50% transparency
2613
-						for ($x = 0; $x < $this->thumbnail_width; $x++) {
2614
-							for ($y = 0; $y < $this->thumbnail_height; $y++) {
2615
-								$AlphaChannelPixel = phpthumb_functions::GetPixelColor($img_alpha_mixdown_dither, $x, $y);
2616
-								if ($AlphaChannelPixel['red'] > 127) {
2617
-									imagesetpixel($this->gdimg_output, $x, $y, $TransparentColor);
2618
-								}
2619
-							}
2620
-						}
2621
-						imagedestroy($img_alpha_mixdown_dither);
2622
-
2623
-						$this->DebugMessage('AlphaChannelFlatten() set image to 255+1 colors with transparency for GIF output', __FILE__, __LINE__);
2624
-						return true;
2625
-
2626
-					} else {
2627
-						$this->DebugMessage('AlphaChannelFlatten() failed imagecreate('.imagesx($this->gdimg_output).', '.imagesy($this->gdimg_output).')', __FILE__, __LINE__);
2628
-						return false;
2629
-					}
2630
-
2631
-				} else {
2632
-					// a single transparent color already defined, leave as-is
2633
-					$this->DebugMessage('skipping AlphaChannelFlatten() because ($this->thumbnailFormat == "'.$this->thumbnailFormat.'") and imagecolortransparent() returned "'.$CurrentImageColorTransparent.'"', __FILE__, __LINE__);
2634
-					return true;
2635
-				}
2636
-				break;
2637
-		}
2638
-		$this->DebugMessage('continuing AlphaChannelFlatten() for output format "'.$this->thumbnailFormat.'"', __FILE__, __LINE__);
2639
-		// image has alpha transparency, and is being output in a format that doesn't support it -- flatten
2640
-		if ($gdimg_flatten_temp = phpthumb_functions::ImageCreateFunction($this->thumbnail_width, $this->thumbnail_height)) {
2641
-
2642
-			$this->config_background_hexcolor = ($this->bg ? $this->bg : $this->config_background_hexcolor);
2643
-			if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
2644
-				return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
2645
-			}
2646
-			$background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor);
2647
-			imagefilledrectangle($gdimg_flatten_temp, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color);
2648
-			imagecopy($gdimg_flatten_temp, $this->gdimg_output, 0, 0, 0, 0, $this->thumbnail_width, $this->thumbnail_height);
2649
-
2650
-			imagealphablending($this->gdimg_output, true);
2651
-			imagesavealpha($this->gdimg_output, false);
2652
-			imagecolortransparent($this->gdimg_output, -1);
2653
-			imagecopy($this->gdimg_output, $gdimg_flatten_temp, 0, 0, 0, 0, $this->thumbnail_width, $this->thumbnail_height);
2654
-
2655
-			imagedestroy($gdimg_flatten_temp);
2656
-			return true;
2657
-
2658
-		} else {
2659
-			$this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
2660
-		}
2661
-		return false;
2662
-	}
2663
-
2664
-
2665
-	public function ApplyFilters() {
2666
-		if ($this->fltr && is_array($this->fltr)) {
2667
-			if (!include_once( __DIR__ .'/phpthumb.filters.php')) {
2668
-				$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
2669
-				return false;
2670
-			}
2671
-			$phpthumbFilters = new phpthumb_filters();
2672
-			$phpthumbFilters->phpThumbObject = &$this;
2673
-			foreach ($this->fltr as $filtercommand) {
2674
-				@list($command, $parameter) = explode('|', $filtercommand, 2);
2675
-				$this->DebugMessage('Attempting to process filter command "'.$command.'('.$parameter.')"', __FILE__, __LINE__);
2676
-				switch ($command) {
2677
-					case 'brit': // Brightness
2678
-						$phpthumbFilters->Brightness($this->gdimg_output, $parameter);
2679
-						break;
2680
-
2681
-					case 'cont': // Contrast
2682
-						$phpthumbFilters->Contrast($this->gdimg_output, $parameter);
2683
-						break;
2684
-
2685
-					case 'ds': // Desaturation
2686
-						$phpthumbFilters->Desaturate($this->gdimg_output, $parameter, '');
2687
-						break;
2688
-
2689
-					case 'sat': // Saturation
2690
-						$phpthumbFilters->Saturation($this->gdimg_output, $parameter, '');
2691
-						break;
2692
-
2693
-					case 'gray': // Grayscale
2694
-						$phpthumbFilters->Grayscale($this->gdimg_output);
2695
-						break;
2696
-
2697
-					case 'clr': // Colorize
2698
-						if (phpthumb_functions::gd_version() < 2) {
2699
-							$this->DebugMessage('Skipping Colorize() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2700
-							break;
2701
-						}
2702
-						@list($amount, $color) = explode('|', $parameter, 2);
2703
-						$phpthumbFilters->Colorize($this->gdimg_output, $amount, $color);
2704
-						break;
2705
-
2706
-					case 'sep': // Sepia
2707
-						if (phpthumb_functions::gd_version() < 2) {
2708
-							$this->DebugMessage('Skipping Sepia() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2709
-							break;
2710
-						}
2711
-						@list($amount, $color) = explode('|', $parameter, 2);
2712
-						$phpthumbFilters->Sepia($this->gdimg_output, $amount, $color);
2713
-						break;
2714
-
2715
-					case 'gam': // Gamma correction
2716
-						$phpthumbFilters->Gamma($this->gdimg_output, $parameter);
2717
-						break;
2718
-
2719
-					case 'neg': // Negative colors
2720
-						$phpthumbFilters->Negative($this->gdimg_output);
2721
-						break;
2722
-
2723
-					case 'th': // Threshold
2724
-						$phpthumbFilters->Threshold($this->gdimg_output, $parameter);
2725
-						break;
2726
-
2727
-					case 'rcd': // ReduceColorDepth
2728
-						if (phpthumb_functions::gd_version() < 2) {
2729
-							$this->DebugMessage('Skipping ReduceColorDepth() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2730
-							break;
2731
-						}
2732
-						@list($colors, $dither) = explode('|', $parameter, 2);
2733
-						$colors = ($colors                ?  (int) $colors : 256);
2734
-						$dither  = ((strlen($dither) > 0) ? (bool) $dither : true);
2735
-						$phpthumbFilters->ReduceColorDepth($this->gdimg_output, $colors, $dither);
2736
-						break;
2737
-
2738
-					case 'flip': // Flip
2739
-						$phpthumbFilters->Flip($this->gdimg_output, (strpos(strtolower($parameter), 'x') !== false), (strpos(strtolower($parameter), 'y') !== false));
2740
-						break;
2741
-
2742
-					case 'edge': // EdgeDetect
2743
-						$phpthumbFilters->EdgeDetect($this->gdimg_output);
2744
-						break;
2745
-
2746
-					case 'emb': // Emboss
2747
-						$phpthumbFilters->Emboss($this->gdimg_output);
2748
-						break;
2749
-
2750
-					case 'bvl': // Bevel
2751
-						@list($width, $color1, $color2) = explode('|', $parameter, 3);
2752
-						$phpthumbFilters->Bevel($this->gdimg_output, $width, $color1, $color2);
2753
-						break;
2754
-
2755
-					case 'lvl': // autoLevels
2756
-						@list($band, $method, $threshold) = explode('|', $parameter, 3);
2757
-						$band      = ($band ? preg_replace('#[^RGBA\\*]#', '', strtoupper($band)) : '*');
2758
-						$method    = ((strlen($method) > 0)    ? (int) $method :   2);
2759
-						$threshold = ((strlen($threshold) > 0) ? (float) $threshold : 0.1);
2760
-
2761
-						$phpthumbFilters->HistogramStretch($this->gdimg_output, $band, $method, $threshold);
2762
-						break;
2763
-
2764
-					case 'wb': // WhiteBalance
2765
-						$phpthumbFilters->WhiteBalance($this->gdimg_output, $parameter);
2766
-						break;
2767
-
2768
-					case 'hist': // Histogram overlay
2769
-						if (phpthumb_functions::gd_version() < 2) {
2770
-							$this->DebugMessage('Skipping HistogramOverlay() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2771
-							break;
2772
-						}
2773
-						@list($bands, $colors, $width, $height, $alignment, $opacity, $margin_x, $margin_y) = explode('|', $parameter, 8);
2774
-						$bands     = ($bands     ? $bands     :  '*');
2775
-						$colors    = ($colors    ? $colors    :   '');
2776
-						$width     = ($width     ? $width     : 0.25);
2777
-						$height    = ($height    ? $height    : 0.25);
2778
-						$alignment = ($alignment ? $alignment : 'BR');
2779
-						$opacity   = ($opacity   ? $opacity   :   50);
2780
-						$margin_x  = ($margin_x  ? $margin_x  :    5);
2781
-						// $margin_y -- it wasn't forgotten, let the value always pass unchanged
2782
-						$phpthumbFilters->HistogramOverlay($this->gdimg_output, $bands, $colors, $width, $height, $alignment, $opacity, $margin_x, $margin_y);
2783
-						break;
2784
-
2785
-					case 'fram': // Frame
2786
-						@list($frame_width, $edge_width, $color_frame, $color1, $color2) = explode('|', $parameter, 5);
2787
-						$phpthumbFilters->Frame($this->gdimg_output, $frame_width, $edge_width, $color_frame, $color1, $color2);
2788
-						break;
2789
-
2790
-					case 'drop': // DropShadow
2791
-						if (phpthumb_functions::gd_version() < 2) {
2792
-							$this->DebugMessage('Skipping DropShadow() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2793
-							return false;
2794
-						}
2795
-						$this->is_alpha = true;
2796
-						@list($distance, $width, $color, $angle, $fade) = explode('|', $parameter, 5);
2797
-						$phpthumbFilters->DropShadow($this->gdimg_output, $distance, $width, $color, $angle, $fade);
2798
-						break;
2799
-
2800
-					case 'mask': // Mask cropping
2801
-						if (phpthumb_functions::gd_version() < 2) {
2802
-							$this->DebugMessage('Skipping Mask() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2803
-							return false;
2804
-						}
2805
-						@list($mask_filename, $invert) = explode('|', $parameter, 2);
2806
-						$mask_filename = $this->ResolveFilenameToAbsolute($mask_filename);
2807
-						if (@is_readable($mask_filename) && ($fp_mask = @fopen($mask_filename, 'rb'))) {
2808
-							$MaskImageData = '';
2809
-							do {
2810
-								$buffer = fread($fp_mask, 8192);
2811
-								$MaskImageData .= $buffer;
2812
-							} while (strlen($buffer) > 0);
2813
-							fclose($fp_mask);
2814
-							if ($gdimg_mask = $this->ImageCreateFromStringReplacement($MaskImageData)) {
2815
-								if ($invert && phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
2816
-									imagefilter($gdimg_mask, IMG_FILTER_NEGATE);
2817
-								}
2818
-								$this->is_alpha = true;
2819
-								$phpthumbFilters->ApplyMask($gdimg_mask, $this->gdimg_output);
2820
-								imagedestroy($gdimg_mask);
2821
-							} else {
2822
-								$this->DebugMessage('ImageCreateFromStringReplacement() failed for "'.$mask_filename.'"', __FILE__, __LINE__);
2823
-							}
2824
-						} else {
2825
-							$this->DebugMessage('Cannot open mask file "'.$mask_filename.'"', __FILE__, __LINE__);
2826
-						}
2827
-						break;
2828
-
2829
-					case 'elip': // Ellipse cropping
2830
-						if (phpthumb_functions::gd_version() < 2) {
2831
-							$this->DebugMessage('Skipping Ellipse() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2832
-							return false;
2833
-						}
2834
-						$this->is_alpha = true;
2835
-						$phpthumbFilters->Ellipse($this->gdimg_output);
2836
-						break;
2837
-
2838
-					case 'ric': // RoundedImageCorners
2839
-						if (phpthumb_functions::gd_version() < 2) {
2840
-							$this->DebugMessage('Skipping RoundedImageCorners() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2841
-							return false;
2842
-						}
2843
-						@list($radius_x, $radius_y) = explode('|', $parameter, 2);
2844
-						if (($radius_x < 1) || ($radius_y < 1)) {
2845
-							$this->DebugMessage('Skipping RoundedImageCorners('.$radius_x.', '.$radius_y.') because x/y radius is less than 1', __FILE__, __LINE__);
2846
-							break;
2847
-						}
2848
-						$this->is_alpha = true;
2849
-						$phpthumbFilters->RoundedImageCorners($this->gdimg_output, $radius_x, $radius_y);
2850
-						break;
2851
-
2852
-					case 'crop': // Crop
2853
-						@list($left, $right, $top, $bottom) = explode('|', $parameter, 4);
2854
-						$phpthumbFilters->Crop($this->gdimg_output, $left, $right, $top, $bottom);
2855
-						break;
2856
-
2857
-					case 'bord': // Border
2858
-						@list($border_width, $radius_x, $radius_y, $hexcolor_border) = explode('|', $parameter, 4);
2859
-						$this->is_alpha = true;
2860
-						$phpthumbFilters->ImageBorder($this->gdimg_output, $border_width, $radius_x, $radius_y, $hexcolor_border);
2861
-						break;
2862
-
2863
-					case 'over': // Overlay
2864
-						@list($filename, $underlay, $margin, $opacity) = explode('|', $parameter, 4);
2865
-						$underlay = (bool) ($underlay              ? $underlay : false);
2866
-						$margin   =        ((strlen($margin)  > 0) ? $margin   : ($underlay ? 0.1 : 0.0));
2867
-						$opacity  =        ((strlen($opacity) > 0) ? $opacity  : 100);
2868
-						if (($margin > 0) && ($margin < 1)) {
2869
-							$margin = min(0.499, $margin);
2870
-						} elseif (($margin > -1) && ($margin < 0)) {
2871
-							$margin = max(-0.499, $margin);
2872
-						}
2873
-
2874
-						$filename = $this->ResolveFilenameToAbsolute($filename);
2875
-						if (@is_readable($filename) && ($fp_watermark = @fopen($filename, 'rb'))) {
2876
-							$WatermarkImageData = '';
2877
-							do {
2878
-								$buffer = fread($fp_watermark, 8192);
2879
-								$WatermarkImageData .= $buffer;
2880
-							} while (strlen($buffer) > 0);
2881
-							fclose($fp_watermark);
2882
-							if ($img_watermark = $this->ImageCreateFromStringReplacement($WatermarkImageData)) {
2883
-								if (($margin > 0) && ($margin < 1)) {
2884
-									$resized_x = max(1, imagesx($this->gdimg_output) - round(2 * (imagesx($this->gdimg_output) * $margin)));
2885
-									$resized_y = max(1, imagesy($this->gdimg_output) - round(2 * (imagesy($this->gdimg_output) * $margin)));
2886
-								} else {
2887
-									$resized_x = max(1, imagesx($this->gdimg_output) - round(2 * $margin));
2888
-									$resized_y = max(1, imagesy($this->gdimg_output) - round(2 * $margin));
2889
-								}
2890
-
2891
-								if ($underlay) {
2892
-
2893
-									if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) {
2894
-										imagealphablending($img_watermark_resized, false);
2895
-										imagesavealpha($img_watermark_resized, true);
2896
-										$this->ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark_resized), imagesy($img_watermark_resized), imagesx($img_watermark), imagesy($img_watermark));
2897
-										if ($img_source_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) {
2898
-											imagealphablending($img_source_resized, false);
2899
-											imagesavealpha($img_source_resized, true);
2900
-											$this->ImageResizeFunction($img_source_resized, $this->gdimg_output, 0, 0, 0, 0, imagesx($img_source_resized), imagesy($img_source_resized), imagesx($this->gdimg_output), imagesy($this->gdimg_output));
2901
-											$phpthumbFilters->WatermarkOverlay($img_watermark_resized, $img_source_resized, 'C', $opacity, $margin);
2902
-											imagecopy($this->gdimg_output, $img_watermark_resized, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output));
2903
-										} else {
2904
-											$this->DebugMessage('phpthumb_functions::ImageCreateFunction('.$resized_x.', '.$resized_y.')', __FILE__, __LINE__);
2905
-										}
2906
-										imagedestroy($img_watermark_resized);
2907
-									} else {
2908
-										$this->DebugMessage('phpthumb_functions::ImageCreateFunction('.imagesx($this->gdimg_output).', '.imagesy($this->gdimg_output).')', __FILE__, __LINE__);
2909
-									}
2910
-
2911
-								} else { // overlay
2912
-
2913
-									if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) {
2914
-										imagealphablending($img_watermark_resized, false);
2915
-										imagesavealpha($img_watermark_resized, true);
2916
-										$this->ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark_resized), imagesy($img_watermark_resized), imagesx($img_watermark), imagesy($img_watermark));
2917
-										$phpthumbFilters->WatermarkOverlay($this->gdimg_output, $img_watermark_resized, 'C', $opacity, $margin);
2918
-										imagedestroy($img_watermark_resized);
2919
-									} else {
2920
-										$this->DebugMessage('phpthumb_functions::ImageCreateFunction('.$resized_x.', '.$resized_y.')', __FILE__, __LINE__);
2921
-									}
2922
-
2923
-								}
2924
-								imagedestroy($img_watermark);
2925
-
2926
-							} else {
2927
-								$this->DebugMessage('ImageCreateFromStringReplacement() failed for "'.$filename.'"', __FILE__, __LINE__);
2928
-							}
2929
-						} else {
2930
-							$this->DebugMessage('Cannot open overlay file "'.$filename.'"', __FILE__, __LINE__);
2931
-						}
2932
-						break;
2933
-
2934
-					case 'wmi': // WaterMarkImage
2935
-						@list($filename, $alignment, $opacity, $margin['x'], $margin['y'], $rotate_angle) = explode('|', $parameter, 6);
2936
-						// $margin can be pixel margin or percent margin if $alignment is text, or max width/height if $alignment is position like "50x75"
2937
-						$alignment    = ($alignment            ? $alignment            : 'BR');
2938
-						$opacity      = (strlen($opacity)      ? (int) $opacity : 50);
2939
-						$rotate_angle = (strlen($rotate_angle) ? (int) $rotate_angle : 0);
2940
-						if (!preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
2941
-							$margins = array('x', 'y');
2942
-							foreach ($margins as $xy) {
2943
-								$margin[$xy] = (strlen($margin[$xy]) ? $margin[$xy] : 5);
2944
-								if (($margin[$xy] > 0) && ($margin[$xy] < 1)) {
2945
-									$margin[$xy] = min(0.499, $margin[$xy]);
2946
-								} elseif (($margin[$xy] > -1) && ($margin[$xy] < 0)) {
2947
-									$margin[$xy] = max(-0.499, $margin[$xy]);
2948
-								}
2949
-							}
2950
-						}
2951
-
2952
-						$filename = $this->ResolveFilenameToAbsolute($filename);
2953
-						if (@is_readable($filename)) {
2954
-							if ($img_watermark = $this->ImageCreateFromFilename($filename)) {
2955
-								if ($rotate_angle !== 0) {
2956
-									$phpthumbFilters->ImprovedImageRotate($img_watermark, $rotate_angle, 'FFFFFF', null, $this);
2957
-								}
2958
-								if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
2959
-									$watermark_max_width  = (int) ($margin[ 'x'] ? $margin[ 'x'] : imagesx($img_watermark));
2960
-									$watermark_max_height = (int) ($margin[ 'y'] ? $margin[ 'y'] : imagesy($img_watermark));
2961
-									$scale = phpthumb_functions::ScaleToFitInBox(imagesx($img_watermark), imagesy($img_watermark), $watermark_max_width, $watermark_max_height, true, true);
2962
-									$this->DebugMessage('Scaling watermark by a factor of '.number_format($scale, 4), __FILE__, __LINE__);
2963
-									if (($scale > 1) || ($scale < 1)) {
2964
-										if ($img_watermark2 = phpthumb_functions::ImageCreateFunction($scale * imagesx($img_watermark), $scale * imagesy($img_watermark))) {
2965
-											imagealphablending($img_watermark2, false);
2966
-											imagesavealpha($img_watermark2, true);
2967
-											$this->ImageResizeFunction($img_watermark2, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark2), imagesy($img_watermark2), imagesx($img_watermark), imagesy($img_watermark));
2968
-											$img_watermark = $img_watermark2;
2969
-										} else {
2970
-											$this->DebugMessage('ImageCreateFunction('.($scale * imagesx($img_watermark)).', '.($scale * imagesx($img_watermark)).') failed', __FILE__, __LINE__);
2971
-										}
2972
-									}
2973
-									$watermark_dest_x = round($matches[1] - (imagesx($img_watermark) / 2));
2974
-									$watermark_dest_y = round($matches[2] - (imagesy($img_watermark) / 2));
2975
-									$alignment = $watermark_dest_x.'x'.$watermark_dest_y;
2976
-								}
2977
-								$phpthumbFilters->WatermarkOverlay($this->gdimg_output, $img_watermark, $alignment, $opacity, $margin['x'], $margin['y']);
2978
-								imagedestroy($img_watermark);
2979
-								if (isset($img_watermark2) && is_resource($img_watermark2)) {
2980
-									imagedestroy($img_watermark2);
2981
-								}
2982
-							} else {
2983
-								$this->DebugMessage('ImageCreateFromFilename() failed for "'.$filename.'"', __FILE__, __LINE__);
2984
-							}
2985
-						} else {
2986
-							$this->DebugMessage('!is_readable('.$filename.')', __FILE__, __LINE__);
2987
-						}
2988
-						break;
2989
-
2990
-					case 'wmt': // WaterMarkText
2991
-						@list($text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle, $bg_color, $bg_opacity, $fillextend, $lineheight) = explode('|', $parameter, 12);
2992
-						$text       = ($text            ? $text       : '');
2993
-						$size       = ($size            ? $size       : 3);
2994
-						$alignment  = ($alignment       ? $alignment  : 'BR');
2995
-						$hex_color  = ($hex_color       ? $hex_color  : '000000');
2996
-						$ttffont    = ($ttffont         ? $ttffont    : '');
2997
-						$opacity    = (strlen($opacity) ? $opacity    : 50);
2998
-						$margin     = (strlen($margin)  ? $margin     : 5);
2999
-						$angle      = (strlen($angle)   ? $angle      : 0);
3000
-						$bg_color   = ($bg_color        ? $bg_color   : false);
3001
-						$bg_opacity = ($bg_opacity      ? $bg_opacity : 0);
3002
-						$fillextend = ($fillextend      ? $fillextend : '');
3003
-						$lineheight = ($lineheight      ? $lineheight : 1.0);
3004
-
3005
-						if (basename($ttffont) == $ttffont) {
3006
-							$ttffont = $this->realPathSafe($this->config_ttf_directory.DIRECTORY_SEPARATOR.$ttffont);
3007
-						} else {
3008
-							$ttffont = $this->ResolveFilenameToAbsolute($ttffont);
3009
-						}
3010
-						$phpthumbFilters->WatermarkText($this->gdimg_output, $text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle, $bg_color, $bg_opacity, $fillextend, $lineheight);
3011
-						break;
3012
-
3013
-					case 'blur': // Blur
3014
-						@list($radius) = explode('|', $parameter, 1);
3015
-						$radius = ($radius ? $radius : 1);
3016
-						if (phpthumb_functions::gd_version() >= 2) {
3017
-							$phpthumbFilters->Blur($this->gdimg_output, $radius);
3018
-						} else {
3019
-							$this->DebugMessage('Skipping Blur() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
3020
-						}
3021
-						break;
3022
-
3023
-					case 'gblr': // Gaussian Blur
3024
-						$phpthumbFilters->BlurGaussian($this->gdimg_output);
3025
-						break;
3026
-
3027
-					case 'sblr': // Selective Blur
3028
-						$phpthumbFilters->BlurSelective($this->gdimg_output);
3029
-						break;
3030
-
3031
-					case 'mean': // MeanRemoval blur
3032
-						$phpthumbFilters->MeanRemoval($this->gdimg_output);
3033
-						break;
3034
-
3035
-					case 'smth': // Smooth blur
3036
-						$phpthumbFilters->Smooth($this->gdimg_output, $parameter);
3037
-						break;
3038
-
3039
-					case 'usm': // UnSharpMask sharpening
3040
-						@list($amount, $radius, $threshold) = explode('|', $parameter, 3);
3041
-						$amount    = ($amount            ? $amount    : 80);
3042
-						$radius    = ($radius            ? $radius    : 0.5);
3043
-						$threshold = (strlen($threshold) ? $threshold : 3);
3044
-						if (phpthumb_functions::gd_version() >= 2.0) {
3045
-							ob_start();
3046
-							if (!@include_once( __DIR__ .'/phpthumb.unsharp.php')) {
3047
-								$include_error = ob_get_contents();
3048
-								if ($include_error) {
3049
-									$this->DebugMessage('include_once("'. __DIR__ .'/phpthumb.unsharp.php") generated message: "'.$include_error.'"', __FILE__, __LINE__);
3050
-								}
3051
-								$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.unsharp.php" which is required for unsharp masking', __FILE__, __LINE__);
3052
-								ob_end_clean();
3053
-								return false;
3054
-							}
3055
-							ob_end_clean();
3056
-							phpUnsharpMask::applyUnsharpMask($this->gdimg_output, $amount, $radius, $threshold);
3057
-						} else {
3058
-							$this->DebugMessage('Skipping unsharp mask because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
3059
-							return false;
3060
-						}
3061
-						break;
3062
-
3063
-					case 'size': // Resize
3064
-						@list($newwidth, $newheight, $stretch) = explode('|', $parameter);
3065
-						$newwidth  = (!$newwidth  ? imagesx($this->gdimg_output) : ((($newwidth  > 0) && ($newwidth  < 1)) ? round($newwidth  * imagesx($this->gdimg_output)) : round($newwidth)));
3066
-						$newheight = (!$newheight ? imagesy($this->gdimg_output) : ((($newheight > 0) && ($newheight < 1)) ? round($newheight * imagesy($this->gdimg_output)) : round($newheight)));
3067
-						$stretch   = ($stretch ? true : false);
3068
-						if ($stretch) {
3069
-							$scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesx($this->gdimg_output), $newwidth,  $newwidth,  true, true);
3070
-							$scale_y = phpthumb_functions::ScaleToFitInBox(imagesy($this->gdimg_output), imagesy($this->gdimg_output), $newheight, $newheight, true, true);
3071
-						} else {
3072
-							$scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesy($this->gdimg_output), $newwidth, $newheight, true, true);
3073
-							$scale_y = $scale_x;
3074
-						}
3075
-						$this->DebugMessage('Scaling watermark ('.($stretch ? 'with' : 'without').' stretch) by a factor of "'.number_format($scale_x, 4).' x '.number_format($scale_y, 4).'"', __FILE__, __LINE__);
3076
-						if (($scale_x > 1) || ($scale_x < 1) || ($scale_y > 1) || ($scale_y < 1)) {
3077
-							if ($img_temp = phpthumb_functions::ImageCreateFunction(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) {
3078
-								imagecopy($img_temp, $this->gdimg_output, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output));
3079
-								if ($this->gdimg_output = phpthumb_functions::ImageCreateFunction($scale_x * imagesx($img_temp), $scale_y * imagesy($img_temp))) {
3080
-									imagealphablending($this->gdimg_output, false);
3081
-									imagesavealpha($this->gdimg_output, true);
3082
-									$this->ImageResizeFunction($this->gdimg_output, $img_temp, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output), imagesx($img_temp), imagesy($img_temp));
3083
-								} else {
3084
-									$this->DebugMessage('ImageCreateFunction('.($scale_x * imagesx($img_temp)).', '.($scale_y * imagesy($img_temp)).') failed', __FILE__, __LINE__);
3085
-								}
3086
-								imagedestroy($img_temp);
3087
-							} else {
3088
-								$this->DebugMessage('ImageCreateFunction('.imagesx($this->gdimg_output).', '.imagesy($this->gdimg_output).') failed', __FILE__, __LINE__);
3089
-							}
3090
-						}
3091
-						break;
3092
-
3093
-					case 'rot': // ROTate
3094
-						@list($angle, $bgcolor) = explode('|', $parameter, 2);
3095
-						$phpthumbFilters->ImprovedImageRotate($this->gdimg_output, $angle, $bgcolor, null, $this);
3096
-						break;
3097
-
3098
-					case 'stc': // Source Transparent Color
3099
-						@list($hexcolor, $min_limit, $max_limit) = explode('|', $parameter, 3);
3100
-						if (!phpthumb_functions::IsHexColor($hexcolor)) {
3101
-							$this->DebugMessage('Skipping SourceTransparentColor hex color is invalid ('.$hexcolor.')', __FILE__, __LINE__);
3102
-							return false;
3103
-						}
3104
-						$min_limit = (strlen($min_limit) ? $min_limit :  5);
3105
-						$max_limit = (strlen($max_limit) ? $max_limit : 10);
3106
-						if ($gdimg_mask = $phpthumbFilters->SourceTransparentColorMask($this->gdimg_output, $hexcolor, $min_limit, $max_limit)) {
3107
-							$this->is_alpha = true;
3108
-							$phpthumbFilters->ApplyMask($gdimg_mask, $this->gdimg_output);
3109
-							imagedestroy($gdimg_mask);
3110
-						} else {
3111
-							$this->DebugMessage('SourceTransparentColorMask() failed for "'.$hexcolor.','.$min_limit.','.$max_limit.'"', __FILE__, __LINE__);
3112
-						}
3113
-						break;
3114
-				}
3115
-				$this->DebugMessage('Finished processing filter command "'.$command.'('.$parameter.')"', __FILE__, __LINE__);
3116
-			}
3117
-		}
3118
-		return true;
3119
-	}
3120
-
3121
-
3122
-	public function MaxFileSize() {
3123
-		if (phpthumb_functions::gd_version() < 2) {
3124
-			$this->DebugMessage('Skipping MaxFileSize() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
3125
-			return false;
3126
-		}
3127
-		if ($this->maxb > 0) {
3128
-			switch ($this->thumbnailFormat) {
3129
-				case 'png':
3130
-				case 'gif':
3131
-					$imgRenderFunction = 'image'.$this->thumbnailFormat;
3132
-
3133
-					ob_start();
3134
-					$imgRenderFunction($this->gdimg_output);
3135
-					$imgdata = ob_get_contents();
3136
-					ob_end_clean();
3137
-
3138
-					if (strlen($imgdata) > $this->maxb) {
3139
-						for ($i = 8; $i >= 1; $i--) {
3140
-							$tempIMG = imagecreatetruecolor(imagesx($this->gdimg_output), imagesy($this->gdimg_output));
3141
-							imagecopy($tempIMG, $this->gdimg_output, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output));
3142
-							imagetruecolortopalette($tempIMG, true, pow(2, $i));
3143
-							ob_start();
3144
-							$imgRenderFunction($tempIMG);
3145
-							$imgdata = ob_get_contents();
3146
-							ob_end_clean();
3147
-
3148
-							if (strlen($imgdata) <= $this->maxb) {
3149
-								imagetruecolortopalette($this->gdimg_output, true, pow(2, $i));
3150
-								break;
3151
-							}
3152
-						}
3153
-					}
3154
-					break;
3155
-
3156
-				case 'jpeg':
3157
-					ob_start();
3158
-					imagejpeg($this->gdimg_output);
3159
-					$imgdata = ob_get_contents();
3160
-					ob_end_clean();
3161
-
3162
-					if (strlen($imgdata) > $this->maxb) {
3163
-						for ($i = 3; $i < 20; $i++) {
3164
-							$q = round(100 * (1 - log10($i / 2)));
3165
-							ob_start();
3166
-							imagejpeg($this->gdimg_output, null, $q);
3167
-							$imgdata = ob_get_contents();
3168
-							ob_end_clean();
3169
-
3170
-							$this->thumbnailQuality = $q;
3171
-							if (strlen($imgdata) <= $this->maxb) {
3172
-								break;
3173
-							}
3174
-						}
3175
-					}
3176
-					if (strlen($imgdata) > $this->maxb) {
3177
-						return false;
3178
-					}
3179
-					break;
3180
-
3181
-				default:
3182
-					return false;
3183
-			}
3184
-		}
3185
-		return true;
3186
-	}
3187
-
3188
-
3189
-	public function CalculateThumbnailDimensions() {
3190
-		$this->DebugMessage('CalculateThumbnailDimensions() starting with [W,H,sx,sy,sw,sh] initially set to ['.$this->source_width.','.$this->source_height.','.$this->sx.','.$this->sy.','.$this->sw.','.$this->sh.']', __FILE__, __LINE__);
1810
+                                    $commandline .= ' -repage';
1811
+                                } else {
1812
+                                    $this->DebugMessage('Skipping "-repage" because ImageMagick (v'.$this->ImageMagickVersion().') does not support it', __FILE__, __LINE__);
1813
+                                }
1814
+                                if ($IMuseExplicitImageOutputDimensions) {
1815
+                                    if ($this->w && !$this->h) {
1816
+                                        $this->h = ceil($this->w / ($this->source_width / $this->source_height));
1817
+                                    } elseif ($this->h && !$this->w) {
1818
+                                        $this->w = ceil($this->h * ($this->source_width / $this->source_height));
1819
+                                    }
1820
+                                }
1821
+                                $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($this->w.'x'.$this->h);
1822
+                            }
1823
+
1824
+                        } else {
1825
+
1826
+                            if ($this->iar && ((int) $this->w > 0) && ((int) $this->h > 0)) {
1827
+
1828
+                                list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra);
1829
+                                $nw = ((round($nw) != 0) ? round($nw) : '');
1830
+                                $nh = ((round($nh) != 0) ? round($nh) : '');
1831
+                                $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($nw.'x'.$nh.'!');
1832
+
1833
+                            } elseif ($this->far && ((int) $this->w > 0) && ((int) $this->h > 0)) {
1834
+
1835
+                                $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(phpthumb_functions::nonempty_min($this->w, $getimagesize[0]).'x'.phpthumb_functions::nonempty_min($this->h, $getimagesize[1]));
1836
+                                $commandline .= ' -gravity center';
1837
+                                $commandline .= ' -background '.phpthumb_functions::escapeshellarg_replacement('#'.$this->bg);
1838
+                                $commandline .= ' -extent '.phpthumb_functions::escapeshellarg_replacement($this->w.'x'.$this->h);
1839
+
1840
+                            } else {
1841
+
1842
+                                $this->w = (($this->aoe && $this->w) ? $this->w : ($this->w ? phpthumb_functions::nonempty_min($this->w, $getimagesize[0]) : ''));
1843
+                                $this->h = (($this->aoe && $this->h) ? $this->h : ($this->h ? phpthumb_functions::nonempty_min($this->h, $getimagesize[1]) : ''));
1844
+                                if ($this->w || $this->h) {
1845
+                                    if ($IMuseExplicitImageOutputDimensions) {
1846
+                                        if ($this->w && !$this->h) {
1847
+                                            $this->h = ceil($this->w / ($this->source_width / $this->source_height));
1848
+                                        } elseif ($this->h && !$this->w) {
1849
+                                            $this->w = ceil($this->h * ($this->source_width / $this->source_height));
1850
+                                        }
1851
+                                    }
1852
+                                    list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra);
1853
+                                    $nw = ((round($nw) != 0) ? round($nw) : '');
1854
+                                    $nh = ((round($nh) != 0) ? round($nh) : '');
1855
+                                    $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($nw.'x'.$nh);
1856
+                                }
1857
+
1858
+                            }
1859
+                        }
1860
+                    }
1861
+
1862
+                } else {
1863
+
1864
+                    $this->DebugMessage('getimagesize('.$this->sourceFilename.') failed', __FILE__, __LINE__);
1865
+                    if ($this->w || $this->h) {
1866
+                        $exactDimensionsBang = (($this->iar && ((int) $this->w > 0) && ((int) $this->h > 0)) ? '!' : '');
1867
+                        if ($IMuseExplicitImageOutputDimensions) {
1868
+                            // unknown source aspect ratio, just put large number and hope IM figures it out
1869
+                            $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(($this->w ? $this->w : '9999').'x'.($this->h ? $this->h : '9999').$exactDimensionsBang);
1870
+                        } else {
1871
+                            $commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($this->w.'x'.$this->h.$exactDimensionsBang);
1872
+                        }
1873
+                    }
1874
+
1875
+                }
1876
+
1877
+                if ($this->ra) {
1878
+                    $this->ra = (int) $this->ra;
1879
+                    if ($this->ImageMagickSwitchAvailable('rotate')) {
1880
+                        if (!preg_match('#('.implode('|', $this->AlphaCapableFormats).')#i', $outputFormat) || phpthumb_functions::version_compare_replacement($this->ImageMagickVersion(), '6.3.7', '>=')) {
1881
+                            $this->DebugMessage('Using ImageMagick rotate', __FILE__, __LINE__);
1882
+                            $commandline .= ' -rotate '.phpthumb_functions::escapeshellarg_replacement($this->ra);
1883
+                            if (($this->ra % 90) != 0) {
1884
+                                if (preg_match('#('.implode('|', $this->AlphaCapableFormats).')#i', $outputFormat)) {
1885
+                                    // alpha-capable format
1886
+                                    $commandline .= ' -background rgba(255,255,255,0)';
1887
+                                } else {
1888
+                                    $commandline .= ' -background '.phpthumb_functions::escapeshellarg_replacement('#'.($this->bg ? $this->bg : 'FFFFFF'));
1889
+                                }
1890
+                            }
1891
+                            $this->ra = 0;
1892
+                        } else {
1893
+                            $this->DebugMessage('Not using ImageMagick rotate because alpha background buggy before v6.3.7', __FILE__, __LINE__);
1894
+                        }
1895
+                    } else {
1896
+                        $this->DebugMessage('Not using ImageMagick rotate because not supported', __FILE__, __LINE__);
1897
+                    }
1898
+                }
1899
+
1900
+                $successfullyProcessedFilters = array();
1901
+                foreach ($this->fltr as $filterkey => $filtercommand) {
1902
+                    @list($command, $parameter) = explode('|', $filtercommand, 2);
1903
+                    switch ($command) {
1904
+                        case 'brit':
1905
+                            if ($this->ImageMagickSwitchAvailable('modulate')) {
1906
+                                $commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement((100 + (int) $parameter).',100,100');
1907
+                                $successfullyProcessedFilters[] = $filterkey;
1908
+                            }
1909
+                            break;
1910
+
1911
+                        case 'cont':
1912
+                            if ($this->ImageMagickSwitchAvailable('contrast')) {
1913
+                                $contDiv10 = round((int) $parameter / 10);
1914
+                                if ($contDiv10 > 0) {
1915
+                                    $contDiv10 = min($contDiv10, 100);
1916
+                                    for ($i = 0; $i < $contDiv10; $i++) {
1917
+                                        $commandline .= ' -contrast'; // increase contrast by 10%
1918
+                                    }
1919
+                                } elseif ($contDiv10 < 0) {
1920
+                                    $contDiv10 = max($contDiv10, -100);
1921
+                                    for ($i = $contDiv10; $i < 0; $i++) {
1922
+                                        $commandline .= ' +contrast'; // decrease contrast by 10%
1923
+                                    }
1924
+                                } else {
1925
+                                    // do nothing
1926
+                                }
1927
+                                $successfullyProcessedFilters[] = $filterkey;
1928
+                            }
1929
+                            break;
1930
+
1931
+                        case 'ds':
1932
+                            if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) {
1933
+                                if ($parameter == 100) {
1934
+                                    $commandline .= ' -colorspace GRAY';
1935
+                                    $commandline .= ' -modulate 100,0,100';
1936
+                                } else {
1937
+                                    $commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement('100,'.(100 - (int) $parameter).',100');
1938
+                                }
1939
+                                $successfullyProcessedFilters[] = $filterkey;
1940
+                            }
1941
+                            break;
1942
+
1943
+                        case 'sat':
1944
+                            if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) {
1945
+                                if ($parameter == -100) {
1946
+                                    $commandline .= ' -colorspace GRAY';
1947
+                                    $commandline .= ' -modulate 100,0,100';
1948
+                                } else {
1949
+                                    $commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement('100,'.(100 + (int) $parameter).',100');
1950
+                                }
1951
+                                $successfullyProcessedFilters[] = $filterkey;
1952
+                            }
1953
+                            break;
1954
+
1955
+                        case 'gray':
1956
+                            if ($this->ImageMagickSwitchAvailable(array('colorspace', 'modulate'))) {
1957
+                                $commandline .= ' -colorspace GRAY';
1958
+                                $commandline .= ' -modulate 100,0,100';
1959
+                                $successfullyProcessedFilters[] = $filterkey;
1960
+                            }
1961
+                            break;
1962
+
1963
+                        case 'clr':
1964
+                            if ($this->ImageMagickSwitchAvailable(array('fill', 'colorize'))) {
1965
+                                @list($amount, $color) = explode('|', $parameter);
1966
+                                $commandline .= ' -fill '.phpthumb_functions::escapeshellarg_replacement('#'.preg_replace('#[^0-9A-F]#i', '', $color));
1967
+                                $commandline .= ' -colorize '.phpthumb_functions::escapeshellarg_replacement(min(max((int) $amount, 0), 100));
1968
+                            }
1969
+                            break;
1970
+
1971
+                        case 'sep':
1972
+                            if ($this->ImageMagickSwitchAvailable('sepia-tone')) {
1973
+                                @list($amount, $color) = explode('|', $parameter);
1974
+                                $amount = ($amount ? $amount : 80);
1975
+                                if (!$color) {
1976
+                                    $commandline .= ' -sepia-tone '.phpthumb_functions::escapeshellarg_replacement(min(max((int) $amount, 0), 100).'%');
1977
+                                    $successfullyProcessedFilters[] = $filterkey;
1978
+                                }
1979
+                            }
1980
+                            break;
1981
+
1982
+                        case 'gam':
1983
+                            @list($amount) = explode('|', $parameter);
1984
+                            $amount = min(max((float) $amount, 0.001), 10);
1985
+                            if (number_format($amount, 3) != '1.000') {
1986
+                                if ($this->ImageMagickSwitchAvailable('gamma')) {
1987
+                                    $commandline .= ' -gamma '.phpthumb_functions::escapeshellarg_replacement($amount);
1988
+                                    $successfullyProcessedFilters[] = $filterkey;
1989
+                                }
1990
+                            }
1991
+                            break;
1992
+
1993
+                        case 'neg':
1994
+                            if ($this->ImageMagickSwitchAvailable('negate')) {
1995
+                                $commandline .= ' -negate';
1996
+                                $successfullyProcessedFilters[] = $filterkey;
1997
+                            }
1998
+                            break;
1999
+
2000
+                        case 'th':
2001
+                            @list($amount) = explode('|', $parameter);
2002
+                            if ($this->ImageMagickSwitchAvailable(array('threshold', 'dither', 'monochrome'))) {
2003
+                                $commandline .= ' -threshold '.phpthumb_functions::escapeshellarg_replacement(round(min(max((int) $amount, 0), 255) / 2.55).'%');
2004
+                                $commandline .= ' -dither';
2005
+                                $commandline .= ' -monochrome';
2006
+                                $successfullyProcessedFilters[] = $filterkey;
2007
+                            }
2008
+                            break;
2009
+
2010
+                        case 'rcd':
2011
+                            if ($this->ImageMagickSwitchAvailable(array('colors', 'dither'))) {
2012
+                                @list($colors, $dither) = explode('|', $parameter);
2013
+                                $colors = ($colors                ?  (int) $colors : 256);
2014
+                                $dither  = ((strlen($dither) > 0) ? (bool) $dither : true);
2015
+                                $commandline .= ' -colors '.phpthumb_functions::escapeshellarg_replacement(max($colors, 8)); // ImageMagick will otherwise fail with "cannot quantize to fewer than 8 colors"
2016
+                                $commandline .= ($dither ? ' -dither' : ' +dither');
2017
+                                $successfullyProcessedFilters[] = $filterkey;
2018
+                            }
2019
+                            break;
2020
+
2021
+                        case 'flip':
2022
+                            if ($this->ImageMagickSwitchAvailable(array('flip', 'flop'))) {
2023
+                                if (strpos(strtolower($parameter), 'x') !== false) {
2024
+                                    $commandline .= ' -flop';
2025
+                                }
2026
+                                if (strpos(strtolower($parameter), 'y') !== false) {
2027
+                                    $commandline .= ' -flip';
2028
+                                }
2029
+                                $successfullyProcessedFilters[] = $filterkey;
2030
+                            }
2031
+                            break;
2032
+
2033
+                        case 'edge':
2034
+                            if ($this->ImageMagickSwitchAvailable('edge')) {
2035
+                                $parameter = (!empty($parameter) ? $parameter : 2);
2036
+                                $commandline .= ' -edge '.phpthumb_functions::escapeshellarg_replacement(!empty($parameter) ? (int) $parameter : 1);
2037
+                                $successfullyProcessedFilters[] = $filterkey;
2038
+                            }
2039
+                            break;
2040
+
2041
+                        case 'emb':
2042
+                            if ($this->ImageMagickSwitchAvailable(array('emboss', 'negate'))) {
2043
+                                $parameter = (!empty($parameter) ? $parameter : 2);
2044
+                                $commandline .= ' -emboss '.phpthumb_functions::escapeshellarg_replacement((int) $parameter);
2045
+                                if ($parameter < 2) {
2046
+                                    $commandline .= ' -negate'; // ImageMagick negates the image for some reason with '-emboss 1';
2047
+                                }
2048
+                                $successfullyProcessedFilters[] = $filterkey;
2049
+                            }
2050
+                            break;
2051
+
2052
+                        case 'lvl':
2053
+                            @list($band, $method, $threshold) = explode('|', $parameter);
2054
+                            $band      = ($band ? preg_replace('#[^RGBA\\*]#', '', strtoupper($band))       : '*');
2055
+                            $method    = ((strlen($method) > 0)    ? (int) $method :   2);
2056
+                            $threshold = ((strlen($threshold) > 0) ? min(max((float) $threshold, 0), 100) : 0.1);
2057
+
2058
+                            $band = preg_replace('#[^RGBA\\*]#', '', strtoupper($band));
2059
+
2060
+                            if (($method > 1) && !$this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) {
2061
+                                // Because ImageMagick processing happens before PHP-GD filters, and because some
2062
+                                // clipping is involved in the "lvl" filter, if "lvl" happens before "wb" then the
2063
+                                // "wb" filter will have (almost) no effect. Therefore, if "wb" is enabled then
2064
+                                // force the "lvl" filter to be processed by GD, not ImageMagick.
2065
+                                foreach ($this->fltr as $fltr_key => $fltr_value) {
2066
+                                    list($fltr_cmd) = explode('|', $fltr_value);
2067
+                                    if ($fltr_cmd == 'wb') {
2068
+                                        $this->DebugMessage('Setting "lvl" filter method to "0" (from "'.$method.'") because white-balance filter also enabled', __FILE__, __LINE__);
2069
+                                        $method = 0;
2070
+                                    }
2071
+                                }
2072
+                            }
2073
+
2074
+                            switch ($method) {
2075
+                                case 0: // internal RGB
2076
+                                case 1: // internal grayscale
2077
+                                    break;
2078
+                                case 2: // ImageMagick "contrast-stretch"
2079
+                                    if ($this->ImageMagickSwitchAvailable('contrast-stretch')) {
2080
+                                        if ($band != '*') {
2081
+                                            $commandline .= ' -channel '.phpthumb_functions::escapeshellarg_replacement(strtoupper($band));
2082
+                                        }
2083
+                                        $threshold = preg_replace('#[^0-9\\.]#', '', $threshold); // should be unneccesary, but just to be double-sure
2084
+                                        //$commandline .= ' -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%');
2085
+                                        $commandline .= ' -contrast-stretch \''.$threshold.'%\'';
2086
+                                        if ($band != '*') {
2087
+                                            $commandline .= ' +channel';
2088
+                                        }
2089
+                                        $successfullyProcessedFilters[] = $filterkey;
2090
+                                    }
2091
+                                    break;
2092
+                                case 3: // ImageMagick "normalize"
2093
+                                    if ($this->ImageMagickSwitchAvailable('normalize')) {
2094
+                                        if ($band != '*') {
2095
+                                            $commandline .= ' -channel '.phpthumb_functions::escapeshellarg_replacement(strtoupper($band));
2096
+                                        }
2097
+                                        $commandline .= ' -normalize';
2098
+                                        if ($band != '*') {
2099
+                                            $commandline .= ' +channel';
2100
+                                        }
2101
+                                        $successfullyProcessedFilters[] = $filterkey;
2102
+                                    }
2103
+                                    break;
2104
+                                default:
2105
+                                    $this->DebugMessage('unsupported method ('.$method.') for "lvl" filter', __FILE__, __LINE__);
2106
+                                    break;
2107
+                            }
2108
+                            if (isset($this->fltr[$filterkey]) && ($method > 1)) {
2109
+                                $this->fltr[$filterkey] = $command.'|'.$band.'|0|'.$threshold;
2110
+                                $this->DebugMessage('filter "lvl" remapped from method "'.$method.'" to method "0" because ImageMagick support is missing', __FILE__, __LINE__);
2111
+                            }
2112
+                            break;
2113
+
2114
+                        case 'wb':
2115
+                            if ($this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) {
2116
+                                @list($threshold) = explode('|', $parameter);
2117
+                                $threshold = (!empty($threshold) ? min(max((float) $threshold, 0), 100) : 0.1);
2118
+                                $threshold = preg_replace('#[^0-9\\.]#', '', $threshold); // should be unneccesary, but just to be double-sure
2119
+                                //$commandline .= ' -channel R -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // doesn't work on Windows because most versions of PHP do not properly
2120
+                                //$commandline .= ' -channel G -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // escape special characters (such as %) and just replace them with spaces
2121
+                                //$commandline .= ' -channel B -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // https://bugs.php.net/bug.php?id=43261
2122
+                                $commandline .= ' -channel R -contrast-stretch \''.$threshold.'%\'';
2123
+                                $commandline .= ' -channel G -contrast-stretch \''.$threshold.'%\'';
2124
+                                $commandline .= ' -channel B -contrast-stretch \''.$threshold.'%\'';
2125
+                                $commandline .= ' +channel';
2126
+                                $successfullyProcessedFilters[] = $filterkey;
2127
+                            }
2128
+                            break;
2129
+
2130
+                        case 'blur':
2131
+                            if ($this->ImageMagickSwitchAvailable('blur')) {
2132
+                                @list($radius) = explode('|', $parameter);
2133
+                                $radius = (!empty($radius) ? min(max((int) $radius, 0), 25) : 1);
2134
+                                $commandline .= ' -blur '.phpthumb_functions::escapeshellarg_replacement($radius);
2135
+                                $successfullyProcessedFilters[] = $filterkey;
2136
+                            }
2137
+                            break;
2138
+
2139
+                        case 'gblr':
2140
+                            @list($radius) = explode('|', $parameter);
2141
+                            $radius = (!empty($radius) ? min(max((int) $radius, 0), 25) : 1);
2142
+                            // "-gaussian" changed to "-gaussian-blur" sometime around 2009
2143
+                            if ($this->ImageMagickSwitchAvailable('gaussian-blur')) {
2144
+                                $commandline .= ' -gaussian-blur '.phpthumb_functions::escapeshellarg_replacement($radius);
2145
+                                $successfullyProcessedFilters[] = $filterkey;
2146
+                            } elseif ($this->ImageMagickSwitchAvailable('gaussian')) {
2147
+                                $commandline .= ' -gaussian '.phpthumb_functions::escapeshellarg_replacement($radius);
2148
+                                $successfullyProcessedFilters[] = $filterkey;
2149
+                            }
2150
+                            break;
2151
+
2152
+                        case 'usm':
2153
+                            if ($this->ImageMagickSwitchAvailable('unsharp')) {
2154
+                                @list($amount, $radius, $threshold) = explode('|', $parameter);
2155
+                                $amount    = ($amount            ? min(max((int) $amount,    0), 255) : 80);
2156
+                                $radius    = ($radius            ? min(max((int) $radius,    0),  10) : 0.5);
2157
+                                $threshold = (strlen($threshold) ? min(max((int) $threshold, 0),  50) : 3);
2158
+                                $commandline .= ' -unsharp '.phpthumb_functions::escapeshellarg_replacement(number_format(($radius * 2) - 1, 2, '.', '').'x1+'.number_format($amount / 100, 2, '.', '').'+'.number_format($threshold / 100, 2, '.', ''));
2159
+                                $successfullyProcessedFilters[] = $filterkey;
2160
+                            }
2161
+                            break;
2162
+
2163
+                        case 'bord':
2164
+                            if ($this->ImageMagickSwitchAvailable(array('border', 'bordercolor', 'thumbnail', 'crop'))) {
2165
+                                if (!$this->zc) {
2166
+                                    @list($width, $rX, $rY, $color) = explode('|', $parameter);
2167
+                                    $width = (int) $width;
2168
+                                    $rX    = (int) $rX;
2169
+                                    $rY    = (int) $rY;
2170
+                                    if ($width && !$rX && !$rY) {
2171
+                                        if (!phpthumb_functions::IsHexColor($color)) {
2172
+                                            $color = ((!empty($this->bc) && phpthumb_functions::IsHexColor($this->bc)) ? $this->bc : '000000');
2173
+                                        }
2174
+                                        $commandline .= ' -border '.phpthumb_functions::escapeshellarg_replacement((int) $width);
2175
+                                        $commandline .= ' -bordercolor '.phpthumb_functions::escapeshellarg_replacement('#'.$color);
2176
+
2177
+                                        if (preg_match('# \\-crop "([0-9]+)x([0-9]+)\\+0\\+0" #', $commandline, $matches)) {
2178
+                                            $commandline = str_replace(' -crop "'.$matches[1].'x'.$matches[2].'+0+0" ', ' -crop '.phpthumb_functions::escapeshellarg_replacement(($matches[1] - (2 * $width)).'x'.($matches[2] - (2 * $width)).'+0+0').' ', $commandline);
2179
+                                        } elseif (preg_match('# \\-'.$IMresizeParameter.' "([0-9]+)x([0-9]+)" #', $commandline, $matches)) {
2180
+                                            $commandline = str_replace(' -'.$IMresizeParameter.' "'.$matches[1].'x'.$matches[2].'" ', ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(($matches[1] - (2 * $width)).'x'.($matches[2] - (2 * $width))).' ', $commandline);
2181
+                                        }
2182
+                                        $successfullyProcessedFilters[] = $filterkey;
2183
+                                    }
2184
+                                }
2185
+                            }
2186
+                            break;
2187
+
2188
+                        case 'crop':
2189
+                            break;
2190
+
2191
+                        case 'sblr':
2192
+                            break;
2193
+
2194
+                        case 'mean':
2195
+                            break;
2196
+
2197
+                        case 'smth':
2198
+                            break;
2199
+
2200
+                        case 'bvl':
2201
+                            break;
2202
+
2203
+                        case 'wmi':
2204
+                            break;
2205
+
2206
+                        case 'wmt':
2207
+                            break;
2208
+
2209
+                        case 'over':
2210
+                            break;
2211
+
2212
+                        case 'hist':
2213
+                            break;
2214
+
2215
+                        case 'fram':
2216
+                            break;
2217
+
2218
+                        case 'drop':
2219
+                            break;
2220
+
2221
+                        case 'mask':
2222
+                            break;
2223
+
2224
+                        case 'elip':
2225
+                            break;
2226
+
2227
+                        case 'ric':
2228
+                            break;
2229
+
2230
+                        case 'stc':
2231
+                            break;
2232
+
2233
+                        case 'size':
2234
+                            break;
2235
+
2236
+                        default:
2237
+                            $this->DebugMessage('Unknown $this->fltr['.$filterkey.'] ('.$filtercommand.') -- deleting filter command', __FILE__, __LINE__);
2238
+                            $successfullyProcessedFilters[] = $filterkey;
2239
+                            break;
2240
+                    }
2241
+                    if (!isset($this->fltr[$filterkey])) {
2242
+                        $this->DebugMessage('Processed $this->fltr['.$filterkey.'] ('.$filtercommand.') with ImageMagick', __FILE__, __LINE__);
2243
+                    } else {
2244
+                        $this->DebugMessage('Skipping $this->fltr['.$filterkey.'] ('.$filtercommand.') with ImageMagick', __FILE__, __LINE__);
2245
+                    }
2246
+                }
2247
+                $this->DebugMessage('Remaining $this->fltr after ImageMagick: ('.$this->phpThumbDebugVarDump($this->fltr).')', __FILE__, __LINE__);
2248
+                if (count($this->fltr) > 0) {
2249
+                    $this->useRawIMoutput = false;
2250
+                }
2251
+
2252
+                if (preg_match('#jpe?g#i', $outputFormat) && $this->q) {
2253
+                    if ($this->ImageMagickSwitchAvailable(array('quality', 'interlace'))) {
2254
+                        $commandline .= ' -quality '.phpthumb_functions::escapeshellarg_replacement($this->thumbnailQuality);
2255
+                        if ($this->config_output_interlace) {
2256
+                            // causes weird things with animated GIF... leave for JPEG only
2257
+                            $commandline .= ' -interlace line '; // Use Line or Plane to create an interlaced PNG or GIF or progressive JPEG image
2258
+                        }
2259
+                    }
2260
+                }
2261
+                $commandline .= ' '.$outputFormat.':'.phpthumb_functions::escapeshellarg_replacement($IMtempfilename);
2262
+                if (!$this->iswindows) {
2263
+                    $commandline .= ' 2>&1';
2264
+                }
2265
+                $this->DebugMessage('ImageMagick called as ('.$commandline.')', __FILE__, __LINE__);
2266
+                $IMresult = phpthumb_functions::SafeExec($commandline);
2267
+                clearstatcache();
2268
+                if (!@file_exists($IMtempfilename) || !@filesize($IMtempfilename)) {
2269
+                    $this->FatalError('ImageMagick failed with message ('.trim($IMresult).')');
2270
+                    $this->DebugMessage('ImageMagick failed with message ('.trim($IMresult).')', __FILE__, __LINE__);
2271
+                    if ($this->iswindows && !$IMresult) {
2272
+                        $this->DebugMessage('Check to make sure that PHP has read+write permissions to "'.dirname($IMtempfilename).'"', __FILE__, __LINE__);
2273
+                    }
2274
+
2275
+                } else {
2276
+
2277
+                    foreach ($successfullyProcessedFilters as $dummy => $filterkey) {
2278
+                        unset($this->fltr[$filterkey]);
2279
+                    }
2280
+                    $this->IMresizedData = file_get_contents($IMtempfilename);
2281
+                    $getimagesize_imresized = @getimagesize($IMtempfilename);
2282
+                    $this->DebugMessage('getimagesize('.$IMtempfilename.') returned [w='.$getimagesize_imresized[0].';h='.$getimagesize_imresized[1].';f='.$getimagesize_imresized[2].']', __FILE__, __LINE__);
2283
+                    if (($this->config_max_source_pixels > 0) && (($getimagesize_imresized[0] * $getimagesize_imresized[1]) > $this->config_max_source_pixels)) {
2284
+                        $this->DebugMessage('skipping ImageMagickThumbnailToGD::'.$ImageCreateFunction.'() because IM output is too large ('.$getimagesize_imresized[0].'x'.$getimagesize_imresized[0].' = '.($getimagesize_imresized[0] * $getimagesize_imresized[1]).' > '.$this->config_max_source_pixels.')', __FILE__, __LINE__);
2285
+                    } elseif (function_exists(@$ImageCreateFunction) && ($this->gdimg_source = @$ImageCreateFunction($IMtempfilename))) {
2286
+                        $this->source_width  = imagesx($this->gdimg_source);
2287
+                        $this->source_height = imagesy($this->gdimg_source);
2288
+                        $this->DebugMessage('ImageMagickThumbnailToGD::'.$ImageCreateFunction.'() succeeded, $this->gdimg_source is now ('.$this->source_width.'x'.$this->source_height.')', __FILE__, __LINE__);
2289
+                        $this->DebugMessage('ImageMagickThumbnailToGD() returning $this->IMresizedData ('.strlen($this->IMresizedData).' bytes)', __FILE__, __LINE__);
2290
+                    } else {
2291
+                        $this->useRawIMoutput = true;
2292
+                        $this->DebugMessage('$this->useRawIMoutput set to TRUE because '.@$ImageCreateFunction.'('.$IMtempfilename.') failed', __FILE__, __LINE__);
2293
+                    }
2294
+                    if (file_exists($IMtempfilename)) {
2295
+                        $this->DebugMessage('deleting "'.$IMtempfilename.'"', __FILE__, __LINE__);
2296
+                        @unlink($IMtempfilename);
2297
+                    }
2298
+                    return true;
2299
+
2300
+                }
2301
+                if (file_exists($IMtempfilename)) {
2302
+                    $this->DebugMessage('deleting "'.$IMtempfilename.'"', __FILE__, __LINE__);
2303
+                    @unlink($IMtempfilename);
2304
+                }
2305
+
2306
+            } elseif ($this->issafemode) {
2307
+                $this->DebugMessage('ImageMagickThumbnailToGD() aborting because PHP safe_mode is enabled and phpThumb_tempnam() failed', __FILE__, __LINE__);
2308
+                $this->useRawIMoutput = false;
2309
+            } else {
2310
+                if (file_exists($IMtempfilename)) {
2311
+                    $this->DebugMessage('deleting "'.$IMtempfilename.'"', __FILE__, __LINE__);
2312
+                    @unlink($IMtempfilename);
2313
+                }
2314
+                $this->DebugMessage('ImageMagickThumbnailToGD() aborting, phpThumb_tempnam() failed', __FILE__, __LINE__);
2315
+            }
2316
+        } else {
2317
+            $this->DebugMessage('ImageMagickThumbnailToGD() aborting because ImageMagickCommandlineBase() failed', __FILE__, __LINE__);
2318
+        }
2319
+        $this->useRawIMoutput = false;
2320
+        return false;
2321
+    }
2322
+
2323
+
2324
+    public function Rotate() {
2325
+        if ($this->ra || $this->ar) {
2326
+            if (!function_exists('imagerotate')) {
2327
+                $this->DebugMessage('!function_exists(imagerotate)', __FILE__, __LINE__);
2328
+                return false;
2329
+            }
2330
+            if (!include_once( __DIR__ .'/phpthumb.filters.php')) {
2331
+                $this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
2332
+                return false;
2333
+            }
2334
+
2335
+            $this->config_background_hexcolor = ($this->bg ? $this->bg : $this->config_background_hexcolor);
2336
+            if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
2337
+                return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
2338
+            }
2339
+
2340
+            $rotate_angle = 0;
2341
+            if ($this->ra) {
2342
+
2343
+                $rotate_angle = (float) $this->ra;
2344
+
2345
+            } else {
2346
+
2347
+                if ($this->ar == 'x') {
2348
+                    if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.2.0', '>=')) {
2349
+                        if ($this->sourceFilename) {
2350
+                            if (function_exists('exif_read_data')) {
2351
+                                if ($exif_data = @exif_read_data($this->sourceFilename, 'IFD0')) {
2352
+                                    // http://sylvana.net/jpegcrop/exif_orientation.html
2353
+                                    switch (@$exif_data['Orientation']) {
2354
+                                        case 1:
2355
+                                            $rotate_angle = 0;
2356
+                                            break;
2357
+                                        case 3:
2358
+                                            $rotate_angle = 180;
2359
+                                            break;
2360
+                                        case 6:
2361
+                                            $rotate_angle = 270;
2362
+                                            break;
2363
+                                        case 8:
2364
+                                            $rotate_angle = 90;
2365
+                                            break;
2366
+
2367
+                                        default:
2368
+                                            $this->DebugMessage('EXIF auto-rotate failed because unknown $exif_data[Orientation] "'.@$exif_data['Orientation'].'"', __FILE__, __LINE__);
2369
+                                            return false;
2370
+                                            break;
2371
+                                    }
2372
+                                    $this->DebugMessage('EXIF auto-rotate set to '.$rotate_angle.' degrees ($exif_data[Orientation] = "'.@$exif_data['Orientation'].'")', __FILE__, __LINE__);
2373
+                                } else {
2374
+                                    $this->DebugMessage('failed: exif_read_data('.$this->sourceFilename.')', __FILE__, __LINE__);
2375
+                                    return false;
2376
+                                }
2377
+                            } else {
2378
+                                $this->DebugMessage('!function_exists(exif_read_data)', __FILE__, __LINE__);
2379
+                                return false;
2380
+                            }
2381
+                        } else {
2382
+                            $this->DebugMessage('Cannot auto-rotate from EXIF data because $this->sourceFilename is empty', __FILE__, __LINE__);
2383
+                            return false;
2384
+                        }
2385
+                    } else {
2386
+                        $this->DebugMessage('Cannot auto-rotate from EXIF data because PHP is less than v4.2.0 ('. PHP_VERSION .')', __FILE__, __LINE__);
2387
+                        return false;
2388
+                    }
2389
+                } elseif (($this->ar == 'l') && ($this->source_height > $this->source_width)) {
2390
+                    $rotate_angle = 270;
2391
+                } elseif (($this->ar == 'L') && ($this->source_height > $this->source_width)) {
2392
+                    $rotate_angle = 90;
2393
+                } elseif (($this->ar == 'p') && ($this->source_width > $this->source_height)) {
2394
+                    $rotate_angle = 90;
2395
+                } elseif (($this->ar == 'P') && ($this->source_width > $this->source_height)) {
2396
+                    $rotate_angle = 270;
2397
+                }
2398
+
2399
+            }
2400
+            if ($rotate_angle % 90) {
2401
+                $this->is_alpha = true;
2402
+            }
2403
+            phpthumb_filters::ImprovedImageRotate($this->gdimg_source, $rotate_angle, $this->config_background_hexcolor, $this->bg, $this);
2404
+            $this->source_width  = imagesx($this->gdimg_source);
2405
+            $this->source_height = imagesy($this->gdimg_source);
2406
+        }
2407
+        return true;
2408
+    }
2409
+
2410
+
2411
+    public function FixedAspectRatio() {
2412
+        // optional fixed-dimension images (regardless of aspect ratio)
2413
+
2414
+        if (!$this->far) {
2415
+            // do nothing
2416
+            return true;
2417
+        }
2418
+
2419
+        if (!$this->w || !$this->h) {
2420
+            return false;
2421
+        }
2422
+        $this->thumbnail_width  = $this->w;
2423
+        $this->thumbnail_height = $this->h;
2424
+        $this->is_alpha = true;
2425
+        if ($this->thumbnail_image_width >= $this->thumbnail_width) {
2426
+
2427
+            $aspectratio = $this->thumbnail_image_height / $this->thumbnail_image_width;
2428
+            if ($this->w) {
2429
+                $this->thumbnail_image_height = round($this->thumbnail_image_width * $aspectratio);
2430
+                $this->thumbnail_height = ($this->h ? $this->h : $this->thumbnail_image_height);
2431
+            } elseif ($this->thumbnail_image_height < $this->thumbnail_height) {
2432
+                $this->thumbnail_image_height = $this->thumbnail_height;
2433
+                $this->thumbnail_image_width  = round($this->thumbnail_image_height / $aspectratio);
2434
+            }
2435
+
2436
+        } else {
2437
+
2438
+            $aspectratio = $this->thumbnail_image_width / $this->thumbnail_image_height;
2439
+            if ($this->h) {
2440
+                $this->thumbnail_image_width = round($this->thumbnail_image_height * $aspectratio);
2441
+            } elseif ($this->thumbnail_image_width < $this->thumbnail_width) {
2442
+                $this->thumbnail_image_width = $this->thumbnail_width;
2443
+                $this->thumbnail_image_height  = round($this->thumbnail_image_width / $aspectratio);
2444
+            }
2445
+
2446
+        }
2447
+        return true;
2448
+    }
2449
+
2450
+
2451
+    public function OffsiteDomainIsAllowed($hostname, $allowed_domains) {
2452
+        static $domain_is_allowed = array();
2453
+        $hostname = strtolower($hostname);
2454
+        if (!isset($domain_is_allowed[$hostname])) {
2455
+            $domain_is_allowed[$hostname] = false;
2456
+            foreach ($allowed_domains as $valid_domain) {
2457
+                $starpos = strpos($valid_domain, '*');
2458
+                if ($starpos !== false) {
2459
+                    $valid_domain = substr($valid_domain, $starpos + 1);
2460
+                    if (preg_match('#'.preg_quote($valid_domain).'$#', $hostname)) {
2461
+                        $domain_is_allowed[$hostname] = true;
2462
+                        break;
2463
+                    }
2464
+                } else {
2465
+                    if (strtolower($valid_domain) === $hostname) {
2466
+                        $domain_is_allowed[$hostname] = true;
2467
+                        break;
2468
+                    }
2469
+                }
2470
+            }
2471
+        }
2472
+        return $domain_is_allowed[$hostname];
2473
+    }
2474
+
2475
+
2476
+    public function AntiOffsiteLinking() {
2477
+        // Optional anti-offsite hijacking of the thumbnail script
2478
+        $allow   = true;
2479
+        if ($allow && $this->config_nooffsitelink_enabled && (@$_SERVER['HTTP_REFERER'] || $this->config_nooffsitelink_require_refer)) {
2480
+            $this->DebugMessage('AntiOffsiteLinking() checking $_SERVER[HTTP_REFERER] "'.@$_SERVER['HTTP_REFERER'].'"', __FILE__, __LINE__);
2481
+            foreach ($this->config_nooffsitelink_valid_domains as $key => $valid_domain) {
2482
+                // $_SERVER['HTTP_HOST'] contains the port number, so strip it out here to make default configuration work
2483
+                list($clean_domain) = explode(':', $valid_domain);
2484
+                $this->config_nooffsitelink_valid_domains[$key] = $clean_domain;
2485
+            }
2486
+            $parsed_url = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
2487
+            if (!$this->OffsiteDomainIsAllowed(@$parsed_url['host'], $this->config_nooffsitelink_valid_domains)) {
2488
+                $allow   = false;
2489
+                //$this->DebugMessage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is NOT in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
2490
+                $this->ErrorImage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is NOT in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')');
2491
+            } else {
2492
+                $this->DebugMessage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
2493
+            }
2494
+        }
2495
+
2496
+        if ($allow && $this->config_nohotlink_enabled && preg_match('#^(f|ht)tps?\://#i', $this->src)) {
2497
+            $parsed_url = phpthumb_functions::ParseURLbetter($this->src);
2498
+            //if (!phpthumb_functions::CaseInsensitiveInArray(@$parsed_url['host'], $this->config_nohotlink_valid_domains)) {
2499
+            if (!$this->OffsiteDomainIsAllowed(@$parsed_url['host'], $this->config_nohotlink_valid_domains)) {
2500
+                // This domain is not allowed
2501
+                $allow = false;
2502
+                $this->DebugMessage('AntiOffsiteLinking() - "'.$parsed_url['host'].'" is NOT in $this->config_nohotlink_valid_domains ('.implode(';', $this->config_nohotlink_valid_domains).')', __FILE__, __LINE__);
2503
+            } else {
2504
+                $this->DebugMessage('AntiOffsiteLinking() - "'.$parsed_url['host'].'" is in $this->config_nohotlink_valid_domains ('.implode(';', $this->config_nohotlink_valid_domains).')', __FILE__, __LINE__);
2505
+            }
2506
+        }
2507
+
2508
+        if ($allow) {
2509
+            $this->DebugMessage('AntiOffsiteLinking() says this is allowed', __FILE__, __LINE__);
2510
+            return true;
2511
+        }
2512
+
2513
+        if (!phpthumb_functions::IsHexColor($this->config_error_bgcolor)) {
2514
+            return $this->ErrorImage('Invalid hex color string "'.$this->config_error_bgcolor.'" for $this->config_error_bgcolor');
2515
+        }
2516
+        if (!phpthumb_functions::IsHexColor($this->config_error_textcolor)) {
2517
+            return $this->ErrorImage('Invalid hex color string "'.$this->config_error_textcolor.'" for $this->config_error_textcolor');
2518
+        }
2519
+        if ($this->config_nooffsitelink_erase_image) {
2520
+
2521
+            return $this->ErrorImage($this->config_nooffsitelink_text_message, $this->thumbnail_width, $this->thumbnail_height);
2522
+
2523
+        } else {
2524
+
2525
+            $this->config_nooffsitelink_watermark_src = $this->ResolveFilenameToAbsolute($this->config_nooffsitelink_watermark_src);
2526
+            if (is_file($this->config_nooffsitelink_watermark_src)) {
2527
+
2528
+                if (!include_once( __DIR__ .'/phpthumb.filters.php')) {
2529
+                    $this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.filters.php" which is required for applying watermark', __FILE__, __LINE__);
2530
+                    return false;
2531
+                }
2532
+                $watermark_img = $this->ImageCreateFromStringReplacement(file_get_contents($this->config_nooffsitelink_watermark_src));
2533
+                $phpthumbFilters = new phpthumb_filters();
2534
+                $phpthumbFilters->phpThumbObject = &$this;
2535
+                $opacity = 50;
2536
+                $margin  = 5;
2537
+                $phpthumbFilters->WatermarkOverlay($this->gdimg_output, $watermark_img, '*', $opacity, $margin);
2538
+                imagedestroy($watermark_img);
2539
+                unset($phpthumbFilters);
2540
+
2541
+            } else {
2542
+
2543
+                $nohotlink_text_array = explode("\n", wordwrap($this->config_nooffsitelink_text_message, floor($this->thumbnail_width / imagefontwidth($this->config_error_fontsize)), "\n"));
2544
+                $nohotlink_text_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_error_textcolor);
2545
+
2546
+                $topoffset = round(($this->thumbnail_height - (count($nohotlink_text_array) * imagefontheight($this->config_error_fontsize))) / 2);
2547
+
2548
+                $rowcounter = 0;
2549
+                $this->DebugMessage('AntiOffsiteLinking() writing '.count($nohotlink_text_array).' lines of text "'.$this->config_nooffsitelink_text_message.'" (in #'.$this->config_error_textcolor.') on top of image', __FILE__, __LINE__);
2550
+                foreach ($nohotlink_text_array as $textline) {
2551
+                    $leftoffset = max(0, round(($this->thumbnail_width - (strlen($textline) * imagefontwidth($this->config_error_fontsize))) / 2));
2552
+                    imagestring($this->gdimg_output, $this->config_error_fontsize, $leftoffset, $topoffset + ($rowcounter++ * imagefontheight($this->config_error_fontsize)), $textline, $nohotlink_text_color);
2553
+                }
2554
+
2555
+            }
2556
+
2557
+        }
2558
+        return true;
2559
+    }
2560
+
2561
+
2562
+    public function AlphaChannelFlatten() {
2563
+        if (!$this->is_alpha) {
2564
+            // image doesn't have alpha transparency, no need to flatten
2565
+            $this->DebugMessage('skipping AlphaChannelFlatten() because !$this->is_alpha', __FILE__, __LINE__);
2566
+            return false;
2567
+        }
2568
+        switch ($this->thumbnailFormat) {
2569
+            case 'png':
2570
+            case 'ico':
2571
+                // image has alpha transparency, but output as PNG or ICO which can handle it
2572
+                $this->DebugMessage('skipping AlphaChannelFlatten() because ($this->thumbnailFormat == "'.$this->thumbnailFormat.'")', __FILE__, __LINE__);
2573
+                return false;
2574
+                break;
2575
+
2576
+            case 'gif':
2577
+                // image has alpha transparency, but output as GIF which can handle only single-color transparency
2578
+                $CurrentImageColorTransparent = imagecolortransparent($this->gdimg_output);
2579
+                if ($CurrentImageColorTransparent == -1) {
2580
+                    // no transparent color defined
2581
+
2582
+                    if (phpthumb_functions::gd_version() < 2.0) {
2583
+                        $this->DebugMessage('AlphaChannelFlatten() failed because GD version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2584
+                        return false;
2585
+                    }
2586
+
2587
+                    if ($img_alpha_mixdown_dither = @imagecreatetruecolor(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) {
2588
+
2589
+                        $dither_color = array();
2590
+                        for ($i = 0; $i <= 255; $i++) {
2591
+                            $dither_color[$i] = imagecolorallocate($img_alpha_mixdown_dither, $i, $i, $i);
2592
+                        }
2593
+
2594
+                        // scan through current truecolor image copy alpha channel to temp image as grayscale
2595
+                        for ($x = 0; $x < $this->thumbnail_width; $x++) {
2596
+                            for ($y = 0; $y < $this->thumbnail_height; $y++) {
2597
+                                $PixelColor = phpthumb_functions::GetPixelColor($this->gdimg_output, $x, $y);
2598
+                                imagesetpixel($img_alpha_mixdown_dither, $x, $y, $dither_color[($PixelColor['alpha'] * 2)]);
2599
+                            }
2600
+                        }
2601
+
2602
+                        // dither alpha channel grayscale version down to 2 colors
2603
+                        imagetruecolortopalette($img_alpha_mixdown_dither, true, 2);
2604
+
2605
+                        // reduce color palette to 256-1 colors (leave one palette position for transparent color)
2606
+                        imagetruecolortopalette($this->gdimg_output, true, 255);
2607
+
2608
+                        // allocate a new color for transparent color index
2609
+                        $TransparentColor = imagecolorallocate($this->gdimg_output, 1, 254, 253);
2610
+                        imagecolortransparent($this->gdimg_output, $TransparentColor);
2611
+
2612
+                        // scan through alpha channel image and note pixels with >50% transparency
2613
+                        for ($x = 0; $x < $this->thumbnail_width; $x++) {
2614
+                            for ($y = 0; $y < $this->thumbnail_height; $y++) {
2615
+                                $AlphaChannelPixel = phpthumb_functions::GetPixelColor($img_alpha_mixdown_dither, $x, $y);
2616
+                                if ($AlphaChannelPixel['red'] > 127) {
2617
+                                    imagesetpixel($this->gdimg_output, $x, $y, $TransparentColor);
2618
+                                }
2619
+                            }
2620
+                        }
2621
+                        imagedestroy($img_alpha_mixdown_dither);
2622
+
2623
+                        $this->DebugMessage('AlphaChannelFlatten() set image to 255+1 colors with transparency for GIF output', __FILE__, __LINE__);
2624
+                        return true;
2625
+
2626
+                    } else {
2627
+                        $this->DebugMessage('AlphaChannelFlatten() failed imagecreate('.imagesx($this->gdimg_output).', '.imagesy($this->gdimg_output).')', __FILE__, __LINE__);
2628
+                        return false;
2629
+                    }
2630
+
2631
+                } else {
2632
+                    // a single transparent color already defined, leave as-is
2633
+                    $this->DebugMessage('skipping AlphaChannelFlatten() because ($this->thumbnailFormat == "'.$this->thumbnailFormat.'") and imagecolortransparent() returned "'.$CurrentImageColorTransparent.'"', __FILE__, __LINE__);
2634
+                    return true;
2635
+                }
2636
+                break;
2637
+        }
2638
+        $this->DebugMessage('continuing AlphaChannelFlatten() for output format "'.$this->thumbnailFormat.'"', __FILE__, __LINE__);
2639
+        // image has alpha transparency, and is being output in a format that doesn't support it -- flatten
2640
+        if ($gdimg_flatten_temp = phpthumb_functions::ImageCreateFunction($this->thumbnail_width, $this->thumbnail_height)) {
2641
+
2642
+            $this->config_background_hexcolor = ($this->bg ? $this->bg : $this->config_background_hexcolor);
2643
+            if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
2644
+                return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
2645
+            }
2646
+            $background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor);
2647
+            imagefilledrectangle($gdimg_flatten_temp, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color);
2648
+            imagecopy($gdimg_flatten_temp, $this->gdimg_output, 0, 0, 0, 0, $this->thumbnail_width, $this->thumbnail_height);
2649
+
2650
+            imagealphablending($this->gdimg_output, true);
2651
+            imagesavealpha($this->gdimg_output, false);
2652
+            imagecolortransparent($this->gdimg_output, -1);
2653
+            imagecopy($this->gdimg_output, $gdimg_flatten_temp, 0, 0, 0, 0, $this->thumbnail_width, $this->thumbnail_height);
2654
+
2655
+            imagedestroy($gdimg_flatten_temp);
2656
+            return true;
2657
+
2658
+        } else {
2659
+            $this->DebugMessage('ImageCreateFunction() failed', __FILE__, __LINE__);
2660
+        }
2661
+        return false;
2662
+    }
2663
+
2664
+
2665
+    public function ApplyFilters() {
2666
+        if ($this->fltr && is_array($this->fltr)) {
2667
+            if (!include_once( __DIR__ .'/phpthumb.filters.php')) {
2668
+                $this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
2669
+                return false;
2670
+            }
2671
+            $phpthumbFilters = new phpthumb_filters();
2672
+            $phpthumbFilters->phpThumbObject = &$this;
2673
+            foreach ($this->fltr as $filtercommand) {
2674
+                @list($command, $parameter) = explode('|', $filtercommand, 2);
2675
+                $this->DebugMessage('Attempting to process filter command "'.$command.'('.$parameter.')"', __FILE__, __LINE__);
2676
+                switch ($command) {
2677
+                    case 'brit': // Brightness
2678
+                        $phpthumbFilters->Brightness($this->gdimg_output, $parameter);
2679
+                        break;
2680
+
2681
+                    case 'cont': // Contrast
2682
+                        $phpthumbFilters->Contrast($this->gdimg_output, $parameter);
2683
+                        break;
2684
+
2685
+                    case 'ds': // Desaturation
2686
+                        $phpthumbFilters->Desaturate($this->gdimg_output, $parameter, '');
2687
+                        break;
2688
+
2689
+                    case 'sat': // Saturation
2690
+                        $phpthumbFilters->Saturation($this->gdimg_output, $parameter, '');
2691
+                        break;
2692
+
2693
+                    case 'gray': // Grayscale
2694
+                        $phpthumbFilters->Grayscale($this->gdimg_output);
2695
+                        break;
2696
+
2697
+                    case 'clr': // Colorize
2698
+                        if (phpthumb_functions::gd_version() < 2) {
2699
+                            $this->DebugMessage('Skipping Colorize() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2700
+                            break;
2701
+                        }
2702
+                        @list($amount, $color) = explode('|', $parameter, 2);
2703
+                        $phpthumbFilters->Colorize($this->gdimg_output, $amount, $color);
2704
+                        break;
2705
+
2706
+                    case 'sep': // Sepia
2707
+                        if (phpthumb_functions::gd_version() < 2) {
2708
+                            $this->DebugMessage('Skipping Sepia() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2709
+                            break;
2710
+                        }
2711
+                        @list($amount, $color) = explode('|', $parameter, 2);
2712
+                        $phpthumbFilters->Sepia($this->gdimg_output, $amount, $color);
2713
+                        break;
2714
+
2715
+                    case 'gam': // Gamma correction
2716
+                        $phpthumbFilters->Gamma($this->gdimg_output, $parameter);
2717
+                        break;
2718
+
2719
+                    case 'neg': // Negative colors
2720
+                        $phpthumbFilters->Negative($this->gdimg_output);
2721
+                        break;
2722
+
2723
+                    case 'th': // Threshold
2724
+                        $phpthumbFilters->Threshold($this->gdimg_output, $parameter);
2725
+                        break;
2726
+
2727
+                    case 'rcd': // ReduceColorDepth
2728
+                        if (phpthumb_functions::gd_version() < 2) {
2729
+                            $this->DebugMessage('Skipping ReduceColorDepth() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2730
+                            break;
2731
+                        }
2732
+                        @list($colors, $dither) = explode('|', $parameter, 2);
2733
+                        $colors = ($colors                ?  (int) $colors : 256);
2734
+                        $dither  = ((strlen($dither) > 0) ? (bool) $dither : true);
2735
+                        $phpthumbFilters->ReduceColorDepth($this->gdimg_output, $colors, $dither);
2736
+                        break;
2737
+
2738
+                    case 'flip': // Flip
2739
+                        $phpthumbFilters->Flip($this->gdimg_output, (strpos(strtolower($parameter), 'x') !== false), (strpos(strtolower($parameter), 'y') !== false));
2740
+                        break;
2741
+
2742
+                    case 'edge': // EdgeDetect
2743
+                        $phpthumbFilters->EdgeDetect($this->gdimg_output);
2744
+                        break;
2745
+
2746
+                    case 'emb': // Emboss
2747
+                        $phpthumbFilters->Emboss($this->gdimg_output);
2748
+                        break;
2749
+
2750
+                    case 'bvl': // Bevel
2751
+                        @list($width, $color1, $color2) = explode('|', $parameter, 3);
2752
+                        $phpthumbFilters->Bevel($this->gdimg_output, $width, $color1, $color2);
2753
+                        break;
2754
+
2755
+                    case 'lvl': // autoLevels
2756
+                        @list($band, $method, $threshold) = explode('|', $parameter, 3);
2757
+                        $band      = ($band ? preg_replace('#[^RGBA\\*]#', '', strtoupper($band)) : '*');
2758
+                        $method    = ((strlen($method) > 0)    ? (int) $method :   2);
2759
+                        $threshold = ((strlen($threshold) > 0) ? (float) $threshold : 0.1);
2760
+
2761
+                        $phpthumbFilters->HistogramStretch($this->gdimg_output, $band, $method, $threshold);
2762
+                        break;
2763
+
2764
+                    case 'wb': // WhiteBalance
2765
+                        $phpthumbFilters->WhiteBalance($this->gdimg_output, $parameter);
2766
+                        break;
2767
+
2768
+                    case 'hist': // Histogram overlay
2769
+                        if (phpthumb_functions::gd_version() < 2) {
2770
+                            $this->DebugMessage('Skipping HistogramOverlay() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2771
+                            break;
2772
+                        }
2773
+                        @list($bands, $colors, $width, $height, $alignment, $opacity, $margin_x, $margin_y) = explode('|', $parameter, 8);
2774
+                        $bands     = ($bands     ? $bands     :  '*');
2775
+                        $colors    = ($colors    ? $colors    :   '');
2776
+                        $width     = ($width     ? $width     : 0.25);
2777
+                        $height    = ($height    ? $height    : 0.25);
2778
+                        $alignment = ($alignment ? $alignment : 'BR');
2779
+                        $opacity   = ($opacity   ? $opacity   :   50);
2780
+                        $margin_x  = ($margin_x  ? $margin_x  :    5);
2781
+                        // $margin_y -- it wasn't forgotten, let the value always pass unchanged
2782
+                        $phpthumbFilters->HistogramOverlay($this->gdimg_output, $bands, $colors, $width, $height, $alignment, $opacity, $margin_x, $margin_y);
2783
+                        break;
2784
+
2785
+                    case 'fram': // Frame
2786
+                        @list($frame_width, $edge_width, $color_frame, $color1, $color2) = explode('|', $parameter, 5);
2787
+                        $phpthumbFilters->Frame($this->gdimg_output, $frame_width, $edge_width, $color_frame, $color1, $color2);
2788
+                        break;
2789
+
2790
+                    case 'drop': // DropShadow
2791
+                        if (phpthumb_functions::gd_version() < 2) {
2792
+                            $this->DebugMessage('Skipping DropShadow() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2793
+                            return false;
2794
+                        }
2795
+                        $this->is_alpha = true;
2796
+                        @list($distance, $width, $color, $angle, $fade) = explode('|', $parameter, 5);
2797
+                        $phpthumbFilters->DropShadow($this->gdimg_output, $distance, $width, $color, $angle, $fade);
2798
+                        break;
2799
+
2800
+                    case 'mask': // Mask cropping
2801
+                        if (phpthumb_functions::gd_version() < 2) {
2802
+                            $this->DebugMessage('Skipping Mask() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2803
+                            return false;
2804
+                        }
2805
+                        @list($mask_filename, $invert) = explode('|', $parameter, 2);
2806
+                        $mask_filename = $this->ResolveFilenameToAbsolute($mask_filename);
2807
+                        if (@is_readable($mask_filename) && ($fp_mask = @fopen($mask_filename, 'rb'))) {
2808
+                            $MaskImageData = '';
2809
+                            do {
2810
+                                $buffer = fread($fp_mask, 8192);
2811
+                                $MaskImageData .= $buffer;
2812
+                            } while (strlen($buffer) > 0);
2813
+                            fclose($fp_mask);
2814
+                            if ($gdimg_mask = $this->ImageCreateFromStringReplacement($MaskImageData)) {
2815
+                                if ($invert && phpthumb_functions::version_compare_replacement(PHP_VERSION, '5.0.0', '>=') && phpthumb_functions::gd_is_bundled()) {
2816
+                                    imagefilter($gdimg_mask, IMG_FILTER_NEGATE);
2817
+                                }
2818
+                                $this->is_alpha = true;
2819
+                                $phpthumbFilters->ApplyMask($gdimg_mask, $this->gdimg_output);
2820
+                                imagedestroy($gdimg_mask);
2821
+                            } else {
2822
+                                $this->DebugMessage('ImageCreateFromStringReplacement() failed for "'.$mask_filename.'"', __FILE__, __LINE__);
2823
+                            }
2824
+                        } else {
2825
+                            $this->DebugMessage('Cannot open mask file "'.$mask_filename.'"', __FILE__, __LINE__);
2826
+                        }
2827
+                        break;
2828
+
2829
+                    case 'elip': // Ellipse cropping
2830
+                        if (phpthumb_functions::gd_version() < 2) {
2831
+                            $this->DebugMessage('Skipping Ellipse() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2832
+                            return false;
2833
+                        }
2834
+                        $this->is_alpha = true;
2835
+                        $phpthumbFilters->Ellipse($this->gdimg_output);
2836
+                        break;
2837
+
2838
+                    case 'ric': // RoundedImageCorners
2839
+                        if (phpthumb_functions::gd_version() < 2) {
2840
+                            $this->DebugMessage('Skipping RoundedImageCorners() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
2841
+                            return false;
2842
+                        }
2843
+                        @list($radius_x, $radius_y) = explode('|', $parameter, 2);
2844
+                        if (($radius_x < 1) || ($radius_y < 1)) {
2845
+                            $this->DebugMessage('Skipping RoundedImageCorners('.$radius_x.', '.$radius_y.') because x/y radius is less than 1', __FILE__, __LINE__);
2846
+                            break;
2847
+                        }
2848
+                        $this->is_alpha = true;
2849
+                        $phpthumbFilters->RoundedImageCorners($this->gdimg_output, $radius_x, $radius_y);
2850
+                        break;
2851
+
2852
+                    case 'crop': // Crop
2853
+                        @list($left, $right, $top, $bottom) = explode('|', $parameter, 4);
2854
+                        $phpthumbFilters->Crop($this->gdimg_output, $left, $right, $top, $bottom);
2855
+                        break;
2856
+
2857
+                    case 'bord': // Border
2858
+                        @list($border_width, $radius_x, $radius_y, $hexcolor_border) = explode('|', $parameter, 4);
2859
+                        $this->is_alpha = true;
2860
+                        $phpthumbFilters->ImageBorder($this->gdimg_output, $border_width, $radius_x, $radius_y, $hexcolor_border);
2861
+                        break;
2862
+
2863
+                    case 'over': // Overlay
2864
+                        @list($filename, $underlay, $margin, $opacity) = explode('|', $parameter, 4);
2865
+                        $underlay = (bool) ($underlay              ? $underlay : false);
2866
+                        $margin   =        ((strlen($margin)  > 0) ? $margin   : ($underlay ? 0.1 : 0.0));
2867
+                        $opacity  =        ((strlen($opacity) > 0) ? $opacity  : 100);
2868
+                        if (($margin > 0) && ($margin < 1)) {
2869
+                            $margin = min(0.499, $margin);
2870
+                        } elseif (($margin > -1) && ($margin < 0)) {
2871
+                            $margin = max(-0.499, $margin);
2872
+                        }
2873
+
2874
+                        $filename = $this->ResolveFilenameToAbsolute($filename);
2875
+                        if (@is_readable($filename) && ($fp_watermark = @fopen($filename, 'rb'))) {
2876
+                            $WatermarkImageData = '';
2877
+                            do {
2878
+                                $buffer = fread($fp_watermark, 8192);
2879
+                                $WatermarkImageData .= $buffer;
2880
+                            } while (strlen($buffer) > 0);
2881
+                            fclose($fp_watermark);
2882
+                            if ($img_watermark = $this->ImageCreateFromStringReplacement($WatermarkImageData)) {
2883
+                                if (($margin > 0) && ($margin < 1)) {
2884
+                                    $resized_x = max(1, imagesx($this->gdimg_output) - round(2 * (imagesx($this->gdimg_output) * $margin)));
2885
+                                    $resized_y = max(1, imagesy($this->gdimg_output) - round(2 * (imagesy($this->gdimg_output) * $margin)));
2886
+                                } else {
2887
+                                    $resized_x = max(1, imagesx($this->gdimg_output) - round(2 * $margin));
2888
+                                    $resized_y = max(1, imagesy($this->gdimg_output) - round(2 * $margin));
2889
+                                }
2890
+
2891
+                                if ($underlay) {
2892
+
2893
+                                    if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) {
2894
+                                        imagealphablending($img_watermark_resized, false);
2895
+                                        imagesavealpha($img_watermark_resized, true);
2896
+                                        $this->ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark_resized), imagesy($img_watermark_resized), imagesx($img_watermark), imagesy($img_watermark));
2897
+                                        if ($img_source_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) {
2898
+                                            imagealphablending($img_source_resized, false);
2899
+                                            imagesavealpha($img_source_resized, true);
2900
+                                            $this->ImageResizeFunction($img_source_resized, $this->gdimg_output, 0, 0, 0, 0, imagesx($img_source_resized), imagesy($img_source_resized), imagesx($this->gdimg_output), imagesy($this->gdimg_output));
2901
+                                            $phpthumbFilters->WatermarkOverlay($img_watermark_resized, $img_source_resized, 'C', $opacity, $margin);
2902
+                                            imagecopy($this->gdimg_output, $img_watermark_resized, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output));
2903
+                                        } else {
2904
+                                            $this->DebugMessage('phpthumb_functions::ImageCreateFunction('.$resized_x.', '.$resized_y.')', __FILE__, __LINE__);
2905
+                                        }
2906
+                                        imagedestroy($img_watermark_resized);
2907
+                                    } else {
2908
+                                        $this->DebugMessage('phpthumb_functions::ImageCreateFunction('.imagesx($this->gdimg_output).', '.imagesy($this->gdimg_output).')', __FILE__, __LINE__);
2909
+                                    }
2910
+
2911
+                                } else { // overlay
2912
+
2913
+                                    if ($img_watermark_resized = phpthumb_functions::ImageCreateFunction($resized_x, $resized_y)) {
2914
+                                        imagealphablending($img_watermark_resized, false);
2915
+                                        imagesavealpha($img_watermark_resized, true);
2916
+                                        $this->ImageResizeFunction($img_watermark_resized, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark_resized), imagesy($img_watermark_resized), imagesx($img_watermark), imagesy($img_watermark));
2917
+                                        $phpthumbFilters->WatermarkOverlay($this->gdimg_output, $img_watermark_resized, 'C', $opacity, $margin);
2918
+                                        imagedestroy($img_watermark_resized);
2919
+                                    } else {
2920
+                                        $this->DebugMessage('phpthumb_functions::ImageCreateFunction('.$resized_x.', '.$resized_y.')', __FILE__, __LINE__);
2921
+                                    }
2922
+
2923
+                                }
2924
+                                imagedestroy($img_watermark);
2925
+
2926
+                            } else {
2927
+                                $this->DebugMessage('ImageCreateFromStringReplacement() failed for "'.$filename.'"', __FILE__, __LINE__);
2928
+                            }
2929
+                        } else {
2930
+                            $this->DebugMessage('Cannot open overlay file "'.$filename.'"', __FILE__, __LINE__);
2931
+                        }
2932
+                        break;
2933
+
2934
+                    case 'wmi': // WaterMarkImage
2935
+                        @list($filename, $alignment, $opacity, $margin['x'], $margin['y'], $rotate_angle) = explode('|', $parameter, 6);
2936
+                        // $margin can be pixel margin or percent margin if $alignment is text, or max width/height if $alignment is position like "50x75"
2937
+                        $alignment    = ($alignment            ? $alignment            : 'BR');
2938
+                        $opacity      = (strlen($opacity)      ? (int) $opacity : 50);
2939
+                        $rotate_angle = (strlen($rotate_angle) ? (int) $rotate_angle : 0);
2940
+                        if (!preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
2941
+                            $margins = array('x', 'y');
2942
+                            foreach ($margins as $xy) {
2943
+                                $margin[$xy] = (strlen($margin[$xy]) ? $margin[$xy] : 5);
2944
+                                if (($margin[$xy] > 0) && ($margin[$xy] < 1)) {
2945
+                                    $margin[$xy] = min(0.499, $margin[$xy]);
2946
+                                } elseif (($margin[$xy] > -1) && ($margin[$xy] < 0)) {
2947
+                                    $margin[$xy] = max(-0.499, $margin[$xy]);
2948
+                                }
2949
+                            }
2950
+                        }
2951
+
2952
+                        $filename = $this->ResolveFilenameToAbsolute($filename);
2953
+                        if (@is_readable($filename)) {
2954
+                            if ($img_watermark = $this->ImageCreateFromFilename($filename)) {
2955
+                                if ($rotate_angle !== 0) {
2956
+                                    $phpthumbFilters->ImprovedImageRotate($img_watermark, $rotate_angle, 'FFFFFF', null, $this);
2957
+                                }
2958
+                                if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
2959
+                                    $watermark_max_width  = (int) ($margin[ 'x'] ? $margin[ 'x'] : imagesx($img_watermark));
2960
+                                    $watermark_max_height = (int) ($margin[ 'y'] ? $margin[ 'y'] : imagesy($img_watermark));
2961
+                                    $scale = phpthumb_functions::ScaleToFitInBox(imagesx($img_watermark), imagesy($img_watermark), $watermark_max_width, $watermark_max_height, true, true);
2962
+                                    $this->DebugMessage('Scaling watermark by a factor of '.number_format($scale, 4), __FILE__, __LINE__);
2963
+                                    if (($scale > 1) || ($scale < 1)) {
2964
+                                        if ($img_watermark2 = phpthumb_functions::ImageCreateFunction($scale * imagesx($img_watermark), $scale * imagesy($img_watermark))) {
2965
+                                            imagealphablending($img_watermark2, false);
2966
+                                            imagesavealpha($img_watermark2, true);
2967
+                                            $this->ImageResizeFunction($img_watermark2, $img_watermark, 0, 0, 0, 0, imagesx($img_watermark2), imagesy($img_watermark2), imagesx($img_watermark), imagesy($img_watermark));
2968
+                                            $img_watermark = $img_watermark2;
2969
+                                        } else {
2970
+                                            $this->DebugMessage('ImageCreateFunction('.($scale * imagesx($img_watermark)).', '.($scale * imagesx($img_watermark)).') failed', __FILE__, __LINE__);
2971
+                                        }
2972
+                                    }
2973
+                                    $watermark_dest_x = round($matches[1] - (imagesx($img_watermark) / 2));
2974
+                                    $watermark_dest_y = round($matches[2] - (imagesy($img_watermark) / 2));
2975
+                                    $alignment = $watermark_dest_x.'x'.$watermark_dest_y;
2976
+                                }
2977
+                                $phpthumbFilters->WatermarkOverlay($this->gdimg_output, $img_watermark, $alignment, $opacity, $margin['x'], $margin['y']);
2978
+                                imagedestroy($img_watermark);
2979
+                                if (isset($img_watermark2) && is_resource($img_watermark2)) {
2980
+                                    imagedestroy($img_watermark2);
2981
+                                }
2982
+                            } else {
2983
+                                $this->DebugMessage('ImageCreateFromFilename() failed for "'.$filename.'"', __FILE__, __LINE__);
2984
+                            }
2985
+                        } else {
2986
+                            $this->DebugMessage('!is_readable('.$filename.')', __FILE__, __LINE__);
2987
+                        }
2988
+                        break;
2989
+
2990
+                    case 'wmt': // WaterMarkText
2991
+                        @list($text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle, $bg_color, $bg_opacity, $fillextend, $lineheight) = explode('|', $parameter, 12);
2992
+                        $text       = ($text            ? $text       : '');
2993
+                        $size       = ($size            ? $size       : 3);
2994
+                        $alignment  = ($alignment       ? $alignment  : 'BR');
2995
+                        $hex_color  = ($hex_color       ? $hex_color  : '000000');
2996
+                        $ttffont    = ($ttffont         ? $ttffont    : '');
2997
+                        $opacity    = (strlen($opacity) ? $opacity    : 50);
2998
+                        $margin     = (strlen($margin)  ? $margin     : 5);
2999
+                        $angle      = (strlen($angle)   ? $angle      : 0);
3000
+                        $bg_color   = ($bg_color        ? $bg_color   : false);
3001
+                        $bg_opacity = ($bg_opacity      ? $bg_opacity : 0);
3002
+                        $fillextend = ($fillextend      ? $fillextend : '');
3003
+                        $lineheight = ($lineheight      ? $lineheight : 1.0);
3004
+
3005
+                        if (basename($ttffont) == $ttffont) {
3006
+                            $ttffont = $this->realPathSafe($this->config_ttf_directory.DIRECTORY_SEPARATOR.$ttffont);
3007
+                        } else {
3008
+                            $ttffont = $this->ResolveFilenameToAbsolute($ttffont);
3009
+                        }
3010
+                        $phpthumbFilters->WatermarkText($this->gdimg_output, $text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle, $bg_color, $bg_opacity, $fillextend, $lineheight);
3011
+                        break;
3012
+
3013
+                    case 'blur': // Blur
3014
+                        @list($radius) = explode('|', $parameter, 1);
3015
+                        $radius = ($radius ? $radius : 1);
3016
+                        if (phpthumb_functions::gd_version() >= 2) {
3017
+                            $phpthumbFilters->Blur($this->gdimg_output, $radius);
3018
+                        } else {
3019
+                            $this->DebugMessage('Skipping Blur() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
3020
+                        }
3021
+                        break;
3022
+
3023
+                    case 'gblr': // Gaussian Blur
3024
+                        $phpthumbFilters->BlurGaussian($this->gdimg_output);
3025
+                        break;
3026
+
3027
+                    case 'sblr': // Selective Blur
3028
+                        $phpthumbFilters->BlurSelective($this->gdimg_output);
3029
+                        break;
3030
+
3031
+                    case 'mean': // MeanRemoval blur
3032
+                        $phpthumbFilters->MeanRemoval($this->gdimg_output);
3033
+                        break;
3034
+
3035
+                    case 'smth': // Smooth blur
3036
+                        $phpthumbFilters->Smooth($this->gdimg_output, $parameter);
3037
+                        break;
3038
+
3039
+                    case 'usm': // UnSharpMask sharpening
3040
+                        @list($amount, $radius, $threshold) = explode('|', $parameter, 3);
3041
+                        $amount    = ($amount            ? $amount    : 80);
3042
+                        $radius    = ($radius            ? $radius    : 0.5);
3043
+                        $threshold = (strlen($threshold) ? $threshold : 3);
3044
+                        if (phpthumb_functions::gd_version() >= 2.0) {
3045
+                            ob_start();
3046
+                            if (!@include_once( __DIR__ .'/phpthumb.unsharp.php')) {
3047
+                                $include_error = ob_get_contents();
3048
+                                if ($include_error) {
3049
+                                    $this->DebugMessage('include_once("'. __DIR__ .'/phpthumb.unsharp.php") generated message: "'.$include_error.'"', __FILE__, __LINE__);
3050
+                                }
3051
+                                $this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.unsharp.php" which is required for unsharp masking', __FILE__, __LINE__);
3052
+                                ob_end_clean();
3053
+                                return false;
3054
+                            }
3055
+                            ob_end_clean();
3056
+                            phpUnsharpMask::applyUnsharpMask($this->gdimg_output, $amount, $radius, $threshold);
3057
+                        } else {
3058
+                            $this->DebugMessage('Skipping unsharp mask because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
3059
+                            return false;
3060
+                        }
3061
+                        break;
3062
+
3063
+                    case 'size': // Resize
3064
+                        @list($newwidth, $newheight, $stretch) = explode('|', $parameter);
3065
+                        $newwidth  = (!$newwidth  ? imagesx($this->gdimg_output) : ((($newwidth  > 0) && ($newwidth  < 1)) ? round($newwidth  * imagesx($this->gdimg_output)) : round($newwidth)));
3066
+                        $newheight = (!$newheight ? imagesy($this->gdimg_output) : ((($newheight > 0) && ($newheight < 1)) ? round($newheight * imagesy($this->gdimg_output)) : round($newheight)));
3067
+                        $stretch   = ($stretch ? true : false);
3068
+                        if ($stretch) {
3069
+                            $scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesx($this->gdimg_output), $newwidth,  $newwidth,  true, true);
3070
+                            $scale_y = phpthumb_functions::ScaleToFitInBox(imagesy($this->gdimg_output), imagesy($this->gdimg_output), $newheight, $newheight, true, true);
3071
+                        } else {
3072
+                            $scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesy($this->gdimg_output), $newwidth, $newheight, true, true);
3073
+                            $scale_y = $scale_x;
3074
+                        }
3075
+                        $this->DebugMessage('Scaling watermark ('.($stretch ? 'with' : 'without').' stretch) by a factor of "'.number_format($scale_x, 4).' x '.number_format($scale_y, 4).'"', __FILE__, __LINE__);
3076
+                        if (($scale_x > 1) || ($scale_x < 1) || ($scale_y > 1) || ($scale_y < 1)) {
3077
+                            if ($img_temp = phpthumb_functions::ImageCreateFunction(imagesx($this->gdimg_output), imagesy($this->gdimg_output))) {
3078
+                                imagecopy($img_temp, $this->gdimg_output, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output));
3079
+                                if ($this->gdimg_output = phpthumb_functions::ImageCreateFunction($scale_x * imagesx($img_temp), $scale_y * imagesy($img_temp))) {
3080
+                                    imagealphablending($this->gdimg_output, false);
3081
+                                    imagesavealpha($this->gdimg_output, true);
3082
+                                    $this->ImageResizeFunction($this->gdimg_output, $img_temp, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output), imagesx($img_temp), imagesy($img_temp));
3083
+                                } else {
3084
+                                    $this->DebugMessage('ImageCreateFunction('.($scale_x * imagesx($img_temp)).', '.($scale_y * imagesy($img_temp)).') failed', __FILE__, __LINE__);
3085
+                                }
3086
+                                imagedestroy($img_temp);
3087
+                            } else {
3088
+                                $this->DebugMessage('ImageCreateFunction('.imagesx($this->gdimg_output).', '.imagesy($this->gdimg_output).') failed', __FILE__, __LINE__);
3089
+                            }
3090
+                        }
3091
+                        break;
3092
+
3093
+                    case 'rot': // ROTate
3094
+                        @list($angle, $bgcolor) = explode('|', $parameter, 2);
3095
+                        $phpthumbFilters->ImprovedImageRotate($this->gdimg_output, $angle, $bgcolor, null, $this);
3096
+                        break;
3097
+
3098
+                    case 'stc': // Source Transparent Color
3099
+                        @list($hexcolor, $min_limit, $max_limit) = explode('|', $parameter, 3);
3100
+                        if (!phpthumb_functions::IsHexColor($hexcolor)) {
3101
+                            $this->DebugMessage('Skipping SourceTransparentColor hex color is invalid ('.$hexcolor.')', __FILE__, __LINE__);
3102
+                            return false;
3103
+                        }
3104
+                        $min_limit = (strlen($min_limit) ? $min_limit :  5);
3105
+                        $max_limit = (strlen($max_limit) ? $max_limit : 10);
3106
+                        if ($gdimg_mask = $phpthumbFilters->SourceTransparentColorMask($this->gdimg_output, $hexcolor, $min_limit, $max_limit)) {
3107
+                            $this->is_alpha = true;
3108
+                            $phpthumbFilters->ApplyMask($gdimg_mask, $this->gdimg_output);
3109
+                            imagedestroy($gdimg_mask);
3110
+                        } else {
3111
+                            $this->DebugMessage('SourceTransparentColorMask() failed for "'.$hexcolor.','.$min_limit.','.$max_limit.'"', __FILE__, __LINE__);
3112
+                        }
3113
+                        break;
3114
+                }
3115
+                $this->DebugMessage('Finished processing filter command "'.$command.'('.$parameter.')"', __FILE__, __LINE__);
3116
+            }
3117
+        }
3118
+        return true;
3119
+    }
3120
+
3121
+
3122
+    public function MaxFileSize() {
3123
+        if (phpthumb_functions::gd_version() < 2) {
3124
+            $this->DebugMessage('Skipping MaxFileSize() because gd_version is "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
3125
+            return false;
3126
+        }
3127
+        if ($this->maxb > 0) {
3128
+            switch ($this->thumbnailFormat) {
3129
+                case 'png':
3130
+                case 'gif':
3131
+                    $imgRenderFunction = 'image'.$this->thumbnailFormat;
3132
+
3133
+                    ob_start();
3134
+                    $imgRenderFunction($this->gdimg_output);
3135
+                    $imgdata = ob_get_contents();
3136
+                    ob_end_clean();
3137
+
3138
+                    if (strlen($imgdata) > $this->maxb) {
3139
+                        for ($i = 8; $i >= 1; $i--) {
3140
+                            $tempIMG = imagecreatetruecolor(imagesx($this->gdimg_output), imagesy($this->gdimg_output));
3141
+                            imagecopy($tempIMG, $this->gdimg_output, 0, 0, 0, 0, imagesx($this->gdimg_output), imagesy($this->gdimg_output));
3142
+                            imagetruecolortopalette($tempIMG, true, pow(2, $i));
3143
+                            ob_start();
3144
+                            $imgRenderFunction($tempIMG);
3145
+                            $imgdata = ob_get_contents();
3146
+                            ob_end_clean();
3147
+
3148
+                            if (strlen($imgdata) <= $this->maxb) {
3149
+                                imagetruecolortopalette($this->gdimg_output, true, pow(2, $i));
3150
+                                break;
3151
+                            }
3152
+                        }
3153
+                    }
3154
+                    break;
3155
+
3156
+                case 'jpeg':
3157
+                    ob_start();
3158
+                    imagejpeg($this->gdimg_output);
3159
+                    $imgdata = ob_get_contents();
3160
+                    ob_end_clean();
3161
+
3162
+                    if (strlen($imgdata) > $this->maxb) {
3163
+                        for ($i = 3; $i < 20; $i++) {
3164
+                            $q = round(100 * (1 - log10($i / 2)));
3165
+                            ob_start();
3166
+                            imagejpeg($this->gdimg_output, null, $q);
3167
+                            $imgdata = ob_get_contents();
3168
+                            ob_end_clean();
3169
+
3170
+                            $this->thumbnailQuality = $q;
3171
+                            if (strlen($imgdata) <= $this->maxb) {
3172
+                                break;
3173
+                            }
3174
+                        }
3175
+                    }
3176
+                    if (strlen($imgdata) > $this->maxb) {
3177
+                        return false;
3178
+                    }
3179
+                    break;
3180
+
3181
+                default:
3182
+                    return false;
3183
+            }
3184
+        }
3185
+        return true;
3186
+    }
3187
+
3188
+
3189
+    public function CalculateThumbnailDimensions() {
3190
+        $this->DebugMessage('CalculateThumbnailDimensions() starting with [W,H,sx,sy,sw,sh] initially set to ['.$this->source_width.','.$this->source_height.','.$this->sx.','.$this->sy.','.$this->sw.','.$this->sh.']', __FILE__, __LINE__);
3191 3191
 //echo $this->source_width.'x'.$this->source_height.'<hr>';
3192
-		$this->thumbnailCropX = ($this->sx ? (($this->sx >= 2) ? $this->sx : round($this->sx * $this->source_width))  : 0);
3192
+        $this->thumbnailCropX = ($this->sx ? (($this->sx >= 2) ? $this->sx : round($this->sx * $this->source_width))  : 0);
3193 3193
 //echo $this->thumbnailCropX.'<br>';
3194
-		$this->thumbnailCropY = ($this->sy ? (($this->sy >= 2) ? $this->sy : round($this->sy * $this->source_height)) : 0);
3194
+        $this->thumbnailCropY = ($this->sy ? (($this->sy >= 2) ? $this->sy : round($this->sy * $this->source_height)) : 0);
3195 3195
 //echo $this->thumbnailCropY.'<br>';
3196
-		$this->thumbnailCropW = ($this->sw ? (($this->sw >= 2) ? $this->sw : round($this->sw * $this->source_width))  : $this->source_width);
3196
+        $this->thumbnailCropW = ($this->sw ? (($this->sw >= 2) ? $this->sw : round($this->sw * $this->source_width))  : $this->source_width);
3197 3197
 //echo $this->thumbnailCropW.'<br>';
3198
-		$this->thumbnailCropH = ($this->sh ? (($this->sh >= 2) ? $this->sh : round($this->sh * $this->source_height)) : $this->source_height);
3198
+        $this->thumbnailCropH = ($this->sh ? (($this->sh >= 2) ? $this->sh : round($this->sh * $this->source_height)) : $this->source_height);
3199 3199
 //echo $this->thumbnailCropH.'<hr>';
3200 3200
 
3201
-		// limit source area to original image area
3202
-		$this->thumbnailCropW = max(1, min($this->thumbnailCropW, $this->source_width  - $this->thumbnailCropX));
3203
-		$this->thumbnailCropH = max(1, min($this->thumbnailCropH, $this->source_height - $this->thumbnailCropY));
3204
-
3205
-		$this->DebugMessage('CalculateThumbnailDimensions() starting with [x,y,w,h] initially set to ['.$this->thumbnailCropX.','.$this->thumbnailCropY.','.$this->thumbnailCropW.','.$this->thumbnailCropH.']', __FILE__, __LINE__);
3206
-
3207
-
3208
-		if ($this->zc && $this->w && $this->h) {
3209
-			// Zoom Crop
3210
-			// retain proportional resizing we did above, but crop off larger dimension so smaller
3211
-			// dimension fully fits available space
3212
-
3213
-			$scaling_X = $this->source_width  / $this->w;
3214
-			$scaling_Y = $this->source_height / $this->h;
3215
-			if ($scaling_X > $scaling_Y) {
3216
-				// some of the width will need to be cropped
3217
-				$allowable_width = $this->source_width / $scaling_X * $scaling_Y;
3218
-				$this->thumbnailCropW = round($allowable_width);
3219
-				$this->thumbnailCropX = round(($this->source_width - $allowable_width) / 2);
3220
-
3221
-			} elseif ($scaling_Y > $scaling_X) {
3222
-				// some of the height will need to be cropped
3223
-				$allowable_height = $this->source_height / $scaling_Y * $scaling_X;
3224
-				$this->thumbnailCropH = round($allowable_height);
3225
-				$this->thumbnailCropY = round(($this->source_height - $allowable_height) / 2);
3226
-
3227
-			} else {
3228
-				// image fits perfectly, no cropping needed
3229
-			}
3230
-			$this->thumbnail_width  = $this->w;
3231
-			$this->thumbnail_height = $this->h;
3232
-			$this->thumbnail_image_width  = $this->thumbnail_width;
3233
-			$this->thumbnail_image_height = $this->thumbnail_height;
3234
-
3235
-		} elseif ($this->iar && $this->w && $this->h) {
3236
-
3237
-			// Ignore Aspect Ratio
3238
-			// stretch image to fit exactly 'w' x 'h'
3239
-			$this->thumbnail_width  = $this->w;
3240
-			$this->thumbnail_height = $this->h;
3241
-			$this->thumbnail_image_width  = $this->thumbnail_width;
3242
-			$this->thumbnail_image_height = $this->thumbnail_height;
3243
-
3244
-		} else {
3245
-
3246
-			$original_aspect_ratio = $this->thumbnailCropW / $this->thumbnailCropH;
3247
-			if ($this->aoe) {
3248
-				if ($this->w && $this->h) {
3249
-					$maxwidth  = min($this->w, $this->h * $original_aspect_ratio);
3250
-					$maxheight = min($this->h, $this->w / $original_aspect_ratio);
3251
-				} elseif ($this->w) {
3252
-					$maxwidth  = $this->w;
3253
-					$maxheight = $this->w / $original_aspect_ratio;
3254
-				} elseif ($this->h) {
3255
-					$maxwidth  = $this->h * $original_aspect_ratio;
3256
-					$maxheight = $this->h;
3257
-				} else {
3258
-					$maxwidth  = $this->thumbnailCropW;
3259
-					$maxheight = $this->thumbnailCropH;
3260
-				}
3261
-			} else {
3262
-				$maxwidth  = phpthumb_functions::nonempty_min($this->w, $this->thumbnailCropW, $this->config_output_maxwidth);
3263
-				$maxheight = phpthumb_functions::nonempty_min($this->h, $this->thumbnailCropH, $this->config_output_maxheight);
3201
+        // limit source area to original image area
3202
+        $this->thumbnailCropW = max(1, min($this->thumbnailCropW, $this->source_width  - $this->thumbnailCropX));
3203
+        $this->thumbnailCropH = max(1, min($this->thumbnailCropH, $this->source_height - $this->thumbnailCropY));
3204
+
3205
+        $this->DebugMessage('CalculateThumbnailDimensions() starting with [x,y,w,h] initially set to ['.$this->thumbnailCropX.','.$this->thumbnailCropY.','.$this->thumbnailCropW.','.$this->thumbnailCropH.']', __FILE__, __LINE__);
3206
+
3207
+
3208
+        if ($this->zc && $this->w && $this->h) {
3209
+            // Zoom Crop
3210
+            // retain proportional resizing we did above, but crop off larger dimension so smaller
3211
+            // dimension fully fits available space
3212
+
3213
+            $scaling_X = $this->source_width  / $this->w;
3214
+            $scaling_Y = $this->source_height / $this->h;
3215
+            if ($scaling_X > $scaling_Y) {
3216
+                // some of the width will need to be cropped
3217
+                $allowable_width = $this->source_width / $scaling_X * $scaling_Y;
3218
+                $this->thumbnailCropW = round($allowable_width);
3219
+                $this->thumbnailCropX = round(($this->source_width - $allowable_width) / 2);
3220
+
3221
+            } elseif ($scaling_Y > $scaling_X) {
3222
+                // some of the height will need to be cropped
3223
+                $allowable_height = $this->source_height / $scaling_Y * $scaling_X;
3224
+                $this->thumbnailCropH = round($allowable_height);
3225
+                $this->thumbnailCropY = round(($this->source_height - $allowable_height) / 2);
3226
+
3227
+            } else {
3228
+                // image fits perfectly, no cropping needed
3229
+            }
3230
+            $this->thumbnail_width  = $this->w;
3231
+            $this->thumbnail_height = $this->h;
3232
+            $this->thumbnail_image_width  = $this->thumbnail_width;
3233
+            $this->thumbnail_image_height = $this->thumbnail_height;
3234
+
3235
+        } elseif ($this->iar && $this->w && $this->h) {
3236
+
3237
+            // Ignore Aspect Ratio
3238
+            // stretch image to fit exactly 'w' x 'h'
3239
+            $this->thumbnail_width  = $this->w;
3240
+            $this->thumbnail_height = $this->h;
3241
+            $this->thumbnail_image_width  = $this->thumbnail_width;
3242
+            $this->thumbnail_image_height = $this->thumbnail_height;
3243
+
3244
+        } else {
3245
+
3246
+            $original_aspect_ratio = $this->thumbnailCropW / $this->thumbnailCropH;
3247
+            if ($this->aoe) {
3248
+                if ($this->w && $this->h) {
3249
+                    $maxwidth  = min($this->w, $this->h * $original_aspect_ratio);
3250
+                    $maxheight = min($this->h, $this->w / $original_aspect_ratio);
3251
+                } elseif ($this->w) {
3252
+                    $maxwidth  = $this->w;
3253
+                    $maxheight = $this->w / $original_aspect_ratio;
3254
+                } elseif ($this->h) {
3255
+                    $maxwidth  = $this->h * $original_aspect_ratio;
3256
+                    $maxheight = $this->h;
3257
+                } else {
3258
+                    $maxwidth  = $this->thumbnailCropW;
3259
+                    $maxheight = $this->thumbnailCropH;
3260
+                }
3261
+            } else {
3262
+                $maxwidth  = phpthumb_functions::nonempty_min($this->w, $this->thumbnailCropW, $this->config_output_maxwidth);
3263
+                $maxheight = phpthumb_functions::nonempty_min($this->h, $this->thumbnailCropH, $this->config_output_maxheight);
3264 3264
 //echo $maxwidth.'x'.$maxheight.'<br>';
3265
-				$maxwidth  = min($maxwidth, $maxheight * $original_aspect_ratio);
3266
-				$maxheight = min($maxheight, $maxwidth / $original_aspect_ratio);
3265
+                $maxwidth  = min($maxwidth, $maxheight * $original_aspect_ratio);
3266
+                $maxheight = min($maxheight, $maxwidth / $original_aspect_ratio);
3267 3267
 //echo $maxwidth.'x'.$maxheight.'<hr>';
3268
-			}
3269
-
3270
-			$this->thumbnail_image_width  = $maxwidth;
3271
-			$this->thumbnail_image_height = $maxheight;
3272
-			$this->thumbnail_width  = $maxwidth;
3273
-			$this->thumbnail_height = $maxheight;
3274
-
3275
-			$this->FixedAspectRatio();
3276
-		}
3277
-
3278
-		$this->thumbnail_width  = max(1, floor($this->thumbnail_width));
3279
-		$this->thumbnail_height = max(1, floor($this->thumbnail_height));
3280
-		return true;
3281
-	}
3282
-
3283
-
3284
-	public function CreateGDoutput() {
3285
-		$this->CalculateThumbnailDimensions();
3286
-
3287
-		// create the GD image (either true-color or 256-color, depending on GD version)
3288
-		$this->gdimg_output = phpthumb_functions::ImageCreateFunction($this->thumbnail_width, $this->thumbnail_height);
3289
-
3290
-		// images that have transparency must have the background filled with the configured 'bg' color otherwise the transparent color will appear as black
3291
-		imagesavealpha($this->gdimg_output, true);
3292
-		if ($this->is_alpha && phpthumb_functions::gd_version() >= 2) {
3293
-
3294
-			imagealphablending($this->gdimg_output, false);
3295
-			$output_full_alpha = phpthumb_functions::ImageColorAllocateAlphaSafe($this->gdimg_output, 255, 255, 255, 127);
3296
-			imagefilledrectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $output_full_alpha);
3297
-
3298
-		} else {
3299
-
3300
-			$current_transparent_color = imagecolortransparent($this->gdimg_source);
3301
-			if ($this->bg || (@$current_transparent_color >= 0)) {
3302
-
3303
-				$this->config_background_hexcolor = ($this->bg ? $this->bg : $this->config_background_hexcolor);
3304
-				if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
3305
-					return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
3306
-				}
3307
-				$background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor);
3308
-				imagefilledrectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color);
3309
-
3310
-			}
3311
-
3312
-		}
3313
-		$this->DebugMessage('CreateGDoutput() returning canvas "'.$this->thumbnail_width.'x'.$this->thumbnail_height.'"', __FILE__, __LINE__);
3314
-		return true;
3315
-	}
3316
-
3317
-	public function SetOrientationDependantWidthHeight() {
3318
-		$this->DebugMessage('SetOrientationDependantWidthHeight() starting with "'.$this->source_width.'"x"'.$this->source_height.'"', __FILE__, __LINE__);
3319
-		if ($this->source_height > $this->source_width) {
3320
-			// portrait
3321
-			$this->w = phpthumb_functions::OneOfThese($this->wp, $this->w, $this->ws, $this->wl);
3322
-			$this->h = phpthumb_functions::OneOfThese($this->hp, $this->h, $this->hs, $this->hl);
3323
-		} elseif ($this->source_height < $this->source_width) {
3324
-			// landscape
3325
-			$this->w = phpthumb_functions::OneOfThese($this->wl, $this->w, $this->ws, $this->wp);
3326
-			$this->h = phpthumb_functions::OneOfThese($this->hl, $this->h, $this->hs, $this->hp);
3327
-		} else {
3328
-			// square
3329
-			$this->w = phpthumb_functions::OneOfThese($this->ws, $this->w, $this->wl, $this->wp);
3330
-			$this->h = phpthumb_functions::OneOfThese($this->hs, $this->h, $this->hl, $this->hp);
3331
-		}
3332
-		//$this->w = round($this->w ? $this->w : (($this->h && $this->source_height) ? $this->h * $this->source_width  / $this->source_height : $this->w));
3333
-		//$this->h = round($this->h ? $this->h : (($this->w && $this->source_width)  ? $this->w * $this->source_height / $this->source_width  : $this->h));
3334
-		$this->DebugMessage('SetOrientationDependantWidthHeight() setting w="'. (int) $this->w .'", h="'. (int) $this->h .'"', __FILE__, __LINE__);
3335
-		return true;
3336
-	}
3337
-
3338
-	public function ExtractEXIFgetImageSize() {
3339
-		$this->DebugMessage('starting ExtractEXIFgetImageSize()', __FILE__, __LINE__);
3340
-
3341
-		if (preg_match('#^http:#i', $this->src) && !$this->sourceFilename && $this->rawImageData) {
3342
-			$this->SourceDataToTempFile();
3343
-		}
3344
-		if (null === $this->getimagesizeinfo) {
3345
-			if ($this->sourceFilename) {
3346
-				$this->getimagesizeinfo = @getimagesize($this->sourceFilename);
3347
-				$this->source_width  = $this->getimagesizeinfo[0];
3348
-				$this->source_height = $this->getimagesizeinfo[1];
3349
-				$this->DebugMessage('getimagesize('.$this->sourceFilename.') says image is '.$this->source_width.'x'.$this->source_height, __FILE__, __LINE__);
3350
-			} else {
3351
-				$this->DebugMessage('skipping getimagesize() because $this->sourceFilename is empty', __FILE__, __LINE__);
3352
-			}
3353
-		} else {
3354
-			$this->DebugMessage('skipping getimagesize() because !is_null($this->getimagesizeinfo)', __FILE__, __LINE__);
3355
-		}
3356
-
3357
-		if (is_resource($this->gdimg_source)) {
3358
-
3359
-			$this->source_width  = imagesx($this->gdimg_source);
3360
-			$this->source_height = imagesy($this->gdimg_source);
3361
-
3362
-			$this->SetOrientationDependantWidthHeight();
3363
-
3364
-		} elseif ($this->rawImageData && !$this->sourceFilename) {
3365
-
3366
-			if ($this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3367
-				$this->DebugMessage('NOT bypassing EXIF and getimagesize sections because source image is too large for GD ('.$this->source_width.'x'.$this->source_width.'='.($this->source_width * $this->source_height * 5).'MB)', __FILE__, __LINE__);
3368
-			} else {
3369
-				$this->DebugMessage('bypassing EXIF and getimagesize sections because $this->rawImageData is set, and $this->sourceFilename is not set, and source image is not too large for GD ('.$this->source_width.'x'.$this->source_width.'='.($this->source_width * $this->source_height * 5).'MB)', __FILE__, __LINE__);
3370
-			}
3371
-
3372
-		}
3373
-
3374
-		if (!empty($this->getimagesizeinfo)) {
3375
-			// great
3376
-			$this->getimagesizeinfo['filesize'] = @filesize($this->sourceFilename);
3377
-		} elseif (!$this->rawImageData) {
3378
-			$this->DebugMessage('getimagesize("'.$this->sourceFilename.'") failed', __FILE__, __LINE__);
3379
-		}
3380
-
3381
-		if ($this->config_prefer_imagemagick) {
3382
-			if ($this->ImageMagickThumbnailToGD()) {
3383
-				return true;
3384
-			}
3385
-			$this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__);
3386
-		}
3387
-
3388
-		$this->source_width  = $this->getimagesizeinfo[0];
3389
-		$this->source_height = $this->getimagesizeinfo[1];
3390
-
3391
-		$this->SetOrientationDependantWidthHeight();
3392
-
3393
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.2.0', '>=') && function_exists('exif_read_data')) {
3394
-			switch ($this->getimagesizeinfo[2]) {
3395
-				case IMAGETYPE_JPEG:
3396
-				case IMAGETYPE_TIFF_II:
3397
-				case IMAGETYPE_TIFF_MM:
3398
-					$this->exif_raw_data = @exif_read_data($this->sourceFilename, 0, true);
3399
-					break;
3400
-			}
3401
-		}
3402
-		if (function_exists('exif_thumbnail') && ($this->getimagesizeinfo[2] == IMAGETYPE_JPEG)) {
3403
-			// Extract EXIF info from JPEGs
3404
-
3405
-			$this->exif_thumbnail_width  = '';
3406
-			$this->exif_thumbnail_height = '';
3407
-			$this->exif_thumbnail_type   = '';
3408
-
3409
-			// The parameters width, height and imagetype are available since PHP v4.3.0
3410
-			if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.3.0', '>=')) {
3411
-
3412
-				$this->exif_thumbnail_data = @exif_thumbnail($this->sourceFilename, $this->exif_thumbnail_width, $this->exif_thumbnail_height, $this->exif_thumbnail_type);
3413
-
3414
-			} else {
3415
-
3416
-				// older versions of exif_thumbnail output an error message but NOT return false on failure
3417
-				ob_start();
3418
-				$this->exif_thumbnail_data = exif_thumbnail($this->sourceFilename);
3419
-				$exit_thumbnail_error = ob_get_contents();
3420
-				ob_end_clean();
3421
-				if (!$exit_thumbnail_error && $this->exif_thumbnail_data) {
3422
-
3423
-					if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
3424
-						$this->exif_thumbnail_width  = imagesx($gdimg_exif_temp);
3425
-						$this->exif_thumbnail_height = imagesy($gdimg_exif_temp);
3426
-						$this->exif_thumbnail_type   = 2; // (2 == JPEG) before PHP v4.3.0 only JPEG format EXIF thumbnails are returned
3427
-						unset($gdimg_exif_temp);
3428
-					} else {
3429
-						return $this->ErrorImage('Failed - $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data) in '.__FILE__.' on line '.__LINE__);
3430
-					}
3431
-
3432
-				}
3433
-
3434
-			}
3435
-
3436
-		} elseif (!function_exists('exif_thumbnail')) {
3437
-
3438
-			$this->DebugMessage('exif_thumbnail() does not exist, cannot extract EXIF thumbnail', __FILE__, __LINE__);
3439
-
3440
-		}
3441
-
3442
-		$this->DebugMessage('EXIF thumbnail extraction: (size='.strlen($this->exif_thumbnail_data).'; type="'.$this->exif_thumbnail_type.'"; '. (int) $this->exif_thumbnail_width .'x'. (int) $this->exif_thumbnail_height .')', __FILE__, __LINE__);
3443
-
3444
-		// see if EXIF thumbnail can be used directly with no processing
3445
-		if ($this->config_use_exif_thumbnail_for_speed && $this->exif_thumbnail_data) {
3446
-			while (true) {
3447
-				if (!$this->xto) {
3448
-					$source_ar = $this->source_width / $this->source_height;
3449
-					$exif_ar = $this->exif_thumbnail_width / $this->exif_thumbnail_height;
3450
-					if (number_format($source_ar, 2) != number_format($exif_ar, 2)) {
3451
-						$this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar ('.$source_ar.' != '.$exif_ar.')', __FILE__, __LINE__);
3452
-						break;
3453
-					}
3454
-					if ($this->w && ($this->w != $this->exif_thumbnail_width)) {
3455
-						$this->DebugMessage('not using EXIF thumbnail because $this->w != $this->exif_thumbnail_width ('.$this->w.' != '.$this->exif_thumbnail_width.')', __FILE__, __LINE__);
3456
-						break;
3457
-					}
3458
-					if ($this->h && ($this->h != $this->exif_thumbnail_height)) {
3459
-						$this->DebugMessage('not using EXIF thumbnail because $this->h != $this->exif_thumbnail_height ('.$this->h.' != '.$this->exif_thumbnail_height.')', __FILE__, __LINE__);
3460
-						break;
3461
-					}
3462
-					$CannotBeSetParameters = array('sx', 'sy', 'sh', 'sw', 'far', 'bg', 'bc', 'fltr', 'phpThumbDebug');
3463
-					foreach ($CannotBeSetParameters as $parameter) {
3464
-						if ($this->$parameter) {
3465
-							break 2;
3466
-						}
3467
-					}
3468
-				}
3469
-
3470
-				$this->DebugMessage('setting $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data)', __FILE__, __LINE__);
3471
-				$this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data);
3472
-				$this->source_width  = imagesx($this->gdimg_source);
3473
-				$this->source_height = imagesy($this->gdimg_source);
3474
-				return true;
3475
-			}
3476
-		}
3477
-
3478
-		if (($this->config_max_source_pixels > 0) && (($this->source_width * $this->source_height) > $this->config_max_source_pixels)) {
3479
-
3480
-			// Source image is larger than would fit in available PHP memory.
3481
-			// If ImageMagick is installed, use it to generate the thumbnail.
3482
-			// Else, if an EXIF thumbnail is available, use that as the source image.
3483
-			// Otherwise, no choice but to fail with an error message
3484
-			$this->DebugMessage('image is '.$this->source_width.'x'.$this->source_height.' and therefore contains more pixels ('.($this->source_width * $this->source_height).') than $this->config_max_source_pixels setting ('.$this->config_max_source_pixels.')', __FILE__, __LINE__);
3485
-			if (!$this->config_prefer_imagemagick && $this->ImageMagickThumbnailToGD()) {
3486
-				// excellent, we have a thumbnailed source image
3487
-				return true;
3488
-			}
3489
-
3490
-		}
3491
-		return true;
3492
-	}
3493
-
3494
-
3495
-	public function SetCacheFilename() {
3496
-		if (null !== $this->cache_filename) {
3497
-			$this->DebugMessage('$this->cache_filename already set, skipping SetCacheFilename()', __FILE__, __LINE__);
3498
-			return true;
3499
-		}
3500
-		if (null === $this->config_cache_directory) {
3501
-			$this->setCacheDirectory();
3502
-			if (!$this->config_cache_directory) {
3503
-				$this->DebugMessage('SetCacheFilename() failed because $this->config_cache_directory is empty', __FILE__, __LINE__);
3504
-				return false;
3505
-			}
3506
-		}
3507
-		$this->setOutputFormat();
3508
-
3509
-		if (!$this->sourceFilename && !$this->rawImageData && $this->src) {
3510
-			$this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src);
3511
-		}
3512
-
3513
-		if ($this->config_cache_default_only_suffix && $this->sourceFilename) {
3514
-			// simplified cache filenames:
3515
-			// only use default parameters in phpThumb.config.php
3516
-			// substitute source filename into * in $this->config_cache_default_only_suffix
3517
-			// (eg: '*_thumb' becomes 'picture_thumb.jpg')
3518
-			if (strpos($this->config_cache_default_only_suffix, '*') === false) {
3519
-				$this->DebugMessage('aborting simplified caching filename because no * in "'.$this->config_cache_default_only_suffix.'"', __FILE__, __LINE__);
3520
-			} else {
3521
-				preg_match('#(.+)(\\.[a-z0-9]+)?$#i', basename($this->sourceFilename), $matches);
3522
-				$this->cache_filename = $this->config_cache_directory.DIRECTORY_SEPARATOR.rawurlencode(str_replace('*', @$matches[1], $this->config_cache_default_only_suffix)).'.'.strtolower($this->thumbnailFormat);
3523
-				return true;
3524
-			}
3525
-		}
3526
-
3527
-		$this->cache_filename = '';
3528
-		if ($this->new) {
3529
-			$broad_directory_name = strtolower(md5($this->new));
3530
-			$this->cache_filename .= '_new'.$broad_directory_name;
3531
-		} elseif ($this->md5s) {
3532
-			// source image MD5 hash provided
3533
-			$this->DebugMessage('SetCacheFilename() _raw set from $this->md5s = "'.$this->md5s.'"', __FILE__, __LINE__);
3534
-			$broad_directory_name = $this->md5s;
3535
-			$this->cache_filename .= '_raw'.$this->md5s;
3536
-		} elseif (!$this->src && $this->rawImageData) {
3537
-			$this->DebugMessage('SetCacheFilename() _raw set from md5($this->rawImageData) = "'.md5($this->rawImageData).'"', __FILE__, __LINE__);
3538
-			$broad_directory_name = strtolower(md5($this->rawImageData));
3539
-			$this->cache_filename .= '_raw'.$broad_directory_name;
3540
-		} else {
3541
-			$this->DebugMessage('SetCacheFilename() _src set from md5($this->sourceFilename) "'.$this->sourceFilename.'" = "'.md5($this->sourceFilename).'"', __FILE__, __LINE__);
3542
-			$broad_directory_name = strtolower(md5($this->sourceFilename));
3543
-			$this->cache_filename .= '_src'.$broad_directory_name;
3544
-		}
3545
-		if (!empty($_SERVER['HTTP_REFERER']) && $this->config_nooffsitelink_enabled) {
3546
-			$parsed_url1 = @phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
3547
-			$parsed_url2 = @phpthumb_functions::ParseURLbetter('http://'.@$_SERVER['HTTP_HOST']);
3548
-			if (@$parsed_url1['host'] && @$parsed_url2['host'] && ($parsed_url1['host'] != $parsed_url2['host'])) {
3549
-				// include "_offsite" only if nooffsitelink_enabled and if referrer doesn't match the domain of the current server
3550
-				$this->cache_filename .= '_offsite';
3551
-			}
3552
-		}
3553
-
3554
-		$ParametersString = '';
3555
-		if ($this->fltr && is_array($this->fltr)) {
3556
-			$ParametersString .= '_fltr'.implode('_fltr', $this->fltr);
3557
-		}
3558
-		$FilenameParameters1 = array('ar', 'bg', 'bc', 'far', 'sx', 'sy', 'sw', 'sh', 'zc');
3559
-		foreach ($FilenameParameters1 as $key) {
3560
-			if ($this->$key) {
3561
-				$ParametersString .= '_'.$key.$this->$key;
3562
-			}
3563
-		}
3564
-		$FilenameParameters2 = array('h', 'w', 'wl', 'wp', 'ws', 'hp', 'hs', 'xto', 'ra', 'iar', 'aoe', 'maxb', 'sfn', 'dpi');
3565
-		foreach ($FilenameParameters2 as $key) {
3566
-			if ($this->$key) {
3567
-				$ParametersString .= '_'.$key. (int) $this->$key;
3568
-			}
3569
-		}
3570
-		if ($this->thumbnailFormat == 'jpeg') {
3571
-			// only JPEG output has variable quality option
3572
-			$ParametersString .= '_q'. (int) $this->thumbnailQuality;
3573
-		}
3574
-		$this->DebugMessage('SetCacheFilename() _par set from md5('.$ParametersString.')', __FILE__, __LINE__);
3575
-		$this->cache_filename .= '_par'.strtolower(md5($ParametersString));
3576
-
3577
-		if ($this->md5s) {
3578
-			// source image MD5 hash provided
3579
-			// do not source image modification date --
3580
-			// cached image will be used even if file was modified or removed
3581
-		} elseif (!$this->config_cache_source_filemtime_ignore_remote && preg_match('#^(f|ht)tps?\://#i', $this->src)) {
3582
-			$this->cache_filename .= '_dat'. (int) phpthumb_functions::filedate_remote($this->src);
3583
-		} elseif (!$this->config_cache_source_filemtime_ignore_local && $this->src && !$this->rawImageData) {
3584
-			$this->cache_filename .= '_dat'. (int) (@filemtime($this->sourceFilename));
3585
-		}
3586
-
3587
-		$this->cache_filename .= '.'.strtolower($this->thumbnailFormat);
3588
-		$broad_directories = '';
3589
-		for ($i = 0; $i < $this->config_cache_directory_depth; $i++) {
3590
-			$broad_directories .= DIRECTORY_SEPARATOR.substr($broad_directory_name, 0, $i + 1);
3591
-		}
3592
-
3593
-		$this->cache_filename = $this->config_cache_directory.$broad_directories.DIRECTORY_SEPARATOR.$this->config_cache_prefix.rawurlencode($this->cache_filename);
3594
-		return true;
3595
-	}
3596
-
3597
-
3598
-	public function SourceImageIsTooLarge($width, $height) {
3599
-		if (!$this->config_max_source_pixels) {
3600
-			return false;
3601
-		}
3602
-		if ($this->php_memory_limit && function_exists('memory_get_usage')) {
3603
-			$available_memory = $this->php_memory_limit - memory_get_usage();
3604
-			return (bool) (($width * $height * 5) > $available_memory);
3605
-		}
3606
-		return (bool) (($width * $height) > $this->config_max_source_pixels);
3607
-	}
3608
-
3609
-	public function ImageCreateFromFilename($filename) {
3610
-		// try to create GD image source directly via GD, if possible,
3611
-		// rather than buffering to memory and creating with imagecreatefromstring
3612
-		$ImageCreateWasAttempted = false;
3613
-		$gd_image = false;
3614
-
3615
-		$this->DebugMessage('starting ImageCreateFromFilename('.$filename.')', __FILE__, __LINE__);
3616
-		if ($filename && ($getimagesizeinfo = @getimagesize($filename))) {
3617
-			if (!$this->SourceImageIsTooLarge($getimagesizeinfo[0], $getimagesizeinfo[1])) {
3618
-				$ImageCreateFromFunction = array(
3619
-					1  => 'imagecreatefromgif',
3620
-					2  => 'imagecreatefromjpeg',
3621
-					3  => 'imagecreatefrompng',
3622
-					15 => 'imagecreatefromwbmp',
3623
-				);
3624
-				$this->DebugMessage('ImageCreateFromFilename found ($getimagesizeinfo[2]=='.@$getimagesizeinfo[2].')', __FILE__, __LINE__);
3625
-				switch (@$getimagesizeinfo[2]) {
3626
-					case 1:  // GIF
3627
-					case 2:  // JPEG
3628
-					case 3:  // PNG
3629
-					case 15: // WBMP
3630
-						$ImageCreateFromFunctionName = $ImageCreateFromFunction[$getimagesizeinfo[2]];
3631
-						if (function_exists($ImageCreateFromFunctionName)) {
3632
-							$this->DebugMessage('Calling '.$ImageCreateFromFunctionName.'('.$filename.')', __FILE__, __LINE__);
3633
-							$ImageCreateWasAttempted = true;
3634
-							$gd_image = $ImageCreateFromFunctionName($filename);
3635
-						} else {
3636
-							$this->DebugMessage('NOT calling '.$ImageCreateFromFunctionName.'('.$filename.') because !function_exists('.$ImageCreateFromFunctionName.')', __FILE__, __LINE__);
3637
-						}
3638
-						break;
3639
-
3640
-					case 4:  // SWF
3641
-					case 5:  // PSD
3642
-					case 6:  // BMP
3643
-					case 7:  // TIFF (LE)
3644
-					case 8:  // TIFF (BE)
3645
-					case 9:  // JPC
3646
-					case 10: // JP2
3647
-					case 11: // JPX
3648
-					case 12: // JB2
3649
-					case 13: // SWC
3650
-					case 14: // IFF
3651
-					case 16: // XBM
3652
-						$this->DebugMessage('No built-in image creation function for image type "'.@$getimagesizeinfo[2].'" ($getimagesizeinfo[2])', __FILE__, __LINE__);
3653
-						break;
3654
-
3655
-					default:
3656
-						$this->DebugMessage('Unknown value for $getimagesizeinfo[2]: "'.@$getimagesizeinfo[2].'"', __FILE__, __LINE__);
3657
-						break;
3658
-				}
3659
-			} else {
3660
-				$this->DebugMessage('image is '.$getimagesizeinfo[0].'x'.$getimagesizeinfo[1].' and therefore contains more pixels ('.($getimagesizeinfo[0] * $getimagesizeinfo[1]).') than $this->config_max_source_pixels setting ('.$this->config_max_source_pixels.')', __FILE__, __LINE__);
3661
-				return false;
3662
-			}
3663
-		} else {
3664
-			$this->DebugMessage('empty $filename or getimagesize('.$filename.') failed', __FILE__, __LINE__);
3665
-		}
3666
-
3667
-		if (!$gd_image) {
3668
-			// cannot create from filename, attempt to create source image with imagecreatefromstring, if possible
3669
-			if ($ImageCreateWasAttempted) {
3670
-				$this->DebugMessage($ImageCreateFromFunctionName.'() was attempted but FAILED', __FILE__, __LINE__);
3671
-			}
3672
-			$this->DebugMessage('Populating $rawimagedata', __FILE__, __LINE__);
3673
-			$rawimagedata = '';
3674
-			if ($fp = @fopen($filename, 'rb')) {
3675
-				$filesize = filesize($filename);
3676
-				$blocksize = 8192;
3677
-				$blockreads = ceil($filesize / $blocksize);
3678
-				for ($i = 0; $i < $blockreads; $i++) {
3679
-					$rawimagedata .= fread($fp, $blocksize);
3680
-				}
3681
-				fclose($fp);
3682
-			} else {
3683
-				$this->DebugMessage('cannot fopen('.$filename.')', __FILE__, __LINE__);
3684
-			}
3685
-			if ($rawimagedata) {
3686
-				$this->DebugMessage('attempting ImageCreateFromStringReplacement($rawimagedata ('.strlen($rawimagedata).' bytes), true)', __FILE__, __LINE__);
3687
-				$gd_image = $this->ImageCreateFromStringReplacement($rawimagedata, true);
3688
-			}
3689
-		}
3690
-		return $gd_image;
3691
-	}
3692
-
3693
-	public function SourceImageToGD() {
3694
-		if (is_resource($this->gdimg_source)) {
3695
-			$this->source_width  = imagesx($this->gdimg_source);
3696
-			$this->source_height = imagesy($this->gdimg_source);
3697
-			$this->DebugMessage('skipping SourceImageToGD() because $this->gdimg_source is already a resource ('.$this->source_width.'x'.$this->source_height.')', __FILE__, __LINE__);
3698
-			return true;
3699
-		}
3700
-		$this->DebugMessage('starting SourceImageToGD()', __FILE__, __LINE__);
3701
-
3702
-		if ($this->config_prefer_imagemagick) {
3703
-			if (empty($this->sourceFilename) && !empty($this->rawImageData)) {
3704
-				$this->DebugMessage('Copying raw image data to temp file and trying again with ImageMagick', __FILE__, __LINE__);
3705
-				if ($tempnam = $this->phpThumb_tempnam()) {
3706
-					if (file_put_contents($tempnam, $this->rawImageData)) {
3707
-						$this->sourceFilename = $tempnam;
3708
-						if ($this->ImageMagickThumbnailToGD()) {
3709
-							// excellent, we have a thumbnailed source image
3710
-							$this->DebugMessage('ImageMagickThumbnailToGD() succeeded', __FILE__, __LINE__);
3711
-						} else {
3712
-							$this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__);
3713
-						}
3714
-						@chmod($tempnam, $this->getParameter('config_file_create_mask'));
3715
-					} else {
3716
-						$this->DebugMessage('failed to put $this->rawImageData into temp file "'.$tempnam.'"', __FILE__, __LINE__);
3717
-					}
3718
-				} else {
3719
-					$this->DebugMessage('failed to generate temp file name', __FILE__, __LINE__);
3720
-				}
3721
-			}
3722
-		}
3723
-		if (!$this->gdimg_source && $this->rawImageData) {
3724
-
3725
-			if ($this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3726
-				$memory_get_usage = (function_exists('memory_get_usage') ? memory_get_usage() : 0);
3727
-				return $this->ErrorImage('Source image is too large ('.$this->source_width.'x'.$this->source_height.' = '.number_format($this->source_width * $this->source_height / 1000000, 1).'Mpx, max='.number_format($this->config_max_source_pixels / 1000000, 1).'Mpx) for GD creation (either install ImageMagick or increase PHP memory_limit to at least '.ceil(($memory_get_usage + (5 * $this->source_width * $this->source_height)) / 1048576).'M).');
3728
-			}
3729
-			if ($this->md5s && ($this->md5s != md5($this->rawImageData))) {
3730
-				return $this->ErrorImage('$this->md5s != md5($this->rawImageData)'."\n".'"'.$this->md5s.'" != '."\n".'"'.md5($this->rawImageData).'"');
3731
-			}
3732
-			//if ($this->issafemode) {
3733
-			//	return $this->ErrorImage('Cannot generate thumbnails from raw image data when PHP SAFE_MODE enabled');
3734
-			//}
3735
-			$this->gdimg_source = $this->ImageCreateFromStringReplacement($this->rawImageData);
3736
-			if (!$this->gdimg_source) {
3737
-				if (substr($this->rawImageData, 0, 2) === 'BM') {
3738
-					$this->getimagesizeinfo[2] = 6; // BMP
3739
-				} elseif (substr($this->rawImageData, 0, 4) === 'II'."\x2A\x00") {
3740
-					$this->getimagesizeinfo[2] = 7; // TIFF (littlendian)
3741
-				} elseif (substr($this->rawImageData, 0, 4) === 'MM'."\x00\x2A") {
3742
-					$this->getimagesizeinfo[2] = 8; // TIFF (bigendian)
3743
-				}
3744
-				$this->DebugMessage('SourceImageToGD.ImageCreateFromStringReplacement() failed with unknown image type "'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).')', __FILE__, __LINE__);
3268
+            }
3269
+
3270
+            $this->thumbnail_image_width  = $maxwidth;
3271
+            $this->thumbnail_image_height = $maxheight;
3272
+            $this->thumbnail_width  = $maxwidth;
3273
+            $this->thumbnail_height = $maxheight;
3274
+
3275
+            $this->FixedAspectRatio();
3276
+        }
3277
+
3278
+        $this->thumbnail_width  = max(1, floor($this->thumbnail_width));
3279
+        $this->thumbnail_height = max(1, floor($this->thumbnail_height));
3280
+        return true;
3281
+    }
3282
+
3283
+
3284
+    public function CreateGDoutput() {
3285
+        $this->CalculateThumbnailDimensions();
3286
+
3287
+        // create the GD image (either true-color or 256-color, depending on GD version)
3288
+        $this->gdimg_output = phpthumb_functions::ImageCreateFunction($this->thumbnail_width, $this->thumbnail_height);
3289
+
3290
+        // images that have transparency must have the background filled with the configured 'bg' color otherwise the transparent color will appear as black
3291
+        imagesavealpha($this->gdimg_output, true);
3292
+        if ($this->is_alpha && phpthumb_functions::gd_version() >= 2) {
3293
+
3294
+            imagealphablending($this->gdimg_output, false);
3295
+            $output_full_alpha = phpthumb_functions::ImageColorAllocateAlphaSafe($this->gdimg_output, 255, 255, 255, 127);
3296
+            imagefilledrectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $output_full_alpha);
3297
+
3298
+        } else {
3299
+
3300
+            $current_transparent_color = imagecolortransparent($this->gdimg_source);
3301
+            if ($this->bg || (@$current_transparent_color >= 0)) {
3302
+
3303
+                $this->config_background_hexcolor = ($this->bg ? $this->bg : $this->config_background_hexcolor);
3304
+                if (!phpthumb_functions::IsHexColor($this->config_background_hexcolor)) {
3305
+                    return $this->ErrorImage('Invalid hex color string "'.$this->config_background_hexcolor.'" for parameter "bg"');
3306
+                }
3307
+                $background_color = phpthumb_functions::ImageHexColorAllocate($this->gdimg_output, $this->config_background_hexcolor);
3308
+                imagefilledrectangle($this->gdimg_output, 0, 0, $this->thumbnail_width, $this->thumbnail_height, $background_color);
3309
+
3310
+            }
3311
+
3312
+        }
3313
+        $this->DebugMessage('CreateGDoutput() returning canvas "'.$this->thumbnail_width.'x'.$this->thumbnail_height.'"', __FILE__, __LINE__);
3314
+        return true;
3315
+    }
3316
+
3317
+    public function SetOrientationDependantWidthHeight() {
3318
+        $this->DebugMessage('SetOrientationDependantWidthHeight() starting with "'.$this->source_width.'"x"'.$this->source_height.'"', __FILE__, __LINE__);
3319
+        if ($this->source_height > $this->source_width) {
3320
+            // portrait
3321
+            $this->w = phpthumb_functions::OneOfThese($this->wp, $this->w, $this->ws, $this->wl);
3322
+            $this->h = phpthumb_functions::OneOfThese($this->hp, $this->h, $this->hs, $this->hl);
3323
+        } elseif ($this->source_height < $this->source_width) {
3324
+            // landscape
3325
+            $this->w = phpthumb_functions::OneOfThese($this->wl, $this->w, $this->ws, $this->wp);
3326
+            $this->h = phpthumb_functions::OneOfThese($this->hl, $this->h, $this->hs, $this->hp);
3327
+        } else {
3328
+            // square
3329
+            $this->w = phpthumb_functions::OneOfThese($this->ws, $this->w, $this->wl, $this->wp);
3330
+            $this->h = phpthumb_functions::OneOfThese($this->hs, $this->h, $this->hl, $this->hp);
3331
+        }
3332
+        //$this->w = round($this->w ? $this->w : (($this->h && $this->source_height) ? $this->h * $this->source_width  / $this->source_height : $this->w));
3333
+        //$this->h = round($this->h ? $this->h : (($this->w && $this->source_width)  ? $this->w * $this->source_height / $this->source_width  : $this->h));
3334
+        $this->DebugMessage('SetOrientationDependantWidthHeight() setting w="'. (int) $this->w .'", h="'. (int) $this->h .'"', __FILE__, __LINE__);
3335
+        return true;
3336
+    }
3337
+
3338
+    public function ExtractEXIFgetImageSize() {
3339
+        $this->DebugMessage('starting ExtractEXIFgetImageSize()', __FILE__, __LINE__);
3340
+
3341
+        if (preg_match('#^http:#i', $this->src) && !$this->sourceFilename && $this->rawImageData) {
3342
+            $this->SourceDataToTempFile();
3343
+        }
3344
+        if (null === $this->getimagesizeinfo) {
3345
+            if ($this->sourceFilename) {
3346
+                $this->getimagesizeinfo = @getimagesize($this->sourceFilename);
3347
+                $this->source_width  = $this->getimagesizeinfo[0];
3348
+                $this->source_height = $this->getimagesizeinfo[1];
3349
+                $this->DebugMessage('getimagesize('.$this->sourceFilename.') says image is '.$this->source_width.'x'.$this->source_height, __FILE__, __LINE__);
3350
+            } else {
3351
+                $this->DebugMessage('skipping getimagesize() because $this->sourceFilename is empty', __FILE__, __LINE__);
3352
+            }
3353
+        } else {
3354
+            $this->DebugMessage('skipping getimagesize() because !is_null($this->getimagesizeinfo)', __FILE__, __LINE__);
3355
+        }
3356
+
3357
+        if (is_resource($this->gdimg_source)) {
3358
+
3359
+            $this->source_width  = imagesx($this->gdimg_source);
3360
+            $this->source_height = imagesy($this->gdimg_source);
3361
+
3362
+            $this->SetOrientationDependantWidthHeight();
3363
+
3364
+        } elseif ($this->rawImageData && !$this->sourceFilename) {
3365
+
3366
+            if ($this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3367
+                $this->DebugMessage('NOT bypassing EXIF and getimagesize sections because source image is too large for GD ('.$this->source_width.'x'.$this->source_width.'='.($this->source_width * $this->source_height * 5).'MB)', __FILE__, __LINE__);
3368
+            } else {
3369
+                $this->DebugMessage('bypassing EXIF and getimagesize sections because $this->rawImageData is set, and $this->sourceFilename is not set, and source image is not too large for GD ('.$this->source_width.'x'.$this->source_width.'='.($this->source_width * $this->source_height * 5).'MB)', __FILE__, __LINE__);
3370
+            }
3371
+
3372
+        }
3373
+
3374
+        if (!empty($this->getimagesizeinfo)) {
3375
+            // great
3376
+            $this->getimagesizeinfo['filesize'] = @filesize($this->sourceFilename);
3377
+        } elseif (!$this->rawImageData) {
3378
+            $this->DebugMessage('getimagesize("'.$this->sourceFilename.'") failed', __FILE__, __LINE__);
3379
+        }
3380
+
3381
+        if ($this->config_prefer_imagemagick) {
3382
+            if ($this->ImageMagickThumbnailToGD()) {
3383
+                return true;
3384
+            }
3385
+            $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__);
3386
+        }
3387
+
3388
+        $this->source_width  = $this->getimagesizeinfo[0];
3389
+        $this->source_height = $this->getimagesizeinfo[1];
3390
+
3391
+        $this->SetOrientationDependantWidthHeight();
3392
+
3393
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.2.0', '>=') && function_exists('exif_read_data')) {
3394
+            switch ($this->getimagesizeinfo[2]) {
3395
+                case IMAGETYPE_JPEG:
3396
+                case IMAGETYPE_TIFF_II:
3397
+                case IMAGETYPE_TIFF_MM:
3398
+                    $this->exif_raw_data = @exif_read_data($this->sourceFilename, 0, true);
3399
+                    break;
3400
+            }
3401
+        }
3402
+        if (function_exists('exif_thumbnail') && ($this->getimagesizeinfo[2] == IMAGETYPE_JPEG)) {
3403
+            // Extract EXIF info from JPEGs
3404
+
3405
+            $this->exif_thumbnail_width  = '';
3406
+            $this->exif_thumbnail_height = '';
3407
+            $this->exif_thumbnail_type   = '';
3408
+
3409
+            // The parameters width, height and imagetype are available since PHP v4.3.0
3410
+            if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.3.0', '>=')) {
3411
+
3412
+                $this->exif_thumbnail_data = @exif_thumbnail($this->sourceFilename, $this->exif_thumbnail_width, $this->exif_thumbnail_height, $this->exif_thumbnail_type);
3413
+
3414
+            } else {
3415
+
3416
+                // older versions of exif_thumbnail output an error message but NOT return false on failure
3417
+                ob_start();
3418
+                $this->exif_thumbnail_data = exif_thumbnail($this->sourceFilename);
3419
+                $exit_thumbnail_error = ob_get_contents();
3420
+                ob_end_clean();
3421
+                if (!$exit_thumbnail_error && $this->exif_thumbnail_data) {
3422
+
3423
+                    if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
3424
+                        $this->exif_thumbnail_width  = imagesx($gdimg_exif_temp);
3425
+                        $this->exif_thumbnail_height = imagesy($gdimg_exif_temp);
3426
+                        $this->exif_thumbnail_type   = 2; // (2 == JPEG) before PHP v4.3.0 only JPEG format EXIF thumbnails are returned
3427
+                        unset($gdimg_exif_temp);
3428
+                    } else {
3429
+                        return $this->ErrorImage('Failed - $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data) in '.__FILE__.' on line '.__LINE__);
3430
+                    }
3431
+
3432
+                }
3433
+
3434
+            }
3435
+
3436
+        } elseif (!function_exists('exif_thumbnail')) {
3437
+
3438
+            $this->DebugMessage('exif_thumbnail() does not exist, cannot extract EXIF thumbnail', __FILE__, __LINE__);
3439
+
3440
+        }
3441
+
3442
+        $this->DebugMessage('EXIF thumbnail extraction: (size='.strlen($this->exif_thumbnail_data).'; type="'.$this->exif_thumbnail_type.'"; '. (int) $this->exif_thumbnail_width .'x'. (int) $this->exif_thumbnail_height .')', __FILE__, __LINE__);
3443
+
3444
+        // see if EXIF thumbnail can be used directly with no processing
3445
+        if ($this->config_use_exif_thumbnail_for_speed && $this->exif_thumbnail_data) {
3446
+            while (true) {
3447
+                if (!$this->xto) {
3448
+                    $source_ar = $this->source_width / $this->source_height;
3449
+                    $exif_ar = $this->exif_thumbnail_width / $this->exif_thumbnail_height;
3450
+                    if (number_format($source_ar, 2) != number_format($exif_ar, 2)) {
3451
+                        $this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar ('.$source_ar.' != '.$exif_ar.')', __FILE__, __LINE__);
3452
+                        break;
3453
+                    }
3454
+                    if ($this->w && ($this->w != $this->exif_thumbnail_width)) {
3455
+                        $this->DebugMessage('not using EXIF thumbnail because $this->w != $this->exif_thumbnail_width ('.$this->w.' != '.$this->exif_thumbnail_width.')', __FILE__, __LINE__);
3456
+                        break;
3457
+                    }
3458
+                    if ($this->h && ($this->h != $this->exif_thumbnail_height)) {
3459
+                        $this->DebugMessage('not using EXIF thumbnail because $this->h != $this->exif_thumbnail_height ('.$this->h.' != '.$this->exif_thumbnail_height.')', __FILE__, __LINE__);
3460
+                        break;
3461
+                    }
3462
+                    $CannotBeSetParameters = array('sx', 'sy', 'sh', 'sw', 'far', 'bg', 'bc', 'fltr', 'phpThumbDebug');
3463
+                    foreach ($CannotBeSetParameters as $parameter) {
3464
+                        if ($this->$parameter) {
3465
+                            break 2;
3466
+                        }
3467
+                    }
3468
+                }
3469
+
3470
+                $this->DebugMessage('setting $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data)', __FILE__, __LINE__);
3471
+                $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data);
3472
+                $this->source_width  = imagesx($this->gdimg_source);
3473
+                $this->source_height = imagesy($this->gdimg_source);
3474
+                return true;
3475
+            }
3476
+        }
3477
+
3478
+        if (($this->config_max_source_pixels > 0) && (($this->source_width * $this->source_height) > $this->config_max_source_pixels)) {
3479
+
3480
+            // Source image is larger than would fit in available PHP memory.
3481
+            // If ImageMagick is installed, use it to generate the thumbnail.
3482
+            // Else, if an EXIF thumbnail is available, use that as the source image.
3483
+            // Otherwise, no choice but to fail with an error message
3484
+            $this->DebugMessage('image is '.$this->source_width.'x'.$this->source_height.' and therefore contains more pixels ('.($this->source_width * $this->source_height).') than $this->config_max_source_pixels setting ('.$this->config_max_source_pixels.')', __FILE__, __LINE__);
3485
+            if (!$this->config_prefer_imagemagick && $this->ImageMagickThumbnailToGD()) {
3486
+                // excellent, we have a thumbnailed source image
3487
+                return true;
3488
+            }
3489
+
3490
+        }
3491
+        return true;
3492
+    }
3493
+
3494
+
3495
+    public function SetCacheFilename() {
3496
+        if (null !== $this->cache_filename) {
3497
+            $this->DebugMessage('$this->cache_filename already set, skipping SetCacheFilename()', __FILE__, __LINE__);
3498
+            return true;
3499
+        }
3500
+        if (null === $this->config_cache_directory) {
3501
+            $this->setCacheDirectory();
3502
+            if (!$this->config_cache_directory) {
3503
+                $this->DebugMessage('SetCacheFilename() failed because $this->config_cache_directory is empty', __FILE__, __LINE__);
3504
+                return false;
3505
+            }
3506
+        }
3507
+        $this->setOutputFormat();
3508
+
3509
+        if (!$this->sourceFilename && !$this->rawImageData && $this->src) {
3510
+            $this->sourceFilename = $this->ResolveFilenameToAbsolute($this->src);
3511
+        }
3512
+
3513
+        if ($this->config_cache_default_only_suffix && $this->sourceFilename) {
3514
+            // simplified cache filenames:
3515
+            // only use default parameters in phpThumb.config.php
3516
+            // substitute source filename into * in $this->config_cache_default_only_suffix
3517
+            // (eg: '*_thumb' becomes 'picture_thumb.jpg')
3518
+            if (strpos($this->config_cache_default_only_suffix, '*') === false) {
3519
+                $this->DebugMessage('aborting simplified caching filename because no * in "'.$this->config_cache_default_only_suffix.'"', __FILE__, __LINE__);
3520
+            } else {
3521
+                preg_match('#(.+)(\\.[a-z0-9]+)?$#i', basename($this->sourceFilename), $matches);
3522
+                $this->cache_filename = $this->config_cache_directory.DIRECTORY_SEPARATOR.rawurlencode(str_replace('*', @$matches[1], $this->config_cache_default_only_suffix)).'.'.strtolower($this->thumbnailFormat);
3523
+                return true;
3524
+            }
3525
+        }
3526
+
3527
+        $this->cache_filename = '';
3528
+        if ($this->new) {
3529
+            $broad_directory_name = strtolower(md5($this->new));
3530
+            $this->cache_filename .= '_new'.$broad_directory_name;
3531
+        } elseif ($this->md5s) {
3532
+            // source image MD5 hash provided
3533
+            $this->DebugMessage('SetCacheFilename() _raw set from $this->md5s = "'.$this->md5s.'"', __FILE__, __LINE__);
3534
+            $broad_directory_name = $this->md5s;
3535
+            $this->cache_filename .= '_raw'.$this->md5s;
3536
+        } elseif (!$this->src && $this->rawImageData) {
3537
+            $this->DebugMessage('SetCacheFilename() _raw set from md5($this->rawImageData) = "'.md5($this->rawImageData).'"', __FILE__, __LINE__);
3538
+            $broad_directory_name = strtolower(md5($this->rawImageData));
3539
+            $this->cache_filename .= '_raw'.$broad_directory_name;
3540
+        } else {
3541
+            $this->DebugMessage('SetCacheFilename() _src set from md5($this->sourceFilename) "'.$this->sourceFilename.'" = "'.md5($this->sourceFilename).'"', __FILE__, __LINE__);
3542
+            $broad_directory_name = strtolower(md5($this->sourceFilename));
3543
+            $this->cache_filename .= '_src'.$broad_directory_name;
3544
+        }
3545
+        if (!empty($_SERVER['HTTP_REFERER']) && $this->config_nooffsitelink_enabled) {
3546
+            $parsed_url1 = @phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
3547
+            $parsed_url2 = @phpthumb_functions::ParseURLbetter('http://'.@$_SERVER['HTTP_HOST']);
3548
+            if (@$parsed_url1['host'] && @$parsed_url2['host'] && ($parsed_url1['host'] != $parsed_url2['host'])) {
3549
+                // include "_offsite" only if nooffsitelink_enabled and if referrer doesn't match the domain of the current server
3550
+                $this->cache_filename .= '_offsite';
3551
+            }
3552
+        }
3553
+
3554
+        $ParametersString = '';
3555
+        if ($this->fltr && is_array($this->fltr)) {
3556
+            $ParametersString .= '_fltr'.implode('_fltr', $this->fltr);
3557
+        }
3558
+        $FilenameParameters1 = array('ar', 'bg', 'bc', 'far', 'sx', 'sy', 'sw', 'sh', 'zc');
3559
+        foreach ($FilenameParameters1 as $key) {
3560
+            if ($this->$key) {
3561
+                $ParametersString .= '_'.$key.$this->$key;
3562
+            }
3563
+        }
3564
+        $FilenameParameters2 = array('h', 'w', 'wl', 'wp', 'ws', 'hp', 'hs', 'xto', 'ra', 'iar', 'aoe', 'maxb', 'sfn', 'dpi');
3565
+        foreach ($FilenameParameters2 as $key) {
3566
+            if ($this->$key) {
3567
+                $ParametersString .= '_'.$key. (int) $this->$key;
3568
+            }
3569
+        }
3570
+        if ($this->thumbnailFormat == 'jpeg') {
3571
+            // only JPEG output has variable quality option
3572
+            $ParametersString .= '_q'. (int) $this->thumbnailQuality;
3573
+        }
3574
+        $this->DebugMessage('SetCacheFilename() _par set from md5('.$ParametersString.')', __FILE__, __LINE__);
3575
+        $this->cache_filename .= '_par'.strtolower(md5($ParametersString));
3576
+
3577
+        if ($this->md5s) {
3578
+            // source image MD5 hash provided
3579
+            // do not source image modification date --
3580
+            // cached image will be used even if file was modified or removed
3581
+        } elseif (!$this->config_cache_source_filemtime_ignore_remote && preg_match('#^(f|ht)tps?\://#i', $this->src)) {
3582
+            $this->cache_filename .= '_dat'. (int) phpthumb_functions::filedate_remote($this->src);
3583
+        } elseif (!$this->config_cache_source_filemtime_ignore_local && $this->src && !$this->rawImageData) {
3584
+            $this->cache_filename .= '_dat'. (int) (@filemtime($this->sourceFilename));
3585
+        }
3586
+
3587
+        $this->cache_filename .= '.'.strtolower($this->thumbnailFormat);
3588
+        $broad_directories = '';
3589
+        for ($i = 0; $i < $this->config_cache_directory_depth; $i++) {
3590
+            $broad_directories .= DIRECTORY_SEPARATOR.substr($broad_directory_name, 0, $i + 1);
3591
+        }
3592
+
3593
+        $this->cache_filename = $this->config_cache_directory.$broad_directories.DIRECTORY_SEPARATOR.$this->config_cache_prefix.rawurlencode($this->cache_filename);
3594
+        return true;
3595
+    }
3596
+
3597
+
3598
+    public function SourceImageIsTooLarge($width, $height) {
3599
+        if (!$this->config_max_source_pixels) {
3600
+            return false;
3601
+        }
3602
+        if ($this->php_memory_limit && function_exists('memory_get_usage')) {
3603
+            $available_memory = $this->php_memory_limit - memory_get_usage();
3604
+            return (bool) (($width * $height * 5) > $available_memory);
3605
+        }
3606
+        return (bool) (($width * $height) > $this->config_max_source_pixels);
3607
+    }
3608
+
3609
+    public function ImageCreateFromFilename($filename) {
3610
+        // try to create GD image source directly via GD, if possible,
3611
+        // rather than buffering to memory and creating with imagecreatefromstring
3612
+        $ImageCreateWasAttempted = false;
3613
+        $gd_image = false;
3614
+
3615
+        $this->DebugMessage('starting ImageCreateFromFilename('.$filename.')', __FILE__, __LINE__);
3616
+        if ($filename && ($getimagesizeinfo = @getimagesize($filename))) {
3617
+            if (!$this->SourceImageIsTooLarge($getimagesizeinfo[0], $getimagesizeinfo[1])) {
3618
+                $ImageCreateFromFunction = array(
3619
+                    1  => 'imagecreatefromgif',
3620
+                    2  => 'imagecreatefromjpeg',
3621
+                    3  => 'imagecreatefrompng',
3622
+                    15 => 'imagecreatefromwbmp',
3623
+                );
3624
+                $this->DebugMessage('ImageCreateFromFilename found ($getimagesizeinfo[2]=='.@$getimagesizeinfo[2].')', __FILE__, __LINE__);
3625
+                switch (@$getimagesizeinfo[2]) {
3626
+                    case 1:  // GIF
3627
+                    case 2:  // JPEG
3628
+                    case 3:  // PNG
3629
+                    case 15: // WBMP
3630
+                        $ImageCreateFromFunctionName = $ImageCreateFromFunction[$getimagesizeinfo[2]];
3631
+                        if (function_exists($ImageCreateFromFunctionName)) {
3632
+                            $this->DebugMessage('Calling '.$ImageCreateFromFunctionName.'('.$filename.')', __FILE__, __LINE__);
3633
+                            $ImageCreateWasAttempted = true;
3634
+                            $gd_image = $ImageCreateFromFunctionName($filename);
3635
+                        } else {
3636
+                            $this->DebugMessage('NOT calling '.$ImageCreateFromFunctionName.'('.$filename.') because !function_exists('.$ImageCreateFromFunctionName.')', __FILE__, __LINE__);
3637
+                        }
3638
+                        break;
3639
+
3640
+                    case 4:  // SWF
3641
+                    case 5:  // PSD
3642
+                    case 6:  // BMP
3643
+                    case 7:  // TIFF (LE)
3644
+                    case 8:  // TIFF (BE)
3645
+                    case 9:  // JPC
3646
+                    case 10: // JP2
3647
+                    case 11: // JPX
3648
+                    case 12: // JB2
3649
+                    case 13: // SWC
3650
+                    case 14: // IFF
3651
+                    case 16: // XBM
3652
+                        $this->DebugMessage('No built-in image creation function for image type "'.@$getimagesizeinfo[2].'" ($getimagesizeinfo[2])', __FILE__, __LINE__);
3653
+                        break;
3654
+
3655
+                    default:
3656
+                        $this->DebugMessage('Unknown value for $getimagesizeinfo[2]: "'.@$getimagesizeinfo[2].'"', __FILE__, __LINE__);
3657
+                        break;
3658
+                }
3659
+            } else {
3660
+                $this->DebugMessage('image is '.$getimagesizeinfo[0].'x'.$getimagesizeinfo[1].' and therefore contains more pixels ('.($getimagesizeinfo[0] * $getimagesizeinfo[1]).') than $this->config_max_source_pixels setting ('.$this->config_max_source_pixels.')', __FILE__, __LINE__);
3661
+                return false;
3662
+            }
3663
+        } else {
3664
+            $this->DebugMessage('empty $filename or getimagesize('.$filename.') failed', __FILE__, __LINE__);
3665
+        }
3666
+
3667
+        if (!$gd_image) {
3668
+            // cannot create from filename, attempt to create source image with imagecreatefromstring, if possible
3669
+            if ($ImageCreateWasAttempted) {
3670
+                $this->DebugMessage($ImageCreateFromFunctionName.'() was attempted but FAILED', __FILE__, __LINE__);
3671
+            }
3672
+            $this->DebugMessage('Populating $rawimagedata', __FILE__, __LINE__);
3673
+            $rawimagedata = '';
3674
+            if ($fp = @fopen($filename, 'rb')) {
3675
+                $filesize = filesize($filename);
3676
+                $blocksize = 8192;
3677
+                $blockreads = ceil($filesize / $blocksize);
3678
+                for ($i = 0; $i < $blockreads; $i++) {
3679
+                    $rawimagedata .= fread($fp, $blocksize);
3680
+                }
3681
+                fclose($fp);
3682
+            } else {
3683
+                $this->DebugMessage('cannot fopen('.$filename.')', __FILE__, __LINE__);
3684
+            }
3685
+            if ($rawimagedata) {
3686
+                $this->DebugMessage('attempting ImageCreateFromStringReplacement($rawimagedata ('.strlen($rawimagedata).' bytes), true)', __FILE__, __LINE__);
3687
+                $gd_image = $this->ImageCreateFromStringReplacement($rawimagedata, true);
3688
+            }
3689
+        }
3690
+        return $gd_image;
3691
+    }
3692
+
3693
+    public function SourceImageToGD() {
3694
+        if (is_resource($this->gdimg_source)) {
3695
+            $this->source_width  = imagesx($this->gdimg_source);
3696
+            $this->source_height = imagesy($this->gdimg_source);
3697
+            $this->DebugMessage('skipping SourceImageToGD() because $this->gdimg_source is already a resource ('.$this->source_width.'x'.$this->source_height.')', __FILE__, __LINE__);
3698
+            return true;
3699
+        }
3700
+        $this->DebugMessage('starting SourceImageToGD()', __FILE__, __LINE__);
3701
+
3702
+        if ($this->config_prefer_imagemagick) {
3703
+            if (empty($this->sourceFilename) && !empty($this->rawImageData)) {
3704
+                $this->DebugMessage('Copying raw image data to temp file and trying again with ImageMagick', __FILE__, __LINE__);
3705
+                if ($tempnam = $this->phpThumb_tempnam()) {
3706
+                    if (file_put_contents($tempnam, $this->rawImageData)) {
3707
+                        $this->sourceFilename = $tempnam;
3708
+                        if ($this->ImageMagickThumbnailToGD()) {
3709
+                            // excellent, we have a thumbnailed source image
3710
+                            $this->DebugMessage('ImageMagickThumbnailToGD() succeeded', __FILE__, __LINE__);
3711
+                        } else {
3712
+                            $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__);
3713
+                        }
3714
+                        @chmod($tempnam, $this->getParameter('config_file_create_mask'));
3715
+                    } else {
3716
+                        $this->DebugMessage('failed to put $this->rawImageData into temp file "'.$tempnam.'"', __FILE__, __LINE__);
3717
+                    }
3718
+                } else {
3719
+                    $this->DebugMessage('failed to generate temp file name', __FILE__, __LINE__);
3720
+                }
3721
+            }
3722
+        }
3723
+        if (!$this->gdimg_source && $this->rawImageData) {
3724
+
3725
+            if ($this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3726
+                $memory_get_usage = (function_exists('memory_get_usage') ? memory_get_usage() : 0);
3727
+                return $this->ErrorImage('Source image is too large ('.$this->source_width.'x'.$this->source_height.' = '.number_format($this->source_width * $this->source_height / 1000000, 1).'Mpx, max='.number_format($this->config_max_source_pixels / 1000000, 1).'Mpx) for GD creation (either install ImageMagick or increase PHP memory_limit to at least '.ceil(($memory_get_usage + (5 * $this->source_width * $this->source_height)) / 1048576).'M).');
3728
+            }
3729
+            if ($this->md5s && ($this->md5s != md5($this->rawImageData))) {
3730
+                return $this->ErrorImage('$this->md5s != md5($this->rawImageData)'."\n".'"'.$this->md5s.'" != '."\n".'"'.md5($this->rawImageData).'"');
3731
+            }
3732
+            //if ($this->issafemode) {
3733
+            //	return $this->ErrorImage('Cannot generate thumbnails from raw image data when PHP SAFE_MODE enabled');
3734
+            //}
3735
+            $this->gdimg_source = $this->ImageCreateFromStringReplacement($this->rawImageData);
3736
+            if (!$this->gdimg_source) {
3737
+                if (substr($this->rawImageData, 0, 2) === 'BM') {
3738
+                    $this->getimagesizeinfo[2] = 6; // BMP
3739
+                } elseif (substr($this->rawImageData, 0, 4) === 'II'."\x2A\x00") {
3740
+                    $this->getimagesizeinfo[2] = 7; // TIFF (littlendian)
3741
+                } elseif (substr($this->rawImageData, 0, 4) === 'MM'."\x00\x2A") {
3742
+                    $this->getimagesizeinfo[2] = 8; // TIFF (bigendian)
3743
+                }
3744
+                $this->DebugMessage('SourceImageToGD.ImageCreateFromStringReplacement() failed with unknown image type "'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).')', __FILE__, __LINE__);
3745 3745
 //				return $this->ErrorImage('Unknown image type identified by "'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).') in SourceImageToGD()['.__LINE__.']');
3746
-			}
3747
-
3748
-		} elseif (!$this->gdimg_source && $this->sourceFilename) {
3749
-
3750
-			if ($this->md5s && ($this->md5s != phpthumb_functions::md5_file_safe($this->sourceFilename))) {
3751
-				return $this->ErrorImage('$this->md5s != md5(sourceFilename)'."\n".'"'.$this->md5s.'" != '."\n".'"'.phpthumb_functions::md5_file_safe($this->sourceFilename).'"');
3752
-			}
3753
-			switch (@$this->getimagesizeinfo[2]) {
3754
-				case 1:
3755
-				case 3:
3756
-					// GIF or PNG input file may have transparency
3757
-					$this->is_alpha = true;
3758
-					break;
3759
-			}
3760
-			if (!$this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3761
-				$this->gdimg_source = $this->ImageCreateFromFilename($this->sourceFilename);
3762
-			}
3763
-
3764
-		}
3765
-
3766
-		while (true) {
3767
-			if ($this->gdimg_source) {
3768
-				$this->DebugMessage('Not using EXIF thumbnail data because $this->gdimg_source is already set', __FILE__, __LINE__);
3769
-				break;
3770
-			}
3771
-			if (!$this->exif_thumbnail_data) {
3772
-				$this->DebugMessage('Not using EXIF thumbnail data because $this->exif_thumbnail_data is empty', __FILE__, __LINE__);
3773
-				break;
3774
-			}
3775
-			if (ini_get('safe_mode')) {
3776
-				if (!$this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3777
-					$this->DebugMessage('Using EXIF thumbnail data because source image too large and safe_mode enabled', __FILE__, __LINE__);
3778
-					$this->aoe = true;
3779
-				} else {
3780
-					break;
3781
-				}
3782
-			} else {
3783
-				if (!$this->config_use_exif_thumbnail_for_speed) {
3784
-					$this->DebugMessage('Not using EXIF thumbnail data because $this->config_use_exif_thumbnail_for_speed is FALSE', __FILE__, __LINE__);
3785
-					break;
3786
-				}
3787
-				if (($this->thumbnailCropX != 0) || ($this->thumbnailCropY != 0)) {
3788
-					$this->DebugMessage('Not using EXIF thumbnail data because source cropping is enabled ('.$this->thumbnailCropX.','.$this->thumbnailCropY.')', __FILE__, __LINE__);
3789
-					break;
3790
-				}
3791
-				if (($this->w > $this->exif_thumbnail_width) || ($this->h > $this->exif_thumbnail_height)) {
3792
-					$this->DebugMessage('Not using EXIF thumbnail data because EXIF thumbnail is too small ('.$this->exif_thumbnail_width.'x'.$this->exif_thumbnail_height.' vs '.$this->w.'x'.$this->h.')', __FILE__, __LINE__);
3793
-					break;
3794
-				}
3795
-				$source_ar = $this->source_width / $this->source_height;
3796
-				$exif_ar   = $this->exif_thumbnail_width / $this->exif_thumbnail_height;
3797
-				if (number_format($source_ar, 2) != number_format($exif_ar, 2)) {
3798
-					$this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar ('.$source_ar.' != '.$exif_ar.')', __FILE__, __LINE__);
3799
-					break;
3800
-				}
3801
-			}
3802
-
3803
-			// EXIF thumbnail exists, and is equal to or larger than destination thumbnail, and will be use as source image
3804
-			$this->DebugMessage('Trying to use EXIF thumbnail as source image', __FILE__, __LINE__);
3805
-
3806
-			if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
3807
-
3808
-				$this->DebugMessage('Successfully using EXIF thumbnail as source image', __FILE__, __LINE__);
3809
-				$this->gdimg_source   = $gdimg_exif_temp;
3810
-				$this->source_width   = $this->exif_thumbnail_width;
3811
-				$this->source_height  = $this->exif_thumbnail_height;
3812
-				$this->thumbnailCropW = $this->source_width;
3813
-				$this->thumbnailCropH = $this->source_height;
3814
-				return true;
3815
-
3816
-			} else {
3817
-				$this->DebugMessage('$this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false) failed', __FILE__, __LINE__);
3818
-			}
3819
-
3820
-			break;
3821
-		}
3822
-
3823
-		if (!$this->gdimg_source) {
3824
-			$this->DebugMessage('$this->gdimg_source is still empty', __FILE__, __LINE__);
3825
-
3826
-			$this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__);
3827
-
3828
-			$imageHeader = '';
3829
-			$gd_info = gd_info();
3830
-			$GDreadSupport = false;
3831
-			switch (@$this->getimagesizeinfo[2]) {
3832
-				case 1:
3833
-					$imageHeader = 'Content-Type: image/gif';
3834
-					$GDreadSupport = (bool) @$gd_info['GIF Read Support'];
3835
-					break;
3836
-				case 2:
3837
-					$imageHeader = 'Content-Type: image/jpeg';
3838
-					$GDreadSupport = (bool) @$gd_info['JPG Support'];
3839
-					break;
3840
-				case 3:
3841
-					$imageHeader = 'Content-Type: image/png';
3842
-					$GDreadSupport = (bool) @$gd_info['PNG Support'];
3843
-					break;
3844
-			}
3845
-			if ($imageHeader) {
3846
-				// cannot create image for whatever reason (maybe imagecreatefromjpeg et al are not available?)
3847
-				// and ImageMagick is not available either, no choice but to output original (not resized/modified) data and exit
3848
-				if ($this->config_error_die_on_source_failure) {
3849
-					$errormessages = array();
3850
-					$errormessages[] = 'All attempts to create GD image source failed.';
3851
-					if ($this->fatalerror) {
3852
-						$errormessages[] = $this->fatalerror;
3853
-					}
3854
-					if ($this->issafemode) {
3855
-						$errormessages[] = 'Safe Mode enabled, therefore ImageMagick is unavailable. (disable Safe Mode if possible)';
3856
-					} elseif (!$this->ImageMagickVersion()) {
3857
-						$errormessages[] = 'ImageMagick is not installed (it is highly recommended that you install it).';
3858
-					}
3859
-					if ($this->SourceImageIsTooLarge($this->getimagesizeinfo[0], $this->getimagesizeinfo[1])) {
3860
-						$memory_get_usage = (function_exists('memory_get_usage') ? memory_get_usage() : 0);
3861
-						$errormessages[] = 'Source image is too large ('.$this->getimagesizeinfo[0].'x'.$this->getimagesizeinfo[1].' = '.number_format($this->getimagesizeinfo[0] * $this->getimagesizeinfo[1] / 1000000, 1).'Mpx, max='.number_format($this->config_max_source_pixels / 1000000, 1).'Mpx) for GD creation (either install ImageMagick or increase PHP memory_limit to at least '.ceil(($memory_get_usage + (5 * $this->getimagesizeinfo[0] * $this->getimagesizeinfo[1])) / 1048576).'M).';
3862
-					} elseif (!$GDreadSupport) {
3863
-						$errormessages[] = 'GD does not have read support for "'.$imageHeader.'".';
3864
-					} else {
3865
-						$errormessages[] = 'Source image probably corrupt.';
3866
-					}
3867
-					$this->ErrorImage(implode("\n", $errormessages));
3868
-
3869
-				} else {
3870
-					$this->DebugMessage('All attempts to create GD image source failed ('.(ini_get('safe_mode') ? 'Safe Mode enabled, ImageMagick unavailable and source image probably too large for GD': ($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"')).'), cannot generate thumbnail');
3871
-					//$this->DebugMessage('All attempts to create GD image source failed ('.($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"').'), outputing raw image', __FILE__, __LINE__);
3872
-					//if (!$this->phpThumbDebug) {
3873
-					//	header($imageHeader);
3874
-					//	echo $this->rawImageData;
3875
-					//	exit;
3876
-					//}
3877
-					return false;
3878
-				}
3879
-			}
3880
-
3881
-			//switch (substr($this->rawImageData, 0, 2)) {
3882
-			//	case 'BM':
3883
-			switch (@$this->getimagesizeinfo[2]) {
3884
-				case 6:
3885
-					ob_start();
3886
-					if (!@include_once( __DIR__ .'/phpthumb.bmp.php')) {
3887
-						ob_end_clean();
3888
-						return $this->ErrorImage('include_once('. __DIR__ .'/phpthumb.bmp.php) failed');
3889
-					}
3890
-					ob_end_clean();
3891
-					if ($fp = @fopen($this->sourceFilename, 'rb')) {
3892
-						$this->rawImageData = '';
3893
-						while (!feof($fp)) {
3894
-							$this->rawImageData .= fread($fp, 32768);
3895
-						}
3896
-						fclose($fp);
3897
-					}
3898
-					$phpthumb_bmp = new phpthumb_bmp();
3899
-					$this->gdimg_source = $phpthumb_bmp->phpthumb_bmp2gd($this->rawImageData, (phpthumb_functions::gd_version() >= 2.0));
3900
-					unset($phpthumb_bmp);
3901
-					if ($this->gdimg_source) {
3902
-						$this->DebugMessage('$phpthumb_bmp->phpthumb_bmp2gd() succeeded', __FILE__, __LINE__);
3903
-					} else {
3904
-						return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on BMP source conversion' : 'phpthumb_bmp2gd() failed');
3905
-					}
3906
-					break;
3907
-			//}
3908
-			//switch (substr($this->rawImageData, 0, 4)) {
3909
-			//	case 'II'."\x2A\x00":
3910
-			//	case 'MM'."\x00\x2A":
3911
-				case 7:
3912
-				case 8:
3913
-					return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on TIFF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support TIFF source images without it');
3914
-					break;
3915
-
3916
-				//case "\xD7\xCD\xC6\x9A":
3917
-				//	return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it');
3918
-				//	break;
3919
-			}
3920
-
3921
-			if (!$this->gdimg_source) {
3922
-				if ($this->rawImageData) {
3923
-					$HeaderFourBytes = substr($this->rawImageData, 0, 4);
3924
-				} elseif ($this->sourceFilename) {
3925
-					if ($fp = @fopen($this->sourceFilename, 'rb')) {
3926
-						$HeaderFourBytes = fread($fp, 4);
3927
-						fclose($fp);
3928
-					} else {
3929
-						return $this->ErrorImage('failed to open "'.$this->sourceFilename.'" SourceImageToGD() ['.__LINE__.']');
3930
-					}
3931
-				} else {
3932
-					return $this->ErrorImage('Unable to create image, neither filename nor image data suppplied in SourceImageToGD() ['.__LINE__.']');
3933
-				}
3934
-				if (!$this->ImageMagickVersion() && !phpthumb_functions::gd_version()) {
3935
-					return $this->ErrorImage('Neither GD nor ImageMagick seem to be installed on this server. At least one (preferably GD), or better both, MUST be installed for phpThumb to work.');
3936
-				} elseif ($HeaderFourBytes == "\xD7\xCD\xC6\x9A") { // WMF
3937
-					return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it');
3938
-				} elseif ($HeaderFourBytes == '%PDF') { // "%PDF"
3939
-					return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick and GhostScript are both required for PDF source images; GhostScript may not be properly configured' : 'ImageMagick and/or GhostScript are unavailable and phpThumb() does not support PDF source images without them');
3940
-				} elseif (substr($HeaderFourBytes, 0, 3) == "\xFF\xD8\xFF") { // JPEG
3941
-					return $this->ErrorImage('Image (JPEG) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting');
3942
-				} elseif ($HeaderFourBytes == '%PNG') { // "%PNG"
3943
-					return $this->ErrorImage('Image (PNG) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting');
3944
-				} elseif (substr($HeaderFourBytes, 0, 3) == 'GIF') { // GIF
3945
-					return $this->ErrorImage('Image (GIF) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting');
3946
-				}
3947
-				return $this->ErrorImage('Unknown image type identified by "'.$HeaderFourBytes.'" ('.phpthumb_functions::HexCharDisplay($HeaderFourBytes).') in SourceImageToGD() ['.__LINE__.']');
3948
-			}
3949
-		}
3950
-
3951
-		if (!$this->gdimg_source) {
3952
-			if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
3953
-				$this->DebugMessage('All other attempts failed, but successfully using EXIF thumbnail as source image', __FILE__, __LINE__);
3954
-				$this->gdimg_source = $gdimg_exif_temp;
3955
-				// override allow-enlarging setting if EXIF thumbnail is the only source available
3956
-				// otherwise thumbnails larger than the EXIF thumbnail will be created at EXIF size
3957
-				$this->aoe = true;
3958
-				return true;
3959
-			}
3960
-			return false;
3961
-		}
3962
-
3963
-		$this->source_width  = imagesx($this->gdimg_source);
3964
-		$this->source_height = imagesy($this->gdimg_source);
3965
-		return true;
3966
-	}
3967
-
3968
-
3969
-	public function phpThumbDebugVarDump($var) {
3970
-		if (null === $var) {
3971
-			return 'NULL';
3972
-		} elseif (is_bool($var)) {
3973
-			return ($var ? 'TRUE' : 'FALSE');
3974
-		} elseif (is_string($var)) {
3975
-			return 'string('.strlen($var).')'.str_repeat(' ', max(0, 3 - strlen(strlen($var)))).' "'.$var.'"';
3976
-		} elseif (is_int($var)) {
3977
-			return 'integer     '.$var;
3978
-		} elseif (is_float($var)) {
3979
-			return 'float       '.$var;
3980
-		} elseif (is_array($var)) {
3981
-			ob_start();
3982
-			var_dump($var);
3983
-			$vardumpoutput = ob_get_contents();
3984
-			ob_end_clean();
3985
-			return strtr($vardumpoutput, "\n\r\t", '   ');
3986
-		}
3987
-		return gettype($var);
3988
-	}
3989
-
3990
-	public function phpThumbDebug($level='') {
3991
-		if ($level && ($this->phpThumbDebug !== $level)) {
3992
-			return true;
3993
-		}
3994
-		if ($this->config_disable_debug) {
3995
-			return $this->ErrorImage('phpThumbDebug disabled');
3996
-		}
3997
-
3998
-		$FunctionsExistance  = array('exif_thumbnail', 'gd_info', 'image_type_to_mime_type', 'getimagesize', 'imagecopyresampled', 'imagecopyresized', 'imagecreate', 'imagecreatefromstring', 'imagecreatetruecolor', 'imageistruecolor', 'imagerotate', 'imagetypes', 'version_compare', 'imagecreatefromgif', 'imagecreatefromjpeg', 'imagecreatefrompng', 'imagecreatefromwbmp', 'imagecreatefromxbm', 'imagecreatefromxpm', 'imagecreatefromstring', 'imagecreatefromgd', 'imagecreatefromgd2', 'imagecreatefromgd2part', 'imagejpeg', 'imagegif', 'imagepng', 'imagewbmp');
3999
-		$ParameterNames      = array('src', 'new', 'w', 'h', 'f', 'q', 'sx', 'sy', 'sw', 'sh', 'far', 'bg', 'bc', 'file', 'goto', 'err', 'xto', 'ra', 'ar', 'aoe', 'iar', 'maxb');
4000
-		$ConfigVariableNames = array('document_root', 'temp_directory', 'output_format', 'output_maxwidth', 'output_maxheight', 'error_message_image_default', 'error_bgcolor', 'error_textcolor', 'error_fontsize', 'error_die_on_error', 'error_silent_die_on_error', 'error_die_on_source_failure', 'nohotlink_enabled', 'nohotlink_valid_domains', 'nohotlink_erase_image', 'nohotlink_text_message', 'nooffsitelink_enabled', 'nooffsitelink_valid_domains', 'nooffsitelink_require_refer', 'nooffsitelink_erase_image', 'nooffsitelink_text_message', 'high_security_enabled', 'allow_src_above_docroot', 'allow_src_above_phpthumb', 'max_source_pixels', 'use_exif_thumbnail_for_speed', 'border_hexcolor', 'background_hexcolor', 'ttf_directory', 'disable_pathinfo_parsing', 'disable_imagecopyresampled');
4001
-		$OtherVariableNames  = array('phpThumbDebug', 'thumbnailQuality', 'thumbnailFormat', 'gdimg_output', 'gdimg_source', 'sourceFilename', 'source_width', 'source_height', 'thumbnailCropX', 'thumbnailCropY', 'thumbnailCropW', 'thumbnailCropH', 'exif_thumbnail_width', 'exif_thumbnail_height', 'exif_thumbnail_type', 'thumbnail_width', 'thumbnail_height', 'thumbnail_image_width', 'thumbnail_image_height');
4002
-
4003
-		$DebugOutput = array();
4004
-		$DebugOutput[] = 'phpThumb() version          = '.$this->phpthumb_version;
4005
-		$DebugOutput[] = 'phpversion()                = '.@PHP_VERSION;
4006
-		$DebugOutput[] = 'PHP_OS                      = '.PHP_OS;
4007
-		$DebugOutput[] = '$_SERVER[SERVER_SOFTWARE]   = '.@$_SERVER['SERVER_SOFTWARE'];
4008
-		$DebugOutput[] = '__FILE__                    = '.__FILE__;
4009
-		$DebugOutput[] = 'realpath(.)                 = '.@realpath('.');
4010
-		$DebugOutput[] = '$_SERVER[PHP_SELF]          = '.@$_SERVER['PHP_SELF'];
4011
-		$DebugOutput[] = '$_SERVER[HOST_NAME]         = '.@$_SERVER['HOST_NAME'];
4012
-		$DebugOutput[] = '$_SERVER[HTTP_REFERER]      = '.@$_SERVER['HTTP_REFERER'];
4013
-		$DebugOutput[] = '$_SERVER[QUERY_STRING]      = '.@$_SERVER['QUERY_STRING'];
4014
-		$DebugOutput[] = '$_SERVER[PATH_INFO]         = '.@$_SERVER['PATH_INFO'];
4015
-		$DebugOutput[] = '$_SERVER[DOCUMENT_ROOT]     = '.@$_SERVER['DOCUMENT_ROOT'];
4016
-		$DebugOutput[] = 'getenv(DOCUMENT_ROOT)       = '.@getenv('DOCUMENT_ROOT');
4017
-		$DebugOutput[] = '';
4018
-
4019
-		$DebugOutput[] = 'get_magic_quotes_gpc()         = '.$this->phpThumbDebugVarDump(@get_magic_quotes_gpc());
4020
-		$DebugOutput[] = 'get_magic_quotes_runtime()     = '.$this->phpThumbDebugVarDump(@get_magic_quotes_runtime());
4021
-		$DebugOutput[] = 'error_reporting()              = '.$this->phpThumbDebugVarDump(error_reporting());
4022
-		$DebugOutput[] = 'ini_get(error_reporting)       = '.$this->phpThumbDebugVarDump(@ini_get('error_reporting'));
4023
-		$DebugOutput[] = 'ini_get(display_errors)        = '.$this->phpThumbDebugVarDump(@ini_get('display_errors'));
4024
-		$DebugOutput[] = 'ini_get(allow_url_fopen)       = '.$this->phpThumbDebugVarDump(@ini_get('allow_url_fopen'));
4025
-		$DebugOutput[] = 'ini_get(disable_functions)     = '.$this->phpThumbDebugVarDump(@ini_get('disable_functions'));
4026
-		$DebugOutput[] = 'get_cfg_var(disable_functions) = '.$this->phpThumbDebugVarDump(@get_cfg_var('disable_functions'));
4027
-		$DebugOutput[] = 'ini_get(safe_mode)             = '.$this->phpThumbDebugVarDump(@ini_get('safe_mode'));
4028
-		$DebugOutput[] = 'ini_get(open_basedir)          = '.$this->phpThumbDebugVarDump(@ini_get('open_basedir'));
4029
-		$DebugOutput[] = 'ini_get(max_execution_time)    = '.$this->phpThumbDebugVarDump(@ini_get('max_execution_time'));
4030
-		$DebugOutput[] = 'ini_get(memory_limit)          = '.$this->phpThumbDebugVarDump(@ini_get('memory_limit'));
4031
-		$DebugOutput[] = 'get_cfg_var(memory_limit)      = '.$this->phpThumbDebugVarDump(@get_cfg_var('memory_limit'));
4032
-		$DebugOutput[] = 'memory_get_usage()             = '.(function_exists('memory_get_usage') ? $this->phpThumbDebugVarDump(@memory_get_usage()) : 'n/a');
4033
-		$DebugOutput[] = '';
4034
-
4035
-		$DebugOutput[] = '$this->config_prefer_imagemagick            = '.$this->phpThumbDebugVarDump($this->config_prefer_imagemagick);
4036
-		$DebugOutput[] = '$this->config_imagemagick_path              = '.$this->phpThumbDebugVarDump($this->config_imagemagick_path);
4037
-		$DebugOutput[] = '$this->ImageMagickWhichConvert()            = '.$this->ImageMagickWhichConvert();
4038
-		$IMpathUsed = ($this->config_imagemagick_path ? $this->config_imagemagick_path : $this->ImageMagickWhichConvert());
4039
-		$DebugOutput[] = '[actual ImageMagick path used]              = '.$this->phpThumbDebugVarDump($IMpathUsed);
4040
-		$DebugOutput[] = 'file_exists([actual ImageMagick path used]) = '.$this->phpThumbDebugVarDump(@file_exists($IMpathUsed));
4041
-		$DebugOutput[] = 'ImageMagickVersion(false)                   = '.$this->ImageMagickVersion(false);
4042
-		$DebugOutput[] = 'ImageMagickVersion(true)                    = '.$this->ImageMagickVersion(true);
4043
-		$DebugOutput[] = '';
4044
-
4045
-		$DebugOutput[] = '$this->config_cache_directory               = '.$this->phpThumbDebugVarDump($this->config_cache_directory);
4046
-		$DebugOutput[] = '$this->config_cache_directory_depth         = '.$this->phpThumbDebugVarDump($this->config_cache_directory_depth);
4047
-		$DebugOutput[] = '$this->config_cache_disable_warning         = '.$this->phpThumbDebugVarDump($this->config_cache_disable_warning);
4048
-		$DebugOutput[] = '$this->config_cache_maxage                  = '.$this->phpThumbDebugVarDump($this->config_cache_maxage);
4049
-		$DebugOutput[] = '$this->config_cache_maxsize                 = '.$this->phpThumbDebugVarDump($this->config_cache_maxsize);
4050
-		$DebugOutput[] = '$this->config_cache_maxfiles                = '.$this->phpThumbDebugVarDump($this->config_cache_maxfiles);
4051
-		$DebugOutput[] = '$this->config_cache_force_passthru          = '.$this->phpThumbDebugVarDump($this->config_cache_force_passthru);
4052
-		$DebugOutput[] = '$this->cache_filename                       = '.$this->phpThumbDebugVarDump($this->cache_filename);
4053
-		$DebugOutput[] = 'is_readable($this->config_cache_directory)  = '.$this->phpThumbDebugVarDump(@is_readable($this->config_cache_directory));
4054
-		$DebugOutput[] = 'is_writable($this->config_cache_directory)  = '.$this->phpThumbDebugVarDump(@is_writable($this->config_cache_directory));
4055
-		$DebugOutput[] = 'is_readable($this->cache_filename)          = '.$this->phpThumbDebugVarDump(@is_readable($this->cache_filename));
4056
-		$DebugOutput[] = 'is_writable($this->cache_filename)          = '.(@file_exists($this->cache_filename) ? $this->phpThumbDebugVarDump(@is_writable($this->cache_filename)) : 'n/a');
4057
-		$DebugOutput[] = '';
4058
-
4059
-		foreach ($ConfigVariableNames as $varname) {
4060
-			$varname = 'config_'.$varname;
4061
-			$value = $this->$varname;
4062
-			$DebugOutput[] = '$this->'.str_pad($varname, 37, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4063
-		}
4064
-		$DebugOutput[] = '';
4065
-		foreach ($OtherVariableNames as $varname) {
4066
-			$value = $this->$varname;
4067
-			$DebugOutput[] = '$this->'.str_pad($varname, 27, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4068
-		}
4069
-		$DebugOutput[] = 'strlen($this->rawImageData)        = '.strlen(@$this->rawImageData);
4070
-		$DebugOutput[] = 'strlen($this->exif_thumbnail_data) = '.strlen(@$this->exif_thumbnail_data);
4071
-		$DebugOutput[] = '';
4072
-
4073
-		foreach ($ParameterNames as $varname) {
4074
-			$value = $this->$varname;
4075
-			$DebugOutput[] = '$this->'.str_pad($varname, 4, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4076
-		}
4077
-		$DebugOutput[] = '';
4078
-
4079
-		foreach ($FunctionsExistance as $functionname) {
4080
-			$DebugOutput[] = 'builtin_function_exists('.$functionname.')'.str_repeat(' ', 23 - strlen($functionname)).' = '.$this->phpThumbDebugVarDump(phpthumb_functions::builtin_function_exists($functionname));
4081
-		}
4082
-		$DebugOutput[] = '';
4083
-
4084
-		$gd_info = gd_info();
4085
-		foreach ($gd_info as $key => $value) {
4086
-			$DebugOutput[] = 'gd_info.'.str_pad($key, 34, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4087
-		}
4088
-		$DebugOutput[] = '';
4089
-
4090
-		$exif_info = phpthumb_functions::exif_info();
4091
-		foreach ($exif_info as $key => $value) {
4092
-			$DebugOutput[] = 'exif_info.'.str_pad($key, 26, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4093
-		}
4094
-		$DebugOutput[] = '';
4095
-
4096
-		if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) {
4097
-			foreach ($ApacheLookupURIarray as $key => $value) {
4098
-				$DebugOutput[] = 'ApacheLookupURIarray.'.str_pad($key, 15, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4099
-			}
4100
-		} else {
4101
-				$DebugOutput[] = 'ApacheLookupURIarray() -- FAILED';
4102
-		}
4103
-		$DebugOutput[] = '';
4104
-
4105
-		if (isset($_GET) && is_array($_GET)) {
4106
-			foreach ($_GET as $key => $value) {
4107
-				$DebugOutput[] = '$_GET['.$key.']'.str_repeat(' ', 30 - strlen($key)).'= '.$this->phpThumbDebugVarDump($value);
4108
-			}
4109
-		}
4110
-		if (isset($_POST) && is_array($_POST)) {
4111
-			foreach ($_POST as $key => $value) {
4112
-				$DebugOutput[] = '$_POST['.$key.']'.str_repeat(' ', 29 - strlen($key)).'= '.$this->phpThumbDebugVarDump($value);
4113
-			}
4114
-		}
4115
-		$DebugOutput[] = '';
4116
-
4117
-		$DebugOutput[] = '$this->debugmessages:';
4118
-		foreach ($this->debugmessages as $errorstring) {
4119
-			$DebugOutput[] = '  * '.$errorstring;
4120
-		}
4121
-		$DebugOutput[] = '';
4122
-
4123
-		$DebugOutput[] = '$this->debugtiming:';
4124
-		foreach ($this->debugtiming as $timestamp => $timingstring) {
4125
-			$DebugOutput[] = '  * '.$timestamp.' '.$timingstring;
4126
-		}
4127
-		$DebugOutput[] = '  * Total processing time: '.number_format(max(array_keys($this->debugtiming)) - min(array_keys($this->debugtiming)), 6);
4128
-
4129
-		$this->f = (isset($_GET['f']) ? $_GET['f'] : $this->f); // debug modes 0-2 don't recognize text mode otherwise
4130
-		return $this->ErrorImage(implode("\n", $DebugOutput), 700, 500, true);
4131
-	}
4132
-
4133
-	public function FatalError($text) {
4134
-		if (null === $this->fatalerror) {
4135
-			$this->fatalerror = $text;
4136
-		}
4137
-		return true;
4138
-	}
4139
-
4140
-	public function ErrorImage($text, $width=0, $height=0, $forcedisplay=false) {
4141
-		$width  = ($width  ? $width  : $this->config_error_image_width);
4142
-		$height = ($height ? $height : $this->config_error_image_height);
4143
-
4144
-		$text = 'phpThumb() v'.$this->phpthumb_version."\n".'http://phpthumb.sourceforge.net'."\n\n".($this->config_disable_debug ? 'Error messages disabled.'."\n\n".'edit phpThumb.config.php and (temporarily) set'."\n".'$PHPTHUMB_CONFIG[\'disable_debug\'] = false;'."\n".'to view the details of this error' : $text);
4145
-
4146
-		$this->FatalError($text);
4147
-		$this->DebugMessage($text, __FILE__, __LINE__);
4148
-		$this->purgeTempFiles();
4149
-		if ($this->config_error_silent_die_on_error) {
4150
-			exit;
4151
-		}
4152
-		if ($this->phpThumbDebug && !$forcedisplay) {
4153
-			return false;
4154
-		}
4155
-		if (!$this->config_error_die_on_error && !$forcedisplay) {
4156
-			return false;
4157
-		}
4158
-		if ($this->err || $this->config_error_message_image_default) {
4159
-			// Show generic custom error image instead of error message
4160
-			// for use on production sites where you don't want debug messages
4161
-			if (($this->err == 'showerror') || $this->phpThumbDebug) {
4162
-				// fall through and actually show error message even if default error image is set
4163
-			} else {
4164
-				header('Location: '.($this->err ? $this->err : $this->config_error_message_image_default));
4165
-				exit;
4166
-			}
4167
-		}
4168
-		$this->setOutputFormat();
4169
-		if (!$this->thumbnailFormat || !$this->config_disable_debug || (phpthumb_functions::gd_version() < 1)) {
4170
-			$this->thumbnailFormat = 'text';
4171
-		}
4172
-		if (@$this->thumbnailFormat == 'text') {
4173
-			// bypass all GD functions and output text error message
4174
-			if (!headers_sent()) {
4175
-				header('Content-type: text/plain');
4176
-				echo $text;
4177
-			} else {
4178
-				echo '<pre>'.htmlspecialchars($text).'</pre>';
4179
-			}
4180
-			exit;
4181
-		}
4182
-
4183
-		$FontWidth  = imagefontwidth($this->config_error_fontsize);
4184
-		$FontHeight = imagefontheight($this->config_error_fontsize);
4185
-
4186
-		$LinesOfText = explode("\n", @wordwrap($text, floor($width / $FontWidth), "\n", true));
4187
-		$height = max($height, count($LinesOfText) * $FontHeight);
4188
-
4189
-		$headers_file = '';
4190
-		$headers_line = '';
4191
-		if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.3.0', '>=') && headers_sent($headers_file, $headers_line)) {
4192
-
4193
-			echo "\n".'**Headers already sent in file "'.$headers_file.'" on line "'.$headers_line.'", dumping error message as text:**<br><pre>'."\n\n".$text."\n".'</pre>';
4194
-
4195
-		} elseif (headers_sent()) {
4196
-
4197
-			echo "\n".'**Headers already sent, dumping error message as text:**<br><pre>'."\n\n".$text."\n".'</pre>';
4198
-
4199
-		} elseif ($gdimg_error = imagecreate($width, $height)) {
4200
-
4201
-			$background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_bgcolor,   true);
4202
-			$text_color       = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_textcolor, true);
4203
-			imagefilledrectangle($gdimg_error, 0, 0, $width, $height, $background_color);
4204
-			$lineYoffset = 0;
4205
-			foreach ($LinesOfText as $line) {
4206
-				imagestring($gdimg_error, $this->config_error_fontsize, 2, $lineYoffset, $line, $text_color);
4207
-				$lineYoffset += $FontHeight;
4208
-			}
4209
-			if (function_exists('imagetypes')) {
4210
-				$imagetypes = imagetypes();
4211
-				if ($imagetypes & IMG_PNG) {
4212
-					header('Content-Type: image/png');
4213
-					imagepng($gdimg_error);
4214
-				} elseif ($imagetypes & IMG_GIF) {
4215
-					header('Content-Type: image/gif');
4216
-					imagegif($gdimg_error);
4217
-				} elseif ($imagetypes & IMG_JPG) {
4218
-					header('Content-Type: image/jpeg');
4219
-					imagejpeg($gdimg_error);
4220
-				} elseif ($imagetypes & IMG_WBMP) {
4221
-					header('Content-Type: image/vnd.wap.wbmp');
4222
-					imagewbmp($gdimg_error);
4223
-				}
4224
-			}
4225
-			imagedestroy($gdimg_error);
4226
-
4227
-		}
4228
-		if (!headers_sent()) {
4229
-			echo "\n".'**Failed to send graphical error image, dumping error message as text:**<br>'."\n\n".$text;
4230
-		}
4231
-		exit;
4232
-	}
4233
-
4234
-	public function ImageCreateFromStringReplacement(&$RawImageData, $DieOnErrors=false) {
4235
-		// there are serious bugs in the non-bundled versions of GD which may cause
4236
-		// PHP to segfault when calling imagecreatefromstring() - avoid if at all possible
4237
-		// when not using a bundled version of GD2
4238
-		if (!phpthumb_functions::gd_version()) {
4239
-			if ($DieOnErrors) {
4240
-				if (!headers_sent()) {
4241
-					// base64-encoded error image in GIF format
4242
-					$ERROR_NOGD = 'R0lGODlhIAAgALMAAAAAABQUFCQkJDY2NkZGRldXV2ZmZnJycoaGhpSUlKWlpbe3t8XFxdXV1eTk5P7+/iwAAAAAIAAgAAAE/vDJSau9WILtTAACUinDNijZtAHfCojS4W5H+qxD8xibIDE9h0OwWaRWDIljJSkUJYsN4bihMB8th3IToAKs1VtYM75cyV8sZ8vygtOE5yMKmGbO4jRdICQCjHdlZzwzNW4qZSQmKDaNjhUMBX4BBAlmMywFSRWEmAI6b5gAlhNxokGhooAIK5o/pi9vEw4Lfj4OLTAUpj6IabMtCwlSFw0DCKBoFqwAB04AjI54PyZ+yY3TD0ss2YcVmN/gvpcu4TOyFivWqYJlbAHPpOntvxNAACcmGHjZzAZqzSzcq5fNjxFmAFw9iFRunD1epU6tsIPmFCAJnWYE0FURk7wJDA0MTKpEzoWAAskiAAA7';
4243
-					header('Content-Type: image/gif');
4244
-					echo base64_decode($ERROR_NOGD);
4245
-				} else {
4246
-					echo '*** ERROR: No PHP-GD support available ***';
4247
-				}
4248
-				exit;
4249
-			} else {
4250
-				$this->DebugMessage('ImageCreateFromStringReplacement() failed: gd_version says "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
4251
-				return false;
4252
-			}
4253
-		}
4254
-		if (phpthumb_functions::gd_is_bundled()) {
4255
-			$this->DebugMessage('ImageCreateFromStringReplacement() calling built-in imagecreatefromstring()', __FILE__, __LINE__);
4256
-			return @imagecreatefromstring($RawImageData);
4257
-		}
4258
-		if ($this->issafemode) {
4259
-			$this->DebugMessage('ImageCreateFromStringReplacement() failed: cannot create temp file in SAFE_MODE', __FILE__, __LINE__);
4260
-			return false;
4261
-		}
4262
-
4263
-		switch (substr($RawImageData, 0, 3)) {
4264
-			case 'GIF':
4265
-				$ICFSreplacementFunctionName = 'imagecreatefromgif';
4266
-				break;
4267
-			case "\xFF\xD8\xFF":
4268
-				$ICFSreplacementFunctionName = 'imagecreatefromjpeg';
4269
-				break;
4270
-			case "\x89".'PN':
4271
-				$ICFSreplacementFunctionName = 'imagecreatefrompng';
4272
-				break;
4273
-			default:
4274
-				$this->DebugMessage('ImageCreateFromStringReplacement() failed: unknown fileformat signature "'.phpthumb_functions::HexCharDisplay(substr($RawImageData, 0, 3)).'"', __FILE__, __LINE__);
4275
-				return false;
4276
-				break;
4277
-		}
4278
-		$ErrorMessage = '';
4279
-		if ($tempnam = $this->phpThumb_tempnam()) {
4280
-			if ($fp_tempnam = @fopen($tempnam, 'wb')) {
4281
-				fwrite($fp_tempnam, $RawImageData);
4282
-				fclose($fp_tempnam);
4283
-				@chmod($tempnam, $this->getParameter('config_file_create_mask'));
4284
-				if (($ICFSreplacementFunctionName == 'imagecreatefromgif') && !function_exists($ICFSreplacementFunctionName)) {
4285
-
4286
-					// Need to create from GIF file, but imagecreatefromgif does not exist
4287
-					ob_start();
4288
-					if (!@include_once( __DIR__ .'/phpthumb.gif.php')) {
4289
-						$ErrorMessage = 'Failed to include required file "'. __DIR__ .'/phpthumb.gif.php" in '.__FILE__.' on line '.__LINE__;
4290
-						$this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4291
-					}
4292
-					ob_end_clean();
4293
-					// gif_loadFileToGDimageResource() cannot read from raw data, write to file first
4294
-					if ($tempfilename = $this->phpThumb_tempnam()) {
4295
-						if ($fp_tempfile = @fopen($tempfilename, 'wb')) {
4296
-							fwrite($fp_tempfile, $RawImageData);
4297
-							fclose($fp_tempfile);
4298
-							$gdimg_source = gif_loadFileToGDimageResource($tempfilename);
4299
-							$this->DebugMessage('gif_loadFileToGDimageResource('.$tempfilename.') completed', __FILE__, __LINE__);
4300
-							$this->DebugMessage('deleting "'.$tempfilename.'"', __FILE__, __LINE__);
4301
-							unlink($tempfilename);
4302
-							return $gdimg_source;
4303
-						} else {
4304
-							$ErrorMessage = 'Failed to open tempfile in '.__FILE__.' on line '.__LINE__;
4305
-							$this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4306
-						}
4307
-					} else {
4308
-						$ErrorMessage = 'Failed to open generate tempfile name in '.__FILE__.' on line '.__LINE__;
4309
-						$this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4310
-					}
4311
-
4312
-				} elseif (function_exists($ICFSreplacementFunctionName) && ($gdimg_source = @$ICFSreplacementFunctionName($tempnam))) {
4313
-
4314
-					// great
4315
-					$this->DebugMessage($ICFSreplacementFunctionName.'('.$tempnam.') succeeded', __FILE__, __LINE__);
4316
-					$this->DebugMessage('deleting "'.$tempnam.'"', __FILE__, __LINE__);
4317
-					unlink($tempnam);
4318
-					return $gdimg_source;
4319
-
4320
-				} else {
4321
-
4322
-					// GD functions not available, or failed to create image
4323
-					$this->DebugMessage($ICFSreplacementFunctionName.'('.$tempnam.') '.(function_exists($ICFSreplacementFunctionName) ? 'failed' : 'does not exist'), __FILE__, __LINE__);
4324
-					if (isset($_GET['phpThumbDebug'])) {
4325
-						$this->phpThumbDebug();
4326
-					}
4327
-
4328
-				}
4329
-			} else {
4330
-				$ErrorMessage = 'Failed to fopen('.$tempnam.', "wb") in '.__FILE__.' on line '.__LINE__."\n".'You may need to set $PHPTHUMB_CONFIG[temp_directory] in phpThumb.config.php';
4331
-				if ($this->issafemode) {
4332
-					$ErrorMessage = 'ImageCreateFromStringReplacement() failed in '.__FILE__.' on line '.__LINE__.': cannot create temp file in SAFE_MODE';
4333
-				}
4334
-				$this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4335
-			}
4336
-			$this->DebugMessage('deleting "'.$tempnam.'"', __FILE__, __LINE__);
4337
-			@unlink($tempnam);
4338
-		} else {
4339
-			$ErrorMessage = 'Failed to generate phpThumb_tempnam() in '.__FILE__.' on line '.__LINE__."\n".'You may need to set $PHPTHUMB_CONFIG[temp_directory] in phpThumb.config.php';
4340
-			if ($this->issafemode) {
4341
-				$ErrorMessage = 'ImageCreateFromStringReplacement() failed in '.__FILE__.' on line '.__LINE__.': cannot create temp file in SAFE_MODE';
4342
-			}
4343
-		}
4344
-		if ($DieOnErrors && $ErrorMessage) {
4345
-			return $this->ErrorImage($ErrorMessage);
4346
-		}
4347
-		return false;
4348
-	}
4349
-
4350
-	public function ImageResizeFunction(&$dst_im, &$src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH) {
4351
-		$this->DebugMessage('ImageResizeFunction($o, $s, '.$dstX.', '.$dstY.', '.$srcX.', '.$srcY.', '.$dstW.', '.$dstH.', '.$srcW.', '.$srcH.')', __FILE__, __LINE__);
4352
-		if (($dstW == $srcW) && ($dstH == $srcH)) {
4353
-			return imagecopy($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH);
4354
-		}
4355
-		if (phpthumb_functions::gd_version() >= 2.0) {
4356
-			if ($this->config_disable_imagecopyresampled) {
4357
-				return phpthumb_functions::ImageCopyResampleBicubic($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);
4358
-			}
4359
-			return imagecopyresampled($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);
4360
-		}
4361
-		return imagecopyresized($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);
4362
-	}
4363
-
4364
-	public function InitializeTempDirSetting() {
4365
-		$this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : $this->realPathSafe((function_exists('sys_get_temp_dir') ? sys_get_temp_dir() : ''))); // sys_get_temp_dir added in PHP v5.2.1
4366
-		$this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : $this->realPathSafe(ini_get('upload_tmp_dir')));
4367
-		$this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : $this->realPathSafe(getenv('TMPDIR')));
4368
-		$this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : $this->realPathSafe(getenv('TMP')));
4369
-		return true;
4370
-	}
4371
-
4372
-	public function phpThumb_tempnam() {
4373
-		$this->InitializeTempDirSetting();
4374
-		$tempnam = $this->realPathSafe(tempnam($this->config_temp_directory, 'pThumb'));
4375
-		$this->tempFilesToDelete[$tempnam] = $tempnam;
4376
-		$this->DebugMessage('phpThumb_tempnam() returning "'.$tempnam.'"', __FILE__, __LINE__);
4377
-		return $tempnam;
4378
-	}
4379
-
4380
-	public function DebugMessage($message, $file='', $line='') {
4381
-		$this->debugmessages[] = $message.($file ? ' in file "'.(basename($file) ? basename($file) : $file).'"' : '').($line ? ' on line '.$line : '');
4382
-		return true;
4383
-	}
4384
-
4385
-	public function DebugTimingMessage($message, $file='', $line='', $timestamp=0) {
4386
-		if (!$timestamp) {
4387
-			$timestamp = array_sum(explode(' ', microtime()));
4388
-		}
4389
-		$this->debugtiming[number_format($timestamp, 6, '.', '')] = ': '.$message.($file ? ' in file "'.(basename($file) ? basename($file) : $file).'"' : '').($line ? ' on line '.$line : '');
4390
-		return true;
4391
-	}
3746
+            }
3747
+
3748
+        } elseif (!$this->gdimg_source && $this->sourceFilename) {
3749
+
3750
+            if ($this->md5s && ($this->md5s != phpthumb_functions::md5_file_safe($this->sourceFilename))) {
3751
+                return $this->ErrorImage('$this->md5s != md5(sourceFilename)'."\n".'"'.$this->md5s.'" != '."\n".'"'.phpthumb_functions::md5_file_safe($this->sourceFilename).'"');
3752
+            }
3753
+            switch (@$this->getimagesizeinfo[2]) {
3754
+                case 1:
3755
+                case 3:
3756
+                    // GIF or PNG input file may have transparency
3757
+                    $this->is_alpha = true;
3758
+                    break;
3759
+            }
3760
+            if (!$this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3761
+                $this->gdimg_source = $this->ImageCreateFromFilename($this->sourceFilename);
3762
+            }
3763
+
3764
+        }
3765
+
3766
+        while (true) {
3767
+            if ($this->gdimg_source) {
3768
+                $this->DebugMessage('Not using EXIF thumbnail data because $this->gdimg_source is already set', __FILE__, __LINE__);
3769
+                break;
3770
+            }
3771
+            if (!$this->exif_thumbnail_data) {
3772
+                $this->DebugMessage('Not using EXIF thumbnail data because $this->exif_thumbnail_data is empty', __FILE__, __LINE__);
3773
+                break;
3774
+            }
3775
+            if (ini_get('safe_mode')) {
3776
+                if (!$this->SourceImageIsTooLarge($this->source_width, $this->source_height)) {
3777
+                    $this->DebugMessage('Using EXIF thumbnail data because source image too large and safe_mode enabled', __FILE__, __LINE__);
3778
+                    $this->aoe = true;
3779
+                } else {
3780
+                    break;
3781
+                }
3782
+            } else {
3783
+                if (!$this->config_use_exif_thumbnail_for_speed) {
3784
+                    $this->DebugMessage('Not using EXIF thumbnail data because $this->config_use_exif_thumbnail_for_speed is FALSE', __FILE__, __LINE__);
3785
+                    break;
3786
+                }
3787
+                if (($this->thumbnailCropX != 0) || ($this->thumbnailCropY != 0)) {
3788
+                    $this->DebugMessage('Not using EXIF thumbnail data because source cropping is enabled ('.$this->thumbnailCropX.','.$this->thumbnailCropY.')', __FILE__, __LINE__);
3789
+                    break;
3790
+                }
3791
+                if (($this->w > $this->exif_thumbnail_width) || ($this->h > $this->exif_thumbnail_height)) {
3792
+                    $this->DebugMessage('Not using EXIF thumbnail data because EXIF thumbnail is too small ('.$this->exif_thumbnail_width.'x'.$this->exif_thumbnail_height.' vs '.$this->w.'x'.$this->h.')', __FILE__, __LINE__);
3793
+                    break;
3794
+                }
3795
+                $source_ar = $this->source_width / $this->source_height;
3796
+                $exif_ar   = $this->exif_thumbnail_width / $this->exif_thumbnail_height;
3797
+                if (number_format($source_ar, 2) != number_format($exif_ar, 2)) {
3798
+                    $this->DebugMessage('not using EXIF thumbnail because $source_ar != $exif_ar ('.$source_ar.' != '.$exif_ar.')', __FILE__, __LINE__);
3799
+                    break;
3800
+                }
3801
+            }
3802
+
3803
+            // EXIF thumbnail exists, and is equal to or larger than destination thumbnail, and will be use as source image
3804
+            $this->DebugMessage('Trying to use EXIF thumbnail as source image', __FILE__, __LINE__);
3805
+
3806
+            if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
3807
+
3808
+                $this->DebugMessage('Successfully using EXIF thumbnail as source image', __FILE__, __LINE__);
3809
+                $this->gdimg_source   = $gdimg_exif_temp;
3810
+                $this->source_width   = $this->exif_thumbnail_width;
3811
+                $this->source_height  = $this->exif_thumbnail_height;
3812
+                $this->thumbnailCropW = $this->source_width;
3813
+                $this->thumbnailCropH = $this->source_height;
3814
+                return true;
3815
+
3816
+            } else {
3817
+                $this->DebugMessage('$this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false) failed', __FILE__, __LINE__);
3818
+            }
3819
+
3820
+            break;
3821
+        }
3822
+
3823
+        if (!$this->gdimg_source) {
3824
+            $this->DebugMessage('$this->gdimg_source is still empty', __FILE__, __LINE__);
3825
+
3826
+            $this->DebugMessage('ImageMagickThumbnailToGD() failed', __FILE__, __LINE__);
3827
+
3828
+            $imageHeader = '';
3829
+            $gd_info = gd_info();
3830
+            $GDreadSupport = false;
3831
+            switch (@$this->getimagesizeinfo[2]) {
3832
+                case 1:
3833
+                    $imageHeader = 'Content-Type: image/gif';
3834
+                    $GDreadSupport = (bool) @$gd_info['GIF Read Support'];
3835
+                    break;
3836
+                case 2:
3837
+                    $imageHeader = 'Content-Type: image/jpeg';
3838
+                    $GDreadSupport = (bool) @$gd_info['JPG Support'];
3839
+                    break;
3840
+                case 3:
3841
+                    $imageHeader = 'Content-Type: image/png';
3842
+                    $GDreadSupport = (bool) @$gd_info['PNG Support'];
3843
+                    break;
3844
+            }
3845
+            if ($imageHeader) {
3846
+                // cannot create image for whatever reason (maybe imagecreatefromjpeg et al are not available?)
3847
+                // and ImageMagick is not available either, no choice but to output original (not resized/modified) data and exit
3848
+                if ($this->config_error_die_on_source_failure) {
3849
+                    $errormessages = array();
3850
+                    $errormessages[] = 'All attempts to create GD image source failed.';
3851
+                    if ($this->fatalerror) {
3852
+                        $errormessages[] = $this->fatalerror;
3853
+                    }
3854
+                    if ($this->issafemode) {
3855
+                        $errormessages[] = 'Safe Mode enabled, therefore ImageMagick is unavailable. (disable Safe Mode if possible)';
3856
+                    } elseif (!$this->ImageMagickVersion()) {
3857
+                        $errormessages[] = 'ImageMagick is not installed (it is highly recommended that you install it).';
3858
+                    }
3859
+                    if ($this->SourceImageIsTooLarge($this->getimagesizeinfo[0], $this->getimagesizeinfo[1])) {
3860
+                        $memory_get_usage = (function_exists('memory_get_usage') ? memory_get_usage() : 0);
3861
+                        $errormessages[] = 'Source image is too large ('.$this->getimagesizeinfo[0].'x'.$this->getimagesizeinfo[1].' = '.number_format($this->getimagesizeinfo[0] * $this->getimagesizeinfo[1] / 1000000, 1).'Mpx, max='.number_format($this->config_max_source_pixels / 1000000, 1).'Mpx) for GD creation (either install ImageMagick or increase PHP memory_limit to at least '.ceil(($memory_get_usage + (5 * $this->getimagesizeinfo[0] * $this->getimagesizeinfo[1])) / 1048576).'M).';
3862
+                    } elseif (!$GDreadSupport) {
3863
+                        $errormessages[] = 'GD does not have read support for "'.$imageHeader.'".';
3864
+                    } else {
3865
+                        $errormessages[] = 'Source image probably corrupt.';
3866
+                    }
3867
+                    $this->ErrorImage(implode("\n", $errormessages));
3868
+
3869
+                } else {
3870
+                    $this->DebugMessage('All attempts to create GD image source failed ('.(ini_get('safe_mode') ? 'Safe Mode enabled, ImageMagick unavailable and source image probably too large for GD': ($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"')).'), cannot generate thumbnail');
3871
+                    //$this->DebugMessage('All attempts to create GD image source failed ('.($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"').'), outputing raw image', __FILE__, __LINE__);
3872
+                    //if (!$this->phpThumbDebug) {
3873
+                    //	header($imageHeader);
3874
+                    //	echo $this->rawImageData;
3875
+                    //	exit;
3876
+                    //}
3877
+                    return false;
3878
+                }
3879
+            }
3880
+
3881
+            //switch (substr($this->rawImageData, 0, 2)) {
3882
+            //	case 'BM':
3883
+            switch (@$this->getimagesizeinfo[2]) {
3884
+                case 6:
3885
+                    ob_start();
3886
+                    if (!@include_once( __DIR__ .'/phpthumb.bmp.php')) {
3887
+                        ob_end_clean();
3888
+                        return $this->ErrorImage('include_once('. __DIR__ .'/phpthumb.bmp.php) failed');
3889
+                    }
3890
+                    ob_end_clean();
3891
+                    if ($fp = @fopen($this->sourceFilename, 'rb')) {
3892
+                        $this->rawImageData = '';
3893
+                        while (!feof($fp)) {
3894
+                            $this->rawImageData .= fread($fp, 32768);
3895
+                        }
3896
+                        fclose($fp);
3897
+                    }
3898
+                    $phpthumb_bmp = new phpthumb_bmp();
3899
+                    $this->gdimg_source = $phpthumb_bmp->phpthumb_bmp2gd($this->rawImageData, (phpthumb_functions::gd_version() >= 2.0));
3900
+                    unset($phpthumb_bmp);
3901
+                    if ($this->gdimg_source) {
3902
+                        $this->DebugMessage('$phpthumb_bmp->phpthumb_bmp2gd() succeeded', __FILE__, __LINE__);
3903
+                    } else {
3904
+                        return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on BMP source conversion' : 'phpthumb_bmp2gd() failed');
3905
+                    }
3906
+                    break;
3907
+            //}
3908
+            //switch (substr($this->rawImageData, 0, 4)) {
3909
+            //	case 'II'."\x2A\x00":
3910
+            //	case 'MM'."\x00\x2A":
3911
+                case 7:
3912
+                case 8:
3913
+                    return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on TIFF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support TIFF source images without it');
3914
+                    break;
3915
+
3916
+                //case "\xD7\xCD\xC6\x9A":
3917
+                //	return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it');
3918
+                //	break;
3919
+            }
3920
+
3921
+            if (!$this->gdimg_source) {
3922
+                if ($this->rawImageData) {
3923
+                    $HeaderFourBytes = substr($this->rawImageData, 0, 4);
3924
+                } elseif ($this->sourceFilename) {
3925
+                    if ($fp = @fopen($this->sourceFilename, 'rb')) {
3926
+                        $HeaderFourBytes = fread($fp, 4);
3927
+                        fclose($fp);
3928
+                    } else {
3929
+                        return $this->ErrorImage('failed to open "'.$this->sourceFilename.'" SourceImageToGD() ['.__LINE__.']');
3930
+                    }
3931
+                } else {
3932
+                    return $this->ErrorImage('Unable to create image, neither filename nor image data suppplied in SourceImageToGD() ['.__LINE__.']');
3933
+                }
3934
+                if (!$this->ImageMagickVersion() && !phpthumb_functions::gd_version()) {
3935
+                    return $this->ErrorImage('Neither GD nor ImageMagick seem to be installed on this server. At least one (preferably GD), or better both, MUST be installed for phpThumb to work.');
3936
+                } elseif ($HeaderFourBytes == "\xD7\xCD\xC6\x9A") { // WMF
3937
+                    return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick failed on WMF source conversion' : 'ImageMagick is unavailable and phpThumb() does not support WMF source images without it');
3938
+                } elseif ($HeaderFourBytes == '%PDF') { // "%PDF"
3939
+                    return $this->ErrorImage($this->ImageMagickVersion() ? 'ImageMagick and GhostScript are both required for PDF source images; GhostScript may not be properly configured' : 'ImageMagick and/or GhostScript are unavailable and phpThumb() does not support PDF source images without them');
3940
+                } elseif (substr($HeaderFourBytes, 0, 3) == "\xFF\xD8\xFF") { // JPEG
3941
+                    return $this->ErrorImage('Image (JPEG) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting');
3942
+                } elseif ($HeaderFourBytes == '%PNG') { // "%PNG"
3943
+                    return $this->ErrorImage('Image (PNG) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting');
3944
+                } elseif (substr($HeaderFourBytes, 0, 3) == 'GIF') { // GIF
3945
+                    return $this->ErrorImage('Image (GIF) is too large for PHP-GD memory_limit, please install ImageMagick or increase php.ini memory_limit setting');
3946
+                }
3947
+                return $this->ErrorImage('Unknown image type identified by "'.$HeaderFourBytes.'" ('.phpthumb_functions::HexCharDisplay($HeaderFourBytes).') in SourceImageToGD() ['.__LINE__.']');
3948
+            }
3949
+        }
3950
+
3951
+        if (!$this->gdimg_source) {
3952
+            if ($gdimg_exif_temp = $this->ImageCreateFromStringReplacement($this->exif_thumbnail_data, false)) {
3953
+                $this->DebugMessage('All other attempts failed, but successfully using EXIF thumbnail as source image', __FILE__, __LINE__);
3954
+                $this->gdimg_source = $gdimg_exif_temp;
3955
+                // override allow-enlarging setting if EXIF thumbnail is the only source available
3956
+                // otherwise thumbnails larger than the EXIF thumbnail will be created at EXIF size
3957
+                $this->aoe = true;
3958
+                return true;
3959
+            }
3960
+            return false;
3961
+        }
3962
+
3963
+        $this->source_width  = imagesx($this->gdimg_source);
3964
+        $this->source_height = imagesy($this->gdimg_source);
3965
+        return true;
3966
+    }
3967
+
3968
+
3969
+    public function phpThumbDebugVarDump($var) {
3970
+        if (null === $var) {
3971
+            return 'NULL';
3972
+        } elseif (is_bool($var)) {
3973
+            return ($var ? 'TRUE' : 'FALSE');
3974
+        } elseif (is_string($var)) {
3975
+            return 'string('.strlen($var).')'.str_repeat(' ', max(0, 3 - strlen(strlen($var)))).' "'.$var.'"';
3976
+        } elseif (is_int($var)) {
3977
+            return 'integer     '.$var;
3978
+        } elseif (is_float($var)) {
3979
+            return 'float       '.$var;
3980
+        } elseif (is_array($var)) {
3981
+            ob_start();
3982
+            var_dump($var);
3983
+            $vardumpoutput = ob_get_contents();
3984
+            ob_end_clean();
3985
+            return strtr($vardumpoutput, "\n\r\t", '   ');
3986
+        }
3987
+        return gettype($var);
3988
+    }
3989
+
3990
+    public function phpThumbDebug($level='') {
3991
+        if ($level && ($this->phpThumbDebug !== $level)) {
3992
+            return true;
3993
+        }
3994
+        if ($this->config_disable_debug) {
3995
+            return $this->ErrorImage('phpThumbDebug disabled');
3996
+        }
3997
+
3998
+        $FunctionsExistance  = array('exif_thumbnail', 'gd_info', 'image_type_to_mime_type', 'getimagesize', 'imagecopyresampled', 'imagecopyresized', 'imagecreate', 'imagecreatefromstring', 'imagecreatetruecolor', 'imageistruecolor', 'imagerotate', 'imagetypes', 'version_compare', 'imagecreatefromgif', 'imagecreatefromjpeg', 'imagecreatefrompng', 'imagecreatefromwbmp', 'imagecreatefromxbm', 'imagecreatefromxpm', 'imagecreatefromstring', 'imagecreatefromgd', 'imagecreatefromgd2', 'imagecreatefromgd2part', 'imagejpeg', 'imagegif', 'imagepng', 'imagewbmp');
3999
+        $ParameterNames      = array('src', 'new', 'w', 'h', 'f', 'q', 'sx', 'sy', 'sw', 'sh', 'far', 'bg', 'bc', 'file', 'goto', 'err', 'xto', 'ra', 'ar', 'aoe', 'iar', 'maxb');
4000
+        $ConfigVariableNames = array('document_root', 'temp_directory', 'output_format', 'output_maxwidth', 'output_maxheight', 'error_message_image_default', 'error_bgcolor', 'error_textcolor', 'error_fontsize', 'error_die_on_error', 'error_silent_die_on_error', 'error_die_on_source_failure', 'nohotlink_enabled', 'nohotlink_valid_domains', 'nohotlink_erase_image', 'nohotlink_text_message', 'nooffsitelink_enabled', 'nooffsitelink_valid_domains', 'nooffsitelink_require_refer', 'nooffsitelink_erase_image', 'nooffsitelink_text_message', 'high_security_enabled', 'allow_src_above_docroot', 'allow_src_above_phpthumb', 'max_source_pixels', 'use_exif_thumbnail_for_speed', 'border_hexcolor', 'background_hexcolor', 'ttf_directory', 'disable_pathinfo_parsing', 'disable_imagecopyresampled');
4001
+        $OtherVariableNames  = array('phpThumbDebug', 'thumbnailQuality', 'thumbnailFormat', 'gdimg_output', 'gdimg_source', 'sourceFilename', 'source_width', 'source_height', 'thumbnailCropX', 'thumbnailCropY', 'thumbnailCropW', 'thumbnailCropH', 'exif_thumbnail_width', 'exif_thumbnail_height', 'exif_thumbnail_type', 'thumbnail_width', 'thumbnail_height', 'thumbnail_image_width', 'thumbnail_image_height');
4002
+
4003
+        $DebugOutput = array();
4004
+        $DebugOutput[] = 'phpThumb() version          = '.$this->phpthumb_version;
4005
+        $DebugOutput[] = 'phpversion()                = '.@PHP_VERSION;
4006
+        $DebugOutput[] = 'PHP_OS                      = '.PHP_OS;
4007
+        $DebugOutput[] = '$_SERVER[SERVER_SOFTWARE]   = '.@$_SERVER['SERVER_SOFTWARE'];
4008
+        $DebugOutput[] = '__FILE__                    = '.__FILE__;
4009
+        $DebugOutput[] = 'realpath(.)                 = '.@realpath('.');
4010
+        $DebugOutput[] = '$_SERVER[PHP_SELF]          = '.@$_SERVER['PHP_SELF'];
4011
+        $DebugOutput[] = '$_SERVER[HOST_NAME]         = '.@$_SERVER['HOST_NAME'];
4012
+        $DebugOutput[] = '$_SERVER[HTTP_REFERER]      = '.@$_SERVER['HTTP_REFERER'];
4013
+        $DebugOutput[] = '$_SERVER[QUERY_STRING]      = '.@$_SERVER['QUERY_STRING'];
4014
+        $DebugOutput[] = '$_SERVER[PATH_INFO]         = '.@$_SERVER['PATH_INFO'];
4015
+        $DebugOutput[] = '$_SERVER[DOCUMENT_ROOT]     = '.@$_SERVER['DOCUMENT_ROOT'];
4016
+        $DebugOutput[] = 'getenv(DOCUMENT_ROOT)       = '.@getenv('DOCUMENT_ROOT');
4017
+        $DebugOutput[] = '';
4018
+
4019
+        $DebugOutput[] = 'get_magic_quotes_gpc()         = '.$this->phpThumbDebugVarDump(@get_magic_quotes_gpc());
4020
+        $DebugOutput[] = 'get_magic_quotes_runtime()     = '.$this->phpThumbDebugVarDump(@get_magic_quotes_runtime());
4021
+        $DebugOutput[] = 'error_reporting()              = '.$this->phpThumbDebugVarDump(error_reporting());
4022
+        $DebugOutput[] = 'ini_get(error_reporting)       = '.$this->phpThumbDebugVarDump(@ini_get('error_reporting'));
4023
+        $DebugOutput[] = 'ini_get(display_errors)        = '.$this->phpThumbDebugVarDump(@ini_get('display_errors'));
4024
+        $DebugOutput[] = 'ini_get(allow_url_fopen)       = '.$this->phpThumbDebugVarDump(@ini_get('allow_url_fopen'));
4025
+        $DebugOutput[] = 'ini_get(disable_functions)     = '.$this->phpThumbDebugVarDump(@ini_get('disable_functions'));
4026
+        $DebugOutput[] = 'get_cfg_var(disable_functions) = '.$this->phpThumbDebugVarDump(@get_cfg_var('disable_functions'));
4027
+        $DebugOutput[] = 'ini_get(safe_mode)             = '.$this->phpThumbDebugVarDump(@ini_get('safe_mode'));
4028
+        $DebugOutput[] = 'ini_get(open_basedir)          = '.$this->phpThumbDebugVarDump(@ini_get('open_basedir'));
4029
+        $DebugOutput[] = 'ini_get(max_execution_time)    = '.$this->phpThumbDebugVarDump(@ini_get('max_execution_time'));
4030
+        $DebugOutput[] = 'ini_get(memory_limit)          = '.$this->phpThumbDebugVarDump(@ini_get('memory_limit'));
4031
+        $DebugOutput[] = 'get_cfg_var(memory_limit)      = '.$this->phpThumbDebugVarDump(@get_cfg_var('memory_limit'));
4032
+        $DebugOutput[] = 'memory_get_usage()             = '.(function_exists('memory_get_usage') ? $this->phpThumbDebugVarDump(@memory_get_usage()) : 'n/a');
4033
+        $DebugOutput[] = '';
4034
+
4035
+        $DebugOutput[] = '$this->config_prefer_imagemagick            = '.$this->phpThumbDebugVarDump($this->config_prefer_imagemagick);
4036
+        $DebugOutput[] = '$this->config_imagemagick_path              = '.$this->phpThumbDebugVarDump($this->config_imagemagick_path);
4037
+        $DebugOutput[] = '$this->ImageMagickWhichConvert()            = '.$this->ImageMagickWhichConvert();
4038
+        $IMpathUsed = ($this->config_imagemagick_path ? $this->config_imagemagick_path : $this->ImageMagickWhichConvert());
4039
+        $DebugOutput[] = '[actual ImageMagick path used]              = '.$this->phpThumbDebugVarDump($IMpathUsed);
4040
+        $DebugOutput[] = 'file_exists([actual ImageMagick path used]) = '.$this->phpThumbDebugVarDump(@file_exists($IMpathUsed));
4041
+        $DebugOutput[] = 'ImageMagickVersion(false)                   = '.$this->ImageMagickVersion(false);
4042
+        $DebugOutput[] = 'ImageMagickVersion(true)                    = '.$this->ImageMagickVersion(true);
4043
+        $DebugOutput[] = '';
4044
+
4045
+        $DebugOutput[] = '$this->config_cache_directory               = '.$this->phpThumbDebugVarDump($this->config_cache_directory);
4046
+        $DebugOutput[] = '$this->config_cache_directory_depth         = '.$this->phpThumbDebugVarDump($this->config_cache_directory_depth);
4047
+        $DebugOutput[] = '$this->config_cache_disable_warning         = '.$this->phpThumbDebugVarDump($this->config_cache_disable_warning);
4048
+        $DebugOutput[] = '$this->config_cache_maxage                  = '.$this->phpThumbDebugVarDump($this->config_cache_maxage);
4049
+        $DebugOutput[] = '$this->config_cache_maxsize                 = '.$this->phpThumbDebugVarDump($this->config_cache_maxsize);
4050
+        $DebugOutput[] = '$this->config_cache_maxfiles                = '.$this->phpThumbDebugVarDump($this->config_cache_maxfiles);
4051
+        $DebugOutput[] = '$this->config_cache_force_passthru          = '.$this->phpThumbDebugVarDump($this->config_cache_force_passthru);
4052
+        $DebugOutput[] = '$this->cache_filename                       = '.$this->phpThumbDebugVarDump($this->cache_filename);
4053
+        $DebugOutput[] = 'is_readable($this->config_cache_directory)  = '.$this->phpThumbDebugVarDump(@is_readable($this->config_cache_directory));
4054
+        $DebugOutput[] = 'is_writable($this->config_cache_directory)  = '.$this->phpThumbDebugVarDump(@is_writable($this->config_cache_directory));
4055
+        $DebugOutput[] = 'is_readable($this->cache_filename)          = '.$this->phpThumbDebugVarDump(@is_readable($this->cache_filename));
4056
+        $DebugOutput[] = 'is_writable($this->cache_filename)          = '.(@file_exists($this->cache_filename) ? $this->phpThumbDebugVarDump(@is_writable($this->cache_filename)) : 'n/a');
4057
+        $DebugOutput[] = '';
4058
+
4059
+        foreach ($ConfigVariableNames as $varname) {
4060
+            $varname = 'config_'.$varname;
4061
+            $value = $this->$varname;
4062
+            $DebugOutput[] = '$this->'.str_pad($varname, 37, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4063
+        }
4064
+        $DebugOutput[] = '';
4065
+        foreach ($OtherVariableNames as $varname) {
4066
+            $value = $this->$varname;
4067
+            $DebugOutput[] = '$this->'.str_pad($varname, 27, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4068
+        }
4069
+        $DebugOutput[] = 'strlen($this->rawImageData)        = '.strlen(@$this->rawImageData);
4070
+        $DebugOutput[] = 'strlen($this->exif_thumbnail_data) = '.strlen(@$this->exif_thumbnail_data);
4071
+        $DebugOutput[] = '';
4072
+
4073
+        foreach ($ParameterNames as $varname) {
4074
+            $value = $this->$varname;
4075
+            $DebugOutput[] = '$this->'.str_pad($varname, 4, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4076
+        }
4077
+        $DebugOutput[] = '';
4078
+
4079
+        foreach ($FunctionsExistance as $functionname) {
4080
+            $DebugOutput[] = 'builtin_function_exists('.$functionname.')'.str_repeat(' ', 23 - strlen($functionname)).' = '.$this->phpThumbDebugVarDump(phpthumb_functions::builtin_function_exists($functionname));
4081
+        }
4082
+        $DebugOutput[] = '';
4083
+
4084
+        $gd_info = gd_info();
4085
+        foreach ($gd_info as $key => $value) {
4086
+            $DebugOutput[] = 'gd_info.'.str_pad($key, 34, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4087
+        }
4088
+        $DebugOutput[] = '';
4089
+
4090
+        $exif_info = phpthumb_functions::exif_info();
4091
+        foreach ($exif_info as $key => $value) {
4092
+            $DebugOutput[] = 'exif_info.'.str_pad($key, 26, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4093
+        }
4094
+        $DebugOutput[] = '';
4095
+
4096
+        if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) {
4097
+            foreach ($ApacheLookupURIarray as $key => $value) {
4098
+                $DebugOutput[] = 'ApacheLookupURIarray.'.str_pad($key, 15, ' ', STR_PAD_RIGHT).' = '.$this->phpThumbDebugVarDump($value);
4099
+            }
4100
+        } else {
4101
+                $DebugOutput[] = 'ApacheLookupURIarray() -- FAILED';
4102
+        }
4103
+        $DebugOutput[] = '';
4104
+
4105
+        if (isset($_GET) && is_array($_GET)) {
4106
+            foreach ($_GET as $key => $value) {
4107
+                $DebugOutput[] = '$_GET['.$key.']'.str_repeat(' ', 30 - strlen($key)).'= '.$this->phpThumbDebugVarDump($value);
4108
+            }
4109
+        }
4110
+        if (isset($_POST) && is_array($_POST)) {
4111
+            foreach ($_POST as $key => $value) {
4112
+                $DebugOutput[] = '$_POST['.$key.']'.str_repeat(' ', 29 - strlen($key)).'= '.$this->phpThumbDebugVarDump($value);
4113
+            }
4114
+        }
4115
+        $DebugOutput[] = '';
4116
+
4117
+        $DebugOutput[] = '$this->debugmessages:';
4118
+        foreach ($this->debugmessages as $errorstring) {
4119
+            $DebugOutput[] = '  * '.$errorstring;
4120
+        }
4121
+        $DebugOutput[] = '';
4122
+
4123
+        $DebugOutput[] = '$this->debugtiming:';
4124
+        foreach ($this->debugtiming as $timestamp => $timingstring) {
4125
+            $DebugOutput[] = '  * '.$timestamp.' '.$timingstring;
4126
+        }
4127
+        $DebugOutput[] = '  * Total processing time: '.number_format(max(array_keys($this->debugtiming)) - min(array_keys($this->debugtiming)), 6);
4128
+
4129
+        $this->f = (isset($_GET['f']) ? $_GET['f'] : $this->f); // debug modes 0-2 don't recognize text mode otherwise
4130
+        return $this->ErrorImage(implode("\n", $DebugOutput), 700, 500, true);
4131
+    }
4132
+
4133
+    public function FatalError($text) {
4134
+        if (null === $this->fatalerror) {
4135
+            $this->fatalerror = $text;
4136
+        }
4137
+        return true;
4138
+    }
4139
+
4140
+    public function ErrorImage($text, $width=0, $height=0, $forcedisplay=false) {
4141
+        $width  = ($width  ? $width  : $this->config_error_image_width);
4142
+        $height = ($height ? $height : $this->config_error_image_height);
4143
+
4144
+        $text = 'phpThumb() v'.$this->phpthumb_version."\n".'http://phpthumb.sourceforge.net'."\n\n".($this->config_disable_debug ? 'Error messages disabled.'."\n\n".'edit phpThumb.config.php and (temporarily) set'."\n".'$PHPTHUMB_CONFIG[\'disable_debug\'] = false;'."\n".'to view the details of this error' : $text);
4145
+
4146
+        $this->FatalError($text);
4147
+        $this->DebugMessage($text, __FILE__, __LINE__);
4148
+        $this->purgeTempFiles();
4149
+        if ($this->config_error_silent_die_on_error) {
4150
+            exit;
4151
+        }
4152
+        if ($this->phpThumbDebug && !$forcedisplay) {
4153
+            return false;
4154
+        }
4155
+        if (!$this->config_error_die_on_error && !$forcedisplay) {
4156
+            return false;
4157
+        }
4158
+        if ($this->err || $this->config_error_message_image_default) {
4159
+            // Show generic custom error image instead of error message
4160
+            // for use on production sites where you don't want debug messages
4161
+            if (($this->err == 'showerror') || $this->phpThumbDebug) {
4162
+                // fall through and actually show error message even if default error image is set
4163
+            } else {
4164
+                header('Location: '.($this->err ? $this->err : $this->config_error_message_image_default));
4165
+                exit;
4166
+            }
4167
+        }
4168
+        $this->setOutputFormat();
4169
+        if (!$this->thumbnailFormat || !$this->config_disable_debug || (phpthumb_functions::gd_version() < 1)) {
4170
+            $this->thumbnailFormat = 'text';
4171
+        }
4172
+        if (@$this->thumbnailFormat == 'text') {
4173
+            // bypass all GD functions and output text error message
4174
+            if (!headers_sent()) {
4175
+                header('Content-type: text/plain');
4176
+                echo $text;
4177
+            } else {
4178
+                echo '<pre>'.htmlspecialchars($text).'</pre>';
4179
+            }
4180
+            exit;
4181
+        }
4182
+
4183
+        $FontWidth  = imagefontwidth($this->config_error_fontsize);
4184
+        $FontHeight = imagefontheight($this->config_error_fontsize);
4185
+
4186
+        $LinesOfText = explode("\n", @wordwrap($text, floor($width / $FontWidth), "\n", true));
4187
+        $height = max($height, count($LinesOfText) * $FontHeight);
4188
+
4189
+        $headers_file = '';
4190
+        $headers_line = '';
4191
+        if (phpthumb_functions::version_compare_replacement(PHP_VERSION, '4.3.0', '>=') && headers_sent($headers_file, $headers_line)) {
4192
+
4193
+            echo "\n".'**Headers already sent in file "'.$headers_file.'" on line "'.$headers_line.'", dumping error message as text:**<br><pre>'."\n\n".$text."\n".'</pre>';
4194
+
4195
+        } elseif (headers_sent()) {
4196
+
4197
+            echo "\n".'**Headers already sent, dumping error message as text:**<br><pre>'."\n\n".$text."\n".'</pre>';
4198
+
4199
+        } elseif ($gdimg_error = imagecreate($width, $height)) {
4200
+
4201
+            $background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_bgcolor,   true);
4202
+            $text_color       = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_textcolor, true);
4203
+            imagefilledrectangle($gdimg_error, 0, 0, $width, $height, $background_color);
4204
+            $lineYoffset = 0;
4205
+            foreach ($LinesOfText as $line) {
4206
+                imagestring($gdimg_error, $this->config_error_fontsize, 2, $lineYoffset, $line, $text_color);
4207
+                $lineYoffset += $FontHeight;
4208
+            }
4209
+            if (function_exists('imagetypes')) {
4210
+                $imagetypes = imagetypes();
4211
+                if ($imagetypes & IMG_PNG) {
4212
+                    header('Content-Type: image/png');
4213
+                    imagepng($gdimg_error);
4214
+                } elseif ($imagetypes & IMG_GIF) {
4215
+                    header('Content-Type: image/gif');
4216
+                    imagegif($gdimg_error);
4217
+                } elseif ($imagetypes & IMG_JPG) {
4218
+                    header('Content-Type: image/jpeg');
4219
+                    imagejpeg($gdimg_error);
4220
+                } elseif ($imagetypes & IMG_WBMP) {
4221
+                    header('Content-Type: image/vnd.wap.wbmp');
4222
+                    imagewbmp($gdimg_error);
4223
+                }
4224
+            }
4225
+            imagedestroy($gdimg_error);
4226
+
4227
+        }
4228
+        if (!headers_sent()) {
4229
+            echo "\n".'**Failed to send graphical error image, dumping error message as text:**<br>'."\n\n".$text;
4230
+        }
4231
+        exit;
4232
+    }
4233
+
4234
+    public function ImageCreateFromStringReplacement(&$RawImageData, $DieOnErrors=false) {
4235
+        // there are serious bugs in the non-bundled versions of GD which may cause
4236
+        // PHP to segfault when calling imagecreatefromstring() - avoid if at all possible
4237
+        // when not using a bundled version of GD2
4238
+        if (!phpthumb_functions::gd_version()) {
4239
+            if ($DieOnErrors) {
4240
+                if (!headers_sent()) {
4241
+                    // base64-encoded error image in GIF format
4242
+                    $ERROR_NOGD = 'R0lGODlhIAAgALMAAAAAABQUFCQkJDY2NkZGRldXV2ZmZnJycoaGhpSUlKWlpbe3t8XFxdXV1eTk5P7+/iwAAAAAIAAgAAAE/vDJSau9WILtTAACUinDNijZtAHfCojS4W5H+qxD8xibIDE9h0OwWaRWDIljJSkUJYsN4bihMB8th3IToAKs1VtYM75cyV8sZ8vygtOE5yMKmGbO4jRdICQCjHdlZzwzNW4qZSQmKDaNjhUMBX4BBAlmMywFSRWEmAI6b5gAlhNxokGhooAIK5o/pi9vEw4Lfj4OLTAUpj6IabMtCwlSFw0DCKBoFqwAB04AjI54PyZ+yY3TD0ss2YcVmN/gvpcu4TOyFivWqYJlbAHPpOntvxNAACcmGHjZzAZqzSzcq5fNjxFmAFw9iFRunD1epU6tsIPmFCAJnWYE0FURk7wJDA0MTKpEzoWAAskiAAA7';
4243
+                    header('Content-Type: image/gif');
4244
+                    echo base64_decode($ERROR_NOGD);
4245
+                } else {
4246
+                    echo '*** ERROR: No PHP-GD support available ***';
4247
+                }
4248
+                exit;
4249
+            } else {
4250
+                $this->DebugMessage('ImageCreateFromStringReplacement() failed: gd_version says "'.phpthumb_functions::gd_version().'"', __FILE__, __LINE__);
4251
+                return false;
4252
+            }
4253
+        }
4254
+        if (phpthumb_functions::gd_is_bundled()) {
4255
+            $this->DebugMessage('ImageCreateFromStringReplacement() calling built-in imagecreatefromstring()', __FILE__, __LINE__);
4256
+            return @imagecreatefromstring($RawImageData);
4257
+        }
4258
+        if ($this->issafemode) {
4259
+            $this->DebugMessage('ImageCreateFromStringReplacement() failed: cannot create temp file in SAFE_MODE', __FILE__, __LINE__);
4260
+            return false;
4261
+        }
4262
+
4263
+        switch (substr($RawImageData, 0, 3)) {
4264
+            case 'GIF':
4265
+                $ICFSreplacementFunctionName = 'imagecreatefromgif';
4266
+                break;
4267
+            case "\xFF\xD8\xFF":
4268
+                $ICFSreplacementFunctionName = 'imagecreatefromjpeg';
4269
+                break;
4270
+            case "\x89".'PN':
4271
+                $ICFSreplacementFunctionName = 'imagecreatefrompng';
4272
+                break;
4273
+            default:
4274
+                $this->DebugMessage('ImageCreateFromStringReplacement() failed: unknown fileformat signature "'.phpthumb_functions::HexCharDisplay(substr($RawImageData, 0, 3)).'"', __FILE__, __LINE__);
4275
+                return false;
4276
+                break;
4277
+        }
4278
+        $ErrorMessage = '';
4279
+        if ($tempnam = $this->phpThumb_tempnam()) {
4280
+            if ($fp_tempnam = @fopen($tempnam, 'wb')) {
4281
+                fwrite($fp_tempnam, $RawImageData);
4282
+                fclose($fp_tempnam);
4283
+                @chmod($tempnam, $this->getParameter('config_file_create_mask'));
4284
+                if (($ICFSreplacementFunctionName == 'imagecreatefromgif') && !function_exists($ICFSreplacementFunctionName)) {
4285
+
4286
+                    // Need to create from GIF file, but imagecreatefromgif does not exist
4287
+                    ob_start();
4288
+                    if (!@include_once( __DIR__ .'/phpthumb.gif.php')) {
4289
+                        $ErrorMessage = 'Failed to include required file "'. __DIR__ .'/phpthumb.gif.php" in '.__FILE__.' on line '.__LINE__;
4290
+                        $this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4291
+                    }
4292
+                    ob_end_clean();
4293
+                    // gif_loadFileToGDimageResource() cannot read from raw data, write to file first
4294
+                    if ($tempfilename = $this->phpThumb_tempnam()) {
4295
+                        if ($fp_tempfile = @fopen($tempfilename, 'wb')) {
4296
+                            fwrite($fp_tempfile, $RawImageData);
4297
+                            fclose($fp_tempfile);
4298
+                            $gdimg_source = gif_loadFileToGDimageResource($tempfilename);
4299
+                            $this->DebugMessage('gif_loadFileToGDimageResource('.$tempfilename.') completed', __FILE__, __LINE__);
4300
+                            $this->DebugMessage('deleting "'.$tempfilename.'"', __FILE__, __LINE__);
4301
+                            unlink($tempfilename);
4302
+                            return $gdimg_source;
4303
+                        } else {
4304
+                            $ErrorMessage = 'Failed to open tempfile in '.__FILE__.' on line '.__LINE__;
4305
+                            $this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4306
+                        }
4307
+                    } else {
4308
+                        $ErrorMessage = 'Failed to open generate tempfile name in '.__FILE__.' on line '.__LINE__;
4309
+                        $this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4310
+                    }
4311
+
4312
+                } elseif (function_exists($ICFSreplacementFunctionName) && ($gdimg_source = @$ICFSreplacementFunctionName($tempnam))) {
4313
+
4314
+                    // great
4315
+                    $this->DebugMessage($ICFSreplacementFunctionName.'('.$tempnam.') succeeded', __FILE__, __LINE__);
4316
+                    $this->DebugMessage('deleting "'.$tempnam.'"', __FILE__, __LINE__);
4317
+                    unlink($tempnam);
4318
+                    return $gdimg_source;
4319
+
4320
+                } else {
4321
+
4322
+                    // GD functions not available, or failed to create image
4323
+                    $this->DebugMessage($ICFSreplacementFunctionName.'('.$tempnam.') '.(function_exists($ICFSreplacementFunctionName) ? 'failed' : 'does not exist'), __FILE__, __LINE__);
4324
+                    if (isset($_GET['phpThumbDebug'])) {
4325
+                        $this->phpThumbDebug();
4326
+                    }
4327
+
4328
+                }
4329
+            } else {
4330
+                $ErrorMessage = 'Failed to fopen('.$tempnam.', "wb") in '.__FILE__.' on line '.__LINE__."\n".'You may need to set $PHPTHUMB_CONFIG[temp_directory] in phpThumb.config.php';
4331
+                if ($this->issafemode) {
4332
+                    $ErrorMessage = 'ImageCreateFromStringReplacement() failed in '.__FILE__.' on line '.__LINE__.': cannot create temp file in SAFE_MODE';
4333
+                }
4334
+                $this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4335
+            }
4336
+            $this->DebugMessage('deleting "'.$tempnam.'"', __FILE__, __LINE__);
4337
+            @unlink($tempnam);
4338
+        } else {
4339
+            $ErrorMessage = 'Failed to generate phpThumb_tempnam() in '.__FILE__.' on line '.__LINE__."\n".'You may need to set $PHPTHUMB_CONFIG[temp_directory] in phpThumb.config.php';
4340
+            if ($this->issafemode) {
4341
+                $ErrorMessage = 'ImageCreateFromStringReplacement() failed in '.__FILE__.' on line '.__LINE__.': cannot create temp file in SAFE_MODE';
4342
+            }
4343
+        }
4344
+        if ($DieOnErrors && $ErrorMessage) {
4345
+            return $this->ErrorImage($ErrorMessage);
4346
+        }
4347
+        return false;
4348
+    }
4349
+
4350
+    public function ImageResizeFunction(&$dst_im, &$src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH) {
4351
+        $this->DebugMessage('ImageResizeFunction($o, $s, '.$dstX.', '.$dstY.', '.$srcX.', '.$srcY.', '.$dstW.', '.$dstH.', '.$srcW.', '.$srcH.')', __FILE__, __LINE__);
4352
+        if (($dstW == $srcW) && ($dstH == $srcH)) {
4353
+            return imagecopy($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH);
4354
+        }
4355
+        if (phpthumb_functions::gd_version() >= 2.0) {
4356
+            if ($this->config_disable_imagecopyresampled) {
4357
+                return phpthumb_functions::ImageCopyResampleBicubic($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);
4358
+            }
4359
+            return imagecopyresampled($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);
4360
+        }
4361
+        return imagecopyresized($dst_im, $src_im, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);
4362
+    }
4363
+
4364
+    public function InitializeTempDirSetting() {
4365
+        $this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : $this->realPathSafe((function_exists('sys_get_temp_dir') ? sys_get_temp_dir() : ''))); // sys_get_temp_dir added in PHP v5.2.1
4366
+        $this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : $this->realPathSafe(ini_get('upload_tmp_dir')));
4367
+        $this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : $this->realPathSafe(getenv('TMPDIR')));
4368
+        $this->config_temp_directory = ($this->config_temp_directory ? $this->config_temp_directory : $this->realPathSafe(getenv('TMP')));
4369
+        return true;
4370
+    }
4371
+
4372
+    public function phpThumb_tempnam() {
4373
+        $this->InitializeTempDirSetting();
4374
+        $tempnam = $this->realPathSafe(tempnam($this->config_temp_directory, 'pThumb'));
4375
+        $this->tempFilesToDelete[$tempnam] = $tempnam;
4376
+        $this->DebugMessage('phpThumb_tempnam() returning "'.$tempnam.'"', __FILE__, __LINE__);
4377
+        return $tempnam;
4378
+    }
4379
+
4380
+    public function DebugMessage($message, $file='', $line='') {
4381
+        $this->debugmessages[] = $message.($file ? ' in file "'.(basename($file) ? basename($file) : $file).'"' : '').($line ? ' on line '.$line : '');
4382
+        return true;
4383
+    }
4384
+
4385
+    public function DebugTimingMessage($message, $file='', $line='', $timestamp=0) {
4386
+        if (!$timestamp) {
4387
+            $timestamp = array_sum(explode(' ', microtime()));
4388
+        }
4389
+        $this->debugtiming[number_format($timestamp, 6, '.', '')] = ': '.$message.($file ? ' in file "'.(basename($file) ? basename($file) : $file).'"' : '').($line ? ' on line '.$line : '');
4390
+        return true;
4391
+    }
4392 4392
 
4393 4393
 }
Please login to merge, or discard this patch.
Spacing   +205 added lines, -205 removed lines patch added patch discarded remove patch
@@ -10,9 +10,9 @@  discard block
 block discarded – undo
10 10
 //////////////////////////////////////////////////////////////
11 11
 
12 12
 ob_start();
13
-if (!include_once( __DIR__ .'/phpthumb.functions.php')) {
13
+if (!include_once(__DIR__.'/phpthumb.functions.php')) {
14 14
 	ob_end_flush();
15
-	die('failed to include_once("'. __DIR__ .'/phpthumb.functions.php")');
15
+	die('failed to include_once("'.__DIR__.'/phpthumb.functions.php")');
16 16
 }
17 17
 ob_end_clean();
18 18
 
@@ -21,42 +21,42 @@  discard block
 block discarded – undo
21 21
 	// public:
22 22
 	// START PARAMETERS (for object mode and phpThumb.php)
23 23
 	// See phpthumb.readme.txt for descriptions of what each of these values are
24
-	public $src  = null;     // SouRCe filename
25
-	public $new  = null;     // NEW image (phpThumb.php only)
26
-	public $w    = null;     // Width
27
-	public $h    = null;     // Height
28
-	public $wp   = null;     // Width  (Portrait Images Only)
29
-	public $hp   = null;     // Height (Portrait Images Only)
30
-	public $wl   = null;     // Width  (Landscape Images Only)
31
-	public $hl   = null;     // Height (Landscape Images Only)
32
-	public $ws   = null;     // Width  (Square Images Only)
33
-	public $hs   = null;     // Height (Square Images Only)
34
-	public $f    = null;     // output image Format
35
-	public $q    = 75;       // jpeg output Quality
36
-	public $sx   = null;     // Source crop top-left X position
37
-	public $sy   = null;     // Source crop top-left Y position
38
-	public $sw   = null;     // Source crop Width
39
-	public $sh   = null;     // Source crop Height
40
-	public $zc   = null;     // Zoom Crop
41
-	public $bc   = null;     // Border Color
42
-	public $bg   = null;     // BackGround color
43
-	public $fltr = array();  // FiLTeRs
44
-	public $goto = null;     // GO TO url after processing
45
-	public $err  = null;     // default ERRor image filename
46
-	public $xto  = null;     // extract eXif Thumbnail Only
47
-	public $ra   = null;     // Rotate by Angle
48
-	public $ar   = null;     // Auto Rotate
49
-	public $aoe  = null;     // Allow Output Enlargement
50
-	public $far  = null;     // Fixed Aspect Ratio
51
-	public $iar  = null;     // Ignore Aspect Ratio
52
-	public $maxb = null;     // MAXimum Bytes
53
-	public $down = null;     // DOWNload thumbnail filename
54
-	public $md5s = null;     // MD5 hash of Source image
55
-	public $sfn  = 0;        // Source Frame Number
56
-	public $dpi  = 150;      // Dots Per Inch for vector source formats
57
-	public $sia  = null;     // Save Image As filename
58
-
59
-	public $file = null;     // >>>deprecated, DO NOT USE, will be removed in future versions<<<
24
+	public $src  = null; // SouRCe filename
25
+	public $new  = null; // NEW image (phpThumb.php only)
26
+	public $w    = null; // Width
27
+	public $h    = null; // Height
28
+	public $wp   = null; // Width  (Portrait Images Only)
29
+	public $hp   = null; // Height (Portrait Images Only)
30
+	public $wl   = null; // Width  (Landscape Images Only)
31
+	public $hl   = null; // Height (Landscape Images Only)
32
+	public $ws   = null; // Width  (Square Images Only)
33
+	public $hs   = null; // Height (Square Images Only)
34
+	public $f    = null; // output image Format
35
+	public $q    = 75; // jpeg output Quality
36
+	public $sx   = null; // Source crop top-left X position
37
+	public $sy   = null; // Source crop top-left Y position
38
+	public $sw   = null; // Source crop Width
39
+	public $sh   = null; // Source crop Height
40
+	public $zc   = null; // Zoom Crop
41
+	public $bc   = null; // Border Color
42
+	public $bg   = null; // BackGround color
43
+	public $fltr = array(); // FiLTeRs
44
+	public $goto = null; // GO TO url after processing
45
+	public $err  = null; // default ERRor image filename
46
+	public $xto  = null; // extract eXif Thumbnail Only
47
+	public $ra   = null; // Rotate by Angle
48
+	public $ar   = null; // Auto Rotate
49
+	public $aoe  = null; // Allow Output Enlargement
50
+	public $far  = null; // Fixed Aspect Ratio
51
+	public $iar  = null; // Ignore Aspect Ratio
52
+	public $maxb = null; // MAXimum Bytes
53
+	public $down = null; // DOWNload thumbnail filename
54
+	public $md5s = null; // MD5 hash of Source image
55
+	public $sfn  = 0; // Source Frame Number
56
+	public $dpi  = 150; // Dots Per Inch for vector source formats
57
+	public $sia  = null; // Save Image As filename
58
+
59
+	public $file = null; // >>>deprecated, DO NOT USE, will be removed in future versions<<<
60 60
 
61 61
 	public $phpThumbDebug = null;
62 62
 	// END PARAMETERS
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
 	public $config_cache_source_filemtime_ignore_remote = true;
128 128
 	public $config_cache_default_only_suffix            = false;
129 129
 	public $config_cache_force_passthru                 = true;
130
-	public $config_cache_prefix                         = '';    // default value set in the constructor below
130
+	public $config_cache_prefix                         = ''; // default value set in the constructor below
131 131
 
132 132
 	// * MySQL
133 133
 	public $config_mysql_extension                      = null;
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
 	public $config_disable_debug                        = true;
145 145
 	public $config_allow_src_above_docroot              = false;
146 146
 	public $config_allow_src_above_phpthumb             = true;
147
-	public $config_auto_allow_symlinks                  = true;    // allow symlink target directories without explicitly whitelisting them
147
+	public $config_auto_allow_symlinks                  = true; // allow symlink target directories without explicitly whitelisting them
148 148
 	public $config_additional_allowed_dirs              = array(); // additional directories to allow source images to be read from
149 149
 	public $config_file_create_mask                     = 0755;
150 150
 	public $config_dir_create_mask                      = 0755;
@@ -208,7 +208,7 @@  discard block
 block discarded – undo
208 208
 	public $tempFilesToDelete = array();
209 209
 	public $cache_filename    = null;
210 210
 
211
-	public $AlphaCapableFormats = array( 'png', 'ico', 'gif');
211
+	public $AlphaCapableFormats = array('png', 'ico', 'gif');
212 212
 	public $is_alpha = false;
213 213
 
214 214
 	public $iswindows        = null;
@@ -230,10 +230,10 @@  discard block
 block discarded – undo
230 230
 
231 231
 		foreach (array(ini_get('memory_limit'), get_cfg_var('memory_limit')) as $php_config_memory_limit) {
232 232
 			if ('' !== $php_config_memory_limit) {
233
-				if (strtoupper($php_config_memory_limit[ strlen($php_config_memory_limit) - 1 ]) == 'G') { // PHP memory limit expressed in Gigabytes
234
-					$php_config_memory_limit = (int) substr($php_config_memory_limit, 0, -1) * 1073741824;
235
-				} elseif (strtoupper($php_config_memory_limit[ strlen($php_config_memory_limit) - 1 ]) == 'M') { // PHP memory limit expressed in Megabytes
236
-					$php_config_memory_limit = (int) substr($php_config_memory_limit, 0, -1) * 1048576;
233
+				if (strtoupper($php_config_memory_limit[strlen($php_config_memory_limit) - 1]) == 'G') { // PHP memory limit expressed in Gigabytes
234
+					$php_config_memory_limit = (int)substr($php_config_memory_limit, 0, -1) * 1073741824;
235
+				} elseif (strtoupper($php_config_memory_limit[strlen($php_config_memory_limit) - 1]) == 'M') { // PHP memory limit expressed in Megabytes
236
+					$php_config_memory_limit = (int)substr($php_config_memory_limit, 0, -1) * 1048576;
237 237
 				}
238 238
 				$this->php_memory_limit = max($this->php_memory_limit, $php_config_memory_limit);
239 239
 			}
@@ -242,10 +242,10 @@  discard block
 block discarded – undo
242 242
 			$this->config_max_source_pixels = round($this->php_memory_limit * 0.20); // 20% of memory_limit
243 243
 		}
244 244
 
245
-		$this->iswindows  = (bool) (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN');
246
-		$this->issafemode = (bool) preg_match('#(1|ON)#i', ini_get('safe_mode'));
247
-		$this->config_document_root = (!empty($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT']   : $this->config_document_root);
248
-		$this->config_cache_prefix  = ( isset($_SERVER['SERVER_NAME'])   ? $_SERVER['SERVER_NAME'].'_' : '');
245
+		$this->iswindows  = (bool)(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN');
246
+		$this->issafemode = (bool)preg_match('#(1|ON)#i', ini_get('safe_mode'));
247
+		$this->config_document_root = (!empty($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'] : $this->config_document_root);
248
+		$this->config_cache_prefix  = (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'].'_' : '');
249 249
 
250 250
 		$this->purgeTempFiles(); // purge existing temp files if re-initializing object
251 251
 
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
 
257 257
 		if (!$this->config_disable_debug) {
258 258
 			// if debug mode is enabled, force phpThumbDebug output, do not allow normal thumbnails to be generated
259
-			$this->phpThumbDebug = (null === $this->phpThumbDebug ? 9 : max(1, (int) $this->phpThumbDebug));
259
+			$this->phpThumbDebug = (null === $this->phpThumbDebug ? 9 : max(1, (int)$this->phpThumbDebug));
260 260
 		}
261 261
 	}
262 262
 
@@ -296,10 +296,10 @@  discard block
 block discarded – undo
296 296
 	}
297 297
 
298 298
 	// public:
299
-	public function setSourceData($rawImageData, $sourceFilename='') {
299
+	public function setSourceData($rawImageData, $sourceFilename = '') {
300 300
 		//$this->resetObject();
301 301
 		//$this->sourceFilename = null;
302
-		$this->rawImageData   = $rawImageData;
302
+		$this->rawImageData = $rawImageData;
303 303
 		$this->DebugMessage('setSourceData() setting $this->rawImageData ('.strlen($this->rawImageData).' bytes; magic="'.substr($this->rawImageData, 0, 4).'" ('.phpthumb_functions::HexCharDisplay(substr($this->rawImageData, 0, 4)).'))', __FILE__, __LINE__);
304 304
 		if ($this->config_cache_source_enabled) {
305 305
 			$sourceFilename = ($sourceFilename ? $sourceFilename : md5($rawImageData));
@@ -381,19 +381,19 @@  discard block
 block discarded – undo
381 381
 			$this->phpThumbDebug('8h');
382 382
 
383 383
 		// default values, also applicable for far="C"
384
-		$destination_offset_x = round(($this->thumbnail_width  - $this->thumbnail_image_width)  / 2);
384
+		$destination_offset_x = round(($this->thumbnail_width - $this->thumbnail_image_width) / 2);
385 385
 		$destination_offset_y = round(($this->thumbnail_height - $this->thumbnail_image_height) / 2);
386 386
 		if (($this->far == 'L') || ($this->far == 'TL') || ($this->far == 'BL')) {
387 387
 			$destination_offset_x = 0;
388 388
 		}
389 389
 		if (($this->far == 'R') || ($this->far == 'TR') || ($this->far == 'BR')) {
390
-			$destination_offset_x =  round($this->thumbnail_width  - $this->thumbnail_image_width);
390
+			$destination_offset_x = round($this->thumbnail_width - $this->thumbnail_image_width);
391 391
 		}
392 392
 		if (($this->far == 'T') || ($this->far == 'TL') || ($this->far == 'TR')) {
393 393
 			$destination_offset_y = 0;
394 394
 		}
395 395
 		if (($this->far == 'B') || ($this->far == 'BL') || ($this->far == 'BR')) {
396
-			$destination_offset_y =  round($this->thumbnail_height - $this->thumbnail_image_height);
396
+			$destination_offset_y = round($this->thumbnail_height - $this->thumbnail_image_height);
397 397
 		}
398 398
 
399 399
 //		// copy/resize image to appropriate dimensions
@@ -461,14 +461,14 @@  discard block
 block discarded – undo
461 461
 		$builtin_formats = array();
462 462
 		if (function_exists('imagetypes')) {
463 463
 			$imagetypes = imagetypes();
464
-			$builtin_formats['wbmp'] = (bool) ($imagetypes & IMG_WBMP);
465
-			$builtin_formats['jpg']  = (bool) ($imagetypes & IMG_JPG);
466
-			$builtin_formats['gif']  = (bool) ($imagetypes & IMG_GIF);
467
-			$builtin_formats['png']  = (bool) ($imagetypes & IMG_PNG);
464
+			$builtin_formats['wbmp'] = (bool)($imagetypes & IMG_WBMP);
465
+			$builtin_formats['jpg']  = (bool)($imagetypes & IMG_JPG);
466
+			$builtin_formats['gif']  = (bool)($imagetypes & IMG_GIF);
467
+			$builtin_formats['png']  = (bool)($imagetypes & IMG_PNG);
468 468
 		}
469 469
 
470
-		$this->DebugMessage('imageinterlace($this->gdimg_output, '. (int) $this->config_output_interlace .')', __FILE__, __LINE__);
471
-		imageinterlace($this->gdimg_output, (int) $this->config_output_interlace);
470
+		$this->DebugMessage('imageinterlace($this->gdimg_output, '.(int)$this->config_output_interlace.')', __FILE__, __LINE__);
471
+		imageinterlace($this->gdimg_output, (int)$this->config_output_interlace);
472 472
 
473 473
 		$this->DebugMessage('RenderOutput() attempting image'.strtolower(@$this->thumbnailFormat).'($this->gdimg_output)', __FILE__, __LINE__);
474 474
 		ob_start();
@@ -535,8 +535,8 @@  discard block
 block discarded – undo
535 535
 				break;
536 536
 
537 537
 			case 'bmp':
538
-				if (!@include_once( __DIR__ .'/phpthumb.bmp.php')) {
539
-					$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
538
+				if (!@include_once(__DIR__.'/phpthumb.bmp.php')) {
539
+					$this->DebugMessage('Error including "'.__DIR__.'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
540 540
 					ob_end_clean();
541 541
 					return false;
542 542
 				}
@@ -546,8 +546,8 @@  discard block
 block discarded – undo
546 546
 				break;
547 547
 
548 548
 			case 'ico':
549
-				if (!@include_once( __DIR__ .'/phpthumb.ico.php')) {
550
-					$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
549
+				if (!@include_once(__DIR__.'/phpthumb.ico.php')) {
550
+					$this->DebugMessage('Error including "'.__DIR__.'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
551 551
 					ob_end_clean();
552 552
 					return false;
553 553
 				}
@@ -637,8 +637,8 @@  discard block
 block discarded – undo
637 637
 
638 638
 		} else {
639 639
 
640
-			$this->DebugMessage('imageinterlace($this->gdimg_output, '. (int) $this->config_output_interlace .')', __FILE__, __LINE__);
641
-			imageinterlace($this->gdimg_output, (int) $this->config_output_interlace);
640
+			$this->DebugMessage('imageinterlace($this->gdimg_output, '.(int)$this->config_output_interlace.')', __FILE__, __LINE__);
641
+			imageinterlace($this->gdimg_output, (int)$this->config_output_interlace);
642 642
 			switch ($this->thumbnailFormat) {
643 643
 				case 'jpeg':
644 644
 					header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($this->thumbnailFormat));
@@ -654,8 +654,8 @@  discard block
 block discarded – undo
654 654
 					break;
655 655
 
656 656
 				case 'bmp':
657
-					if (!@include_once( __DIR__ .'/phpthumb.bmp.php')) {
658
-						$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
657
+					if (!@include_once(__DIR__.'/phpthumb.bmp.php')) {
658
+						$this->DebugMessage('Error including "'.__DIR__.'/phpthumb.bmp.php" which is required for BMP format output', __FILE__, __LINE__);
659 659
 						return false;
660 660
 					}
661 661
 					$phpthumb_bmp = new phpthumb_bmp();
@@ -675,8 +675,8 @@  discard block
 block discarded – undo
675 675
 					break;
676 676
 
677 677
 				case 'ico':
678
-					if (!@include_once( __DIR__ .'/phpthumb.ico.php')) {
679
-						$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
678
+					if (!@include_once(__DIR__.'/phpthumb.ico.php')) {
679
+						$this->DebugMessage('Error including "'.__DIR__.'/phpthumb.ico.php" which is required for ICO format output', __FILE__, __LINE__);
680 680
 						return false;
681 681
 					}
682 682
 					$phpthumb_ico = new phpthumb_ico();
@@ -927,10 +927,10 @@  discard block
 block discarded – undo
927 927
 
928 928
 		$AvailableImageOutputFormats = array();
929 929
 		$AvailableImageOutputFormats[] = 'text';
930
-		if (@is_readable( __DIR__ .'/phpthumb.ico.php')) {
930
+		if (@is_readable(__DIR__.'/phpthumb.ico.php')) {
931 931
 			$AvailableImageOutputFormats[] = 'ico';
932 932
 		}
933
-		if (@is_readable( __DIR__ .'/phpthumb.bmp.php')) {
933
+		if (@is_readable(__DIR__.'/phpthumb.bmp.php')) {
934 934
 			$AvailableImageOutputFormats[] = 'bmp';
935 935
 		}
936 936
 
@@ -956,7 +956,7 @@  discard block
 block discarded – undo
956 956
 				$AvailableImageOutputFormats[] = 'jpeg';
957 957
 			}
958 958
 		} else {
959
-			$this->DebugMessage('imagetypes() does not exist - GD support might not be enabled?',  __FILE__, __LINE__);
959
+			$this->DebugMessage('imagetypes() does not exist - GD support might not be enabled?', __FILE__, __LINE__);
960 960
 		}
961 961
 		if ($this->ImageMagickVersion()) {
962 962
 			$IMformats = array('jpeg', 'png', 'gif', 'bmp', 'ico', 'wbmp');
@@ -993,7 +993,7 @@  discard block
 block discarded – undo
993 993
 		// for JPEG images, quality 1 (worst) to 99 (best)
994 994
 		// quality < 25 is nasty, with not much size savings - not recommended
995 995
 		// problems with 100 - invalid JPEG?
996
-		$this->thumbnailQuality = max(1, min(99, ($this->q ? (int) $this->q : 75)));
996
+		$this->thumbnailQuality = max(1, min(99, ($this->q ? (int)$this->q : 75)));
997 997
 		$this->DebugMessage('$this->thumbnailQuality set to "'.$this->thumbnailQuality.'"', __FILE__, __LINE__);
998 998
 
999 999
 		return true;
@@ -1003,7 +1003,7 @@  discard block
 block discarded – undo
1003 1003
 	public function setCacheDirectory() {
1004 1004
 		// resolve cache directory to absolute pathname
1005 1005
 		$this->DebugMessage('setCacheDirectory() starting with config_cache_directory = "'.$this->config_cache_directory.'"', __FILE__, __LINE__);
1006
-		if ($this->config_cache_directory[ 0 ] == '.') {
1006
+		if ($this->config_cache_directory[0] == '.') {
1007 1007
 			if (preg_match('#^(f|ht)tps?\://#i', $this->src)) {
1008 1008
 				if (!$this->config_cache_disable_warning) {
1009 1009
 					$this->ErrorImage('$this->config_cache_directory ('.$this->config_cache_directory.') cannot be used for remote images. Adjust "cache_directory" or "cache_disable_warning" in phpThumb.config.php');
@@ -1144,7 +1144,7 @@  discard block
 block discarded – undo
1144 1144
 			array_unshift($allowed_dirs, $this->realPathSafe($this->config_document_root));
1145 1145
 		} else {
1146 1146
 			if (!$this->config_allow_src_above_phpthumb) {
1147
-				array_unshift($allowed_dirs, $this->realPathSafe( __DIR__ ));
1147
+				array_unshift($allowed_dirs, $this->realPathSafe(__DIR__));
1148 1148
 			} else {
1149 1149
 				// no checks are needed, offload the work to realpath and forget about it
1150 1150
 				$this->DebugMessage('resolvePath: checks disabled, returning '.$this->realPathSafe($path), __FILE__, __LINE__);
@@ -1201,7 +1201,7 @@  discard block
 block discarded – undo
1201 1201
 			if ($this->config_auto_allow_symlinks) {
1202 1202
 				$allowed_dirs[0] = $path;
1203 1203
 			}
1204
-			$path = $path.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, array_slice($segments,$i + 1));
1204
+			$path = $path.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, array_slice($segments, $i + 1));
1205 1205
 		} while (true);
1206 1206
 		return $path;
1207 1207
 	}
@@ -1217,7 +1217,7 @@  discard block
 block discarded – undo
1217 1217
 		// http://stackoverflow.com/questions/21421569
1218 1218
 		$newfilename = preg_replace('#[\\/]+#', DIRECTORY_SEPARATOR, $filename);
1219 1219
 		if (!preg_match('#^'.DIRECTORY_SEPARATOR.'#', $newfilename)) {
1220
-			$newfilename =  __DIR__ .DIRECTORY_SEPARATOR.$newfilename;
1220
+			$newfilename = __DIR__.DIRECTORY_SEPARATOR.$newfilename;
1221 1221
 		}
1222 1222
 		do {
1223 1223
 			$beforeloop = $newfilename;
@@ -1307,7 +1307,7 @@  discard block
 block discarded – undo
1307 1307
 		} else {
1308 1308
 
1309 1309
 			// relative to current directory (any OS)
1310
-			$AbsoluteFilename =  __DIR__ .DIRECTORY_SEPARATOR.preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $filename);
1310
+			$AbsoluteFilename = __DIR__.DIRECTORY_SEPARATOR.preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $filename);
1311 1311
 
1312 1312
 			if (substr(dirname(@$_SERVER['PHP_SELF']), 0, 2) == '/~') {
1313 1313
 				if ($ApacheLookupURIarray = phpthumb_functions::ApacheLookupURIarray(dirname(@$_SERVER['PHP_SELF']))) {
@@ -1344,15 +1344,15 @@  discard block
 block discarded – undo
1344 1344
 			$this->DebugMessage('!$this->config_allow_src_above_docroot therefore setting "'.$AbsoluteFilename.'" (outside "'.$this->realPathSafe($this->config_document_root).'") to null', __FILE__, __LINE__);
1345 1345
 			return false;
1346 1346
 		}
1347
-		if (!$this->config_allow_src_above_phpthumb && !preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/',  __DIR__ )).'#', $resolvedAbsoluteFilename)) {
1348
-			$this->DebugMessage('!$this->config_allow_src_above_phpthumb therefore setting "'.$AbsoluteFilename.'" (outside "'. __DIR__ .'") to null', __FILE__, __LINE__);
1347
+		if (!$this->config_allow_src_above_phpthumb && !preg_match('#^'.preg_quote(str_replace(DIRECTORY_SEPARATOR, '/', __DIR__)).'#', $resolvedAbsoluteFilename)) {
1348
+			$this->DebugMessage('!$this->config_allow_src_above_phpthumb therefore setting "'.$AbsoluteFilename.'" (outside "'.__DIR__.'") to null', __FILE__, __LINE__);
1349 1349
 			return false;
1350 1350
 		}
1351 1351
 		return $resolvedAbsoluteFilename;
1352 1352
 	}
1353 1353
 
1354 1354
 
1355
-	public function file_exists_ignoreopenbasedir($filename, $cached=true) {
1355
+	public function file_exists_ignoreopenbasedir($filename, $cached = true) {
1356 1356
 		static $open_basedirs = null;
1357 1357
 		static $file_exists_cache = array();
1358 1358
 		if (!$cached || !isset($file_exists_cache[$filename])) {
@@ -1363,7 +1363,7 @@  discard block
 block discarded – undo
1363 1363
 				$file_exists_cache[$filename] = file_exists($filename);
1364 1364
 			} elseif ($this->iswindows) {
1365 1365
 				$ls_filename = trim(phpthumb_functions::SafeExec('dir /b '.phpthumb_functions::escapeshellarg_replacement($filename)));
1366
-				$file_exists_cache[$filename] = ($ls_filename == basename($filename));  // command dir /b return only filename without path
1366
+				$file_exists_cache[$filename] = ($ls_filename == basename($filename)); // command dir /b return only filename without path
1367 1367
 			} else {
1368 1368
 				$ls_filename = trim(phpthumb_functions::SafeExec('ls '.phpthumb_functions::escapeshellarg_replacement($filename)));
1369 1369
 				$file_exists_cache[$filename] = ($ls_filename == $filename);
@@ -1416,10 +1416,10 @@  discard block
 block discarded – undo
1416 1416
 					$this->DebugMessage('Leaving $this->config_imagemagick_path as ('.$this->config_imagemagick_path.') because !is_execuatable($this->realPathSafe($this->config_imagemagick_path)) ('.$this->realPathSafe($this->config_imagemagick_path).')', __FILE__, __LINE__);
1417 1417
 				}
1418 1418
 			}
1419
-			$this->DebugMessage('                  file_exists('.$this->config_imagemagick_path.') = '. (int) (@file_exists($this->config_imagemagick_path)), __FILE__, __LINE__);
1420
-			$this->DebugMessage('file_exists_ignoreopenbasedir('.$this->config_imagemagick_path.') = '. (int) $this->file_exists_ignoreopenbasedir($this->config_imagemagick_path), __FILE__, __LINE__);
1421
-			$this->DebugMessage('                      is_file('.$this->config_imagemagick_path.') = '. (int) (@is_file($this->config_imagemagick_path)), __FILE__, __LINE__);
1422
-			$this->DebugMessage('                is_executable('.$this->config_imagemagick_path.') = '. (int) (@is_executable($this->config_imagemagick_path)), __FILE__, __LINE__);
1419
+			$this->DebugMessage('                  file_exists('.$this->config_imagemagick_path.') = '.(int)(@file_exists($this->config_imagemagick_path)), __FILE__, __LINE__);
1420
+			$this->DebugMessage('file_exists_ignoreopenbasedir('.$this->config_imagemagick_path.') = '.(int)$this->file_exists_ignoreopenbasedir($this->config_imagemagick_path), __FILE__, __LINE__);
1421
+			$this->DebugMessage('                      is_file('.$this->config_imagemagick_path.') = '.(int)(@is_file($this->config_imagemagick_path)), __FILE__, __LINE__);
1422
+			$this->DebugMessage('                is_executable('.$this->config_imagemagick_path.') = '.(int)(@is_executable($this->config_imagemagick_path)), __FILE__, __LINE__);
1423 1423
 
1424 1424
 			if ($this->file_exists_ignoreopenbasedir($this->config_imagemagick_path)) {
1425 1425
 
@@ -1464,7 +1464,7 @@  discard block
 block discarded – undo
1464 1464
 	}
1465 1465
 
1466 1466
 
1467
-	public function ImageMagickVersion($returnRAW=false) {
1467
+	public function ImageMagickVersion($returnRAW = false) {
1468 1468
 		static $versionstring = null;
1469 1469
 		if (null === $versionstring) {
1470 1470
 			$versionstring = array(0=>false, 1=>false);
@@ -1498,7 +1498,7 @@  discard block
 block discarded – undo
1498 1498
 
1499 1499
 			}
1500 1500
 		}
1501
-		return $versionstring[ (int) $returnRAW ];
1501
+		return $versionstring[(int)$returnRAW];
1502 1502
 	}
1503 1503
 
1504 1504
 
@@ -1525,10 +1525,10 @@  discard block
 block discarded – undo
1525 1525
 					break;
1526 1526
 				}
1527 1527
 			}
1528
-			$this->DebugMessage('ImageMagickSwitchAvailable('.implode(';', $switchname).') = '. (int) $allOK .'', __FILE__, __LINE__);
1528
+			$this->DebugMessage('ImageMagickSwitchAvailable('.implode(';', $switchname).') = '.(int)$allOK.'', __FILE__, __LINE__);
1529 1529
 		} else {
1530 1530
 			$allOK = isset($IMoptions[$switchname]);
1531
-			$this->DebugMessage('ImageMagickSwitchAvailable('.$switchname.') = '. (int) $allOK .'', __FILE__, __LINE__);
1531
+			$this->DebugMessage('ImageMagickSwitchAvailable('.$switchname.') = '.(int)$allOK.'', __FILE__, __LINE__);
1532 1532
 		}
1533 1533
 		return $allOK;
1534 1534
 	}
@@ -1655,7 +1655,7 @@  discard block
 block discarded – undo
1655 1655
 
1656 1656
 		$commandline = $this->ImageMagickCommandlineBase();
1657 1657
 		if ($commandline) {
1658
-			$commandline .= ' '.phpthumb_functions::escapeshellarg_replacement(preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $this->sourceFilename).(($outputFormat == 'gif') ? '' : '['. (int) $this->sfn .']')); // [0] means first frame of (GIF) animation, can be ignored
1658
+			$commandline .= ' '.phpthumb_functions::escapeshellarg_replacement(preg_replace('#[/\\\\]#', DIRECTORY_SEPARATOR, $this->sourceFilename).(($outputFormat == 'gif') ? '' : '['.(int)$this->sfn.']')); // [0] means first frame of (GIF) animation, can be ignored
1659 1659
 			if ($IMtempfilename = $this->phpThumb_tempnam()) {
1660 1660
 				$IMtempfilename = $this->realPathSafe($IMtempfilename);
1661 1661
 
@@ -1669,7 +1669,7 @@  discard block
 block discarded – undo
1669 1669
 					$commandline_test = $this->ImageMagickCommandlineBase().' logo: -resize 1x '.phpthumb_functions::escapeshellarg_replacement($IMtempfilename).' 2>&1';
1670 1670
 					$IMresult_test = phpthumb_functions::SafeExec($commandline_test);
1671 1671
 					$IMuseExplicitImageOutputDimensions = preg_match('#image dimensions are zero#i', $IMresult_test);
1672
-					$this->DebugMessage('IMuseExplicitImageOutputDimensions = '. (int) $IMuseExplicitImageOutputDimensions, __FILE__, __LINE__);
1672
+					$this->DebugMessage('IMuseExplicitImageOutputDimensions = '.(int)$IMuseExplicitImageOutputDimensions, __FILE__, __LINE__);
1673 1673
 					if ($fp_im_temp = @fopen($IMtempfilename, 'wb')) {
1674 1674
 						// erase temp image so ImageMagick logo doesn't get output if other processing fails
1675 1675
 						fclose($fp_im_temp);
@@ -1730,13 +1730,13 @@  discard block
 block discarded – undo
1730 1730
 									}
1731 1731
 								}
1732 1732
 							}
1733
-							$wAll = (int) max($this->w, $this->wp, $this->wl, $this->ws) - (2 * $borderThickness);
1734
-							$hAll = (int) max($this->h, $this->hp, $this->hl, $this->hs) - (2 * $borderThickness);
1733
+							$wAll = (int)max($this->w, $this->wp, $this->wl, $this->ws) - (2 * $borderThickness);
1734
+							$hAll = (int)max($this->h, $this->hp, $this->hl, $this->hs) - (2 * $borderThickness);
1735 1735
 							$imAR = $this->source_width / $this->source_height;
1736 1736
 							$zcAR = (($wAll && $hAll) ? $wAll / $hAll : 1);
1737 1737
 							$side  = phpthumb_functions::nonempty_min($this->source_width, $this->source_height, max($wAll, $hAll));
1738
-							$sideX = phpthumb_functions::nonempty_min($this->source_width,                       $wAll, round($hAll * $zcAR));
1739
-							$sideY = phpthumb_functions::nonempty_min(                     $this->source_height, $hAll, round($wAll / $zcAR));
1738
+							$sideX = phpthumb_functions::nonempty_min($this->source_width, $wAll, round($hAll * $zcAR));
1739
+							$sideY = phpthumb_functions::nonempty_min($this->source_height, $hAll, round($wAll / $zcAR));
1740 1740
 
1741 1741
 							$thumbnailH = round(max($sideY, ($sideY * $zcAR) / $imAR));
1742 1742
 							if ($this->aoe == 1) {
@@ -1791,9 +1791,9 @@  discard block
 block discarded – undo
1791 1791
 						} elseif ($this->sw || $this->sh || $this->sx || $this->sy) {
1792 1792
 
1793 1793
 							$crop_param   = '';
1794
-							$crop_param  .=     ($this->sw ? (($this->sw < 2) ? round($this->sw * $this->source_width)  : $this->sw) : $this->source_width);
1794
+							$crop_param  .= ($this->sw ? (($this->sw < 2) ? round($this->sw * $this->source_width) : $this->sw) : $this->source_width);
1795 1795
 							$crop_param  .= 'x'.($this->sh ? (($this->sh < 2) ? round($this->sh * $this->source_height) : $this->sh) : $this->source_height);
1796
-							$crop_param  .= '+'.(($this->sx < 2) ? round($this->sx * $this->source_width)  : $this->sx);
1796
+							$crop_param  .= '+'.(($this->sx < 2) ? round($this->sx * $this->source_width) : $this->sx);
1797 1797
 							$crop_param  .= '+'.(($this->sy < 2) ? round($this->sy * $this->source_height) : $this->sy);
1798 1798
 // TO BE FIXED
1799 1799
 // makes 1x1 output
@@ -1823,14 +1823,14 @@  discard block
 block discarded – undo
1823 1823
 
1824 1824
 						} else {
1825 1825
 
1826
-							if ($this->iar && ((int) $this->w > 0) && ((int) $this->h > 0)) {
1826
+							if ($this->iar && ((int)$this->w > 0) && ((int)$this->h > 0)) {
1827 1827
 
1828 1828
 								list($nw, $nh) = phpthumb_functions::TranslateWHbyAngle($this->w, $this->h, $this->ra);
1829 1829
 								$nw = ((round($nw) != 0) ? round($nw) : '');
1830 1830
 								$nh = ((round($nh) != 0) ? round($nh) : '');
1831 1831
 								$commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement($nw.'x'.$nh.'!');
1832 1832
 
1833
-							} elseif ($this->far && ((int) $this->w > 0) && ((int) $this->h > 0)) {
1833
+							} elseif ($this->far && ((int)$this->w > 0) && ((int)$this->h > 0)) {
1834 1834
 
1835 1835
 								$commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(phpthumb_functions::nonempty_min($this->w, $getimagesize[0]).'x'.phpthumb_functions::nonempty_min($this->h, $getimagesize[1]));
1836 1836
 								$commandline .= ' -gravity center';
@@ -1863,7 +1863,7 @@  discard block
 block discarded – undo
1863 1863
 
1864 1864
 					$this->DebugMessage('getimagesize('.$this->sourceFilename.') failed', __FILE__, __LINE__);
1865 1865
 					if ($this->w || $this->h) {
1866
-						$exactDimensionsBang = (($this->iar && ((int) $this->w > 0) && ((int) $this->h > 0)) ? '!' : '');
1866
+						$exactDimensionsBang = (($this->iar && ((int)$this->w > 0) && ((int)$this->h > 0)) ? '!' : '');
1867 1867
 						if ($IMuseExplicitImageOutputDimensions) {
1868 1868
 							// unknown source aspect ratio, just put large number and hope IM figures it out
1869 1869
 							$commandline .= ' -'.$IMresizeParameter.' '.phpthumb_functions::escapeshellarg_replacement(($this->w ? $this->w : '9999').'x'.($this->h ? $this->h : '9999').$exactDimensionsBang);
@@ -1875,7 +1875,7 @@  discard block
 block discarded – undo
1875 1875
 				}
1876 1876
 
1877 1877
 				if ($this->ra) {
1878
-					$this->ra = (int) $this->ra;
1878
+					$this->ra = (int)$this->ra;
1879 1879
 					if ($this->ImageMagickSwitchAvailable('rotate')) {
1880 1880
 						if (!preg_match('#('.implode('|', $this->AlphaCapableFormats).')#i', $outputFormat) || phpthumb_functions::version_compare_replacement($this->ImageMagickVersion(), '6.3.7', '>=')) {
1881 1881
 							$this->DebugMessage('Using ImageMagick rotate', __FILE__, __LINE__);
@@ -1903,14 +1903,14 @@  discard block
 block discarded – undo
1903 1903
 					switch ($command) {
1904 1904
 						case 'brit':
1905 1905
 							if ($this->ImageMagickSwitchAvailable('modulate')) {
1906
-								$commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement((100 + (int) $parameter).',100,100');
1906
+								$commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement((100 + (int)$parameter).',100,100');
1907 1907
 								$successfullyProcessedFilters[] = $filterkey;
1908 1908
 							}
1909 1909
 							break;
1910 1910
 
1911 1911
 						case 'cont':
1912 1912
 							if ($this->ImageMagickSwitchAvailable('contrast')) {
1913
-								$contDiv10 = round((int) $parameter / 10);
1913
+								$contDiv10 = round((int)$parameter / 10);
1914 1914
 								if ($contDiv10 > 0) {
1915 1915
 									$contDiv10 = min($contDiv10, 100);
1916 1916
 									for ($i = 0; $i < $contDiv10; $i++) {
@@ -1934,7 +1934,7 @@  discard block
 block discarded – undo
1934 1934
 									$commandline .= ' -colorspace GRAY';
1935 1935
 									$commandline .= ' -modulate 100,0,100';
1936 1936
 								} else {
1937
-									$commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement('100,'.(100 - (int) $parameter).',100');
1937
+									$commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement('100,'.(100 - (int)$parameter).',100');
1938 1938
 								}
1939 1939
 								$successfullyProcessedFilters[] = $filterkey;
1940 1940
 							}
@@ -1946,7 +1946,7 @@  discard block
 block discarded – undo
1946 1946
 									$commandline .= ' -colorspace GRAY';
1947 1947
 									$commandline .= ' -modulate 100,0,100';
1948 1948
 								} else {
1949
-									$commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement('100,'.(100 + (int) $parameter).',100');
1949
+									$commandline .= ' -modulate '.phpthumb_functions::escapeshellarg_replacement('100,'.(100 + (int)$parameter).',100');
1950 1950
 								}
1951 1951
 								$successfullyProcessedFilters[] = $filterkey;
1952 1952
 							}
@@ -1964,7 +1964,7 @@  discard block
 block discarded – undo
1964 1964
 							if ($this->ImageMagickSwitchAvailable(array('fill', 'colorize'))) {
1965 1965
 								@list($amount, $color) = explode('|', $parameter);
1966 1966
 								$commandline .= ' -fill '.phpthumb_functions::escapeshellarg_replacement('#'.preg_replace('#[^0-9A-F]#i', '', $color));
1967
-								$commandline .= ' -colorize '.phpthumb_functions::escapeshellarg_replacement(min(max((int) $amount, 0), 100));
1967
+								$commandline .= ' -colorize '.phpthumb_functions::escapeshellarg_replacement(min(max((int)$amount, 0), 100));
1968 1968
 							}
1969 1969
 							break;
1970 1970
 
@@ -1973,7 +1973,7 @@  discard block
 block discarded – undo
1973 1973
 								@list($amount, $color) = explode('|', $parameter);
1974 1974
 								$amount = ($amount ? $amount : 80);
1975 1975
 								if (!$color) {
1976
-									$commandline .= ' -sepia-tone '.phpthumb_functions::escapeshellarg_replacement(min(max((int) $amount, 0), 100).'%');
1976
+									$commandline .= ' -sepia-tone '.phpthumb_functions::escapeshellarg_replacement(min(max((int)$amount, 0), 100).'%');
1977 1977
 									$successfullyProcessedFilters[] = $filterkey;
1978 1978
 								}
1979 1979
 							}
@@ -1981,7 +1981,7 @@  discard block
 block discarded – undo
1981 1981
 
1982 1982
 						case 'gam':
1983 1983
 							@list($amount) = explode('|', $parameter);
1984
-							$amount = min(max((float) $amount, 0.001), 10);
1984
+							$amount = min(max((float)$amount, 0.001), 10);
1985 1985
 							if (number_format($amount, 3) != '1.000') {
1986 1986
 								if ($this->ImageMagickSwitchAvailable('gamma')) {
1987 1987
 									$commandline .= ' -gamma '.phpthumb_functions::escapeshellarg_replacement($amount);
@@ -2000,7 +2000,7 @@  discard block
 block discarded – undo
2000 2000
 						case 'th':
2001 2001
 							@list($amount) = explode('|', $parameter);
2002 2002
 							if ($this->ImageMagickSwitchAvailable(array('threshold', 'dither', 'monochrome'))) {
2003
-								$commandline .= ' -threshold '.phpthumb_functions::escapeshellarg_replacement(round(min(max((int) $amount, 0), 255) / 2.55).'%');
2003
+								$commandline .= ' -threshold '.phpthumb_functions::escapeshellarg_replacement(round(min(max((int)$amount, 0), 255) / 2.55).'%');
2004 2004
 								$commandline .= ' -dither';
2005 2005
 								$commandline .= ' -monochrome';
2006 2006
 								$successfullyProcessedFilters[] = $filterkey;
@@ -2010,8 +2010,8 @@  discard block
 block discarded – undo
2010 2010
 						case 'rcd':
2011 2011
 							if ($this->ImageMagickSwitchAvailable(array('colors', 'dither'))) {
2012 2012
 								@list($colors, $dither) = explode('|', $parameter);
2013
-								$colors = ($colors                ?  (int) $colors : 256);
2014
-								$dither  = ((strlen($dither) > 0) ? (bool) $dither : true);
2013
+								$colors = ($colors ? (int)$colors : 256);
2014
+								$dither = ((strlen($dither) > 0) ? (bool)$dither : true);
2015 2015
 								$commandline .= ' -colors '.phpthumb_functions::escapeshellarg_replacement(max($colors, 8)); // ImageMagick will otherwise fail with "cannot quantize to fewer than 8 colors"
2016 2016
 								$commandline .= ($dither ? ' -dither' : ' +dither');
2017 2017
 								$successfullyProcessedFilters[] = $filterkey;
@@ -2033,7 +2033,7 @@  discard block
 block discarded – undo
2033 2033
 						case 'edge':
2034 2034
 							if ($this->ImageMagickSwitchAvailable('edge')) {
2035 2035
 								$parameter = (!empty($parameter) ? $parameter : 2);
2036
-								$commandline .= ' -edge '.phpthumb_functions::escapeshellarg_replacement(!empty($parameter) ? (int) $parameter : 1);
2036
+								$commandline .= ' -edge '.phpthumb_functions::escapeshellarg_replacement(!empty($parameter) ? (int)$parameter : 1);
2037 2037
 								$successfullyProcessedFilters[] = $filterkey;
2038 2038
 							}
2039 2039
 							break;
@@ -2041,7 +2041,7 @@  discard block
 block discarded – undo
2041 2041
 						case 'emb':
2042 2042
 							if ($this->ImageMagickSwitchAvailable(array('emboss', 'negate'))) {
2043 2043
 								$parameter = (!empty($parameter) ? $parameter : 2);
2044
-								$commandline .= ' -emboss '.phpthumb_functions::escapeshellarg_replacement((int) $parameter);
2044
+								$commandline .= ' -emboss '.phpthumb_functions::escapeshellarg_replacement((int)$parameter);
2045 2045
 								if ($parameter < 2) {
2046 2046
 									$commandline .= ' -negate'; // ImageMagick negates the image for some reason with '-emboss 1';
2047 2047
 								}
@@ -2051,9 +2051,9 @@  discard block
 block discarded – undo
2051 2051
 
2052 2052
 						case 'lvl':
2053 2053
 							@list($band, $method, $threshold) = explode('|', $parameter);
2054
-							$band      = ($band ? preg_replace('#[^RGBA\\*]#', '', strtoupper($band))       : '*');
2055
-							$method    = ((strlen($method) > 0)    ? (int) $method :   2);
2056
-							$threshold = ((strlen($threshold) > 0) ? min(max((float) $threshold, 0), 100) : 0.1);
2054
+							$band      = ($band ? preg_replace('#[^RGBA\\*]#', '', strtoupper($band)) : '*');
2055
+							$method    = ((strlen($method) > 0) ? (int)$method : 2);
2056
+							$threshold = ((strlen($threshold) > 0) ? min(max((float)$threshold, 0), 100) : 0.1);
2057 2057
 
2058 2058
 							$band = preg_replace('#[^RGBA\\*]#', '', strtoupper($band));
2059 2059
 
@@ -2114,7 +2114,7 @@  discard block
 block discarded – undo
2114 2114
 						case 'wb':
2115 2115
 							if ($this->ImageMagickSwitchAvailable(array('channel', 'contrast-stretch'))) {
2116 2116
 								@list($threshold) = explode('|', $parameter);
2117
-								$threshold = (!empty($threshold) ? min(max((float) $threshold, 0), 100) : 0.1);
2117
+								$threshold = (!empty($threshold) ? min(max((float)$threshold, 0), 100) : 0.1);
2118 2118
 								$threshold = preg_replace('#[^0-9\\.]#', '', $threshold); // should be unneccesary, but just to be double-sure
2119 2119
 								//$commandline .= ' -channel R -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // doesn't work on Windows because most versions of PHP do not properly
2120 2120
 								//$commandline .= ' -channel G -contrast-stretch '.phpthumb_functions::escapeshellarg_replacement($threshold.'%'); // escape special characters (such as %) and just replace them with spaces
@@ -2130,7 +2130,7 @@  discard block
 block discarded – undo
2130 2130
 						case 'blur':
2131 2131
 							if ($this->ImageMagickSwitchAvailable('blur')) {
2132 2132
 								@list($radius) = explode('|', $parameter);
2133
-								$radius = (!empty($radius) ? min(max((int) $radius, 0), 25) : 1);
2133
+								$radius = (!empty($radius) ? min(max((int)$radius, 0), 25) : 1);
2134 2134
 								$commandline .= ' -blur '.phpthumb_functions::escapeshellarg_replacement($radius);
2135 2135
 								$successfullyProcessedFilters[] = $filterkey;
2136 2136
 							}
@@ -2138,7 +2138,7 @@  discard block
 block discarded – undo
2138 2138
 
2139 2139
 						case 'gblr':
2140 2140
 							@list($radius) = explode('|', $parameter);
2141
-							$radius = (!empty($radius) ? min(max((int) $radius, 0), 25) : 1);
2141
+							$radius = (!empty($radius) ? min(max((int)$radius, 0), 25) : 1);
2142 2142
 							// "-gaussian" changed to "-gaussian-blur" sometime around 2009
2143 2143
 							if ($this->ImageMagickSwitchAvailable('gaussian-blur')) {
2144 2144
 								$commandline .= ' -gaussian-blur '.phpthumb_functions::escapeshellarg_replacement($radius);
@@ -2152,9 +2152,9 @@  discard block
 block discarded – undo
2152 2152
 						case 'usm':
2153 2153
 							if ($this->ImageMagickSwitchAvailable('unsharp')) {
2154 2154
 								@list($amount, $radius, $threshold) = explode('|', $parameter);
2155
-								$amount    = ($amount            ? min(max((int) $amount,    0), 255) : 80);
2156
-								$radius    = ($radius            ? min(max((int) $radius,    0),  10) : 0.5);
2157
-								$threshold = (strlen($threshold) ? min(max((int) $threshold, 0),  50) : 3);
2155
+								$amount    = ($amount ? min(max((int)$amount, 0), 255) : 80);
2156
+								$radius    = ($radius ? min(max((int)$radius, 0), 10) : 0.5);
2157
+								$threshold = (strlen($threshold) ? min(max((int)$threshold, 0), 50) : 3);
2158 2158
 								$commandline .= ' -unsharp '.phpthumb_functions::escapeshellarg_replacement(number_format(($radius * 2) - 1, 2, '.', '').'x1+'.number_format($amount / 100, 2, '.', '').'+'.number_format($threshold / 100, 2, '.', ''));
2159 2159
 								$successfullyProcessedFilters[] = $filterkey;
2160 2160
 							}
@@ -2164,14 +2164,14 @@  discard block
 block discarded – undo
2164 2164
 							if ($this->ImageMagickSwitchAvailable(array('border', 'bordercolor', 'thumbnail', 'crop'))) {
2165 2165
 								if (!$this->zc) {
2166 2166
 									@list($width, $rX, $rY, $color) = explode('|', $parameter);
2167
-									$width = (int) $width;
2168
-									$rX    = (int) $rX;
2169
-									$rY    = (int) $rY;
2167
+									$width = (int)$width;
2168
+									$rX    = (int)$rX;
2169
+									$rY    = (int)$rY;
2170 2170
 									if ($width && !$rX && !$rY) {
2171 2171
 										if (!phpthumb_functions::IsHexColor($color)) {
2172 2172
 											$color = ((!empty($this->bc) && phpthumb_functions::IsHexColor($this->bc)) ? $this->bc : '000000');
2173 2173
 										}
2174
-										$commandline .= ' -border '.phpthumb_functions::escapeshellarg_replacement((int) $width);
2174
+										$commandline .= ' -border '.phpthumb_functions::escapeshellarg_replacement((int)$width);
2175 2175
 										$commandline .= ' -bordercolor '.phpthumb_functions::escapeshellarg_replacement('#'.$color);
2176 2176
 
2177 2177
 										if (preg_match('# \\-crop "([0-9]+)x([0-9]+)\\+0\\+0" #', $commandline, $matches)) {
@@ -2327,8 +2327,8 @@  discard block
 block discarded – undo
2327 2327
 				$this->DebugMessage('!function_exists(imagerotate)', __FILE__, __LINE__);
2328 2328
 				return false;
2329 2329
 			}
2330
-			if (!include_once( __DIR__ .'/phpthumb.filters.php')) {
2331
-				$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
2330
+			if (!include_once(__DIR__.'/phpthumb.filters.php')) {
2331
+				$this->DebugMessage('Error including "'.__DIR__.'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
2332 2332
 				return false;
2333 2333
 			}
2334 2334
 
@@ -2340,7 +2340,7 @@  discard block
 block discarded – undo
2340 2340
 			$rotate_angle = 0;
2341 2341
 			if ($this->ra) {
2342 2342
 
2343
-				$rotate_angle = (float) $this->ra;
2343
+				$rotate_angle = (float)$this->ra;
2344 2344
 
2345 2345
 			} else {
2346 2346
 
@@ -2383,7 +2383,7 @@  discard block
 block discarded – undo
2383 2383
 							return false;
2384 2384
 						}
2385 2385
 					} else {
2386
-						$this->DebugMessage('Cannot auto-rotate from EXIF data because PHP is less than v4.2.0 ('. PHP_VERSION .')', __FILE__, __LINE__);
2386
+						$this->DebugMessage('Cannot auto-rotate from EXIF data because PHP is less than v4.2.0 ('.PHP_VERSION.')', __FILE__, __LINE__);
2387 2387
 						return false;
2388 2388
 					}
2389 2389
 				} elseif (($this->ar == 'l') && ($this->source_height > $this->source_width)) {
@@ -2440,7 +2440,7 @@  discard block
 block discarded – undo
2440 2440
 				$this->thumbnail_image_width = round($this->thumbnail_image_height * $aspectratio);
2441 2441
 			} elseif ($this->thumbnail_image_width < $this->thumbnail_width) {
2442 2442
 				$this->thumbnail_image_width = $this->thumbnail_width;
2443
-				$this->thumbnail_image_height  = round($this->thumbnail_image_width / $aspectratio);
2443
+				$this->thumbnail_image_height = round($this->thumbnail_image_width / $aspectratio);
2444 2444
 			}
2445 2445
 
2446 2446
 		}
@@ -2475,7 +2475,7 @@  discard block
 block discarded – undo
2475 2475
 
2476 2476
 	public function AntiOffsiteLinking() {
2477 2477
 		// Optional anti-offsite hijacking of the thumbnail script
2478
-		$allow   = true;
2478
+		$allow = true;
2479 2479
 		if ($allow && $this->config_nooffsitelink_enabled && (@$_SERVER['HTTP_REFERER'] || $this->config_nooffsitelink_require_refer)) {
2480 2480
 			$this->DebugMessage('AntiOffsiteLinking() checking $_SERVER[HTTP_REFERER] "'.@$_SERVER['HTTP_REFERER'].'"', __FILE__, __LINE__);
2481 2481
 			foreach ($this->config_nooffsitelink_valid_domains as $key => $valid_domain) {
@@ -2485,7 +2485,7 @@  discard block
 block discarded – undo
2485 2485
 			}
2486 2486
 			$parsed_url = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
2487 2487
 			if (!$this->OffsiteDomainIsAllowed(@$parsed_url['host'], $this->config_nooffsitelink_valid_domains)) {
2488
-				$allow   = false;
2488
+				$allow = false;
2489 2489
 				//$this->DebugMessage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is NOT in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
2490 2490
 				$this->ErrorImage('AntiOffsiteLinking() - "'.@$parsed_url['host'].'" is NOT in $this->config_nooffsitelink_valid_domains ('.implode(';', $this->config_nooffsitelink_valid_domains).')');
2491 2491
 			} else {
@@ -2525,8 +2525,8 @@  discard block
 block discarded – undo
2525 2525
 			$this->config_nooffsitelink_watermark_src = $this->ResolveFilenameToAbsolute($this->config_nooffsitelink_watermark_src);
2526 2526
 			if (is_file($this->config_nooffsitelink_watermark_src)) {
2527 2527
 
2528
-				if (!include_once( __DIR__ .'/phpthumb.filters.php')) {
2529
-					$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.filters.php" which is required for applying watermark', __FILE__, __LINE__);
2528
+				if (!include_once(__DIR__.'/phpthumb.filters.php')) {
2529
+					$this->DebugMessage('Error including "'.__DIR__.'/phpthumb.filters.php" which is required for applying watermark', __FILE__, __LINE__);
2530 2530
 					return false;
2531 2531
 				}
2532 2532
 				$watermark_img = $this->ImageCreateFromStringReplacement(file_get_contents($this->config_nooffsitelink_watermark_src));
@@ -2664,8 +2664,8 @@  discard block
 block discarded – undo
2664 2664
 
2665 2665
 	public function ApplyFilters() {
2666 2666
 		if ($this->fltr && is_array($this->fltr)) {
2667
-			if (!include_once( __DIR__ .'/phpthumb.filters.php')) {
2668
-				$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
2667
+			if (!include_once(__DIR__.'/phpthumb.filters.php')) {
2668
+				$this->DebugMessage('Error including "'.__DIR__.'/phpthumb.filters.php" which is required for applying filters ('.implode(';', $this->fltr).')', __FILE__, __LINE__);
2669 2669
 				return false;
2670 2670
 			}
2671 2671
 			$phpthumbFilters = new phpthumb_filters();
@@ -2730,8 +2730,8 @@  discard block
 block discarded – undo
2730 2730
 							break;
2731 2731
 						}
2732 2732
 						@list($colors, $dither) = explode('|', $parameter, 2);
2733
-						$colors = ($colors                ?  (int) $colors : 256);
2734
-						$dither  = ((strlen($dither) > 0) ? (bool) $dither : true);
2733
+						$colors = ($colors ? (int)$colors : 256);
2734
+						$dither = ((strlen($dither) > 0) ? (bool)$dither : true);
2735 2735
 						$phpthumbFilters->ReduceColorDepth($this->gdimg_output, $colors, $dither);
2736 2736
 						break;
2737 2737
 
@@ -2755,8 +2755,8 @@  discard block
 block discarded – undo
2755 2755
 					case 'lvl': // autoLevels
2756 2756
 						@list($band, $method, $threshold) = explode('|', $parameter, 3);
2757 2757
 						$band      = ($band ? preg_replace('#[^RGBA\\*]#', '', strtoupper($band)) : '*');
2758
-						$method    = ((strlen($method) > 0)    ? (int) $method :   2);
2759
-						$threshold = ((strlen($threshold) > 0) ? (float) $threshold : 0.1);
2758
+						$method    = ((strlen($method) > 0) ? (int)$method : 2);
2759
+						$threshold = ((strlen($threshold) > 0) ? (float)$threshold : 0.1);
2760 2760
 
2761 2761
 						$phpthumbFilters->HistogramStretch($this->gdimg_output, $band, $method, $threshold);
2762 2762
 						break;
@@ -2771,13 +2771,13 @@  discard block
 block discarded – undo
2771 2771
 							break;
2772 2772
 						}
2773 2773
 						@list($bands, $colors, $width, $height, $alignment, $opacity, $margin_x, $margin_y) = explode('|', $parameter, 8);
2774
-						$bands     = ($bands     ? $bands     :  '*');
2775
-						$colors    = ($colors    ? $colors    :   '');
2776
-						$width     = ($width     ? $width     : 0.25);
2777
-						$height    = ($height    ? $height    : 0.25);
2774
+						$bands     = ($bands ? $bands : '*');
2775
+						$colors    = ($colors ? $colors : '');
2776
+						$width     = ($width ? $width : 0.25);
2777
+						$height    = ($height ? $height : 0.25);
2778 2778
 						$alignment = ($alignment ? $alignment : 'BR');
2779
-						$opacity   = ($opacity   ? $opacity   :   50);
2780
-						$margin_x  = ($margin_x  ? $margin_x  :    5);
2779
+						$opacity   = ($opacity ? $opacity : 50);
2780
+						$margin_x  = ($margin_x ? $margin_x : 5);
2781 2781
 						// $margin_y -- it wasn't forgotten, let the value always pass unchanged
2782 2782
 						$phpthumbFilters->HistogramOverlay($this->gdimg_output, $bands, $colors, $width, $height, $alignment, $opacity, $margin_x, $margin_y);
2783 2783
 						break;
@@ -2862,9 +2862,9 @@  discard block
 block discarded – undo
2862 2862
 
2863 2863
 					case 'over': // Overlay
2864 2864
 						@list($filename, $underlay, $margin, $opacity) = explode('|', $parameter, 4);
2865
-						$underlay = (bool) ($underlay              ? $underlay : false);
2866
-						$margin   =        ((strlen($margin)  > 0) ? $margin   : ($underlay ? 0.1 : 0.0));
2867
-						$opacity  =        ((strlen($opacity) > 0) ? $opacity  : 100);
2865
+						$underlay = (bool)($underlay ? $underlay : false);
2866
+						$margin   = ((strlen($margin) > 0) ? $margin : ($underlay ? 0.1 : 0.0));
2867
+						$opacity  = ((strlen($opacity) > 0) ? $opacity : 100);
2868 2868
 						if (($margin > 0) && ($margin < 1)) {
2869 2869
 							$margin = min(0.499, $margin);
2870 2870
 						} elseif (($margin > -1) && ($margin < 0)) {
@@ -2934,9 +2934,9 @@  discard block
 block discarded – undo
2934 2934
 					case 'wmi': // WaterMarkImage
2935 2935
 						@list($filename, $alignment, $opacity, $margin['x'], $margin['y'], $rotate_angle) = explode('|', $parameter, 6);
2936 2936
 						// $margin can be pixel margin or percent margin if $alignment is text, or max width/height if $alignment is position like "50x75"
2937
-						$alignment    = ($alignment            ? $alignment            : 'BR');
2938
-						$opacity      = (strlen($opacity)      ? (int) $opacity : 50);
2939
-						$rotate_angle = (strlen($rotate_angle) ? (int) $rotate_angle : 0);
2937
+						$alignment    = ($alignment ? $alignment : 'BR');
2938
+						$opacity      = (strlen($opacity) ? (int)$opacity : 50);
2939
+						$rotate_angle = (strlen($rotate_angle) ? (int)$rotate_angle : 0);
2940 2940
 						if (!preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
2941 2941
 							$margins = array('x', 'y');
2942 2942
 							foreach ($margins as $xy) {
@@ -2956,8 +2956,8 @@  discard block
 block discarded – undo
2956 2956
 									$phpthumbFilters->ImprovedImageRotate($img_watermark, $rotate_angle, 'FFFFFF', null, $this);
2957 2957
 								}
2958 2958
 								if (preg_match('#^([0-9\\.\\-]*)x([0-9\\.\\-]*)$#i', $alignment, $matches)) {
2959
-									$watermark_max_width  = (int) ($margin[ 'x'] ? $margin[ 'x'] : imagesx($img_watermark));
2960
-									$watermark_max_height = (int) ($margin[ 'y'] ? $margin[ 'y'] : imagesy($img_watermark));
2959
+									$watermark_max_width  = (int)($margin['x'] ? $margin['x'] : imagesx($img_watermark));
2960
+									$watermark_max_height = (int)($margin['y'] ? $margin['y'] : imagesy($img_watermark));
2961 2961
 									$scale = phpthumb_functions::ScaleToFitInBox(imagesx($img_watermark), imagesy($img_watermark), $watermark_max_width, $watermark_max_height, true, true);
2962 2962
 									$this->DebugMessage('Scaling watermark by a factor of '.number_format($scale, 4), __FILE__, __LINE__);
2963 2963
 									if (($scale > 1) || ($scale < 1)) {
@@ -2989,18 +2989,18 @@  discard block
 block discarded – undo
2989 2989
 
2990 2990
 					case 'wmt': // WaterMarkText
2991 2991
 						@list($text, $size, $alignment, $hex_color, $ttffont, $opacity, $margin, $angle, $bg_color, $bg_opacity, $fillextend, $lineheight) = explode('|', $parameter, 12);
2992
-						$text       = ($text            ? $text       : '');
2993
-						$size       = ($size            ? $size       : 3);
2994
-						$alignment  = ($alignment       ? $alignment  : 'BR');
2995
-						$hex_color  = ($hex_color       ? $hex_color  : '000000');
2996
-						$ttffont    = ($ttffont         ? $ttffont    : '');
2997
-						$opacity    = (strlen($opacity) ? $opacity    : 50);
2998
-						$margin     = (strlen($margin)  ? $margin     : 5);
2999
-						$angle      = (strlen($angle)   ? $angle      : 0);
3000
-						$bg_color   = ($bg_color        ? $bg_color   : false);
3001
-						$bg_opacity = ($bg_opacity      ? $bg_opacity : 0);
3002
-						$fillextend = ($fillextend      ? $fillextend : '');
3003
-						$lineheight = ($lineheight      ? $lineheight : 1.0);
2992
+						$text       = ($text ? $text : '');
2993
+						$size       = ($size ? $size : 3);
2994
+						$alignment  = ($alignment ? $alignment : 'BR');
2995
+						$hex_color  = ($hex_color ? $hex_color : '000000');
2996
+						$ttffont    = ($ttffont ? $ttffont : '');
2997
+						$opacity    = (strlen($opacity) ? $opacity : 50);
2998
+						$margin     = (strlen($margin) ? $margin : 5);
2999
+						$angle      = (strlen($angle) ? $angle : 0);
3000
+						$bg_color   = ($bg_color ? $bg_color : false);
3001
+						$bg_opacity = ($bg_opacity ? $bg_opacity : 0);
3002
+						$fillextend = ($fillextend ? $fillextend : '');
3003
+						$lineheight = ($lineheight ? $lineheight : 1.0);
3004 3004
 
3005 3005
 						if (basename($ttffont) == $ttffont) {
3006 3006
 							$ttffont = $this->realPathSafe($this->config_ttf_directory.DIRECTORY_SEPARATOR.$ttffont);
@@ -3038,17 +3038,17 @@  discard block
 block discarded – undo
3038 3038
 
3039 3039
 					case 'usm': // UnSharpMask sharpening
3040 3040
 						@list($amount, $radius, $threshold) = explode('|', $parameter, 3);
3041
-						$amount    = ($amount            ? $amount    : 80);
3042
-						$radius    = ($radius            ? $radius    : 0.5);
3041
+						$amount    = ($amount ? $amount : 80);
3042
+						$radius    = ($radius ? $radius : 0.5);
3043 3043
 						$threshold = (strlen($threshold) ? $threshold : 3);
3044 3044
 						if (phpthumb_functions::gd_version() >= 2.0) {
3045 3045
 							ob_start();
3046
-							if (!@include_once( __DIR__ .'/phpthumb.unsharp.php')) {
3046
+							if (!@include_once(__DIR__.'/phpthumb.unsharp.php')) {
3047 3047
 								$include_error = ob_get_contents();
3048 3048
 								if ($include_error) {
3049
-									$this->DebugMessage('include_once("'. __DIR__ .'/phpthumb.unsharp.php") generated message: "'.$include_error.'"', __FILE__, __LINE__);
3049
+									$this->DebugMessage('include_once("'.__DIR__.'/phpthumb.unsharp.php") generated message: "'.$include_error.'"', __FILE__, __LINE__);
3050 3050
 								}
3051
-								$this->DebugMessage('Error including "'. __DIR__ .'/phpthumb.unsharp.php" which is required for unsharp masking', __FILE__, __LINE__);
3051
+								$this->DebugMessage('Error including "'.__DIR__.'/phpthumb.unsharp.php" which is required for unsharp masking', __FILE__, __LINE__);
3052 3052
 								ob_end_clean();
3053 3053
 								return false;
3054 3054
 							}
@@ -3062,11 +3062,11 @@  discard block
 block discarded – undo
3062 3062
 
3063 3063
 					case 'size': // Resize
3064 3064
 						@list($newwidth, $newheight, $stretch) = explode('|', $parameter);
3065
-						$newwidth  = (!$newwidth  ? imagesx($this->gdimg_output) : ((($newwidth  > 0) && ($newwidth  < 1)) ? round($newwidth  * imagesx($this->gdimg_output)) : round($newwidth)));
3065
+						$newwidth  = (!$newwidth ? imagesx($this->gdimg_output) : ((($newwidth > 0) && ($newwidth < 1)) ? round($newwidth * imagesx($this->gdimg_output)) : round($newwidth)));
3066 3066
 						$newheight = (!$newheight ? imagesy($this->gdimg_output) : ((($newheight > 0) && ($newheight < 1)) ? round($newheight * imagesy($this->gdimg_output)) : round($newheight)));
3067 3067
 						$stretch   = ($stretch ? true : false);
3068 3068
 						if ($stretch) {
3069
-							$scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesx($this->gdimg_output), $newwidth,  $newwidth,  true, true);
3069
+							$scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesx($this->gdimg_output), $newwidth, $newwidth, true, true);
3070 3070
 							$scale_y = phpthumb_functions::ScaleToFitInBox(imagesy($this->gdimg_output), imagesy($this->gdimg_output), $newheight, $newheight, true, true);
3071 3071
 						} else {
3072 3072
 							$scale_x = phpthumb_functions::ScaleToFitInBox(imagesx($this->gdimg_output), imagesy($this->gdimg_output), $newwidth, $newheight, true, true);
@@ -3101,7 +3101,7 @@  discard block
 block discarded – undo
3101 3101
 							$this->DebugMessage('Skipping SourceTransparentColor hex color is invalid ('.$hexcolor.')', __FILE__, __LINE__);
3102 3102
 							return false;
3103 3103
 						}
3104
-						$min_limit = (strlen($min_limit) ? $min_limit :  5);
3104
+						$min_limit = (strlen($min_limit) ? $min_limit : 5);
3105 3105
 						$max_limit = (strlen($max_limit) ? $max_limit : 10);
3106 3106
 						if ($gdimg_mask = $phpthumbFilters->SourceTransparentColorMask($this->gdimg_output, $hexcolor, $min_limit, $max_limit)) {
3107 3107
 							$this->is_alpha = true;
@@ -3189,17 +3189,17 @@  discard block
 block discarded – undo
3189 3189
 	public function CalculateThumbnailDimensions() {
3190 3190
 		$this->DebugMessage('CalculateThumbnailDimensions() starting with [W,H,sx,sy,sw,sh] initially set to ['.$this->source_width.','.$this->source_height.','.$this->sx.','.$this->sy.','.$this->sw.','.$this->sh.']', __FILE__, __LINE__);
3191 3191
 //echo $this->source_width.'x'.$this->source_height.'<hr>';
3192
-		$this->thumbnailCropX = ($this->sx ? (($this->sx >= 2) ? $this->sx : round($this->sx * $this->source_width))  : 0);
3192
+		$this->thumbnailCropX = ($this->sx ? (($this->sx >= 2) ? $this->sx : round($this->sx * $this->source_width)) : 0);
3193 3193
 //echo $this->thumbnailCropX.'<br>';
3194 3194
 		$this->thumbnailCropY = ($this->sy ? (($this->sy >= 2) ? $this->sy : round($this->sy * $this->source_height)) : 0);
3195 3195
 //echo $this->thumbnailCropY.'<br>';
3196
-		$this->thumbnailCropW = ($this->sw ? (($this->sw >= 2) ? $this->sw : round($this->sw * $this->source_width))  : $this->source_width);
3196
+		$this->thumbnailCropW = ($this->sw ? (($this->sw >= 2) ? $this->sw : round($this->sw * $this->source_width)) : $this->source_width);
3197 3197
 //echo $this->thumbnailCropW.'<br>';
3198 3198
 		$this->thumbnailCropH = ($this->sh ? (($this->sh >= 2) ? $this->sh : round($this->sh * $this->source_height)) : $this->source_height);
3199 3199
 //echo $this->thumbnailCropH.'<hr>';
3200 3200
 
3201 3201
 		// limit source area to original image area
3202
-		$this->thumbnailCropW = max(1, min($this->thumbnailCropW, $this->source_width  - $this->thumbnailCropX));
3202
+		$this->thumbnailCropW = max(1, min($this->thumbnailCropW, $this->source_width - $this->thumbnailCropX));
3203 3203
 		$this->thumbnailCropH = max(1, min($this->thumbnailCropH, $this->source_height - $this->thumbnailCropY));
3204 3204
 
3205 3205
 		$this->DebugMessage('CalculateThumbnailDimensions() starting with [x,y,w,h] initially set to ['.$this->thumbnailCropX.','.$this->thumbnailCropY.','.$this->thumbnailCropW.','.$this->thumbnailCropH.']', __FILE__, __LINE__);
@@ -3210,7 +3210,7 @@  discard block
 block discarded – undo
3210 3210
 			// retain proportional resizing we did above, but crop off larger dimension so smaller
3211 3211
 			// dimension fully fits available space
3212 3212
 
3213
-			$scaling_X = $this->source_width  / $this->w;
3213
+			$scaling_X = $this->source_width / $this->w;
3214 3214
 			$scaling_Y = $this->source_height / $this->h;
3215 3215
 			if ($scaling_X > $scaling_Y) {
3216 3216
 				// some of the width will need to be cropped
@@ -3331,7 +3331,7 @@  discard block
 block discarded – undo
3331 3331
 		}
3332 3332
 		//$this->w = round($this->w ? $this->w : (($this->h && $this->source_height) ? $this->h * $this->source_width  / $this->source_height : $this->w));
3333 3333
 		//$this->h = round($this->h ? $this->h : (($this->w && $this->source_width)  ? $this->w * $this->source_height / $this->source_width  : $this->h));
3334
-		$this->DebugMessage('SetOrientationDependantWidthHeight() setting w="'. (int) $this->w .'", h="'. (int) $this->h .'"', __FILE__, __LINE__);
3334
+		$this->DebugMessage('SetOrientationDependantWidthHeight() setting w="'.(int)$this->w.'", h="'.(int)$this->h.'"', __FILE__, __LINE__);
3335 3335
 		return true;
3336 3336
 	}
3337 3337
 
@@ -3439,7 +3439,7 @@  discard block
 block discarded – undo
3439 3439
 
3440 3440
 		}
3441 3441
 
3442
-		$this->DebugMessage('EXIF thumbnail extraction: (size='.strlen($this->exif_thumbnail_data).'; type="'.$this->exif_thumbnail_type.'"; '. (int) $this->exif_thumbnail_width .'x'. (int) $this->exif_thumbnail_height .')', __FILE__, __LINE__);
3442
+		$this->DebugMessage('EXIF thumbnail extraction: (size='.strlen($this->exif_thumbnail_data).'; type="'.$this->exif_thumbnail_type.'"; '.(int)$this->exif_thumbnail_width.'x'.(int)$this->exif_thumbnail_height.')', __FILE__, __LINE__);
3443 3443
 
3444 3444
 		// see if EXIF thumbnail can be used directly with no processing
3445 3445
 		if ($this->config_use_exif_thumbnail_for_speed && $this->exif_thumbnail_data) {
@@ -3564,12 +3564,12 @@  discard block
 block discarded – undo
3564 3564
 		$FilenameParameters2 = array('h', 'w', 'wl', 'wp', 'ws', 'hp', 'hs', 'xto', 'ra', 'iar', 'aoe', 'maxb', 'sfn', 'dpi');
3565 3565
 		foreach ($FilenameParameters2 as $key) {
3566 3566
 			if ($this->$key) {
3567
-				$ParametersString .= '_'.$key. (int) $this->$key;
3567
+				$ParametersString .= '_'.$key.(int)$this->$key;
3568 3568
 			}
3569 3569
 		}
3570 3570
 		if ($this->thumbnailFormat == 'jpeg') {
3571 3571
 			// only JPEG output has variable quality option
3572
-			$ParametersString .= '_q'. (int) $this->thumbnailQuality;
3572
+			$ParametersString .= '_q'.(int)$this->thumbnailQuality;
3573 3573
 		}
3574 3574
 		$this->DebugMessage('SetCacheFilename() _par set from md5('.$ParametersString.')', __FILE__, __LINE__);
3575 3575
 		$this->cache_filename .= '_par'.strtolower(md5($ParametersString));
@@ -3579,9 +3579,9 @@  discard block
 block discarded – undo
3579 3579
 			// do not source image modification date --
3580 3580
 			// cached image will be used even if file was modified or removed
3581 3581
 		} elseif (!$this->config_cache_source_filemtime_ignore_remote && preg_match('#^(f|ht)tps?\://#i', $this->src)) {
3582
-			$this->cache_filename .= '_dat'. (int) phpthumb_functions::filedate_remote($this->src);
3582
+			$this->cache_filename .= '_dat'.(int)phpthumb_functions::filedate_remote($this->src);
3583 3583
 		} elseif (!$this->config_cache_source_filemtime_ignore_local && $this->src && !$this->rawImageData) {
3584
-			$this->cache_filename .= '_dat'. (int) (@filemtime($this->sourceFilename));
3584
+			$this->cache_filename .= '_dat'.(int)(@filemtime($this->sourceFilename));
3585 3585
 		}
3586 3586
 
3587 3587
 		$this->cache_filename .= '.'.strtolower($this->thumbnailFormat);
@@ -3601,9 +3601,9 @@  discard block
 block discarded – undo
3601 3601
 		}
3602 3602
 		if ($this->php_memory_limit && function_exists('memory_get_usage')) {
3603 3603
 			$available_memory = $this->php_memory_limit - memory_get_usage();
3604
-			return (bool) (($width * $height * 5) > $available_memory);
3604
+			return (bool)(($width * $height * 5) > $available_memory);
3605 3605
 		}
3606
-		return (bool) (($width * $height) > $this->config_max_source_pixels);
3606
+		return (bool)(($width * $height) > $this->config_max_source_pixels);
3607 3607
 	}
3608 3608
 
3609 3609
 	public function ImageCreateFromFilename($filename) {
@@ -3831,15 +3831,15 @@  discard block
 block discarded – undo
3831 3831
 			switch (@$this->getimagesizeinfo[2]) {
3832 3832
 				case 1:
3833 3833
 					$imageHeader = 'Content-Type: image/gif';
3834
-					$GDreadSupport = (bool) @$gd_info['GIF Read Support'];
3834
+					$GDreadSupport = (bool)@$gd_info['GIF Read Support'];
3835 3835
 					break;
3836 3836
 				case 2:
3837 3837
 					$imageHeader = 'Content-Type: image/jpeg';
3838
-					$GDreadSupport = (bool) @$gd_info['JPG Support'];
3838
+					$GDreadSupport = (bool)@$gd_info['JPG Support'];
3839 3839
 					break;
3840 3840
 				case 3:
3841 3841
 					$imageHeader = 'Content-Type: image/png';
3842
-					$GDreadSupport = (bool) @$gd_info['PNG Support'];
3842
+					$GDreadSupport = (bool)@$gd_info['PNG Support'];
3843 3843
 					break;
3844 3844
 			}
3845 3845
 			if ($imageHeader) {
@@ -3867,7 +3867,7 @@  discard block
 block discarded – undo
3867 3867
 					$this->ErrorImage(implode("\n", $errormessages));
3868 3868
 
3869 3869
 				} else {
3870
-					$this->DebugMessage('All attempts to create GD image source failed ('.(ini_get('safe_mode') ? 'Safe Mode enabled, ImageMagick unavailable and source image probably too large for GD': ($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"')).'), cannot generate thumbnail');
3870
+					$this->DebugMessage('All attempts to create GD image source failed ('.(ini_get('safe_mode') ? 'Safe Mode enabled, ImageMagick unavailable and source image probably too large for GD' : ($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"')).'), cannot generate thumbnail');
3871 3871
 					//$this->DebugMessage('All attempts to create GD image source failed ('.($GDreadSupport ? 'source image probably corrupt' : 'GD does not have read support for "'.$imageHeader.'"').'), outputing raw image', __FILE__, __LINE__);
3872 3872
 					//if (!$this->phpThumbDebug) {
3873 3873
 					//	header($imageHeader);
@@ -3883,9 +3883,9 @@  discard block
 block discarded – undo
3883 3883
 			switch (@$this->getimagesizeinfo[2]) {
3884 3884
 				case 6:
3885 3885
 					ob_start();
3886
-					if (!@include_once( __DIR__ .'/phpthumb.bmp.php')) {
3886
+					if (!@include_once(__DIR__.'/phpthumb.bmp.php')) {
3887 3887
 						ob_end_clean();
3888
-						return $this->ErrorImage('include_once('. __DIR__ .'/phpthumb.bmp.php) failed');
3888
+						return $this->ErrorImage('include_once('.__DIR__.'/phpthumb.bmp.php) failed');
3889 3889
 					}
3890 3890
 					ob_end_clean();
3891 3891
 					if ($fp = @fopen($this->sourceFilename, 'rb')) {
@@ -3987,7 +3987,7 @@  discard block
 block discarded – undo
3987 3987
 		return gettype($var);
3988 3988
 	}
3989 3989
 
3990
-	public function phpThumbDebug($level='') {
3990
+	public function phpThumbDebug($level = '') {
3991 3991
 		if ($level && ($this->phpThumbDebug !== $level)) {
3992 3992
 			return true;
3993 3993
 		}
@@ -4137,8 +4137,8 @@  discard block
 block discarded – undo
4137 4137
 		return true;
4138 4138
 	}
4139 4139
 
4140
-	public function ErrorImage($text, $width=0, $height=0, $forcedisplay=false) {
4141
-		$width  = ($width  ? $width  : $this->config_error_image_width);
4140
+	public function ErrorImage($text, $width = 0, $height = 0, $forcedisplay = false) {
4141
+		$width  = ($width ? $width : $this->config_error_image_width);
4142 4142
 		$height = ($height ? $height : $this->config_error_image_height);
4143 4143
 
4144 4144
 		$text = 'phpThumb() v'.$this->phpthumb_version."\n".'http://phpthumb.sourceforge.net'."\n\n".($this->config_disable_debug ? 'Error messages disabled.'."\n\n".'edit phpThumb.config.php and (temporarily) set'."\n".'$PHPTHUMB_CONFIG[\'disable_debug\'] = false;'."\n".'to view the details of this error' : $text);
@@ -4198,7 +4198,7 @@  discard block
 block discarded – undo
4198 4198
 
4199 4199
 		} elseif ($gdimg_error = imagecreate($width, $height)) {
4200 4200
 
4201
-			$background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_bgcolor,   true);
4201
+			$background_color = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_bgcolor, true);
4202 4202
 			$text_color       = phpthumb_functions::ImageHexColorAllocate($gdimg_error, $this->config_error_textcolor, true);
4203 4203
 			imagefilledrectangle($gdimg_error, 0, 0, $width, $height, $background_color);
4204 4204
 			$lineYoffset = 0;
@@ -4231,7 +4231,7 @@  discard block
 block discarded – undo
4231 4231
 		exit;
4232 4232
 	}
4233 4233
 
4234
-	public function ImageCreateFromStringReplacement(&$RawImageData, $DieOnErrors=false) {
4234
+	public function ImageCreateFromStringReplacement(&$RawImageData, $DieOnErrors = false) {
4235 4235
 		// there are serious bugs in the non-bundled versions of GD which may cause
4236 4236
 		// PHP to segfault when calling imagecreatefromstring() - avoid if at all possible
4237 4237
 		// when not using a bundled version of GD2
@@ -4285,8 +4285,8 @@  discard block
 block discarded – undo
4285 4285
 
4286 4286
 					// Need to create from GIF file, but imagecreatefromgif does not exist
4287 4287
 					ob_start();
4288
-					if (!@include_once( __DIR__ .'/phpthumb.gif.php')) {
4289
-						$ErrorMessage = 'Failed to include required file "'. __DIR__ .'/phpthumb.gif.php" in '.__FILE__.' on line '.__LINE__;
4288
+					if (!@include_once(__DIR__.'/phpthumb.gif.php')) {
4289
+						$ErrorMessage = 'Failed to include required file "'.__DIR__.'/phpthumb.gif.php" in '.__FILE__.' on line '.__LINE__;
4290 4290
 						$this->DebugMessage($ErrorMessage, __FILE__, __LINE__);
4291 4291
 					}
4292 4292
 					ob_end_clean();
@@ -4377,12 +4377,12 @@  discard block
 block discarded – undo
4377 4377
 		return $tempnam;
4378 4378
 	}
4379 4379
 
4380
-	public function DebugMessage($message, $file='', $line='') {
4380
+	public function DebugMessage($message, $file = '', $line = '') {
4381 4381
 		$this->debugmessages[] = $message.($file ? ' in file "'.(basename($file) ? basename($file) : $file).'"' : '').($line ? ' on line '.$line : '');
4382 4382
 		return true;
4383 4383
 	}
4384 4384
 
4385
-	public function DebugTimingMessage($message, $file='', $line='', $timestamp=0) {
4385
+	public function DebugTimingMessage($message, $file = '', $line = '', $timestamp = 0) {
4386 4386
 		if (!$timestamp) {
4387 4387
 			$timestamp = array_sum(explode(' ', microtime()));
4388 4388
 		}
Please login to merge, or discard this patch.
htdocs/modules/system/class/thumbs/phpThumb.php 2 patches
Indentation   +457 added lines, -457 removed lines patch added patch discarded remove patch
@@ -14,7 +14,7 @@  discard block
 block discarded – undo
14 14
 ini_set('display_errors', '1');
15 15
 ini_set('magic_quotes_runtime', '0');
16 16
 if (ini_get('magic_quotes_runtime')) {
17
-	die('"magic_quotes_runtime" is set in php.ini, cannot run phpThumb with this enabled');
17
+    die('"magic_quotes_runtime" is set in php.ini, cannot run phpThumb with this enabled');
18 18
 }
19 19
 // Set a default timezone if web server has not done already in php.ini
20 20
 if (!ini_get('date.timezone') && function_exists('date_default_timezone_set')) { // PHP >= 5.1.0
@@ -24,84 +24,84 @@  discard block
 block discarded – undo
24 24
 
25 25
 // this script relies on the superglobal arrays, fake it here for old PHP versions
26 26
 if (PHP_VERSION < '4.1.0') {
27
-	$_SERVER = $HTTP_SERVER_VARS;
28
-	$_GET    = $HTTP_GET_VARS;
27
+    $_SERVER = $HTTP_SERVER_VARS;
28
+    $_GET    = $HTTP_GET_VARS;
29 29
 }
30 30
 
31 31
 function SendSaveAsFileHeaderIfNeeded() {
32
-	if (headers_sent()) {
33
-		return false;
34
-	}
35
-	global $phpThumb;
36
-	$downloadfilename = phpthumb_functions::SanitizeFilename(!empty($_GET['sia']) ? $_GET['sia'] : (!empty($_GET['down']) ? $_GET['down'] : 'phpThumb_generated_thumbnail.'.(!empty($_GET['f']) ? $_GET['f'] : 'jpg')));
37
-	if (!empty($downloadfilename)) {
38
-		$phpThumb->DebugMessage('SendSaveAsFileHeaderIfNeeded() sending header: Content-Disposition: '.(!empty($_GET['down']) ? 'attachment' : 'inline').'; filename="'.$downloadfilename.'"', __FILE__, __LINE__);
39
-		header('Content-Disposition: '.(!empty($_GET['down']) ? 'attachment' : 'inline').'; filename="'.$downloadfilename.'"');
40
-	}
41
-	return true;
32
+    if (headers_sent()) {
33
+        return false;
34
+    }
35
+    global $phpThumb;
36
+    $downloadfilename = phpthumb_functions::SanitizeFilename(!empty($_GET['sia']) ? $_GET['sia'] : (!empty($_GET['down']) ? $_GET['down'] : 'phpThumb_generated_thumbnail.'.(!empty($_GET['f']) ? $_GET['f'] : 'jpg')));
37
+    if (!empty($downloadfilename)) {
38
+        $phpThumb->DebugMessage('SendSaveAsFileHeaderIfNeeded() sending header: Content-Disposition: '.(!empty($_GET['down']) ? 'attachment' : 'inline').'; filename="'.$downloadfilename.'"', __FILE__, __LINE__);
39
+        header('Content-Disposition: '.(!empty($_GET['down']) ? 'attachment' : 'inline').'; filename="'.$downloadfilename.'"');
40
+    }
41
+    return true;
42 42
 }
43 43
 
44 44
 function RedirectToCachedFile() {
45
-	global $phpThumb;
46
-
47
-	$nice_cachefile = str_replace(DIRECTORY_SEPARATOR, '/', $phpThumb->cache_filename);
48
-	$nice_docroot   = str_replace(DIRECTORY_SEPARATOR, '/', rtrim($phpThumb->config_document_root, '/\\'));
49
-
50
-	$parsed_url = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
51
-
52
-	$nModified  = filemtime($phpThumb->cache_filename);
53
-
54
-	if ($phpThumb->config_nooffsitelink_enabled && !empty($_SERVER['HTTP_REFERER']) && !in_array(@$parsed_url['host'], $phpThumb->config_nooffsitelink_valid_domains)) {
55
-
56
-		$phpThumb->DebugMessage('Would have used cached (image/'.$phpThumb->thumbnailFormat.') file "'.$phpThumb->cache_filename.'" (Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT), but skipping because $_SERVER[HTTP_REFERER] ('.@$_SERVER['HTTP_REFERER'].') is not in $phpThumb->config_nooffsitelink_valid_domains ('.implode(';', $phpThumb->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
57
-
58
-	} elseif ($phpThumb->phpThumbDebug) {
59
-
60
-		$phpThumb->DebugTimingMessage('skipped using cached image', __FILE__, __LINE__);
61
-		$phpThumb->DebugMessage('Would have used cached file, but skipping due to phpThumbDebug', __FILE__, __LINE__);
62
-		$phpThumb->DebugMessage('* Would have sent headers (1): Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT', __FILE__, __LINE__);
63
-		if ($getimagesize = @getimagesize($phpThumb->cache_filename)) {
64
-			$phpThumb->DebugMessage('* Would have sent headers (2): Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]), __FILE__, __LINE__);
65
-		}
66
-		if (preg_match('#^'.preg_quote($nice_docroot).'(.*)$#', $nice_cachefile, $matches)) {
67
-			$phpThumb->DebugMessage('* Would have sent headers (3): Location: '.dirname($matches[1]).'/'.urlencode(basename($matches[1])), __FILE__, __LINE__);
68
-		} else {
69
-			$phpThumb->DebugMessage('* Would have sent data: readfile('.$phpThumb->cache_filename.')', __FILE__, __LINE__);
70
-		}
71
-
72
-	} else {
73
-
74
-		if (headers_sent()) {
75
-			$phpThumb->ErrorImage('Headers already sent ('.basename(__FILE__).' line '.__LINE__.')');
76
-			exit;
77
-		}
78
-		SendSaveAsFileHeaderIfNeeded();
79
-
80
-		header('Pragma: private');
81
-		header('Cache-Control: max-age='.$phpThumb->getParameter('config_cache_maxage'));
82
-		header('Expires: '.date(DATE_RFC1123,  time() + $phpThumb->getParameter('config_cache_maxage')));
83
-		if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && ($nModified == strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) && !empty($_SERVER['SERVER_PROTOCOL'])) {
84
-			header('Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT');
85
-			header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
86
-			exit;
87
-		}
88
-		header('Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT');
89
-		header('ETag: "'.md5_file($phpThumb->cache_filename).'"');
90
-		if ($getimagesize = @getimagesize($phpThumb->cache_filename)) {
91
-			header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]));
92
-		} elseif (preg_match('#\\.ico$#i', $phpThumb->cache_filename)) {
93
-			header('Content-Type: image/x-icon');
94
-		}
95
-		header('Content-Length: '.filesize($phpThumb->cache_filename));
96
-		if (empty($phpThumb->config_cache_force_passthru) && preg_match('#^'.preg_quote($nice_docroot).'(.*)$#', $nice_cachefile, $matches)) {
97
-			header('Location: '.dirname($matches[1]).'/'.urlencode(basename($matches[1])));
98
-		} else {
99
-			@readfile($phpThumb->cache_filename);
100
-		}
101
-		exit;
102
-
103
-	}
104
-	return true;
45
+    global $phpThumb;
46
+
47
+    $nice_cachefile = str_replace(DIRECTORY_SEPARATOR, '/', $phpThumb->cache_filename);
48
+    $nice_docroot   = str_replace(DIRECTORY_SEPARATOR, '/', rtrim($phpThumb->config_document_root, '/\\'));
49
+
50
+    $parsed_url = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
51
+
52
+    $nModified  = filemtime($phpThumb->cache_filename);
53
+
54
+    if ($phpThumb->config_nooffsitelink_enabled && !empty($_SERVER['HTTP_REFERER']) && !in_array(@$parsed_url['host'], $phpThumb->config_nooffsitelink_valid_domains)) {
55
+
56
+        $phpThumb->DebugMessage('Would have used cached (image/'.$phpThumb->thumbnailFormat.') file "'.$phpThumb->cache_filename.'" (Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT), but skipping because $_SERVER[HTTP_REFERER] ('.@$_SERVER['HTTP_REFERER'].') is not in $phpThumb->config_nooffsitelink_valid_domains ('.implode(';', $phpThumb->config_nooffsitelink_valid_domains).')', __FILE__, __LINE__);
57
+
58
+    } elseif ($phpThumb->phpThumbDebug) {
59
+
60
+        $phpThumb->DebugTimingMessage('skipped using cached image', __FILE__, __LINE__);
61
+        $phpThumb->DebugMessage('Would have used cached file, but skipping due to phpThumbDebug', __FILE__, __LINE__);
62
+        $phpThumb->DebugMessage('* Would have sent headers (1): Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT', __FILE__, __LINE__);
63
+        if ($getimagesize = @getimagesize($phpThumb->cache_filename)) {
64
+            $phpThumb->DebugMessage('* Would have sent headers (2): Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]), __FILE__, __LINE__);
65
+        }
66
+        if (preg_match('#^'.preg_quote($nice_docroot).'(.*)$#', $nice_cachefile, $matches)) {
67
+            $phpThumb->DebugMessage('* Would have sent headers (3): Location: '.dirname($matches[1]).'/'.urlencode(basename($matches[1])), __FILE__, __LINE__);
68
+        } else {
69
+            $phpThumb->DebugMessage('* Would have sent data: readfile('.$phpThumb->cache_filename.')', __FILE__, __LINE__);
70
+        }
71
+
72
+    } else {
73
+
74
+        if (headers_sent()) {
75
+            $phpThumb->ErrorImage('Headers already sent ('.basename(__FILE__).' line '.__LINE__.')');
76
+            exit;
77
+        }
78
+        SendSaveAsFileHeaderIfNeeded();
79
+
80
+        header('Pragma: private');
81
+        header('Cache-Control: max-age='.$phpThumb->getParameter('config_cache_maxage'));
82
+        header('Expires: '.date(DATE_RFC1123,  time() + $phpThumb->getParameter('config_cache_maxage')));
83
+        if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && ($nModified == strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) && !empty($_SERVER['SERVER_PROTOCOL'])) {
84
+            header('Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT');
85
+            header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
86
+            exit;
87
+        }
88
+        header('Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT');
89
+        header('ETag: "'.md5_file($phpThumb->cache_filename).'"');
90
+        if ($getimagesize = @getimagesize($phpThumb->cache_filename)) {
91
+            header('Content-Type: '.phpthumb_functions::ImageTypeToMIMEtype($getimagesize[2]));
92
+        } elseif (preg_match('#\\.ico$#i', $phpThumb->cache_filename)) {
93
+            header('Content-Type: image/x-icon');
94
+        }
95
+        header('Content-Length: '.filesize($phpThumb->cache_filename));
96
+        if (empty($phpThumb->config_cache_force_passthru) && preg_match('#^'.preg_quote($nice_docroot).'(.*)$#', $nice_cachefile, $matches)) {
97
+            header('Location: '.dirname($matches[1]).'/'.urlencode(basename($matches[1])));
98
+        } else {
99
+            @readfile($phpThumb->cache_filename);
100
+        }
101
+        exit;
102
+
103
+    }
104
+    return true;
105 105
 }
106 106
 
107 107
 
@@ -109,8 +109,8 @@  discard block
 block discarded – undo
109 109
 // instantiate a new phpThumb() object
110 110
 ob_start();
111 111
 if (!include_once( __DIR__ .'/phpthumb.class.php')) {
112
-	ob_end_flush();
113
-	die('failed to include_once("'.realpath( __DIR__ .'/phpthumb.class.php').'")');
112
+    ob_end_flush();
113
+    die('failed to include_once("'.realpath( __DIR__ .'/phpthumb.class.php').'")');
114 114
 }
115 115
 ob_end_clean();
116 116
 $phpThumb = new phpThumb();
@@ -118,256 +118,256 @@  discard block
 block discarded – undo
118 118
 $phpThumb->setParameter('config_error_die_on_error', true);
119 119
 
120 120
 if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
121
-	set_time_limit(60);  // shouldn't take nearly this long in most cases, but with many filters and/or a slow server...
121
+    set_time_limit(60);  // shouldn't take nearly this long in most cases, but with many filters and/or a slow server...
122 122
 }
123 123
 
124 124
 // phpThumbDebug[0] used to be here, but may reveal too much
125 125
 // info when high_security_mode should be enabled (not set yet)
126 126
 
127 127
 if (file_exists( __DIR__ .'/phpThumb.config.php')) {
128
-	ob_start();
129
-	if (include_once( __DIR__ .'/phpThumb.config.php')) {
130
-		// great
131
-	} else {
132
-		ob_end_flush();
133
-		$phpThumb->config_disable_debug = false; // otherwise error message won't print
134
-		$phpThumb->ErrorImage('failed to include_once('. __DIR__ .'/phpThumb.config.php) - realpath="'.realpath( __DIR__ .'/phpThumb.config.php').'"');
135
-	}
136
-	ob_end_clean();
128
+    ob_start();
129
+    if (include_once( __DIR__ .'/phpThumb.config.php')) {
130
+        // great
131
+    } else {
132
+        ob_end_flush();
133
+        $phpThumb->config_disable_debug = false; // otherwise error message won't print
134
+        $phpThumb->ErrorImage('failed to include_once('. __DIR__ .'/phpThumb.config.php) - realpath="'.realpath( __DIR__ .'/phpThumb.config.php').'"');
135
+    }
136
+    ob_end_clean();
137 137
 } elseif (file_exists( __DIR__ .'/phpThumb.config.php.default')) {
138
-	$phpThumb->config_disable_debug = false; // otherwise error message won't print
139
-	$phpThumb->ErrorImage('Please rename "phpThumb.config.php.default" to "phpThumb.config.php"');
138
+    $phpThumb->config_disable_debug = false; // otherwise error message won't print
139
+    $phpThumb->ErrorImage('Please rename "phpThumb.config.php.default" to "phpThumb.config.php"');
140 140
 } else {
141
-	$phpThumb->config_disable_debug = false; // otherwise error message won't print
142
-	$phpThumb->ErrorImage('failed to include_once('. __DIR__ .'/phpThumb.config.php) - realpath="'.realpath( __DIR__ .'/phpThumb.config.php').'"');
141
+    $phpThumb->config_disable_debug = false; // otherwise error message won't print
142
+    $phpThumb->ErrorImage('failed to include_once('. __DIR__ .'/phpThumb.config.php) - realpath="'.realpath( __DIR__ .'/phpThumb.config.php').'"');
143 143
 }
144 144
 
145 145
 if (!empty($PHPTHUMB_CONFIG)) {
146
-	foreach ($PHPTHUMB_CONFIG as $key => $value) {
147
-		$keyname = 'config_'.$key;
148
-		$phpThumb->setParameter($keyname, $value);
149
-		if (!preg_match('#(password|mysql)#i', $key)) {
150
-			$phpThumb->DebugMessage('setParameter('.$keyname.', '.$phpThumb->phpThumbDebugVarDump($value).')', __FILE__, __LINE__);
151
-		}
152
-	}
153
-	if (!$phpThumb->config_disable_debug) {
154
-		// if debug mode is enabled, force phpThumbDebug output, do not allow normal thumbnails to be generated
155
-		$_GET['phpThumbDebug'] = (!empty($_GET['phpThumbDebug']) ? max(1, (int) $_GET[ 'phpThumbDebug']) : 9);
156
-		$phpThumb->setParameter('phpThumbDebug', $_GET['phpThumbDebug']);
157
-	}
146
+    foreach ($PHPTHUMB_CONFIG as $key => $value) {
147
+        $keyname = 'config_'.$key;
148
+        $phpThumb->setParameter($keyname, $value);
149
+        if (!preg_match('#(password|mysql)#i', $key)) {
150
+            $phpThumb->DebugMessage('setParameter('.$keyname.', '.$phpThumb->phpThumbDebugVarDump($value).')', __FILE__, __LINE__);
151
+        }
152
+    }
153
+    if (!$phpThumb->config_disable_debug) {
154
+        // if debug mode is enabled, force phpThumbDebug output, do not allow normal thumbnails to be generated
155
+        $_GET['phpThumbDebug'] = (!empty($_GET['phpThumbDebug']) ? max(1, (int) $_GET[ 'phpThumbDebug']) : 9);
156
+        $phpThumb->setParameter('phpThumbDebug', $_GET['phpThumbDebug']);
157
+    }
158 158
 } else {
159
-	$phpThumb->DebugMessage('$PHPTHUMB_CONFIG is empty', __FILE__, __LINE__);
159
+    $phpThumb->DebugMessage('$PHPTHUMB_CONFIG is empty', __FILE__, __LINE__);
160 160
 }
161 161
 
162 162
 if (empty($phpThumb->config_disable_pathinfo_parsing) && (empty($_GET) || isset($_GET['phpThumbDebug'])) && !empty($_SERVER['PATH_INFO'])) {
163
-	$_SERVER['PHP_SELF'] = str_replace($_SERVER['PATH_INFO'], '', @$_SERVER['PHP_SELF']);
164
-
165
-	$args = explode(';', substr($_SERVER['PATH_INFO'], 1));
166
-	$phpThumb->DebugMessage('PATH_INFO.$args set to ('.implode(')(', $args).')', __FILE__, __LINE__);
167
-	if (!empty($args)) {
168
-		$_GET['src'] = @$args[count($args) - 1];
169
-		$phpThumb->DebugMessage('PATH_INFO."src" = "'.$_GET['src'].'"', __FILE__, __LINE__);
170
-		if (preg_match('#^new\=([a-z0-9]+)#i', $_GET['src'], $matches)) {
171
-			unset($_GET['src']);
172
-			$_GET['new'] = $matches[1];
173
-		}
174
-	}
175
-	if (preg_match('#^([0-9]*)x?([0-9]*)$#i', @$args[count($args) - 2], $matches)) {
176
-		$_GET['w'] = $matches[1];
177
-		$_GET['h'] = $matches[2];
178
-		$phpThumb->DebugMessage('PATH_INFO."w"x"h" set to "'.$_GET['w'].'"x"'.$_GET['h'].'"', __FILE__, __LINE__);
179
-	}
180
-	for ($i = 0; $i < count($args) - 2; $i++) {
181
-		@list($key, $value) = explode('=', @$args[$i]);
182
-		if (substr($key, -2) == '[]') {
183
-			$array_key_name = substr($key, 0, -2);
184
-			$_GET[$array_key_name][] = $value;
185
-			$phpThumb->DebugMessage('PATH_INFO."'.$array_key_name.'[]" = "'.$value.'"', __FILE__, __LINE__);
186
-		} else {
187
-			$_GET[$key] = $value;
188
-			$phpThumb->DebugMessage('PATH_INFO."'.$key.'" = "'.$value.'"', __FILE__, __LINE__);
189
-		}
190
-	}
163
+    $_SERVER['PHP_SELF'] = str_replace($_SERVER['PATH_INFO'], '', @$_SERVER['PHP_SELF']);
164
+
165
+    $args = explode(';', substr($_SERVER['PATH_INFO'], 1));
166
+    $phpThumb->DebugMessage('PATH_INFO.$args set to ('.implode(')(', $args).')', __FILE__, __LINE__);
167
+    if (!empty($args)) {
168
+        $_GET['src'] = @$args[count($args) - 1];
169
+        $phpThumb->DebugMessage('PATH_INFO."src" = "'.$_GET['src'].'"', __FILE__, __LINE__);
170
+        if (preg_match('#^new\=([a-z0-9]+)#i', $_GET['src'], $matches)) {
171
+            unset($_GET['src']);
172
+            $_GET['new'] = $matches[1];
173
+        }
174
+    }
175
+    if (preg_match('#^([0-9]*)x?([0-9]*)$#i', @$args[count($args) - 2], $matches)) {
176
+        $_GET['w'] = $matches[1];
177
+        $_GET['h'] = $matches[2];
178
+        $phpThumb->DebugMessage('PATH_INFO."w"x"h" set to "'.$_GET['w'].'"x"'.$_GET['h'].'"', __FILE__, __LINE__);
179
+    }
180
+    for ($i = 0; $i < count($args) - 2; $i++) {
181
+        @list($key, $value) = explode('=', @$args[$i]);
182
+        if (substr($key, -2) == '[]') {
183
+            $array_key_name = substr($key, 0, -2);
184
+            $_GET[$array_key_name][] = $value;
185
+            $phpThumb->DebugMessage('PATH_INFO."'.$array_key_name.'[]" = "'.$value.'"', __FILE__, __LINE__);
186
+        } else {
187
+            $_GET[$key] = $value;
188
+            $phpThumb->DebugMessage('PATH_INFO."'.$key.'" = "'.$value.'"', __FILE__, __LINE__);
189
+        }
190
+    }
191 191
 }
192 192
 
193 193
 if (!empty($phpThumb->config_high_security_enabled)) {
194
-	if (empty($_GET['hash'])) {
195
-		$phpThumb->config_disable_debug = false; // otherwise error message won't print
196
-		$phpThumb->ErrorImage('ERROR: missing hash');
197
-	} elseif (phpthumb_functions::PasswordStrength($phpThumb->config_high_security_password) < 20) {
198
-		$phpThumb->config_disable_debug = false; // otherwise error message won't print
199
-		$phpThumb->ErrorImage('ERROR: $PHPTHUMB_CONFIG[high_security_password] is not complex enough');
200
-	} elseif ($_GET['hash'] != md5(str_replace($phpThumb->config_high_security_url_separator.'hash='.$_GET['hash'], '', $_SERVER['QUERY_STRING']).$phpThumb->config_high_security_password)) {
201
-		header('HTTP/1.0 403 Forbidden');
202
-		sleep(10); // deliberate delay to discourage password-guessing
203
-		$phpThumb->ErrorImage('ERROR: invalid hash');
204
-	}
194
+    if (empty($_GET['hash'])) {
195
+        $phpThumb->config_disable_debug = false; // otherwise error message won't print
196
+        $phpThumb->ErrorImage('ERROR: missing hash');
197
+    } elseif (phpthumb_functions::PasswordStrength($phpThumb->config_high_security_password) < 20) {
198
+        $phpThumb->config_disable_debug = false; // otherwise error message won't print
199
+        $phpThumb->ErrorImage('ERROR: $PHPTHUMB_CONFIG[high_security_password] is not complex enough');
200
+    } elseif ($_GET['hash'] != md5(str_replace($phpThumb->config_high_security_url_separator.'hash='.$_GET['hash'], '', $_SERVER['QUERY_STRING']).$phpThumb->config_high_security_password)) {
201
+        header('HTTP/1.0 403 Forbidden');
202
+        sleep(10); // deliberate delay to discourage password-guessing
203
+        $phpThumb->ErrorImage('ERROR: invalid hash');
204
+    }
205 205
 }
206 206
 
207 207
 ////////////////////////////////////////////////////////////////
208 208
 // Debug output, to try and help me diagnose problems
209 209
 $phpThumb->DebugTimingMessage('phpThumbDebug[0]', __FILE__, __LINE__);
210 210
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '0')) {
211
-	$phpThumb->phpThumbDebug();
211
+    $phpThumb->phpThumbDebug();
212 212
 }
213 213
 ////////////////////////////////////////////////////////////////
214 214
 
215 215
 // returned the fixed string if the evil "magic_quotes_gpc" setting is on
216 216
 if (get_magic_quotes_gpc()) {
217
-	// deprecated: 'err', 'file', 'goto',
218
-	$RequestVarsToStripSlashes = array('src', 'wmf', 'down');
219
-	foreach ($RequestVarsToStripSlashes as $key) {
220
-		if (isset($_GET[$key])) {
221
-			if (is_string($_GET[$key])) {
222
-				$_GET[$key] = stripslashes($_GET[$key]);
223
-			} else {
224
-				unset($_GET[$key]);
225
-			}
226
-		}
227
-	}
217
+    // deprecated: 'err', 'file', 'goto',
218
+    $RequestVarsToStripSlashes = array('src', 'wmf', 'down');
219
+    foreach ($RequestVarsToStripSlashes as $key) {
220
+        if (isset($_GET[$key])) {
221
+            if (is_string($_GET[$key])) {
222
+                $_GET[$key] = stripslashes($_GET[$key]);
223
+            } else {
224
+                unset($_GET[$key]);
225
+            }
226
+        }
227
+    }
228 228
 }
229 229
 
230 230
 if (empty($_SERVER['PATH_INFO']) && empty($_SERVER['QUERY_STRING'])) {
231
-	$phpThumb->config_disable_debug = false; // otherwise error message won't print
232
-	$phpThumb->ErrorImage('ERROR: no parameters specified');
231
+    $phpThumb->config_disable_debug = false; // otherwise error message won't print
232
+    $phpThumb->ErrorImage('ERROR: no parameters specified');
233 233
 }
234 234
 
235 235
 if (!empty($_GET['src']) && isset($_GET['md5s']) && empty($_GET['md5s'])) {
236
-	$md5s = '';
237
-	if (preg_match('#^([a-z0-9]+)://#i', $_GET['src'], $protocol_matches)) {
238
-		if (preg_match('#^(f|ht)tps?://#i', $_GET['src'])) {
239
-			if ($rawImageData = phpthumb_functions::SafeURLread($_GET['src'], $error, $phpThumb->config_http_fopen_timeout, $phpThumb->config_http_follow_redirect)) {
240
-				$md5s = md5($rawImageData);
241
-			}
242
-		} else {
243
-			$phpThumb->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "'.$protocol_matches[1].'" is not');
244
-		}
245
-	} else {
246
-		$SourceFilename = $phpThumb->ResolveFilenameToAbsolute($_GET['src']);
247
-		if (is_readable($SourceFilename)) {
248
-			$md5s = phpthumb_functions::md5_file_safe($SourceFilename);
249
-		} else {
250
-			$phpThumb->ErrorImage('ERROR: "'.$SourceFilename.'" cannot be read');
251
-		}
252
-	}
253
-	if (!empty($_SERVER['HTTP_REFERER'])) {
254
-		$phpThumb->ErrorImage('&md5s='.$md5s);
255
-	} else {
256
-		die('&md5s='.$md5s);
257
-	}
236
+    $md5s = '';
237
+    if (preg_match('#^([a-z0-9]+)://#i', $_GET['src'], $protocol_matches)) {
238
+        if (preg_match('#^(f|ht)tps?://#i', $_GET['src'])) {
239
+            if ($rawImageData = phpthumb_functions::SafeURLread($_GET['src'], $error, $phpThumb->config_http_fopen_timeout, $phpThumb->config_http_follow_redirect)) {
240
+                $md5s = md5($rawImageData);
241
+            }
242
+        } else {
243
+            $phpThumb->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "'.$protocol_matches[1].'" is not');
244
+        }
245
+    } else {
246
+        $SourceFilename = $phpThumb->ResolveFilenameToAbsolute($_GET['src']);
247
+        if (is_readable($SourceFilename)) {
248
+            $md5s = phpthumb_functions::md5_file_safe($SourceFilename);
249
+        } else {
250
+            $phpThumb->ErrorImage('ERROR: "'.$SourceFilename.'" cannot be read');
251
+        }
252
+    }
253
+    if (!empty($_SERVER['HTTP_REFERER'])) {
254
+        $phpThumb->ErrorImage('&md5s='.$md5s);
255
+    } else {
256
+        die('&md5s='.$md5s);
257
+    }
258 258
 }
259 259
 
260 260
 if (!empty($_GET['src']) && empty($phpThumb->config_allow_local_http_src) && preg_match('#^http://'.@$_SERVER['HTTP_HOST'].'(.+)#i', $_GET['src'], $matches)) {
261
-	$phpThumb->ErrorImage('It is MUCH better to specify the "src" parameter as "'.$matches[1].'" instead of "'.$matches[0].'".'."\n\n".'If you really must do it this way, enable "allow_local_http_src" in phpThumb.config.php');
261
+    $phpThumb->ErrorImage('It is MUCH better to specify the "src" parameter as "'.$matches[1].'" instead of "'.$matches[0].'".'."\n\n".'If you really must do it this way, enable "allow_local_http_src" in phpThumb.config.php');
262 262
 }
263 263
 
264 264
 ////////////////////////////////////////////////////////////////
265 265
 // Debug output, to try and help me diagnose problems
266 266
 $phpThumb->DebugTimingMessage('phpThumbDebug[1]', __FILE__, __LINE__);
267 267
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '1')) {
268
-	$phpThumb->phpThumbDebug();
268
+    $phpThumb->phpThumbDebug();
269 269
 }
270 270
 ////////////////////////////////////////////////////////////////
271 271
 
272 272
 $parsed_url_referer = phpthumb_functions::ParseURLbetter(@$_SERVER['HTTP_REFERER']);
273 273
 if ($phpThumb->config_nooffsitelink_require_refer && !in_array(@$parsed_url_referer['host'], $phpThumb->config_nohotlink_valid_domains)) {
274
-	$phpThumb->ErrorImage('config_nooffsitelink_require_refer enabled and '.(@$parsed_url_referer['host'] ? '"'.$parsed_url_referer['host'].'" is not an allowed referer' : 'no HTTP_REFERER exists'));
274
+    $phpThumb->ErrorImage('config_nooffsitelink_require_refer enabled and '.(@$parsed_url_referer['host'] ? '"'.$parsed_url_referer['host'].'" is not an allowed referer' : 'no HTTP_REFERER exists'));
275 275
 }
276 276
 $parsed_url_src = phpthumb_functions::ParseURLbetter(@$_GET['src']);
277 277
 if ($phpThumb->config_nohotlink_enabled && $phpThumb->config_nohotlink_erase_image && preg_match('#^(f|ht)tps?://#i', @$_GET['src']) && !in_array(@$parsed_url_src['host'], $phpThumb->config_nohotlink_valid_domains)) {
278
-	$phpThumb->ErrorImage($phpThumb->config_nohotlink_text_message);
278
+    $phpThumb->ErrorImage($phpThumb->config_nohotlink_text_message);
279 279
 }
280 280
 
281 281
 if ($phpThumb->config_mysql_query) {
282
-	if ($phpThumb->config_mysql_extension == 'mysqli') {
283
-
284
-		$found_missing_function = false;
285
-		foreach (array('mysqli_connect') as $required_mysqli_function) {
286
-			if (!function_exists($required_mysqli_function)) {
287
-				$found_missing_function = $required_mysqli_function;
288
-				break;
289
-			}
290
-		}
291
-		if ($found_missing_function) {
292
-			$phpThumb->ErrorImage('SQL function unavailable: '.$found_missing_function);
293
-		} else {
294
-			$mysqli = new mysqli($phpThumb->config_mysql_hostname, $phpThumb->config_mysql_username, $phpThumb->config_mysql_password, $phpThumb->config_mysql_database);
295
-			if ($mysqli->connect_error) {
296
-				$phpThumb->ErrorImage('MySQLi connect error ('.$mysqli->connect_errno.') '.$mysqli->connect_error);
297
-			} else {
298
-				if ($result = $mysqli->query($phpThumb->config_mysql_query)) {
299
-					if ($row = $result->fetch_array()) {
300
-
301
-						$result->free();
302
-						$mysqli->close();
303
-						$phpThumb->setSourceData($row[0]);
304
-						unset($row);
305
-
306
-					} else {
307
-						$result->free();
308
-						$mysqli->close();
309
-						$phpThumb->ErrorImage('no matching data in database.');
310
-					}
311
-				} else {
312
-					$mysqli->close();
313
-					$phpThumb->ErrorImage('Error in MySQL query: "'.$mysqli->error.'"');
314
-				}
315
-			}
316
-			unset($_GET['id']);
317
-		}
318
-
319
-	} elseif ($phpThumb->config_mysql_extension == 'mysql') {
320
-
321
-		$found_missing_function = false;
322
-		//foreach (array('mysql_connect', 'mysql_select_db', 'mysql_query', 'mysql_fetch_array', 'mysql_free_result', 'mysql_close', 'mysql_error') as $required_mysql_function) {
323
-		foreach (array('mysql_connect') as $required_mysql_function) {
324
-			if (!function_exists($required_mysql_function)) {
325
-				$found_missing_function = $required_mysql_function;
326
-				break;
327
-			}
328
-		}
329
-		if ($found_missing_function) {
330
-			$phpThumb->ErrorImage('SQL function unavailable: '.$found_missing_function);
331
-		} else {
332
-			if ($cid = @mysql_connect($phpThumb->config_mysql_hostname, $phpThumb->config_mysql_username, $phpThumb->config_mysql_password)) {
333
-				if (@mysql_select_db($phpThumb->config_mysql_database, $cid)) {
334
-					if ($result = @mysql_query($phpThumb->config_mysql_query, $cid)) {
335
-						if ($row = @mysql_fetch_array($result)) {
336
-
337
-							mysql_free_result($result);
338
-							mysql_close($cid);
339
-							$phpThumb->setSourceData($row[0]);
340
-							unset($row);
341
-
342
-						} else {
343
-							mysql_free_result($result);
344
-							mysql_close($cid);
345
-							$phpThumb->ErrorImage('no matching data in database.');
346
-						}
347
-					} else {
348
-						mysql_close($cid);
349
-						$phpThumb->ErrorImage('Error in MySQL query: "'.mysql_error($cid).'"');
350
-					}
351
-				} else {
352
-					mysql_close($cid);
353
-					$phpThumb->ErrorImage('cannot select MySQL database: "'.mysql_error($cid).'"');
354
-				}
355
-			} else {
356
-				$phpThumb->ErrorImage('cannot connect to MySQL server');
357
-			}
358
-			unset($_GET['id']);
359
-		}
360
-
361
-	} else {
362
-		$phpThumb->ErrorImage('config_mysql_extension not supported');
363
-	}
282
+    if ($phpThumb->config_mysql_extension == 'mysqli') {
283
+
284
+        $found_missing_function = false;
285
+        foreach (array('mysqli_connect') as $required_mysqli_function) {
286
+            if (!function_exists($required_mysqli_function)) {
287
+                $found_missing_function = $required_mysqli_function;
288
+                break;
289
+            }
290
+        }
291
+        if ($found_missing_function) {
292
+            $phpThumb->ErrorImage('SQL function unavailable: '.$found_missing_function);
293
+        } else {
294
+            $mysqli = new mysqli($phpThumb->config_mysql_hostname, $phpThumb->config_mysql_username, $phpThumb->config_mysql_password, $phpThumb->config_mysql_database);
295
+            if ($mysqli->connect_error) {
296
+                $phpThumb->ErrorImage('MySQLi connect error ('.$mysqli->connect_errno.') '.$mysqli->connect_error);
297
+            } else {
298
+                if ($result = $mysqli->query($phpThumb->config_mysql_query)) {
299
+                    if ($row = $result->fetch_array()) {
300
+
301
+                        $result->free();
302
+                        $mysqli->close();
303
+                        $phpThumb->setSourceData($row[0]);
304
+                        unset($row);
305
+
306
+                    } else {
307
+                        $result->free();
308
+                        $mysqli->close();
309
+                        $phpThumb->ErrorImage('no matching data in database.');
310
+                    }
311
+                } else {
312
+                    $mysqli->close();
313
+                    $phpThumb->ErrorImage('Error in MySQL query: "'.$mysqli->error.'"');
314
+                }
315
+            }
316
+            unset($_GET['id']);
317
+        }
318
+
319
+    } elseif ($phpThumb->config_mysql_extension == 'mysql') {
320
+
321
+        $found_missing_function = false;
322
+        //foreach (array('mysql_connect', 'mysql_select_db', 'mysql_query', 'mysql_fetch_array', 'mysql_free_result', 'mysql_close', 'mysql_error') as $required_mysql_function) {
323
+        foreach (array('mysql_connect') as $required_mysql_function) {
324
+            if (!function_exists($required_mysql_function)) {
325
+                $found_missing_function = $required_mysql_function;
326
+                break;
327
+            }
328
+        }
329
+        if ($found_missing_function) {
330
+            $phpThumb->ErrorImage('SQL function unavailable: '.$found_missing_function);
331
+        } else {
332
+            if ($cid = @mysql_connect($phpThumb->config_mysql_hostname, $phpThumb->config_mysql_username, $phpThumb->config_mysql_password)) {
333
+                if (@mysql_select_db($phpThumb->config_mysql_database, $cid)) {
334
+                    if ($result = @mysql_query($phpThumb->config_mysql_query, $cid)) {
335
+                        if ($row = @mysql_fetch_array($result)) {
336
+
337
+                            mysql_free_result($result);
338
+                            mysql_close($cid);
339
+                            $phpThumb->setSourceData($row[0]);
340
+                            unset($row);
341
+
342
+                        } else {
343
+                            mysql_free_result($result);
344
+                            mysql_close($cid);
345
+                            $phpThumb->ErrorImage('no matching data in database.');
346
+                        }
347
+                    } else {
348
+                        mysql_close($cid);
349
+                        $phpThumb->ErrorImage('Error in MySQL query: "'.mysql_error($cid).'"');
350
+                    }
351
+                } else {
352
+                    mysql_close($cid);
353
+                    $phpThumb->ErrorImage('cannot select MySQL database: "'.mysql_error($cid).'"');
354
+                }
355
+            } else {
356
+                $phpThumb->ErrorImage('cannot connect to MySQL server');
357
+            }
358
+            unset($_GET['id']);
359
+        }
360
+
361
+    } else {
362
+        $phpThumb->ErrorImage('config_mysql_extension not supported');
363
+    }
364 364
 }
365 365
 
366 366
 ////////////////////////////////////////////////////////////////
367 367
 // Debug output, to try and help me diagnose problems
368 368
 $phpThumb->DebugTimingMessage('phpThumbDebug[2]', __FILE__, __LINE__);
369 369
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '2')) {
370
-	$phpThumb->phpThumbDebug();
370
+    $phpThumb->phpThumbDebug();
371 371
 }
372 372
 ////////////////////////////////////////////////////////////////
373 373
 
@@ -376,34 +376,34 @@  discard block
 block discarded – undo
376 376
 // deprecated: 'err', 'file', 'goto',
377 377
 $allowedGETparameters = array('src', 'new', 'w', 'h', 'wp', 'hp', 'wl', 'hl', 'ws', 'hs', 'f', 'q', 'sx', 'sy', 'sw', 'sh', 'zc', 'bc', 'bg', 'bgt', 'fltr', 'xto', 'ra', 'ar', 'aoe', 'far', 'iar', 'maxb', 'down', 'phpThumbDebug', 'hash', 'md5s', 'sfn', 'dpi', 'sia', 'nocache');
378 378
 foreach ($_GET as $key => $value) {
379
-	if (!empty($PHPTHUMB_DEFAULTS_DISABLEGETPARAMS) && ($key != 'src')) {
380
-		// disabled, do not set parameter
381
-		$phpThumb->DebugMessage('ignoring $_GET['.$key.'] because of $PHPTHUMB_DEFAULTS_DISABLEGETPARAMS', __FILE__, __LINE__);
382
-	} elseif (in_array($key, $allowedGETparameters)) {
383
-		$phpThumb->DebugMessage('setParameter('.$key.', '.$phpThumb->phpThumbDebugVarDump($value).')', __FILE__, __LINE__);
384
-		$phpThumb->setParameter($key, $value);
385
-	} else {
386
-		$phpThumb->ErrorImage('Forbidden parameter: '.$key);
387
-	}
379
+    if (!empty($PHPTHUMB_DEFAULTS_DISABLEGETPARAMS) && ($key != 'src')) {
380
+        // disabled, do not set parameter
381
+        $phpThumb->DebugMessage('ignoring $_GET['.$key.'] because of $PHPTHUMB_DEFAULTS_DISABLEGETPARAMS', __FILE__, __LINE__);
382
+    } elseif (in_array($key, $allowedGETparameters)) {
383
+        $phpThumb->DebugMessage('setParameter('.$key.', '.$phpThumb->phpThumbDebugVarDump($value).')', __FILE__, __LINE__);
384
+        $phpThumb->setParameter($key, $value);
385
+    } else {
386
+        $phpThumb->ErrorImage('Forbidden parameter: '.$key);
387
+    }
388 388
 }
389 389
 
390 390
 if (!empty($PHPTHUMB_DEFAULTS) && is_array($PHPTHUMB_DEFAULTS)) {
391
-	$phpThumb->DebugMessage('setting $PHPTHUMB_DEFAULTS['.implode(';', array_keys($PHPTHUMB_DEFAULTS)).']', __FILE__, __LINE__);
392
-	foreach ($PHPTHUMB_DEFAULTS as $key => $value) {
393
-		if (!$PHPTHUMB_DEFAULTS_GETSTRINGOVERRIDE || !isset($_GET[$key])) { // set parameter to default value if config is set to allow _GET to override default, OR if no value is passed via _GET for this parameter
394
-			//$_GET[$key] = $value;
395
-			//$phpThumb->DebugMessage('PHPTHUMB_DEFAULTS assigning ('.(is_array($value) ? print_r($value, true) : $value).') to $_GET['.$key.']', __FILE__, __LINE__);
396
-			$phpThumb->setParameter($key, $value);
397
-			$phpThumb->DebugMessage('setParameter('.$key.', '.$phpThumb->phpThumbDebugVarDump($value).') from $PHPTHUMB_DEFAULTS', __FILE__, __LINE__);
398
-		}
399
-	}
391
+    $phpThumb->DebugMessage('setting $PHPTHUMB_DEFAULTS['.implode(';', array_keys($PHPTHUMB_DEFAULTS)).']', __FILE__, __LINE__);
392
+    foreach ($PHPTHUMB_DEFAULTS as $key => $value) {
393
+        if (!$PHPTHUMB_DEFAULTS_GETSTRINGOVERRIDE || !isset($_GET[$key])) { // set parameter to default value if config is set to allow _GET to override default, OR if no value is passed via _GET for this parameter
394
+            //$_GET[$key] = $value;
395
+            //$phpThumb->DebugMessage('PHPTHUMB_DEFAULTS assigning ('.(is_array($value) ? print_r($value, true) : $value).') to $_GET['.$key.']', __FILE__, __LINE__);
396
+            $phpThumb->setParameter($key, $value);
397
+            $phpThumb->DebugMessage('setParameter('.$key.', '.$phpThumb->phpThumbDebugVarDump($value).') from $PHPTHUMB_DEFAULTS', __FILE__, __LINE__);
398
+        }
399
+    }
400 400
 }
401 401
 
402 402
 ////////////////////////////////////////////////////////////////
403 403
 // Debug output, to try and help me diagnose problems
404 404
 $phpThumb->DebugTimingMessage('phpThumbDebug[3]', __FILE__, __LINE__);
405 405
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '3')) {
406
-	$phpThumb->phpThumbDebug();
406
+    $phpThumb->phpThumbDebug();
407 407
 }
408 408
 ////////////////////////////////////////////////////////////////
409 409
 
@@ -422,214 +422,214 @@  discard block
 block discarded – undo
422 422
 // check to see if file can be output from source with no processing or caching
423 423
 $CanPassThroughDirectly = true;
424 424
 if ($phpThumb->rawImageData) {
425
-	// data from SQL, should be fine
425
+    // data from SQL, should be fine
426 426
 } elseif (preg_match('#^http\://[^\\?&]+\\.(jpe?g|gif|png)$#i', $phpThumb->src)) {
427
-	// assume is ok to passthru if no other parameters specified
427
+    // assume is ok to passthru if no other parameters specified
428 428
 } elseif (preg_match('#^(f|ht)tp\://#i', $phpThumb->src)) {
429
-	$phpThumb->DebugMessage('$CanPassThroughDirectly=false because preg_match("#^(f|ht)tp\://#i", '.$phpThumb->src.')', __FILE__, __LINE__);
430
-	$CanPassThroughDirectly = false;
429
+    $phpThumb->DebugMessage('$CanPassThroughDirectly=false because preg_match("#^(f|ht)tp\://#i", '.$phpThumb->src.')', __FILE__, __LINE__);
430
+    $CanPassThroughDirectly = false;
431 431
 } elseif (!@is_readable($phpThumb->sourceFilename)) {
432
-	$phpThumb->DebugMessage('$CanPassThroughDirectly=false because !@is_readable('.$phpThumb->sourceFilename.')', __FILE__, __LINE__);
433
-	$CanPassThroughDirectly = false;
432
+    $phpThumb->DebugMessage('$CanPassThroughDirectly=false because !@is_readable('.$phpThumb->sourceFilename.')', __FILE__, __LINE__);
433
+    $CanPassThroughDirectly = false;
434 434
 } elseif (!@is_file($phpThumb->sourceFilename)) {
435
-	$phpThumb->DebugMessage('$CanPassThroughDirectly=false because !@is_file('.$phpThumb->sourceFilename.')', __FILE__, __LINE__);
436
-	$CanPassThroughDirectly = false;
435
+    $phpThumb->DebugMessage('$CanPassThroughDirectly=false because !@is_file('.$phpThumb->sourceFilename.')', __FILE__, __LINE__);
436
+    $CanPassThroughDirectly = false;
437 437
 }
438 438
 foreach ($_GET as $key => $value) {
439
-	switch ($key) {
440
-		case 'src':
441
-			// allowed
442
-			break;
443
-
444
-		case 'w':
445
-		case 'h':
446
-			// might be OK if exactly matches original
447
-			if (preg_match('#^http\://[^\\?&]+\\.(jpe?g|gif|png)$#i', $phpThumb->src)) {
448
-				// assume it is not ok for direct-passthru of remote image
449
-				$CanPassThroughDirectly = false;
450
-			}
451
-			break;
452
-
453
-		case 'phpThumbDebug':
454
-			// handled in direct-passthru code
455
-			break;
456
-
457
-		default:
458
-			// all other parameters will cause some processing,
459
-			// therefore cannot pass through original image unmodified
460
-			$CanPassThroughDirectly = false;
461
-			$UnAllowedGET[] = $key;
462
-			break;
463
-	}
439
+    switch ($key) {
440
+        case 'src':
441
+            // allowed
442
+            break;
443
+
444
+        case 'w':
445
+        case 'h':
446
+            // might be OK if exactly matches original
447
+            if (preg_match('#^http\://[^\\?&]+\\.(jpe?g|gif|png)$#i', $phpThumb->src)) {
448
+                // assume it is not ok for direct-passthru of remote image
449
+                $CanPassThroughDirectly = false;
450
+            }
451
+            break;
452
+
453
+        case 'phpThumbDebug':
454
+            // handled in direct-passthru code
455
+            break;
456
+
457
+        default:
458
+            // all other parameters will cause some processing,
459
+            // therefore cannot pass through original image unmodified
460
+            $CanPassThroughDirectly = false;
461
+            $UnAllowedGET[] = $key;
462
+            break;
463
+    }
464 464
 }
465 465
 if (!empty($UnAllowedGET)) {
466
-	$phpThumb->DebugMessage('$CanPassThroughDirectly=false because $_GET['.implode(';', array_unique($UnAllowedGET)).'] are set', __FILE__, __LINE__);
466
+    $phpThumb->DebugMessage('$CanPassThroughDirectly=false because $_GET['.implode(';', array_unique($UnAllowedGET)).'] are set', __FILE__, __LINE__);
467 467
 }
468 468
 
469 469
 ////////////////////////////////////////////////////////////////
470 470
 // Debug output, to try and help me diagnose problems
471 471
 $phpThumb->DebugTimingMessage('phpThumbDebug[4]', __FILE__, __LINE__);
472 472
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '4')) {
473
-	$phpThumb->phpThumbDebug();
473
+    $phpThumb->phpThumbDebug();
474 474
 }
475 475
 ////////////////////////////////////////////////////////////////
476 476
 
477 477
 $phpThumb->DebugMessage('$CanPassThroughDirectly="'. (int) $CanPassThroughDirectly .'" && $phpThumb->src="'.$phpThumb->src.'"', __FILE__, __LINE__);
478 478
 while ($CanPassThroughDirectly && $phpThumb->src) {
479
-	// no parameters set, passthru
480
-
481
-	if (preg_match('#^http\://[^\\?&]+\.(jpe?g|gif|png)$#i', $phpThumb->src)) {
482
-		$phpThumb->DebugMessage('Passing HTTP source through directly as Location: redirect ('.$phpThumb->src.')', __FILE__, __LINE__);
483
-		header('Location: '.$phpThumb->src);
484
-		exit;
485
-	}
486
-
487
-	$SourceFilename = $phpThumb->ResolveFilenameToAbsolute($phpThumb->src);
488
-
489
-	// security and size checks
490
-	if ($phpThumb->getimagesizeinfo = @getimagesize($SourceFilename)) {
491
-		$phpThumb->DebugMessage('Direct passthru getimagesize() returned [w='.$phpThumb->getimagesizeinfo[0].';h='.$phpThumb->getimagesizeinfo[1].';t='.$phpThumb->getimagesizeinfo[2].']', __FILE__, __LINE__);
492
-
493
-		if (!@$_GET['w'] && !@$_GET['wp'] && !@$_GET['wl'] && !@$_GET['ws'] && !@$_GET['h'] && !@$_GET['hp'] && !@$_GET['hl'] && !@$_GET['hs']) {
494
-			// no resizing needed
495
-			$phpThumb->DebugMessage('Passing "'.$SourceFilename.'" through directly, no resizing required ("'.$phpThumb->getimagesizeinfo[0].'"x"'.$phpThumb->getimagesizeinfo[1].'")', __FILE__, __LINE__);
496
-		} elseif (($phpThumb->getimagesizeinfo[0] <= @$_GET['w']) && ($phpThumb->getimagesizeinfo[1] <= @$_GET['h']) && ((@$_GET['w'] == $phpThumb->getimagesizeinfo[0]) || (@$_GET['h'] == $phpThumb->getimagesizeinfo[1]))) {
497
-			// image fits into 'w'x'h' box, and at least one dimension matches exactly, therefore no resizing needed
498
-			$phpThumb->DebugMessage('Passing "'.$SourceFilename.'" through directly, no resizing required ("'.$phpThumb->getimagesizeinfo[0].'"x"'.$phpThumb->getimagesizeinfo[1].'" fits inside "'.@$_GET['w'].'"x"'.@$_GET['h'].'")', __FILE__, __LINE__);
499
-		} else {
500
-			$phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because resizing required (from "'.$phpThumb->getimagesizeinfo[0].'"x"'.$phpThumb->getimagesizeinfo[1].'" to "'.@$_GET['w'].'"x"'.@$_GET['h'].'")', __FILE__, __LINE__);
501
-			break;
502
-		}
503
-		switch ($phpThumb->getimagesizeinfo[2]) {
504
-			case 1: // GIF
505
-			case 2: // JPG
506
-			case 3: // PNG
507
-				// great, let it through
508
-				break;
509
-			default:
510
-				// browser probably can't handle format, remangle it to JPEG/PNG/GIF
511
-				$phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because $phpThumb->getimagesizeinfo[2] = "'.$phpThumb->getimagesizeinfo[2].'"', __FILE__, __LINE__);
512
-				break 2;
513
-		}
514
-
515
-		$ImageCreateFunctions = array(1=>'imagecreatefromgif', 2=>'imagecreatefromjpeg', 3=>'imagecreatefrompng');
516
-		$theImageCreateFunction = @$ImageCreateFunctions[$phpThumb->getimagesizeinfo[2]];
517
-		$dummyImage = false;
518
-		if ($phpThumb->config_disable_onlycreateable_passthru || (function_exists($theImageCreateFunction) && ($dummyImage = @$theImageCreateFunction($SourceFilename)))) {
519
-
520
-			// great
521
-			if (@is_resource($dummyImage)) {
522
-				unset($dummyImage);
523
-			}
524
-
525
-			if (headers_sent()) {
526
-				$phpThumb->ErrorImage('Headers already sent ('.basename(__FILE__).' line '.__LINE__.')');
527
-				exit;
528
-			}
529
-			if (!empty($_GET['phpThumbDebug'])) {
530
-				$phpThumb->DebugTimingMessage('skipped direct $SourceFilename passthru', __FILE__, __LINE__);
531
-				$phpThumb->DebugMessage('Would have passed "'.$SourceFilename.'" through directly, but skipping due to phpThumbDebug', __FILE__, __LINE__);
532
-				break;
533
-			}
534
-
535
-			SendSaveAsFileHeaderIfNeeded();
536
-			header('Last-Modified: '.gmdate('D, d M Y H:i:s', @filemtime($SourceFilename)).' GMT');
537
-			if ($contentType = phpthumb_functions::ImageTypeToMIMEtype(@$phpThumb->getimagesizeinfo[2])) {
538
-				header('Content-Type: '.$contentType);
539
-			}
540
-			@readfile($SourceFilename);
541
-			exit;
542
-
543
-		} else {
544
-			$phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because ($phpThumb->config_disable_onlycreateable_passthru = "'.$phpThumb->config_disable_onlycreateable_passthru.'") and '.$theImageCreateFunction.'() failed', __FILE__, __LINE__);
545
-			break;
546
-		}
547
-
548
-	} else {
549
-		$phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because getimagesize() failed', __FILE__, __LINE__);
550
-		break;
551
-	}
552
-	break;
479
+    // no parameters set, passthru
480
+
481
+    if (preg_match('#^http\://[^\\?&]+\.(jpe?g|gif|png)$#i', $phpThumb->src)) {
482
+        $phpThumb->DebugMessage('Passing HTTP source through directly as Location: redirect ('.$phpThumb->src.')', __FILE__, __LINE__);
483
+        header('Location: '.$phpThumb->src);
484
+        exit;
485
+    }
486
+
487
+    $SourceFilename = $phpThumb->ResolveFilenameToAbsolute($phpThumb->src);
488
+
489
+    // security and size checks
490
+    if ($phpThumb->getimagesizeinfo = @getimagesize($SourceFilename)) {
491
+        $phpThumb->DebugMessage('Direct passthru getimagesize() returned [w='.$phpThumb->getimagesizeinfo[0].';h='.$phpThumb->getimagesizeinfo[1].';t='.$phpThumb->getimagesizeinfo[2].']', __FILE__, __LINE__);
492
+
493
+        if (!@$_GET['w'] && !@$_GET['wp'] && !@$_GET['wl'] && !@$_GET['ws'] && !@$_GET['h'] && !@$_GET['hp'] && !@$_GET['hl'] && !@$_GET['hs']) {
494
+            // no resizing needed
495
+            $phpThumb->DebugMessage('Passing "'.$SourceFilename.'" through directly, no resizing required ("'.$phpThumb->getimagesizeinfo[0].'"x"'.$phpThumb->getimagesizeinfo[1].'")', __FILE__, __LINE__);
496
+        } elseif (($phpThumb->getimagesizeinfo[0] <= @$_GET['w']) && ($phpThumb->getimagesizeinfo[1] <= @$_GET['h']) && ((@$_GET['w'] == $phpThumb->getimagesizeinfo[0]) || (@$_GET['h'] == $phpThumb->getimagesizeinfo[1]))) {
497
+            // image fits into 'w'x'h' box, and at least one dimension matches exactly, therefore no resizing needed
498
+            $phpThumb->DebugMessage('Passing "'.$SourceFilename.'" through directly, no resizing required ("'.$phpThumb->getimagesizeinfo[0].'"x"'.$phpThumb->getimagesizeinfo[1].'" fits inside "'.@$_GET['w'].'"x"'.@$_GET['h'].'")', __FILE__, __LINE__);
499
+        } else {
500
+            $phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because resizing required (from "'.$phpThumb->getimagesizeinfo[0].'"x"'.$phpThumb->getimagesizeinfo[1].'" to "'.@$_GET['w'].'"x"'.@$_GET['h'].'")', __FILE__, __LINE__);
501
+            break;
502
+        }
503
+        switch ($phpThumb->getimagesizeinfo[2]) {
504
+            case 1: // GIF
505
+            case 2: // JPG
506
+            case 3: // PNG
507
+                // great, let it through
508
+                break;
509
+            default:
510
+                // browser probably can't handle format, remangle it to JPEG/PNG/GIF
511
+                $phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because $phpThumb->getimagesizeinfo[2] = "'.$phpThumb->getimagesizeinfo[2].'"', __FILE__, __LINE__);
512
+                break 2;
513
+        }
514
+
515
+        $ImageCreateFunctions = array(1=>'imagecreatefromgif', 2=>'imagecreatefromjpeg', 3=>'imagecreatefrompng');
516
+        $theImageCreateFunction = @$ImageCreateFunctions[$phpThumb->getimagesizeinfo[2]];
517
+        $dummyImage = false;
518
+        if ($phpThumb->config_disable_onlycreateable_passthru || (function_exists($theImageCreateFunction) && ($dummyImage = @$theImageCreateFunction($SourceFilename)))) {
519
+
520
+            // great
521
+            if (@is_resource($dummyImage)) {
522
+                unset($dummyImage);
523
+            }
524
+
525
+            if (headers_sent()) {
526
+                $phpThumb->ErrorImage('Headers already sent ('.basename(__FILE__).' line '.__LINE__.')');
527
+                exit;
528
+            }
529
+            if (!empty($_GET['phpThumbDebug'])) {
530
+                $phpThumb->DebugTimingMessage('skipped direct $SourceFilename passthru', __FILE__, __LINE__);
531
+                $phpThumb->DebugMessage('Would have passed "'.$SourceFilename.'" through directly, but skipping due to phpThumbDebug', __FILE__, __LINE__);
532
+                break;
533
+            }
534
+
535
+            SendSaveAsFileHeaderIfNeeded();
536
+            header('Last-Modified: '.gmdate('D, d M Y H:i:s', @filemtime($SourceFilename)).' GMT');
537
+            if ($contentType = phpthumb_functions::ImageTypeToMIMEtype(@$phpThumb->getimagesizeinfo[2])) {
538
+                header('Content-Type: '.$contentType);
539
+            }
540
+            @readfile($SourceFilename);
541
+            exit;
542
+
543
+        } else {
544
+            $phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because ($phpThumb->config_disable_onlycreateable_passthru = "'.$phpThumb->config_disable_onlycreateable_passthru.'") and '.$theImageCreateFunction.'() failed', __FILE__, __LINE__);
545
+            break;
546
+        }
547
+
548
+    } else {
549
+        $phpThumb->DebugMessage('Not passing "'.$SourceFilename.'" through directly because getimagesize() failed', __FILE__, __LINE__);
550
+        break;
551
+    }
552
+    break;
553 553
 }
554 554
 
555 555
 ////////////////////////////////////////////////////////////////
556 556
 // Debug output, to try and help me diagnose problems
557 557
 $phpThumb->DebugTimingMessage('phpThumbDebug[5]', __FILE__, __LINE__);
558 558
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '5')) {
559
-	$phpThumb->phpThumbDebug();
559
+    $phpThumb->phpThumbDebug();
560 560
 }
561 561
 ////////////////////////////////////////////////////////////////
562 562
 
563 563
 // check to see if file already exists in cache, and output it with no processing if it does
564 564
 $phpThumb->SetCacheFilename();
565 565
 if (@is_readable($phpThumb->cache_filename)) {
566
-	RedirectToCachedFile();
566
+    RedirectToCachedFile();
567 567
 } else {
568
-	$phpThumb->DebugMessage('Cached file "'.$phpThumb->cache_filename.'" does not exist, processing as normal', __FILE__, __LINE__);
568
+    $phpThumb->DebugMessage('Cached file "'.$phpThumb->cache_filename.'" does not exist, processing as normal', __FILE__, __LINE__);
569 569
 }
570 570
 
571 571
 ////////////////////////////////////////////////////////////////
572 572
 // Debug output, to try and help me diagnose problems
573 573
 $phpThumb->DebugTimingMessage('phpThumbDebug[6]', __FILE__, __LINE__);
574 574
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '6')) {
575
-	$phpThumb->phpThumbDebug();
575
+    $phpThumb->phpThumbDebug();
576 576
 }
577 577
 ////////////////////////////////////////////////////////////////
578 578
 
579 579
 if ($phpThumb->rawImageData) {
580 580
 
581
-	// great
581
+    // great
582 582
 
583 583
 } elseif (!empty($_GET['new'])) {
584 584
 
585
-	// generate a blank image resource of the specified size/background color/opacity
586
-	if (($phpThumb->w <= 0) || ($phpThumb->h <= 0)) {
587
-		$phpThumb->ErrorImage('"w" and "h" parameters required for "new"');
588
-	}
589
-	@list($bghexcolor, $opacity) = explode('|', $_GET['new']);
590
-	if (!phpthumb_functions::IsHexColor($bghexcolor)) {
591
-		$phpThumb->ErrorImage('BGcolor parameter for "new" is not valid');
592
-	}
593
-	$opacity = ('' !== $opacity ? $opacity : 100);
594
-	if ($phpThumb->gdimg_source = phpthumb_functions::ImageCreateFunction($phpThumb->w, $phpThumb->h)) {
595
-		$alpha = (100 - min(100, max(0, $opacity))) * 1.27;
596
-		if ($alpha) {
597
-			$phpThumb->setParameter('is_alpha', true);
598
-			imagealphablending($phpThumb->gdimg_source, false);
599
-			imagesavealpha($phpThumb->gdimg_source, true);
600
-		}
601
-		$new_background_color = phpthumb_functions::ImageHexColorAllocate($phpThumb->gdimg_source, $bghexcolor, false, $alpha);
602
-		imagefilledrectangle($phpThumb->gdimg_source, 0, 0, $phpThumb->w, $phpThumb->h, $new_background_color);
603
-	} else {
604
-		$phpThumb->ErrorImage('failed to create "new" image ('.$phpThumb->w.'x'.$phpThumb->h.')');
605
-	}
585
+    // generate a blank image resource of the specified size/background color/opacity
586
+    if (($phpThumb->w <= 0) || ($phpThumb->h <= 0)) {
587
+        $phpThumb->ErrorImage('"w" and "h" parameters required for "new"');
588
+    }
589
+    @list($bghexcolor, $opacity) = explode('|', $_GET['new']);
590
+    if (!phpthumb_functions::IsHexColor($bghexcolor)) {
591
+        $phpThumb->ErrorImage('BGcolor parameter for "new" is not valid');
592
+    }
593
+    $opacity = ('' !== $opacity ? $opacity : 100);
594
+    if ($phpThumb->gdimg_source = phpthumb_functions::ImageCreateFunction($phpThumb->w, $phpThumb->h)) {
595
+        $alpha = (100 - min(100, max(0, $opacity))) * 1.27;
596
+        if ($alpha) {
597
+            $phpThumb->setParameter('is_alpha', true);
598
+            imagealphablending($phpThumb->gdimg_source, false);
599
+            imagesavealpha($phpThumb->gdimg_source, true);
600
+        }
601
+        $new_background_color = phpthumb_functions::ImageHexColorAllocate($phpThumb->gdimg_source, $bghexcolor, false, $alpha);
602
+        imagefilledrectangle($phpThumb->gdimg_source, 0, 0, $phpThumb->w, $phpThumb->h, $new_background_color);
603
+    } else {
604
+        $phpThumb->ErrorImage('failed to create "new" image ('.$phpThumb->w.'x'.$phpThumb->h.')');
605
+    }
606 606
 
607 607
 } elseif (!$phpThumb->src) {
608 608
 
609
-	$phpThumb->ErrorImage('Usage: '.$_SERVER['PHP_SELF'].'?src=/path/and/filename.jpg'."\n".'read Usage comments for details');
609
+    $phpThumb->ErrorImage('Usage: '.$_SERVER['PHP_SELF'].'?src=/path/and/filename.jpg'."\n".'read Usage comments for details');
610 610
 
611 611
 } elseif (preg_match('#^([a-z0-9]+)://#i', $_GET['src'], $protocol_matches)) {
612 612
 
613
-	if (preg_match('#^(f|ht)tps?://#i', $_GET['src'])) {
614
-		$phpThumb->DebugMessage('$phpThumb->src ('.$phpThumb->src.') is remote image, attempting to download', __FILE__, __LINE__);
615
-		if ($phpThumb->config_http_user_agent) {
616
-			$phpThumb->DebugMessage('Setting "user_agent" to "'.$phpThumb->config_http_user_agent.'"', __FILE__, __LINE__);
617
-			ini_set('user_agent', $phpThumb->config_http_user_agent);
618
-		}
619
-		$cleanedupurl = phpthumb_functions::CleanUpURLencoding($phpThumb->src);
620
-		$phpThumb->DebugMessage('CleanUpURLencoding('.$phpThumb->src.') returned "'.$cleanedupurl.'"', __FILE__, __LINE__);
621
-		$phpThumb->src = $cleanedupurl;
622
-		unset($cleanedupurl);
623
-		if ($rawImageData = phpthumb_functions::SafeURLread($phpThumb->src, $error, $phpThumb->config_http_fopen_timeout, $phpThumb->config_http_follow_redirect)) {
624
-			$phpThumb->DebugMessage('SafeURLread('.$phpThumb->src.') succeeded'.($error ? ' with messages: "'.$error.'"' : ''), __FILE__, __LINE__);
625
-			$phpThumb->DebugMessage('Setting source data from URL "'.$phpThumb->src.'"', __FILE__, __LINE__);
626
-			$phpThumb->setSourceData($rawImageData, urlencode($phpThumb->src));
627
-		} else {
628
-			$phpThumb->ErrorImage($error);
629
-		}
630
-	} else {
631
-		$phpThumb->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "'.$protocol_matches[1].'" is not');
632
-	}
613
+    if (preg_match('#^(f|ht)tps?://#i', $_GET['src'])) {
614
+        $phpThumb->DebugMessage('$phpThumb->src ('.$phpThumb->src.') is remote image, attempting to download', __FILE__, __LINE__);
615
+        if ($phpThumb->config_http_user_agent) {
616
+            $phpThumb->DebugMessage('Setting "user_agent" to "'.$phpThumb->config_http_user_agent.'"', __FILE__, __LINE__);
617
+            ini_set('user_agent', $phpThumb->config_http_user_agent);
618
+        }
619
+        $cleanedupurl = phpthumb_functions::CleanUpURLencoding($phpThumb->src);
620
+        $phpThumb->DebugMessage('CleanUpURLencoding('.$phpThumb->src.') returned "'.$cleanedupurl.'"', __FILE__, __LINE__);
621
+        $phpThumb->src = $cleanedupurl;
622
+        unset($cleanedupurl);
623
+        if ($rawImageData = phpthumb_functions::SafeURLread($phpThumb->src, $error, $phpThumb->config_http_fopen_timeout, $phpThumb->config_http_follow_redirect)) {
624
+            $phpThumb->DebugMessage('SafeURLread('.$phpThumb->src.') succeeded'.($error ? ' with messages: "'.$error.'"' : ''), __FILE__, __LINE__);
625
+            $phpThumb->DebugMessage('Setting source data from URL "'.$phpThumb->src.'"', __FILE__, __LINE__);
626
+            $phpThumb->setSourceData($rawImageData, urlencode($phpThumb->src));
627
+        } else {
628
+            $phpThumb->ErrorImage($error);
629
+        }
630
+    } else {
631
+        $phpThumb->ErrorImage('only FTP and HTTP/HTTPS protocols are allowed, "'.$protocol_matches[1].'" is not');
632
+    }
633 633
 
634 634
 }
635 635
 
@@ -637,7 +637,7 @@  discard block
 block discarded – undo
637 637
 // Debug output, to try and help me diagnose problems
638 638
 $phpThumb->DebugTimingMessage('phpThumbDebug[7]', __FILE__, __LINE__);
639 639
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '7')) {
640
-	$phpThumb->phpThumbDebug();
640
+    $phpThumb->phpThumbDebug();
641 641
 }
642 642
 ////////////////////////////////////////////////////////////////
643 643
 
@@ -647,32 +647,32 @@  discard block
 block discarded – undo
647 647
 // Debug output, to try and help me diagnose problems
648 648
 $phpThumb->DebugTimingMessage('phpThumbDebug[8]', __FILE__, __LINE__);
649 649
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '8')) {
650
-	$phpThumb->phpThumbDebug();
650
+    $phpThumb->phpThumbDebug();
651 651
 }
652 652
 ////////////////////////////////////////////////////////////////
653 653
 
654 654
 if (!empty($phpThumb->config_high_security_enabled) && !empty($_GET['nocache'])) {
655 655
 
656
-	// cache disabled, don't write cachefile
656
+    // cache disabled, don't write cachefile
657 657
 
658 658
 } else {
659 659
 
660
-	phpthumb_functions::EnsureDirectoryExists(dirname($phpThumb->cache_filename));
661
-	if (is_writable(dirname($phpThumb->cache_filename)) || (file_exists($phpThumb->cache_filename) && is_writable($phpThumb->cache_filename))) {
660
+    phpthumb_functions::EnsureDirectoryExists(dirname($phpThumb->cache_filename));
661
+    if (is_writable(dirname($phpThumb->cache_filename)) || (file_exists($phpThumb->cache_filename) && is_writable($phpThumb->cache_filename))) {
662 662
 
663
-		$phpThumb->CleanUpCacheDirectory();
664
-		if ($phpThumb->RenderToFile($phpThumb->cache_filename) && is_readable($phpThumb->cache_filename)) {
665
-			chmod($phpThumb->cache_filename, 0644);
666
-			RedirectToCachedFile();
667
-		} else {
668
-			$phpThumb->DebugMessage('Failed: RenderToFile('.$phpThumb->cache_filename.')', __FILE__, __LINE__);
669
-		}
663
+        $phpThumb->CleanUpCacheDirectory();
664
+        if ($phpThumb->RenderToFile($phpThumb->cache_filename) && is_readable($phpThumb->cache_filename)) {
665
+            chmod($phpThumb->cache_filename, 0644);
666
+            RedirectToCachedFile();
667
+        } else {
668
+            $phpThumb->DebugMessage('Failed: RenderToFile('.$phpThumb->cache_filename.')', __FILE__, __LINE__);
669
+        }
670 670
 
671
-	} else {
671
+    } else {
672 672
 
673
-		$phpThumb->DebugMessage('Cannot write to $phpThumb->cache_filename ('.$phpThumb->cache_filename.') because that directory ('.dirname($phpThumb->cache_filename).') is not writable', __FILE__, __LINE__);
673
+        $phpThumb->DebugMessage('Cannot write to $phpThumb->cache_filename ('.$phpThumb->cache_filename.') because that directory ('.dirname($phpThumb->cache_filename).') is not writable', __FILE__, __LINE__);
674 674
 
675
-	}
675
+    }
676 676
 
677 677
 }
678 678
 
@@ -680,18 +680,18 @@  discard block
 block discarded – undo
680 680
 // Debug output, to try and help me diagnose problems
681 681
 $phpThumb->DebugTimingMessage('phpThumbDebug[9]', __FILE__, __LINE__);
682 682
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '9')) {
683
-	$phpThumb->phpThumbDebug();
683
+    $phpThumb->phpThumbDebug();
684 684
 }
685 685
 ////////////////////////////////////////////////////////////////
686 686
 
687 687
 if (!$phpThumb->OutputThumbnail()) {
688
-	$phpThumb->ErrorImage('Error in OutputThumbnail():'."\n".$phpThumb->debugmessages[(count($phpThumb->debugmessages) - 1)]);
688
+    $phpThumb->ErrorImage('Error in OutputThumbnail():'."\n".$phpThumb->debugmessages[(count($phpThumb->debugmessages) - 1)]);
689 689
 }
690 690
 
691 691
 ////////////////////////////////////////////////////////////////
692 692
 // Debug output, to try and help me diagnose problems
693 693
 $phpThumb->DebugTimingMessage('phpThumbDebug[10]', __FILE__, __LINE__);
694 694
 if (isset($_GET['phpThumbDebug']) && ($_GET['phpThumbDebug'] == '10')) {
695
-	$phpThumb->phpThumbDebug();
695
+    $phpThumb->phpThumbDebug();
696 696
 }
697 697
 ////////////////////////////////////////////////////////////////
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -79,7 +79,7 @@  discard block
 block discarded – undo
79 79
 
80 80
 		header('Pragma: private');
81 81
 		header('Cache-Control: max-age='.$phpThumb->getParameter('config_cache_maxage'));
82
-		header('Expires: '.date(DATE_RFC1123,  time() + $phpThumb->getParameter('config_cache_maxage')));
82
+		header('Expires: '.date(DATE_RFC1123, time() + $phpThumb->getParameter('config_cache_maxage')));
83 83
 		if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) && ($nModified == strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) && !empty($_SERVER['SERVER_PROTOCOL'])) {
84 84
 			header('Last-Modified: '.gmdate('D, d M Y H:i:s', $nModified).' GMT');
85 85
 			header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
@@ -108,9 +108,9 @@  discard block
 block discarded – undo
108 108
 
109 109
 // instantiate a new phpThumb() object
110 110
 ob_start();
111
-if (!include_once( __DIR__ .'/phpthumb.class.php')) {
111
+if (!include_once(__DIR__.'/phpthumb.class.php')) {
112 112
 	ob_end_flush();
113
-	die('failed to include_once("'.realpath( __DIR__ .'/phpthumb.class.php').'")');
113
+	die('failed to include_once("'.realpath(__DIR__.'/phpthumb.class.php').'")');
114 114
 }
115 115
 ob_end_clean();
116 116
 $phpThumb = new phpThumb();
@@ -118,28 +118,28 @@  discard block
 block discarded – undo
118 118
 $phpThumb->setParameter('config_error_die_on_error', true);
119 119
 
120 120
 if (!phpthumb_functions::FunctionIsDisabled('set_time_limit')) {
121
-	set_time_limit(60);  // shouldn't take nearly this long in most cases, but with many filters and/or a slow server...
121
+	set_time_limit(60); // shouldn't take nearly this long in most cases, but with many filters and/or a slow server...
122 122
 }
123 123
 
124 124
 // phpThumbDebug[0] used to be here, but may reveal too much
125 125
 // info when high_security_mode should be enabled (not set yet)
126 126
 
127
-if (file_exists( __DIR__ .'/phpThumb.config.php')) {
127
+if (file_exists(__DIR__.'/phpThumb.config.php')) {
128 128
 	ob_start();
129
-	if (include_once( __DIR__ .'/phpThumb.config.php')) {
129
+	if (include_once(__DIR__.'/phpThumb.config.php')) {
130 130
 		// great
131 131
 	} else {
132 132
 		ob_end_flush();
133 133
 		$phpThumb->config_disable_debug = false; // otherwise error message won't print
134
-		$phpThumb->ErrorImage('failed to include_once('. __DIR__ .'/phpThumb.config.php) - realpath="'.realpath( __DIR__ .'/phpThumb.config.php').'"');
134
+		$phpThumb->ErrorImage('failed to include_once('.__DIR__.'/phpThumb.config.php) - realpath="'.realpath(__DIR__.'/phpThumb.config.php').'"');
135 135
 	}
136 136
 	ob_end_clean();
137
-} elseif (file_exists( __DIR__ .'/phpThumb.config.php.default')) {
137
+} elseif (file_exists(__DIR__.'/phpThumb.config.php.default')) {
138 138
 	$phpThumb->config_disable_debug = false; // otherwise error message won't print
139 139
 	$phpThumb->ErrorImage('Please rename "phpThumb.config.php.default" to "phpThumb.config.php"');
140 140
 } else {
141 141
 	$phpThumb->config_disable_debug = false; // otherwise error message won't print
142
-	$phpThumb->ErrorImage('failed to include_once('. __DIR__ .'/phpThumb.config.php) - realpath="'.realpath( __DIR__ .'/phpThumb.config.php').'"');
142
+	$phpThumb->ErrorImage('failed to include_once('.__DIR__.'/phpThumb.config.php) - realpath="'.realpath(__DIR__.'/phpThumb.config.php').'"');
143 143
 }
144 144
 
145 145
 if (!empty($PHPTHUMB_CONFIG)) {
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
 	}
153 153
 	if (!$phpThumb->config_disable_debug) {
154 154
 		// if debug mode is enabled, force phpThumbDebug output, do not allow normal thumbnails to be generated
155
-		$_GET['phpThumbDebug'] = (!empty($_GET['phpThumbDebug']) ? max(1, (int) $_GET[ 'phpThumbDebug']) : 9);
155
+		$_GET['phpThumbDebug'] = (!empty($_GET['phpThumbDebug']) ? max(1, (int)$_GET['phpThumbDebug']) : 9);
156 156
 		$phpThumb->setParameter('phpThumbDebug', $_GET['phpThumbDebug']);
157 157
 	}
158 158
 } else {
@@ -371,7 +371,7 @@  discard block
 block discarded – undo
371 371
 }
372 372
 ////////////////////////////////////////////////////////////////
373 373
 
374
-$PHPTHUMB_DEFAULTS_DISABLEGETPARAMS = (bool) ($phpThumb->config_cache_default_only_suffix && (strpos($phpThumb->config_cache_default_only_suffix, '*') !== false));
374
+$PHPTHUMB_DEFAULTS_DISABLEGETPARAMS = (bool)($phpThumb->config_cache_default_only_suffix && (strpos($phpThumb->config_cache_default_only_suffix, '*') !== false));
375 375
 
376 376
 // deprecated: 'err', 'file', 'goto',
377 377
 $allowedGETparameters = array('src', 'new', 'w', 'h', 'wp', 'hp', 'wl', 'hl', 'ws', 'hs', 'f', 'q', 'sx', 'sy', 'sw', 'sh', 'zc', 'bc', 'bg', 'bgt', 'fltr', 'xto', 'ra', 'ar', 'aoe', 'far', 'iar', 'maxb', 'down', 'phpThumbDebug', 'hash', 'md5s', 'sfn', 'dpi', 'sia', 'nocache');
@@ -474,7 +474,7 @@  discard block
 block discarded – undo
474 474
 }
475 475
 ////////////////////////////////////////////////////////////////
476 476
 
477
-$phpThumb->DebugMessage('$CanPassThroughDirectly="'. (int) $CanPassThroughDirectly .'" && $phpThumb->src="'.$phpThumb->src.'"', __FILE__, __LINE__);
477
+$phpThumb->DebugMessage('$CanPassThroughDirectly="'.(int)$CanPassThroughDirectly.'" && $phpThumb->src="'.$phpThumb->src.'"', __FILE__, __LINE__);
478 478
 while ($CanPassThroughDirectly && $phpThumb->src) {
479 479
 	// no parameters set, passthru
480 480
 
Please login to merge, or discard this patch.
htdocs/modules/system/class/thumbs/phpthumb.functions.php 2 patches
Indentation   +1027 added lines, -1027 removed lines patch added patch discarded remove patch
@@ -11,911 +11,911 @@  discard block
 block discarded – undo
11 11
 
12 12
 class phpthumb_functions {
13 13
 
14
-	public static function user_function_exists($functionname) {
15
-		if (function_exists('get_defined_functions')) {
16
-			static $get_defined_functions = array();
17
-			if (empty($get_defined_functions)) {
18
-				$get_defined_functions = get_defined_functions();
19
-			}
20
-			return in_array(strtolower($functionname), $get_defined_functions['user']);
21
-		}
22
-		return function_exists($functionname);
23
-	}
24
-
25
-
26
-	public static function builtin_function_exists($functionname) {
27
-		if (function_exists('get_defined_functions')) {
28
-			static $get_defined_functions = array();
29
-			if (empty($get_defined_functions)) {
30
-				$get_defined_functions = get_defined_functions();
31
-			}
32
-			return in_array(strtolower($functionname), $get_defined_functions['internal']);
33
-		}
34
-		return function_exists($functionname);
35
-	}
36
-
37
-
38
-	public static function version_compare_replacement_sub($version1, $version2, $operator='') {
39
-		// If you specify the third optional operator argument, you can test for a particular relationship.
40
-		// The possible operators are: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne respectively.
41
-		// Using this argument, the function will return 1 if the relationship is the one specified by the operator, 0 otherwise.
42
-
43
-		// If a part contains special version strings these are handled in the following order:
44
-		// (any string not found in this list) < (dev) < (alpha = a) < (beta = b) < (RC = rc) < (#) < (pl = p)
45
-		static $versiontype_lookup = array();
46
-		if (empty($versiontype_lookup)) {
47
-			$versiontype_lookup['dev']   = 10001;
48
-			$versiontype_lookup['a']     = 10002;
49
-			$versiontype_lookup['alpha'] = 10002;
50
-			$versiontype_lookup['b']     = 10003;
51
-			$versiontype_lookup['beta']  = 10003;
52
-			$versiontype_lookup['RC']    = 10004;
53
-			$versiontype_lookup['rc']    = 10004;
54
-			$versiontype_lookup['#']     = 10005;
55
-			$versiontype_lookup['pl']    = 10006;
56
-			$versiontype_lookup['p']     = 10006;
57
-		}
58
-		$version1 = (isset($versiontype_lookup[$version1]) ? $versiontype_lookup[$version1] : $version1);
59
-		$version2 = (isset($versiontype_lookup[$version2]) ? $versiontype_lookup[$version2] : $version2);
60
-
61
-		switch ($operator) {
62
-			case '<':
63
-			case 'lt':
64
-				return (int) ($version1 < $version2);
65
-				break;
66
-			case '<=':
67
-			case 'le':
68
-				return (int) ($version1 <= $version2);
69
-				break;
70
-			case '>':
71
-			case 'gt':
72
-				return (int) ($version1 > $version2);
73
-				break;
74
-			case '>=':
75
-			case 'ge':
76
-				return (int) ($version1 >= $version2);
77
-				break;
78
-			case '==':
79
-			case '=':
80
-			case 'eq':
81
-				return (int) ($version1 == $version2);
82
-				break;
83
-			case '!=':
84
-			case '<>':
85
-			case 'ne':
86
-				return (int) ($version1 != $version2);
87
-				break;
88
-		}
89
-		if ($version1 == $version2) {
90
-			return 0;
91
-		} elseif ($version1 < $version2) {
92
-			return -1;
93
-		}
94
-		return 1;
95
-	}
96
-
97
-
98
-	public static function version_compare_replacement($version1, $version2, $operator='') {
99
-		if (function_exists('version_compare')) {
100
-			// built into PHP v4.1.0+
101
-			return version_compare($version1, $version2, $operator);
102
-		}
103
-
104
-		// The function first replaces _, - and + with a dot . in the version strings
105
-		$version1 = strtr($version1, '_-+', '...');
106
-		$version2 = strtr($version2, '_-+', '...');
107
-
108
-		// and also inserts dots . before and after any non number so that for example '4.3.2RC1' becomes '4.3.2.RC.1'.
109
-		// Then it splits the results like if you were using explode('.',$ver). Then it compares the parts starting from left to right.
110
-		$version1 = preg_replace('#([0-9]+)([A-Z]+)([0-9]+)#i', "$1.$2.$3", $version1);
111
-		$version2 = preg_replace('#([0-9]+)([A-Z]+)([0-9]+)#i', "$1.$2.$3", $version2);
112
-
113
-		$parts1 = explode('.', $version1);
114
-		$parts2 = explode('.', $version1);
115
-		$parts_count = max(count($parts1), count($parts2));
116
-		for ($i = 0; $i < $parts_count; $i++) {
117
-			$comparison = self::version_compare_replacement_sub($version1, $version2, $operator);
118
-			if ($comparison != 0) {
119
-				return $comparison;
120
-			}
121
-		}
122
-		return 0;
123
-	}
124
-
125
-	public static function escapeshellarg_replacement($arg) {
126
-		if (function_exists('escapeshellarg') && !self::FunctionIsDisabled('escapeshellarg')) {
127
-			return escapeshellarg($arg);
128
-		}
129
-		return '\''.str_replace('\'', '\\\'', $arg).'\'';
130
-	}
131
-
132
-	public static function phpinfo_array() {
133
-		static $phpinfo_array = array();
134
-		if (empty($phpinfo_array)) {
135
-			ob_start();
136
-			phpinfo();
137
-			$phpinfo = ob_get_contents();
138
-			ob_end_clean();
139
-			$phpinfo_array = explode("\n", $phpinfo);
140
-		}
141
-		return $phpinfo_array;
142
-	}
143
-
144
-
145
-	public static function exif_info() {
146
-		static $exif_info = array();
147
-		if (empty($exif_info)) {
148
-			// based on code by johnschaefer at gmx dot de
149
-			// from PHP help on gd_info()
150
-			$exif_info = array(
151
-				'EXIF Support'           => '',
152
-				'EXIF Version'           => '',
153
-				'Supported EXIF Version' => '',
154
-				'Supported filetypes'    => ''
155
-			);
156
-			$phpinfo_array = self::phpinfo_array();
157
-			foreach ($phpinfo_array as $line) {
158
-				$line = trim(strip_tags($line));
159
-				foreach ($exif_info as $key => $value) {
160
-					if (strpos($line, $key) === 0) {
161
-						$newvalue = trim(str_replace($key, '', $line));
162
-						$exif_info[$key] = $newvalue;
163
-					}
164
-				}
165
-			}
166
-		}
167
-		return $exif_info;
168
-	}
169
-
170
-
171
-	public static function ImageTypeToMIMEtype($imagetype) {
172
-		if (function_exists('image_type_to_mime_type') && ($imagetype >= 1) && ($imagetype <= 16)) {
173
-			// PHP v4.3.0+
174
-			return image_type_to_mime_type($imagetype);
175
-		}
176
-		static $image_type_to_mime_type = array(
177
-			1  => 'image/gif',                     // IMAGETYPE_GIF
178
-			2  => 'image/jpeg',                    // IMAGETYPE_JPEG
179
-			3  => 'image/png',                     // IMAGETYPE_PNG
180
-			4  => 'application/x-shockwave-flash', // IMAGETYPE_SWF
181
-			5  => 'image/psd',                     // IMAGETYPE_PSD
182
-			6  => 'image/bmp',                     // IMAGETYPE_BMP
183
-			7  => 'image/tiff',                    // IMAGETYPE_TIFF_II (intel byte order)
184
-			8  => 'image/tiff',                    // IMAGETYPE_TIFF_MM (motorola byte order)
185
-			9  => 'application/octet-stream',      // IMAGETYPE_JPC
186
-			10 => 'image/jp2',                     // IMAGETYPE_JP2
187
-			11 => 'application/octet-stream',      // IMAGETYPE_JPX
188
-			12 => 'application/octet-stream',      // IMAGETYPE_JB2
189
-			13 => 'application/x-shockwave-flash', // IMAGETYPE_SWC
190
-			14 => 'image/iff',                     // IMAGETYPE_IFF
191
-			15 => 'image/vnd.wap.wbmp',            // IMAGETYPE_WBMP
192
-			16 => 'image/xbm',                     // IMAGETYPE_XBM
193
-
194
-			'gif'  => 'image/gif',                 // IMAGETYPE_GIF
195
-			'jpg'  => 'image/jpeg',                // IMAGETYPE_JPEG
196
-			'jpeg' => 'image/jpeg',                // IMAGETYPE_JPEG
197
-			'png'  => 'image/png',                 // IMAGETYPE_PNG
198
-			'bmp'  => 'image/bmp',                 // IMAGETYPE_BMP
199
-			'ico'  => 'image/x-icon',
200
-		);
201
-
202
-		return (isset($image_type_to_mime_type[$imagetype]) ? $image_type_to_mime_type[$imagetype] : false);
203
-	}
204
-
205
-
206
-	public static function TranslateWHbyAngle($width, $height, $angle) {
207
-		if (($angle % 180) == 0) {
208
-			return array($width, $height);
209
-		}
210
-		$newwidth  = (abs(sin(deg2rad($angle))) * $height) + (abs(cos(deg2rad($angle))) * $width);
211
-		$newheight = (abs(sin(deg2rad($angle))) * $width)  + (abs(cos(deg2rad($angle))) * $height);
212
-		return array($newwidth, $newheight);
213
-	}
214
-
215
-	public static function HexCharDisplay($string) {
216
-		$len = strlen($string);
217
-		$output = '';
218
-		for ($i = 0; $i < $len; $i++) {
219
-			$output .= ' 0x'.str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT);
220
-		}
221
-		return $output;
222
-	}
223
-
224
-
225
-	public static function IsHexColor($HexColorString) {
226
-		return preg_match('#^[0-9A-F]{6}$#i', $HexColorString);
227
-	}
228
-
229
-
230
-	public static function ImageColorAllocateAlphaSafe(&$gdimg_hexcolorallocate, $R, $G, $B, $alpha=false) {
231
-		if (self::version_compare_replacement(PHP_VERSION, '4.3.2', '>=') && ($alpha !== false)) {
232
-			return imagecolorallocatealpha($gdimg_hexcolorallocate, $R, $G, $B, (int) $alpha);
233
-		} else {
234
-			return imagecolorallocate($gdimg_hexcolorallocate, $R, $G, $B);
235
-		}
236
-	}
237
-
238
-	public static function ImageHexColorAllocate(&$gdimg_hexcolorallocate, $HexColorString, $dieOnInvalid=false, $alpha=false) {
239
-		if (!is_resource($gdimg_hexcolorallocate)) {
240
-			die('$gdimg_hexcolorallocate is not a GD resource in ImageHexColorAllocate()');
241
-		}
242
-		if (self::IsHexColor($HexColorString)) {
243
-			$R = hexdec(substr($HexColorString, 0, 2));
244
-			$G = hexdec(substr($HexColorString, 2, 2));
245
-			$B = hexdec(substr($HexColorString, 4, 2));
246
-			return self::ImageColorAllocateAlphaSafe($gdimg_hexcolorallocate, $R, $G, $B, $alpha);
247
-		}
248
-		if ($dieOnInvalid) {
249
-			die('Invalid hex color string: "'.$HexColorString.'"');
250
-		}
251
-		return imagecolorallocate($gdimg_hexcolorallocate, 0x00, 0x00, 0x00);
252
-	}
253
-
254
-
255
-	public static function HexColorXOR($hexcolor) {
256
-		return strtoupper(str_pad(dechex(~hexdec($hexcolor) & 0xFFFFFF), 6, '0', STR_PAD_LEFT));
257
-	}
258
-
259
-
260
-	public static function GetPixelColor(&$img, $x, $y) {
261
-		if (!is_resource($img)) {
262
-			return false;
263
-		}
264
-		return @imagecolorsforindex($img, @imagecolorat($img, $x, $y));
265
-	}
266
-
267
-
268
-	public static function PixelColorDifferencePercent($currentPixel, $targetPixel) {
269
-		$diff = 0;
270
-		foreach ($targetPixel as $channel => $currentvalue) {
271
-			$diff = max($diff, (max($currentPixel[$channel], $targetPixel[$channel]) - min($currentPixel[$channel], $targetPixel[$channel])) / 255);
272
-		}
273
-		return $diff * 100;
274
-	}
275
-
276
-	public static function GrayscaleValue($r, $g, $b) {
277
-		return round(($r * 0.30) + ($g * 0.59) + ($b * 0.11));
278
-	}
279
-
280
-
281
-	public static function GrayscalePixel($OriginalPixel) {
282
-		$gray = self::GrayscaleValue($OriginalPixel[ 'red'], $OriginalPixel[ 'green'], $OriginalPixel[ 'blue']);
283
-		return array('red'=>$gray, 'green'=>$gray, 'blue'=>$gray);
284
-	}
285
-
286
-
287
-	public static function GrayscalePixelRGB($rgb) {
288
-		$r = ($rgb >> 16) & 0xFF;
289
-		$g = ($rgb >>  8) & 0xFF;
290
-		$b =  $rgb        & 0xFF;
291
-		return ($r * 0.299) + ($g * 0.587) + ($b * 0.114);
292
-	}
293
-
294
-
295
-	public static function ScaleToFitInBox($width, $height, $maxwidth=null, $maxheight=null, $allow_enlarge=true, $allow_reduce=true) {
296
-		$maxwidth  = (null === $maxwidth  ? $width  : $maxwidth);
297
-		$maxheight = (null === $maxheight ? $height : $maxheight);
298
-		$scale_x = 1;
299
-		$scale_y = 1;
300
-		if (($width > $maxwidth) || ($width < $maxwidth)) {
301
-			$scale_x = ($maxwidth / $width);
302
-		}
303
-		if (($height > $maxheight) || ($height < $maxheight)) {
304
-			$scale_y = ($maxheight / $height);
305
-		}
306
-		$scale = min($scale_x, $scale_y);
307
-		if (!$allow_enlarge) {
308
-			$scale = min($scale, 1);
309
-		}
310
-		if (!$allow_reduce) {
311
-			$scale = max($scale, 1);
312
-		}
313
-		return $scale;
314
-	}
315
-
316
-	public static function ImageCopyResampleBicubic($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
317
-		// ron at korving dot demon dot nl
318
-		// http://www.php.net/imagecopyresampled
319
-
320
-		$scaleX = ($src_w - 1) / $dst_w;
321
-		$scaleY = ($src_h - 1) / $dst_h;
322
-
323
-		$scaleX2 = $scaleX / 2.0;
324
-		$scaleY2 = $scaleY / 2.0;
325
-
326
-		$isTrueColor = imageistruecolor($src_img);
327
-
328
-		for ($y = $src_y; $y < $src_y + $dst_h; $y++) {
329
-			$sY   = $y * $scaleY;
330
-			$siY  = (int) $sY;
331
-			$siY2 = (int) $sY + $scaleY2;
332
-
333
-			for ($x = $src_x; $x < $src_x + $dst_w; $x++) {
334
-				$sX   = $x * $scaleX;
335
-				$siX  = (int) $sX;
336
-				$siX2 = (int) $sX + $scaleX2;
337
-
338
-				if ($isTrueColor) {
339
-
340
-					$c1 = imagecolorat($src_img, $siX, $siY2);
341
-					$c2 = imagecolorat($src_img, $siX, $siY);
342
-					$c3 = imagecolorat($src_img, $siX2, $siY2);
343
-					$c4 = imagecolorat($src_img, $siX2, $siY);
344
-
345
-					$r = (( $c1             +  $c2             +  $c3             +  $c4            ) >> 2) & 0xFF0000;
346
-					$g = ((($c1 & 0x00FF00) + ($c2 & 0x00FF00) + ($c3 & 0x00FF00) + ($c4 & 0x00FF00)) >> 2) & 0x00FF00;
347
-					$b = ((($c1 & 0x0000FF) + ($c2 & 0x0000FF) + ($c3 & 0x0000FF) + ($c4 & 0x0000FF)) >> 2);
348
-
349
-				} else {
350
-
351
-					$c1 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX, $siY2));
352
-					$c2 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX, $siY));
353
-					$c3 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY2));
354
-					$c4 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY));
355
-
356
-					$r = ($c1['red']   + $c2['red']   + $c3['red']   + $c4['red'] )  << 14;
357
-					$g = ($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) <<  6;
358
-					$b = ($c1['blue']  + $c2['blue']  + $c3['blue']  + $c4['blue'] ) >>  2;
359
-
360
-				}
361
-				imagesetpixel($dst_img, $dst_x + $x - $src_x, $dst_y + $y - $src_y, $r+$g+$b);
362
-			}
363
-		}
364
-		return true;
365
-	}
366
-
367
-
368
-	public static function ImageCreateFunction($x_size, $y_size) {
369
-		$ImageCreateFunction = 'imagecreate';
370
-		if (self::gd_version() >= 2.0) {
371
-			$ImageCreateFunction = 'imagecreatetruecolor';
372
-		}
373
-		if (!function_exists($ImageCreateFunction)) {
374
-			return phpthumb::ErrorImage($ImageCreateFunction.'() does not exist - no GD support?');
375
-		}
376
-		if (($x_size <= 0) || ($y_size <= 0)) {
377
-			return phpthumb::ErrorImage('Invalid image dimensions: '.$ImageCreateFunction.'('.$x_size.', '.$y_size.')');
378
-		}
379
-		return $ImageCreateFunction(round($x_size), round($y_size));
380
-	}
381
-
382
-
383
-	public static function ImageCopyRespectAlpha(&$dst_im, &$src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $opacity_pct=100) {
384
-		$opacipct = $opacity_pct / 100;
385
-		for ($x = $src_x; $x < $src_w; $x++) {
386
-			for ($y = $src_y; $y < $src_h; $y++) {
387
-				$RealPixel    = self::GetPixelColor($dst_im, $dst_x + $x, $dst_y + $y);
388
-				$OverlayPixel = self::GetPixelColor($src_im, $x, $y);
389
-				$alphapct = $OverlayPixel['alpha'] / 127;
390
-				$overlaypct = (1 - $alphapct) * $opacipct;
391
-
392
-				$newcolor = self::ImageColorAllocateAlphaSafe(
393
-					$dst_im,
394
-					round($RealPixel['red']   * (1 - $overlaypct)) + ($OverlayPixel['red']   * $overlaypct),
395
-					round($RealPixel['green'] * (1 - $overlaypct)) + ($OverlayPixel['green'] * $overlaypct),
396
-					round($RealPixel['blue']  * (1 - $overlaypct)) + ($OverlayPixel['blue']  * $overlaypct),
397
-					//$RealPixel['alpha']);
398
-					0);
399
-
400
-				imagesetpixel($dst_im, $dst_x + $x, $dst_y + $y, $newcolor);
401
-			}
402
-		}
403
-		return true;
404
-	}
405
-
406
-
407
-	public static function ProportionalResize($old_width, $old_height, $new_width=false, $new_height=false) {
408
-		$old_aspect_ratio = $old_width / $old_height;
409
-		if (($new_width === false) && ($new_height === false)) {
410
-			return false;
411
-		} elseif ($new_width === false) {
412
-			$new_width = $new_height * $old_aspect_ratio;
413
-		} elseif ($new_height === false) {
414
-			$new_height = $new_width / $old_aspect_ratio;
415
-		}
416
-		$new_aspect_ratio = $new_width / $new_height;
417
-		if ($new_aspect_ratio == $old_aspect_ratio) {
418
-			// great, done
419
-		} elseif ($new_aspect_ratio < $old_aspect_ratio) {
420
-			// limited by width
421
-			$new_height = $new_width / $old_aspect_ratio;
422
-		} elseif ($new_aspect_ratio > $old_aspect_ratio) {
423
-			// limited by height
424
-			$new_width = $new_height * $old_aspect_ratio;
425
-		}
426
-		return array(
427
-			(int) round($new_width),
428
-			(int) round($new_height)
429
-		);
430
-	}
431
-
432
-
433
-	public static function FunctionIsDisabled($function) {
434
-		static $DisabledFunctions = null;
435
-		if (null === $DisabledFunctions) {
436
-			$disable_functions_local  = explode(',',     strtolower(@ini_get('disable_functions')));
437
-			$disable_functions_global = explode(',', strtolower(@get_cfg_var('disable_functions')));
438
-			foreach ($disable_functions_local as $key => $value) {
439
-				$DisabledFunctions[trim($value)] = 'local';
440
-			}
441
-			foreach ($disable_functions_global as $key => $value) {
442
-				$DisabledFunctions[trim($value)] = 'global';
443
-			}
444
-			if (@ini_get('safe_mode')) {
445
-				$DisabledFunctions['shell_exec']     = 'local';
446
-				$DisabledFunctions['set_time_limit'] = 'local';
447
-			}
448
-		}
449
-		return isset($DisabledFunctions[strtolower($function)]);
450
-	}
451
-
452
-
453
-	public static function SafeExec($command) {
454
-		static $AllowedExecFunctions = array();
455
-		if (empty($AllowedExecFunctions)) {
456
-			$AllowedExecFunctions = array('shell_exec'=>true, 'passthru'=>true, 'system'=>true, 'exec'=>true);
457
-			foreach ($AllowedExecFunctions as $key => $value) {
458
-				$AllowedExecFunctions[$key] = !self::FunctionIsDisabled($key);
459
-			}
460
-		}
461
-		$command .= ' 2>&1'; // force redirect stderr to stdout
462
-		foreach ($AllowedExecFunctions as $execfunction => $is_allowed) {
463
-			if (!$is_allowed) {
464
-				continue;
465
-			}
466
-			$returnvalue = false;
467
-			switch ($execfunction) {
468
-				case 'passthru':
469
-				case 'system':
470
-					ob_start();
471
-					$execfunction($command);
472
-					$returnvalue = ob_get_contents();
473
-					ob_end_clean();
474
-					break;
475
-
476
-				case 'exec':
477
-					$output = array();
478
-					$lastline = $execfunction($command, $output);
479
-					$returnvalue = implode("\n", $output);
480
-					break;
481
-
482
-				case 'shell_exec':
483
-					ob_start();
484
-					$returnvalue = $execfunction($command);
485
-					ob_end_clean();
486
-					break;
487
-			}
488
-			return $returnvalue;
489
-		}
490
-		return false;
491
-	}
492
-
493
-
494
-	public static function ApacheLookupURIarray($filename) {
495
-		// apache_lookup_uri() only works when PHP is installed as an Apache module.
496
-		if (PHP_SAPI == 'apache') {
497
-			//$property_exists_exists = function_exists('property_exists');
498
-			$keys = array('status', 'the_request', 'status_line', 'method', 'content_type', 'handler', 'uri', 'filename', 'path_info', 'args', 'boundary', 'no_cache', 'no_local_copy', 'allowed', 'send_bodyct', 'bytes_sent', 'byterange', 'clength', 'unparsed_uri', 'mtime', 'request_time');
499
-			if ($apacheLookupURIobject = @apache_lookup_uri($filename)) {
500
-				$apacheLookupURIarray = array();
501
-				foreach ($keys as $key) {
502
-					$apacheLookupURIarray[$key] = @$apacheLookupURIobject->$key;
503
-				}
504
-				return $apacheLookupURIarray;
505
-			}
506
-		}
507
-		return false;
508
-	}
509
-
510
-
511
-	public static function gd_is_bundled() {
512
-		static $isbundled = null;
513
-		if (null === $isbundled) {
514
-			$gd_info = gd_info();
515
-			$isbundled = (strpos($gd_info['GD Version'], 'bundled') !== false);
516
-		}
517
-		return $isbundled;
518
-	}
519
-
520
-
521
-	public static function gd_version($fullstring=false) {
522
-		static $cache_gd_version = array();
523
-		if (empty($cache_gd_version)) {
524
-			$gd_info = gd_info();
525
-			if (preg_match('#bundled \((.+)\)$#i', $gd_info['GD Version'], $matches)) {
526
-				$cache_gd_version[1] = $gd_info['GD Version'];  // e.g. "bundled (2.0.15 compatible)"
527
-				$cache_gd_version[0] = (float) $matches[1];     // e.g. "2.0" (not "bundled (2.0.15 compatible)")
528
-			} else {
529
-				$cache_gd_version[1] = $gd_info['GD Version'];                       // e.g. "1.6.2 or higher"
530
-				$cache_gd_version[0] = (float) substr($gd_info['GD Version'], 0, 3); // e.g. "1.6" (not "1.6.2 or higher")
531
-			}
532
-		}
533
-		return $cache_gd_version[ (int) $fullstring ];
534
-	}
535
-
536
-
537
-	public static function filesize_remote($remotefile, $timeout=10) {
538
-		$size = false;
539
-		$url = self::ParseURLbetter($remotefile);
540
-		if ($fp = @fsockopen($url['host'], ($url['port'] ? $url['port'] : 80), $errno, $errstr, $timeout)) {
541
-			fwrite($fp, 'HEAD '.@$url['path'].@$url['query'].' HTTP/1.0'."\r\n".'Host: '.@$url['host']."\r\n\r\n");
542
-			if (self::version_compare_replacement(PHP_VERSION, '4.3.0', '>=')) {
543
-				stream_set_timeout($fp, $timeout);
544
-			}
545
-			while (!feof($fp)) {
546
-				$headerline = fgets($fp, 4096);
547
-				if (preg_match('#^Content-Length: (.*)#i', $headerline, $matches)) {
548
-					$size = (int) $matches[ 1];
549
-					break;
550
-				}
551
-			}
552
-			fclose ($fp);
553
-		}
554
-		return $size;
555
-	}
556
-
557
-
558
-	public static function filedate_remote($remotefile, $timeout=10) {
559
-		$date = false;
560
-		$url = self::ParseURLbetter($remotefile);
561
-		if ($fp = @fsockopen($url['host'], ($url['port'] ? $url['port'] : 80), $errno, $errstr, $timeout)) {
562
-			fwrite($fp, 'HEAD '.@$url['path'].@$url['query'].' HTTP/1.0'."\r\n".'Host: '.@$url['host']."\r\n\r\n");
563
-			if (self::version_compare_replacement(PHP_VERSION, '4.3.0', '>=')) {
564
-				stream_set_timeout($fp, $timeout);
565
-			}
566
-			while (!feof($fp)) {
567
-				$headerline = fgets($fp, 4096);
568
-				if (preg_match('#^Last-Modified: (.*)#i', $headerline, $matches)) {
569
-					$date = strtotime($matches[1]) - date('Z');
570
-					break;
571
-				}
572
-			}
573
-			fclose ($fp);
574
-		}
575
-		return $date;
576
-	}
577
-
578
-
579
-	public static function md5_file_safe($filename) {
580
-		// md5_file() doesn't exist in PHP < 4.2.0
581
-		if (function_exists('md5_file')) {
582
-			return md5_file($filename);
583
-		}
584
-		if ($fp = @fopen($filename, 'rb')) {
585
-			$rawData = '';
586
-			do {
587
-				$buffer = fread($fp, 8192);
588
-				$rawData .= $buffer;
589
-			} while (strlen($buffer) > 0);
590
-			fclose($fp);
591
-			return md5($rawData);
592
-		}
593
-		return false;
594
-	}
595
-
596
-
597
-	public static function nonempty_min() {
598
-		$arg_list = func_get_args();
599
-		$acceptable = array();
600
-		foreach ($arg_list as $arg) {
601
-			if ($arg) {
602
-				$acceptable[] = $arg;
603
-			}
604
-		}
605
-		return min($acceptable);
606
-	}
607
-
608
-
609
-	public static function LittleEndian2String($number, $minbytes=1) {
610
-		$intstring = '';
611
-		while ($number > 0) {
612
-			$intstring .= chr($number & 255);
613
-			$number    >>= 8;
614
-		}
615
-		return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
616
-	}
617
-
618
-	public static function OneOfThese() {
619
-		// return the first useful (non-empty/non-zero/non-false) value from those passed
620
-		$arg_list = func_get_args();
621
-		foreach ($arg_list as $key => $value) {
622
-			if ($value) {
623
-				return $value;
624
-			}
625
-		}
626
-		return false;
627
-	}
628
-
629
-	public static function CaseInsensitiveInArray($needle, $haystack) {
630
-		$needle = strtolower($needle);
631
-		foreach ($haystack as $key => $value) {
632
-			if (is_array($value)) {
633
-				// skip?
634
-			} elseif ($needle == strtolower($value)) {
635
-				return true;
636
-			}
637
-		}
638
-		return false;
639
-	}
640
-
641
-	public static function URLreadFsock($host, $file, &$errstr, $successonly=true, $port=80, $timeout=10) {
642
-		if (!function_exists('fsockopen') || self::FunctionIsDisabled('fsockopen')) {
643
-			$errstr = 'fsockopen() unavailable';
644
-			return false;
645
-		}
646
-		//if ($fp = @fsockopen($host, $port, $errno, $errstr, $timeout)) {
647
-		if ($fp = @fsockopen((($port == 443) ? 'ssl://' : '').$host, $port, $errno, $errstr, $timeout)) { // https://github.com/JamesHeinrich/phpThumb/issues/39
648
-			$out  = 'GET '.$file.' HTTP/1.0'."\r\n";
649
-			$out .= 'Host: '.$host."\r\n";
650
-			$out .= 'Connection: Close'."\r\n\r\n";
651
-			fwrite($fp, $out);
652
-
653
-			$isHeader = true;
654
-			$Data_header = '';
655
-			$Data_body   = '';
656
-			$header_newlocation = '';
657
-			while (!feof($fp)) {
658
-				$line = fgets($fp, 1024);
659
-				if ($isHeader) {
660
-					$Data_header .= $line;
661
-				} else {
662
-					$Data_body .= $line;
663
-				}
664
-				if (preg_match('#^HTTP/[\\.0-9]+ ([0-9]+) (.+)$#i', rtrim($line), $matches)) {
665
-					list( , $errno, $errstr) = $matches;
666
-					$errno = (int) $errno;
667
-				} elseif (preg_match('#^Location: (.*)$#i', rtrim($line), $matches)) {
668
-					$header_newlocation = $matches[1];
669
-				}
670
-				if ($isHeader && ($line == "\r\n")) {
671
-					$isHeader = false;
672
-					if ($successonly) {
673
-						switch ($errno) {
674
-							case 200:
675
-								// great, continue
676
-								break;
677
-
678
-							default:
679
-								$errstr = $errno.' '.$errstr.($header_newlocation ? '; Location: '.$header_newlocation : '');
680
-								fclose($fp);
681
-								return false;
682
-								break;
683
-						}
684
-					}
685
-				}
686
-			}
687
-			fclose($fp);
688
-			return $Data_body;
689
-		}
690
-		return null;
691
-	}
692
-
693
-	public static function CleanUpURLencoding($url, $queryseperator='&') {
694
-		if (!preg_match('#^http#i', $url)) {
695
-			return $url;
696
-		}
697
-		$parse_url = self::ParseURLbetter($url);
698
-		$pathelements = explode('/', $parse_url['path']);
699
-		$CleanPathElements = array();
700
-		$TranslationMatrix = array(' '=>'%20');
701
-		foreach ($pathelements as $key => $pathelement) {
702
-			$CleanPathElements[] = strtr($pathelement, $TranslationMatrix);
703
-		}
704
-		foreach ($CleanPathElements as $key => $value) {
705
-			if ($value === '') {
706
-				unset($CleanPathElements[$key]);
707
-			}
708
-		}
709
-
710
-		$queries = explode($queryseperator, (isset($parse_url['query']) ? $parse_url['query'] : ''));
711
-		$CleanQueries = array();
712
-		foreach ($queries as $key => $query) {
713
-			@list($param, $value) = explode('=', $query);
714
-			$CleanQueries[] = strtr($param, $TranslationMatrix).($value ? '='.strtr($value, $TranslationMatrix) : '');
715
-		}
716
-		foreach ($CleanQueries as $key => $value) {
717
-			if ($value === '') {
718
-				unset($CleanQueries[$key]);
719
-			}
720
-		}
721
-
722
-		$cleaned_url  = $parse_url['scheme'].'://';
723
-		$cleaned_url .= (@$parse_url['username'] ? $parse_url['host'].(@$parse_url['password'] ? ':'.$parse_url['password'] : '').'@' : '');
724
-		$cleaned_url .= $parse_url['host'];
725
-		$cleaned_url .= ((!empty($parse_url['port']) && ($parse_url['port'] != 80)) ? ':'.$parse_url['port'] : '');
726
-		$cleaned_url .= '/'.implode('/', $CleanPathElements);
727
-		$cleaned_url .= (@$CleanQueries ? '?'.implode($queryseperator, $CleanQueries) : '');
728
-		return $cleaned_url;
729
-	}
730
-
731
-	public static function ParseURLbetter($url) {
732
-		$parsedURL = @parse_url($url);
733
-		if (!@$parsedURL['port']) {
734
-			switch (strtolower(@$parsedURL['scheme'])) {
735
-				case 'ftp':
736
-					$parsedURL['port'] = 21;
737
-					break;
738
-				case 'https':
739
-					$parsedURL['port'] = 443;
740
-					break;
741
-				case 'http':
742
-					$parsedURL['port'] = 80;
743
-					break;
744
-			}
745
-		}
746
-		return $parsedURL;
747
-	}
748
-
749
-	public static function SafeURLread($url, &$error, $timeout=10, $followredirects=true) {
750
-		$error   = '';
751
-		$errstr  = '';
752
-		$rawData = '';
753
-
754
-		$parsed_url = self::ParseURLbetter($url);
755
-		$alreadyLookedAtURLs[trim($url)] = true;
756
-
757
-		while (true) {
758
-			$tryagain = false;
759
-			$rawData = self::URLreadFsock(@$parsed_url[ 'host'], @$parsed_url[ 'path'].'?'.@$parsed_url[ 'query'], $errstr, true, (@$parsed_url[ 'port'] ? @$parsed_url[ 'port'] : 80), $timeout);
760
-			if ($followredirects && preg_match('#302 [a-z ]+; Location\\: (http.*)#i', $errstr, $matches)) {
761
-				$matches[1] = trim(@$matches[1]);
762
-				if (!@$alreadyLookedAtURLs[$matches[1]]) {
763
-					// loop through and examine new URL
764
-					$error .= 'URL "'.$url.'" redirected to "'.$matches[1].'"';
765
-
766
-					$tryagain = true;
767
-					$alreadyLookedAtURLs[$matches[1]] = true;
768
-					$parsed_url = self::ParseURLbetter($matches[ 1]);
769
-				}
770
-			}
771
-			if (!$tryagain) {
772
-				break;
773
-			}
774
-		}
775
-
776
-		if ($rawData === false) {
777
-			$error .= 'Error opening "'.$url.'":'."\n\n".$errstr;
778
-			return false;
779
-		} elseif ($rawData === null) {
780
-			// fall through
781
-			$error .= 'Error opening "'.$url.'":'."\n\n".$errstr;
782
-		} else {
783
-			return $rawData;
784
-		}
785
-
786
-		if (function_exists('curl_version') && !self::FunctionIsDisabled('curl_exec')) {
787
-			$ch = curl_init();
788
-			curl_setopt($ch, CURLOPT_URL, $url);
789
-			curl_setopt($ch, CURLOPT_HEADER, false);
790
-			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
791
-			curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
792
-			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
793
-			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
794
-			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, (bool) $followredirects);
795
-			curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
796
-			$rawData = curl_exec($ch);
797
-			curl_close($ch);
798
-			if (strlen($rawData) > 0) {
799
-				$error .= 'CURL succeeded ('.strlen($rawData).' bytes); ';
800
-				return $rawData;
801
-			}
802
-			$error .= 'CURL available but returned no data; ';
803
-		} else {
804
-			$error .= 'CURL unavailable; ';
805
-		}
806
-
807
-		$BrokenURLfopenPHPversions = array('4.4.2');
808
-		if (in_array(PHP_VERSION, $BrokenURLfopenPHPversions)) {
809
-			$error .= 'fopen(URL) broken in PHP v'. PHP_VERSION .'; ';
810
-		} elseif (@ini_get('allow_url_fopen')) {
811
-			$rawData = '';
812
-			$error_fopen = '';
813
-			ob_start();
814
-			if ($fp = fopen($url, 'rb')) {
815
-				do {
816
-					$buffer = fread($fp, 8192);
817
-					$rawData .= $buffer;
818
-				} while (strlen($buffer) > 0);
819
-				fclose($fp);
820
-			} else {
821
-				$error_fopen .= trim(strip_tags(ob_get_contents()));
822
-			}
823
-			ob_end_clean();
824
-			$error .= $error_fopen;
825
-			if (!$error_fopen) {
826
-				$error .= '; "allow_url_fopen" succeeded ('.strlen($rawData).' bytes); ';
827
-				return $rawData;
828
-			}
829
-			$error .= '; "allow_url_fopen" enabled but returned no data ('.$error_fopen.'); ';
830
-		} else {
831
-			$error .= '"allow_url_fopen" disabled; ';
832
-		}
833
-
834
-		return false;
835
-	}
836
-
837
-	public static function EnsureDirectoryExists($dirname, $mask = 0755) {
838
-		$directory_elements = explode(DIRECTORY_SEPARATOR, $dirname);
839
-		$startoffset = (!$directory_elements[0] ? 2 : 1);  // unix with leading "/" then start with 2nd element; Windows with leading "c:\" then start with 1st element
840
-		$open_basedirs = preg_split('#[;:]#', ini_get('open_basedir'));
841
-		foreach ($open_basedirs as $key => $open_basedir) {
842
-			if (preg_match('#^'.preg_quote($open_basedir).'#', $dirname) && (strlen($dirname) > strlen($open_basedir))) {
843
-				$startoffset = substr_count($open_basedir, DIRECTORY_SEPARATOR) + 1;
844
-				break;
845
-			}
846
-		}
847
-		$i = $startoffset;
848
-		$endoffset = count($directory_elements);
849
-		for ($i = $startoffset; $i <= $endoffset; $i++) {
850
-			$test_directory = implode(DIRECTORY_SEPARATOR, array_slice($directory_elements, 0, $i));
851
-			if (!$test_directory) {
852
-				continue;
853
-			}
854
-			if (!@is_dir($test_directory)) {
855
-				if (@file_exists($test_directory)) {
856
-					// directory name already exists as a file
857
-					return false;
858
-				}
859
-				@mkdir($test_directory, $mask);
860
-				@chmod($test_directory, $mask);
861
-				if (!@is_dir($test_directory) || !@is_writable($test_directory)) {
862
-					return false;
863
-				}
864
-			}
865
-		}
866
-		return true;
867
-	}
868
-
869
-
870
-	public static function GetAllFilesInSubfolders($dirname) {
871
-		$AllFiles = array();
872
-		$dirname = rtrim(realpath($dirname), '/\\');
873
-		if ($dirhandle = @opendir($dirname)) {
874
-			while (($file = readdir($dirhandle)) !== false) {
875
-				$fullfilename = $dirname.DIRECTORY_SEPARATOR.$file;
876
-				if (is_file($fullfilename)) {
877
-					$AllFiles[] = $fullfilename;
878
-				} elseif (is_dir($fullfilename)) {
879
-					switch ($file) {
880
-						case '.':
881
-						case '..':
882
-							break;
883
-
884
-						default:
885
-							$AllFiles[] = $fullfilename;
886
-							$subfiles = self::GetAllFilesInSubfolders($fullfilename);
887
-							foreach ($subfiles as $filename) {
888
-								$AllFiles[] = $filename;
889
-							}
890
-							break;
891
-					}
892
-				} else {
893
-					// ignore?
894
-				}
895
-			}
896
-			closedir($dirhandle);
897
-		}
898
-		sort($AllFiles);
899
-		return array_unique($AllFiles);
900
-	}
901
-
902
-
903
-	public static function SanitizeFilename($filename) {
904
-		$filename = preg_replace('/[^'.preg_quote(' !#$%^()+,-.;<>=@[]_{}').'a-zA-Z0-9]/', '_', $filename);
905
-		if (self::version_compare_replacement(PHP_VERSION, '4.1.0', '>=')) {
906
-			$filename = trim($filename, '.');
907
-		}
908
-		return $filename;
909
-	}
910
-
911
-	public static function PasswordStrength($password) {
912
-		$strength = 0;
913
-		$strength += strlen(preg_replace('#[^a-z]#',       '', $password)) * 0.5; // lowercase characters are weak
914
-		$strength += strlen(preg_replace('#[^A-Z]#',       '', $password)) * 0.8; // uppercase characters are somewhat better
915
-		$strength += strlen(preg_replace('#[^0-9]#',       '', $password)) * 1.0; // numbers are somewhat better
916
-		$strength += strlen(preg_replace('#[a-zA-Z0-9]#',  '', $password)) * 2.0; // other non-alphanumeric characters are best
917
-		return $strength;
918
-	}
14
+    public static function user_function_exists($functionname) {
15
+        if (function_exists('get_defined_functions')) {
16
+            static $get_defined_functions = array();
17
+            if (empty($get_defined_functions)) {
18
+                $get_defined_functions = get_defined_functions();
19
+            }
20
+            return in_array(strtolower($functionname), $get_defined_functions['user']);
21
+        }
22
+        return function_exists($functionname);
23
+    }
24
+
25
+
26
+    public static function builtin_function_exists($functionname) {
27
+        if (function_exists('get_defined_functions')) {
28
+            static $get_defined_functions = array();
29
+            if (empty($get_defined_functions)) {
30
+                $get_defined_functions = get_defined_functions();
31
+            }
32
+            return in_array(strtolower($functionname), $get_defined_functions['internal']);
33
+        }
34
+        return function_exists($functionname);
35
+    }
36
+
37
+
38
+    public static function version_compare_replacement_sub($version1, $version2, $operator='') {
39
+        // If you specify the third optional operator argument, you can test for a particular relationship.
40
+        // The possible operators are: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne respectively.
41
+        // Using this argument, the function will return 1 if the relationship is the one specified by the operator, 0 otherwise.
42
+
43
+        // If a part contains special version strings these are handled in the following order:
44
+        // (any string not found in this list) < (dev) < (alpha = a) < (beta = b) < (RC = rc) < (#) < (pl = p)
45
+        static $versiontype_lookup = array();
46
+        if (empty($versiontype_lookup)) {
47
+            $versiontype_lookup['dev']   = 10001;
48
+            $versiontype_lookup['a']     = 10002;
49
+            $versiontype_lookup['alpha'] = 10002;
50
+            $versiontype_lookup['b']     = 10003;
51
+            $versiontype_lookup['beta']  = 10003;
52
+            $versiontype_lookup['RC']    = 10004;
53
+            $versiontype_lookup['rc']    = 10004;
54
+            $versiontype_lookup['#']     = 10005;
55
+            $versiontype_lookup['pl']    = 10006;
56
+            $versiontype_lookup['p']     = 10006;
57
+        }
58
+        $version1 = (isset($versiontype_lookup[$version1]) ? $versiontype_lookup[$version1] : $version1);
59
+        $version2 = (isset($versiontype_lookup[$version2]) ? $versiontype_lookup[$version2] : $version2);
60
+
61
+        switch ($operator) {
62
+            case '<':
63
+            case 'lt':
64
+                return (int) ($version1 < $version2);
65
+                break;
66
+            case '<=':
67
+            case 'le':
68
+                return (int) ($version1 <= $version2);
69
+                break;
70
+            case '>':
71
+            case 'gt':
72
+                return (int) ($version1 > $version2);
73
+                break;
74
+            case '>=':
75
+            case 'ge':
76
+                return (int) ($version1 >= $version2);
77
+                break;
78
+            case '==':
79
+            case '=':
80
+            case 'eq':
81
+                return (int) ($version1 == $version2);
82
+                break;
83
+            case '!=':
84
+            case '<>':
85
+            case 'ne':
86
+                return (int) ($version1 != $version2);
87
+                break;
88
+        }
89
+        if ($version1 == $version2) {
90
+            return 0;
91
+        } elseif ($version1 < $version2) {
92
+            return -1;
93
+        }
94
+        return 1;
95
+    }
96
+
97
+
98
+    public static function version_compare_replacement($version1, $version2, $operator='') {
99
+        if (function_exists('version_compare')) {
100
+            // built into PHP v4.1.0+
101
+            return version_compare($version1, $version2, $operator);
102
+        }
103
+
104
+        // The function first replaces _, - and + with a dot . in the version strings
105
+        $version1 = strtr($version1, '_-+', '...');
106
+        $version2 = strtr($version2, '_-+', '...');
107
+
108
+        // and also inserts dots . before and after any non number so that for example '4.3.2RC1' becomes '4.3.2.RC.1'.
109
+        // Then it splits the results like if you were using explode('.',$ver). Then it compares the parts starting from left to right.
110
+        $version1 = preg_replace('#([0-9]+)([A-Z]+)([0-9]+)#i', "$1.$2.$3", $version1);
111
+        $version2 = preg_replace('#([0-9]+)([A-Z]+)([0-9]+)#i', "$1.$2.$3", $version2);
112
+
113
+        $parts1 = explode('.', $version1);
114
+        $parts2 = explode('.', $version1);
115
+        $parts_count = max(count($parts1), count($parts2));
116
+        for ($i = 0; $i < $parts_count; $i++) {
117
+            $comparison = self::version_compare_replacement_sub($version1, $version2, $operator);
118
+            if ($comparison != 0) {
119
+                return $comparison;
120
+            }
121
+        }
122
+        return 0;
123
+    }
124
+
125
+    public static function escapeshellarg_replacement($arg) {
126
+        if (function_exists('escapeshellarg') && !self::FunctionIsDisabled('escapeshellarg')) {
127
+            return escapeshellarg($arg);
128
+        }
129
+        return '\''.str_replace('\'', '\\\'', $arg).'\'';
130
+    }
131
+
132
+    public static function phpinfo_array() {
133
+        static $phpinfo_array = array();
134
+        if (empty($phpinfo_array)) {
135
+            ob_start();
136
+            phpinfo();
137
+            $phpinfo = ob_get_contents();
138
+            ob_end_clean();
139
+            $phpinfo_array = explode("\n", $phpinfo);
140
+        }
141
+        return $phpinfo_array;
142
+    }
143
+
144
+
145
+    public static function exif_info() {
146
+        static $exif_info = array();
147
+        if (empty($exif_info)) {
148
+            // based on code by johnschaefer at gmx dot de
149
+            // from PHP help on gd_info()
150
+            $exif_info = array(
151
+                'EXIF Support'           => '',
152
+                'EXIF Version'           => '',
153
+                'Supported EXIF Version' => '',
154
+                'Supported filetypes'    => ''
155
+            );
156
+            $phpinfo_array = self::phpinfo_array();
157
+            foreach ($phpinfo_array as $line) {
158
+                $line = trim(strip_tags($line));
159
+                foreach ($exif_info as $key => $value) {
160
+                    if (strpos($line, $key) === 0) {
161
+                        $newvalue = trim(str_replace($key, '', $line));
162
+                        $exif_info[$key] = $newvalue;
163
+                    }
164
+                }
165
+            }
166
+        }
167
+        return $exif_info;
168
+    }
169
+
170
+
171
+    public static function ImageTypeToMIMEtype($imagetype) {
172
+        if (function_exists('image_type_to_mime_type') && ($imagetype >= 1) && ($imagetype <= 16)) {
173
+            // PHP v4.3.0+
174
+            return image_type_to_mime_type($imagetype);
175
+        }
176
+        static $image_type_to_mime_type = array(
177
+            1  => 'image/gif',                     // IMAGETYPE_GIF
178
+            2  => 'image/jpeg',                    // IMAGETYPE_JPEG
179
+            3  => 'image/png',                     // IMAGETYPE_PNG
180
+            4  => 'application/x-shockwave-flash', // IMAGETYPE_SWF
181
+            5  => 'image/psd',                     // IMAGETYPE_PSD
182
+            6  => 'image/bmp',                     // IMAGETYPE_BMP
183
+            7  => 'image/tiff',                    // IMAGETYPE_TIFF_II (intel byte order)
184
+            8  => 'image/tiff',                    // IMAGETYPE_TIFF_MM (motorola byte order)
185
+            9  => 'application/octet-stream',      // IMAGETYPE_JPC
186
+            10 => 'image/jp2',                     // IMAGETYPE_JP2
187
+            11 => 'application/octet-stream',      // IMAGETYPE_JPX
188
+            12 => 'application/octet-stream',      // IMAGETYPE_JB2
189
+            13 => 'application/x-shockwave-flash', // IMAGETYPE_SWC
190
+            14 => 'image/iff',                     // IMAGETYPE_IFF
191
+            15 => 'image/vnd.wap.wbmp',            // IMAGETYPE_WBMP
192
+            16 => 'image/xbm',                     // IMAGETYPE_XBM
193
+
194
+            'gif'  => 'image/gif',                 // IMAGETYPE_GIF
195
+            'jpg'  => 'image/jpeg',                // IMAGETYPE_JPEG
196
+            'jpeg' => 'image/jpeg',                // IMAGETYPE_JPEG
197
+            'png'  => 'image/png',                 // IMAGETYPE_PNG
198
+            'bmp'  => 'image/bmp',                 // IMAGETYPE_BMP
199
+            'ico'  => 'image/x-icon',
200
+        );
201
+
202
+        return (isset($image_type_to_mime_type[$imagetype]) ? $image_type_to_mime_type[$imagetype] : false);
203
+    }
204
+
205
+
206
+    public static function TranslateWHbyAngle($width, $height, $angle) {
207
+        if (($angle % 180) == 0) {
208
+            return array($width, $height);
209
+        }
210
+        $newwidth  = (abs(sin(deg2rad($angle))) * $height) + (abs(cos(deg2rad($angle))) * $width);
211
+        $newheight = (abs(sin(deg2rad($angle))) * $width)  + (abs(cos(deg2rad($angle))) * $height);
212
+        return array($newwidth, $newheight);
213
+    }
214
+
215
+    public static function HexCharDisplay($string) {
216
+        $len = strlen($string);
217
+        $output = '';
218
+        for ($i = 0; $i < $len; $i++) {
219
+            $output .= ' 0x'.str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT);
220
+        }
221
+        return $output;
222
+    }
223
+
224
+
225
+    public static function IsHexColor($HexColorString) {
226
+        return preg_match('#^[0-9A-F]{6}$#i', $HexColorString);
227
+    }
228
+
229
+
230
+    public static function ImageColorAllocateAlphaSafe(&$gdimg_hexcolorallocate, $R, $G, $B, $alpha=false) {
231
+        if (self::version_compare_replacement(PHP_VERSION, '4.3.2', '>=') && ($alpha !== false)) {
232
+            return imagecolorallocatealpha($gdimg_hexcolorallocate, $R, $G, $B, (int) $alpha);
233
+        } else {
234
+            return imagecolorallocate($gdimg_hexcolorallocate, $R, $G, $B);
235
+        }
236
+    }
237
+
238
+    public static function ImageHexColorAllocate(&$gdimg_hexcolorallocate, $HexColorString, $dieOnInvalid=false, $alpha=false) {
239
+        if (!is_resource($gdimg_hexcolorallocate)) {
240
+            die('$gdimg_hexcolorallocate is not a GD resource in ImageHexColorAllocate()');
241
+        }
242
+        if (self::IsHexColor($HexColorString)) {
243
+            $R = hexdec(substr($HexColorString, 0, 2));
244
+            $G = hexdec(substr($HexColorString, 2, 2));
245
+            $B = hexdec(substr($HexColorString, 4, 2));
246
+            return self::ImageColorAllocateAlphaSafe($gdimg_hexcolorallocate, $R, $G, $B, $alpha);
247
+        }
248
+        if ($dieOnInvalid) {
249
+            die('Invalid hex color string: "'.$HexColorString.'"');
250
+        }
251
+        return imagecolorallocate($gdimg_hexcolorallocate, 0x00, 0x00, 0x00);
252
+    }
253
+
254
+
255
+    public static function HexColorXOR($hexcolor) {
256
+        return strtoupper(str_pad(dechex(~hexdec($hexcolor) & 0xFFFFFF), 6, '0', STR_PAD_LEFT));
257
+    }
258
+
259
+
260
+    public static function GetPixelColor(&$img, $x, $y) {
261
+        if (!is_resource($img)) {
262
+            return false;
263
+        }
264
+        return @imagecolorsforindex($img, @imagecolorat($img, $x, $y));
265
+    }
266
+
267
+
268
+    public static function PixelColorDifferencePercent($currentPixel, $targetPixel) {
269
+        $diff = 0;
270
+        foreach ($targetPixel as $channel => $currentvalue) {
271
+            $diff = max($diff, (max($currentPixel[$channel], $targetPixel[$channel]) - min($currentPixel[$channel], $targetPixel[$channel])) / 255);
272
+        }
273
+        return $diff * 100;
274
+    }
275
+
276
+    public static function GrayscaleValue($r, $g, $b) {
277
+        return round(($r * 0.30) + ($g * 0.59) + ($b * 0.11));
278
+    }
279
+
280
+
281
+    public static function GrayscalePixel($OriginalPixel) {
282
+        $gray = self::GrayscaleValue($OriginalPixel[ 'red'], $OriginalPixel[ 'green'], $OriginalPixel[ 'blue']);
283
+        return array('red'=>$gray, 'green'=>$gray, 'blue'=>$gray);
284
+    }
285
+
286
+
287
+    public static function GrayscalePixelRGB($rgb) {
288
+        $r = ($rgb >> 16) & 0xFF;
289
+        $g = ($rgb >>  8) & 0xFF;
290
+        $b =  $rgb        & 0xFF;
291
+        return ($r * 0.299) + ($g * 0.587) + ($b * 0.114);
292
+    }
293
+
294
+
295
+    public static function ScaleToFitInBox($width, $height, $maxwidth=null, $maxheight=null, $allow_enlarge=true, $allow_reduce=true) {
296
+        $maxwidth  = (null === $maxwidth  ? $width  : $maxwidth);
297
+        $maxheight = (null === $maxheight ? $height : $maxheight);
298
+        $scale_x = 1;
299
+        $scale_y = 1;
300
+        if (($width > $maxwidth) || ($width < $maxwidth)) {
301
+            $scale_x = ($maxwidth / $width);
302
+        }
303
+        if (($height > $maxheight) || ($height < $maxheight)) {
304
+            $scale_y = ($maxheight / $height);
305
+        }
306
+        $scale = min($scale_x, $scale_y);
307
+        if (!$allow_enlarge) {
308
+            $scale = min($scale, 1);
309
+        }
310
+        if (!$allow_reduce) {
311
+            $scale = max($scale, 1);
312
+        }
313
+        return $scale;
314
+    }
315
+
316
+    public static function ImageCopyResampleBicubic($dst_img, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) {
317
+        // ron at korving dot demon dot nl
318
+        // http://www.php.net/imagecopyresampled
319
+
320
+        $scaleX = ($src_w - 1) / $dst_w;
321
+        $scaleY = ($src_h - 1) / $dst_h;
322
+
323
+        $scaleX2 = $scaleX / 2.0;
324
+        $scaleY2 = $scaleY / 2.0;
325
+
326
+        $isTrueColor = imageistruecolor($src_img);
327
+
328
+        for ($y = $src_y; $y < $src_y + $dst_h; $y++) {
329
+            $sY   = $y * $scaleY;
330
+            $siY  = (int) $sY;
331
+            $siY2 = (int) $sY + $scaleY2;
332
+
333
+            for ($x = $src_x; $x < $src_x + $dst_w; $x++) {
334
+                $sX   = $x * $scaleX;
335
+                $siX  = (int) $sX;
336
+                $siX2 = (int) $sX + $scaleX2;
337
+
338
+                if ($isTrueColor) {
339
+
340
+                    $c1 = imagecolorat($src_img, $siX, $siY2);
341
+                    $c2 = imagecolorat($src_img, $siX, $siY);
342
+                    $c3 = imagecolorat($src_img, $siX2, $siY2);
343
+                    $c4 = imagecolorat($src_img, $siX2, $siY);
344
+
345
+                    $r = (( $c1             +  $c2             +  $c3             +  $c4            ) >> 2) & 0xFF0000;
346
+                    $g = ((($c1 & 0x00FF00) + ($c2 & 0x00FF00) + ($c3 & 0x00FF00) + ($c4 & 0x00FF00)) >> 2) & 0x00FF00;
347
+                    $b = ((($c1 & 0x0000FF) + ($c2 & 0x0000FF) + ($c3 & 0x0000FF) + ($c4 & 0x0000FF)) >> 2);
348
+
349
+                } else {
350
+
351
+                    $c1 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX, $siY2));
352
+                    $c2 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX, $siY));
353
+                    $c3 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY2));
354
+                    $c4 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY));
355
+
356
+                    $r = ($c1['red']   + $c2['red']   + $c3['red']   + $c4['red'] )  << 14;
357
+                    $g = ($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) <<  6;
358
+                    $b = ($c1['blue']  + $c2['blue']  + $c3['blue']  + $c4['blue'] ) >>  2;
359
+
360
+                }
361
+                imagesetpixel($dst_img, $dst_x + $x - $src_x, $dst_y + $y - $src_y, $r+$g+$b);
362
+            }
363
+        }
364
+        return true;
365
+    }
366
+
367
+
368
+    public static function ImageCreateFunction($x_size, $y_size) {
369
+        $ImageCreateFunction = 'imagecreate';
370
+        if (self::gd_version() >= 2.0) {
371
+            $ImageCreateFunction = 'imagecreatetruecolor';
372
+        }
373
+        if (!function_exists($ImageCreateFunction)) {
374
+            return phpthumb::ErrorImage($ImageCreateFunction.'() does not exist - no GD support?');
375
+        }
376
+        if (($x_size <= 0) || ($y_size <= 0)) {
377
+            return phpthumb::ErrorImage('Invalid image dimensions: '.$ImageCreateFunction.'('.$x_size.', '.$y_size.')');
378
+        }
379
+        return $ImageCreateFunction(round($x_size), round($y_size));
380
+    }
381
+
382
+
383
+    public static function ImageCopyRespectAlpha(&$dst_im, &$src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $opacity_pct=100) {
384
+        $opacipct = $opacity_pct / 100;
385
+        for ($x = $src_x; $x < $src_w; $x++) {
386
+            for ($y = $src_y; $y < $src_h; $y++) {
387
+                $RealPixel    = self::GetPixelColor($dst_im, $dst_x + $x, $dst_y + $y);
388
+                $OverlayPixel = self::GetPixelColor($src_im, $x, $y);
389
+                $alphapct = $OverlayPixel['alpha'] / 127;
390
+                $overlaypct = (1 - $alphapct) * $opacipct;
391
+
392
+                $newcolor = self::ImageColorAllocateAlphaSafe(
393
+                    $dst_im,
394
+                    round($RealPixel['red']   * (1 - $overlaypct)) + ($OverlayPixel['red']   * $overlaypct),
395
+                    round($RealPixel['green'] * (1 - $overlaypct)) + ($OverlayPixel['green'] * $overlaypct),
396
+                    round($RealPixel['blue']  * (1 - $overlaypct)) + ($OverlayPixel['blue']  * $overlaypct),
397
+                    //$RealPixel['alpha']);
398
+                    0);
399
+
400
+                imagesetpixel($dst_im, $dst_x + $x, $dst_y + $y, $newcolor);
401
+            }
402
+        }
403
+        return true;
404
+    }
405
+
406
+
407
+    public static function ProportionalResize($old_width, $old_height, $new_width=false, $new_height=false) {
408
+        $old_aspect_ratio = $old_width / $old_height;
409
+        if (($new_width === false) && ($new_height === false)) {
410
+            return false;
411
+        } elseif ($new_width === false) {
412
+            $new_width = $new_height * $old_aspect_ratio;
413
+        } elseif ($new_height === false) {
414
+            $new_height = $new_width / $old_aspect_ratio;
415
+        }
416
+        $new_aspect_ratio = $new_width / $new_height;
417
+        if ($new_aspect_ratio == $old_aspect_ratio) {
418
+            // great, done
419
+        } elseif ($new_aspect_ratio < $old_aspect_ratio) {
420
+            // limited by width
421
+            $new_height = $new_width / $old_aspect_ratio;
422
+        } elseif ($new_aspect_ratio > $old_aspect_ratio) {
423
+            // limited by height
424
+            $new_width = $new_height * $old_aspect_ratio;
425
+        }
426
+        return array(
427
+            (int) round($new_width),
428
+            (int) round($new_height)
429
+        );
430
+    }
431
+
432
+
433
+    public static function FunctionIsDisabled($function) {
434
+        static $DisabledFunctions = null;
435
+        if (null === $DisabledFunctions) {
436
+            $disable_functions_local  = explode(',',     strtolower(@ini_get('disable_functions')));
437
+            $disable_functions_global = explode(',', strtolower(@get_cfg_var('disable_functions')));
438
+            foreach ($disable_functions_local as $key => $value) {
439
+                $DisabledFunctions[trim($value)] = 'local';
440
+            }
441
+            foreach ($disable_functions_global as $key => $value) {
442
+                $DisabledFunctions[trim($value)] = 'global';
443
+            }
444
+            if (@ini_get('safe_mode')) {
445
+                $DisabledFunctions['shell_exec']     = 'local';
446
+                $DisabledFunctions['set_time_limit'] = 'local';
447
+            }
448
+        }
449
+        return isset($DisabledFunctions[strtolower($function)]);
450
+    }
451
+
452
+
453
+    public static function SafeExec($command) {
454
+        static $AllowedExecFunctions = array();
455
+        if (empty($AllowedExecFunctions)) {
456
+            $AllowedExecFunctions = array('shell_exec'=>true, 'passthru'=>true, 'system'=>true, 'exec'=>true);
457
+            foreach ($AllowedExecFunctions as $key => $value) {
458
+                $AllowedExecFunctions[$key] = !self::FunctionIsDisabled($key);
459
+            }
460
+        }
461
+        $command .= ' 2>&1'; // force redirect stderr to stdout
462
+        foreach ($AllowedExecFunctions as $execfunction => $is_allowed) {
463
+            if (!$is_allowed) {
464
+                continue;
465
+            }
466
+            $returnvalue = false;
467
+            switch ($execfunction) {
468
+                case 'passthru':
469
+                case 'system':
470
+                    ob_start();
471
+                    $execfunction($command);
472
+                    $returnvalue = ob_get_contents();
473
+                    ob_end_clean();
474
+                    break;
475
+
476
+                case 'exec':
477
+                    $output = array();
478
+                    $lastline = $execfunction($command, $output);
479
+                    $returnvalue = implode("\n", $output);
480
+                    break;
481
+
482
+                case 'shell_exec':
483
+                    ob_start();
484
+                    $returnvalue = $execfunction($command);
485
+                    ob_end_clean();
486
+                    break;
487
+            }
488
+            return $returnvalue;
489
+        }
490
+        return false;
491
+    }
492
+
493
+
494
+    public static function ApacheLookupURIarray($filename) {
495
+        // apache_lookup_uri() only works when PHP is installed as an Apache module.
496
+        if (PHP_SAPI == 'apache') {
497
+            //$property_exists_exists = function_exists('property_exists');
498
+            $keys = array('status', 'the_request', 'status_line', 'method', 'content_type', 'handler', 'uri', 'filename', 'path_info', 'args', 'boundary', 'no_cache', 'no_local_copy', 'allowed', 'send_bodyct', 'bytes_sent', 'byterange', 'clength', 'unparsed_uri', 'mtime', 'request_time');
499
+            if ($apacheLookupURIobject = @apache_lookup_uri($filename)) {
500
+                $apacheLookupURIarray = array();
501
+                foreach ($keys as $key) {
502
+                    $apacheLookupURIarray[$key] = @$apacheLookupURIobject->$key;
503
+                }
504
+                return $apacheLookupURIarray;
505
+            }
506
+        }
507
+        return false;
508
+    }
509
+
510
+
511
+    public static function gd_is_bundled() {
512
+        static $isbundled = null;
513
+        if (null === $isbundled) {
514
+            $gd_info = gd_info();
515
+            $isbundled = (strpos($gd_info['GD Version'], 'bundled') !== false);
516
+        }
517
+        return $isbundled;
518
+    }
519
+
520
+
521
+    public static function gd_version($fullstring=false) {
522
+        static $cache_gd_version = array();
523
+        if (empty($cache_gd_version)) {
524
+            $gd_info = gd_info();
525
+            if (preg_match('#bundled \((.+)\)$#i', $gd_info['GD Version'], $matches)) {
526
+                $cache_gd_version[1] = $gd_info['GD Version'];  // e.g. "bundled (2.0.15 compatible)"
527
+                $cache_gd_version[0] = (float) $matches[1];     // e.g. "2.0" (not "bundled (2.0.15 compatible)")
528
+            } else {
529
+                $cache_gd_version[1] = $gd_info['GD Version'];                       // e.g. "1.6.2 or higher"
530
+                $cache_gd_version[0] = (float) substr($gd_info['GD Version'], 0, 3); // e.g. "1.6" (not "1.6.2 or higher")
531
+            }
532
+        }
533
+        return $cache_gd_version[ (int) $fullstring ];
534
+    }
535
+
536
+
537
+    public static function filesize_remote($remotefile, $timeout=10) {
538
+        $size = false;
539
+        $url = self::ParseURLbetter($remotefile);
540
+        if ($fp = @fsockopen($url['host'], ($url['port'] ? $url['port'] : 80), $errno, $errstr, $timeout)) {
541
+            fwrite($fp, 'HEAD '.@$url['path'].@$url['query'].' HTTP/1.0'."\r\n".'Host: '.@$url['host']."\r\n\r\n");
542
+            if (self::version_compare_replacement(PHP_VERSION, '4.3.0', '>=')) {
543
+                stream_set_timeout($fp, $timeout);
544
+            }
545
+            while (!feof($fp)) {
546
+                $headerline = fgets($fp, 4096);
547
+                if (preg_match('#^Content-Length: (.*)#i', $headerline, $matches)) {
548
+                    $size = (int) $matches[ 1];
549
+                    break;
550
+                }
551
+            }
552
+            fclose ($fp);
553
+        }
554
+        return $size;
555
+    }
556
+
557
+
558
+    public static function filedate_remote($remotefile, $timeout=10) {
559
+        $date = false;
560
+        $url = self::ParseURLbetter($remotefile);
561
+        if ($fp = @fsockopen($url['host'], ($url['port'] ? $url['port'] : 80), $errno, $errstr, $timeout)) {
562
+            fwrite($fp, 'HEAD '.@$url['path'].@$url['query'].' HTTP/1.0'."\r\n".'Host: '.@$url['host']."\r\n\r\n");
563
+            if (self::version_compare_replacement(PHP_VERSION, '4.3.0', '>=')) {
564
+                stream_set_timeout($fp, $timeout);
565
+            }
566
+            while (!feof($fp)) {
567
+                $headerline = fgets($fp, 4096);
568
+                if (preg_match('#^Last-Modified: (.*)#i', $headerline, $matches)) {
569
+                    $date = strtotime($matches[1]) - date('Z');
570
+                    break;
571
+                }
572
+            }
573
+            fclose ($fp);
574
+        }
575
+        return $date;
576
+    }
577
+
578
+
579
+    public static function md5_file_safe($filename) {
580
+        // md5_file() doesn't exist in PHP < 4.2.0
581
+        if (function_exists('md5_file')) {
582
+            return md5_file($filename);
583
+        }
584
+        if ($fp = @fopen($filename, 'rb')) {
585
+            $rawData = '';
586
+            do {
587
+                $buffer = fread($fp, 8192);
588
+                $rawData .= $buffer;
589
+            } while (strlen($buffer) > 0);
590
+            fclose($fp);
591
+            return md5($rawData);
592
+        }
593
+        return false;
594
+    }
595
+
596
+
597
+    public static function nonempty_min() {
598
+        $arg_list = func_get_args();
599
+        $acceptable = array();
600
+        foreach ($arg_list as $arg) {
601
+            if ($arg) {
602
+                $acceptable[] = $arg;
603
+            }
604
+        }
605
+        return min($acceptable);
606
+    }
607
+
608
+
609
+    public static function LittleEndian2String($number, $minbytes=1) {
610
+        $intstring = '';
611
+        while ($number > 0) {
612
+            $intstring .= chr($number & 255);
613
+            $number    >>= 8;
614
+        }
615
+        return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
616
+    }
617
+
618
+    public static function OneOfThese() {
619
+        // return the first useful (non-empty/non-zero/non-false) value from those passed
620
+        $arg_list = func_get_args();
621
+        foreach ($arg_list as $key => $value) {
622
+            if ($value) {
623
+                return $value;
624
+            }
625
+        }
626
+        return false;
627
+    }
628
+
629
+    public static function CaseInsensitiveInArray($needle, $haystack) {
630
+        $needle = strtolower($needle);
631
+        foreach ($haystack as $key => $value) {
632
+            if (is_array($value)) {
633
+                // skip?
634
+            } elseif ($needle == strtolower($value)) {
635
+                return true;
636
+            }
637
+        }
638
+        return false;
639
+    }
640
+
641
+    public static function URLreadFsock($host, $file, &$errstr, $successonly=true, $port=80, $timeout=10) {
642
+        if (!function_exists('fsockopen') || self::FunctionIsDisabled('fsockopen')) {
643
+            $errstr = 'fsockopen() unavailable';
644
+            return false;
645
+        }
646
+        //if ($fp = @fsockopen($host, $port, $errno, $errstr, $timeout)) {
647
+        if ($fp = @fsockopen((($port == 443) ? 'ssl://' : '').$host, $port, $errno, $errstr, $timeout)) { // https://github.com/JamesHeinrich/phpThumb/issues/39
648
+            $out  = 'GET '.$file.' HTTP/1.0'."\r\n";
649
+            $out .= 'Host: '.$host."\r\n";
650
+            $out .= 'Connection: Close'."\r\n\r\n";
651
+            fwrite($fp, $out);
652
+
653
+            $isHeader = true;
654
+            $Data_header = '';
655
+            $Data_body   = '';
656
+            $header_newlocation = '';
657
+            while (!feof($fp)) {
658
+                $line = fgets($fp, 1024);
659
+                if ($isHeader) {
660
+                    $Data_header .= $line;
661
+                } else {
662
+                    $Data_body .= $line;
663
+                }
664
+                if (preg_match('#^HTTP/[\\.0-9]+ ([0-9]+) (.+)$#i', rtrim($line), $matches)) {
665
+                    list( , $errno, $errstr) = $matches;
666
+                    $errno = (int) $errno;
667
+                } elseif (preg_match('#^Location: (.*)$#i', rtrim($line), $matches)) {
668
+                    $header_newlocation = $matches[1];
669
+                }
670
+                if ($isHeader && ($line == "\r\n")) {
671
+                    $isHeader = false;
672
+                    if ($successonly) {
673
+                        switch ($errno) {
674
+                            case 200:
675
+                                // great, continue
676
+                                break;
677
+
678
+                            default:
679
+                                $errstr = $errno.' '.$errstr.($header_newlocation ? '; Location: '.$header_newlocation : '');
680
+                                fclose($fp);
681
+                                return false;
682
+                                break;
683
+                        }
684
+                    }
685
+                }
686
+            }
687
+            fclose($fp);
688
+            return $Data_body;
689
+        }
690
+        return null;
691
+    }
692
+
693
+    public static function CleanUpURLencoding($url, $queryseperator='&') {
694
+        if (!preg_match('#^http#i', $url)) {
695
+            return $url;
696
+        }
697
+        $parse_url = self::ParseURLbetter($url);
698
+        $pathelements = explode('/', $parse_url['path']);
699
+        $CleanPathElements = array();
700
+        $TranslationMatrix = array(' '=>'%20');
701
+        foreach ($pathelements as $key => $pathelement) {
702
+            $CleanPathElements[] = strtr($pathelement, $TranslationMatrix);
703
+        }
704
+        foreach ($CleanPathElements as $key => $value) {
705
+            if ($value === '') {
706
+                unset($CleanPathElements[$key]);
707
+            }
708
+        }
709
+
710
+        $queries = explode($queryseperator, (isset($parse_url['query']) ? $parse_url['query'] : ''));
711
+        $CleanQueries = array();
712
+        foreach ($queries as $key => $query) {
713
+            @list($param, $value) = explode('=', $query);
714
+            $CleanQueries[] = strtr($param, $TranslationMatrix).($value ? '='.strtr($value, $TranslationMatrix) : '');
715
+        }
716
+        foreach ($CleanQueries as $key => $value) {
717
+            if ($value === '') {
718
+                unset($CleanQueries[$key]);
719
+            }
720
+        }
721
+
722
+        $cleaned_url  = $parse_url['scheme'].'://';
723
+        $cleaned_url .= (@$parse_url['username'] ? $parse_url['host'].(@$parse_url['password'] ? ':'.$parse_url['password'] : '').'@' : '');
724
+        $cleaned_url .= $parse_url['host'];
725
+        $cleaned_url .= ((!empty($parse_url['port']) && ($parse_url['port'] != 80)) ? ':'.$parse_url['port'] : '');
726
+        $cleaned_url .= '/'.implode('/', $CleanPathElements);
727
+        $cleaned_url .= (@$CleanQueries ? '?'.implode($queryseperator, $CleanQueries) : '');
728
+        return $cleaned_url;
729
+    }
730
+
731
+    public static function ParseURLbetter($url) {
732
+        $parsedURL = @parse_url($url);
733
+        if (!@$parsedURL['port']) {
734
+            switch (strtolower(@$parsedURL['scheme'])) {
735
+                case 'ftp':
736
+                    $parsedURL['port'] = 21;
737
+                    break;
738
+                case 'https':
739
+                    $parsedURL['port'] = 443;
740
+                    break;
741
+                case 'http':
742
+                    $parsedURL['port'] = 80;
743
+                    break;
744
+            }
745
+        }
746
+        return $parsedURL;
747
+    }
748
+
749
+    public static function SafeURLread($url, &$error, $timeout=10, $followredirects=true) {
750
+        $error   = '';
751
+        $errstr  = '';
752
+        $rawData = '';
753
+
754
+        $parsed_url = self::ParseURLbetter($url);
755
+        $alreadyLookedAtURLs[trim($url)] = true;
756
+
757
+        while (true) {
758
+            $tryagain = false;
759
+            $rawData = self::URLreadFsock(@$parsed_url[ 'host'], @$parsed_url[ 'path'].'?'.@$parsed_url[ 'query'], $errstr, true, (@$parsed_url[ 'port'] ? @$parsed_url[ 'port'] : 80), $timeout);
760
+            if ($followredirects && preg_match('#302 [a-z ]+; Location\\: (http.*)#i', $errstr, $matches)) {
761
+                $matches[1] = trim(@$matches[1]);
762
+                if (!@$alreadyLookedAtURLs[$matches[1]]) {
763
+                    // loop through and examine new URL
764
+                    $error .= 'URL "'.$url.'" redirected to "'.$matches[1].'"';
765
+
766
+                    $tryagain = true;
767
+                    $alreadyLookedAtURLs[$matches[1]] = true;
768
+                    $parsed_url = self::ParseURLbetter($matches[ 1]);
769
+                }
770
+            }
771
+            if (!$tryagain) {
772
+                break;
773
+            }
774
+        }
775
+
776
+        if ($rawData === false) {
777
+            $error .= 'Error opening "'.$url.'":'."\n\n".$errstr;
778
+            return false;
779
+        } elseif ($rawData === null) {
780
+            // fall through
781
+            $error .= 'Error opening "'.$url.'":'."\n\n".$errstr;
782
+        } else {
783
+            return $rawData;
784
+        }
785
+
786
+        if (function_exists('curl_version') && !self::FunctionIsDisabled('curl_exec')) {
787
+            $ch = curl_init();
788
+            curl_setopt($ch, CURLOPT_URL, $url);
789
+            curl_setopt($ch, CURLOPT_HEADER, false);
790
+            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
791
+            curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
792
+            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
793
+            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
794
+            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, (bool) $followredirects);
795
+            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
796
+            $rawData = curl_exec($ch);
797
+            curl_close($ch);
798
+            if (strlen($rawData) > 0) {
799
+                $error .= 'CURL succeeded ('.strlen($rawData).' bytes); ';
800
+                return $rawData;
801
+            }
802
+            $error .= 'CURL available but returned no data; ';
803
+        } else {
804
+            $error .= 'CURL unavailable; ';
805
+        }
806
+
807
+        $BrokenURLfopenPHPversions = array('4.4.2');
808
+        if (in_array(PHP_VERSION, $BrokenURLfopenPHPversions)) {
809
+            $error .= 'fopen(URL) broken in PHP v'. PHP_VERSION .'; ';
810
+        } elseif (@ini_get('allow_url_fopen')) {
811
+            $rawData = '';
812
+            $error_fopen = '';
813
+            ob_start();
814
+            if ($fp = fopen($url, 'rb')) {
815
+                do {
816
+                    $buffer = fread($fp, 8192);
817
+                    $rawData .= $buffer;
818
+                } while (strlen($buffer) > 0);
819
+                fclose($fp);
820
+            } else {
821
+                $error_fopen .= trim(strip_tags(ob_get_contents()));
822
+            }
823
+            ob_end_clean();
824
+            $error .= $error_fopen;
825
+            if (!$error_fopen) {
826
+                $error .= '; "allow_url_fopen" succeeded ('.strlen($rawData).' bytes); ';
827
+                return $rawData;
828
+            }
829
+            $error .= '; "allow_url_fopen" enabled but returned no data ('.$error_fopen.'); ';
830
+        } else {
831
+            $error .= '"allow_url_fopen" disabled; ';
832
+        }
833
+
834
+        return false;
835
+    }
836
+
837
+    public static function EnsureDirectoryExists($dirname, $mask = 0755) {
838
+        $directory_elements = explode(DIRECTORY_SEPARATOR, $dirname);
839
+        $startoffset = (!$directory_elements[0] ? 2 : 1);  // unix with leading "/" then start with 2nd element; Windows with leading "c:\" then start with 1st element
840
+        $open_basedirs = preg_split('#[;:]#', ini_get('open_basedir'));
841
+        foreach ($open_basedirs as $key => $open_basedir) {
842
+            if (preg_match('#^'.preg_quote($open_basedir).'#', $dirname) && (strlen($dirname) > strlen($open_basedir))) {
843
+                $startoffset = substr_count($open_basedir, DIRECTORY_SEPARATOR) + 1;
844
+                break;
845
+            }
846
+        }
847
+        $i = $startoffset;
848
+        $endoffset = count($directory_elements);
849
+        for ($i = $startoffset; $i <= $endoffset; $i++) {
850
+            $test_directory = implode(DIRECTORY_SEPARATOR, array_slice($directory_elements, 0, $i));
851
+            if (!$test_directory) {
852
+                continue;
853
+            }
854
+            if (!@is_dir($test_directory)) {
855
+                if (@file_exists($test_directory)) {
856
+                    // directory name already exists as a file
857
+                    return false;
858
+                }
859
+                @mkdir($test_directory, $mask);
860
+                @chmod($test_directory, $mask);
861
+                if (!@is_dir($test_directory) || !@is_writable($test_directory)) {
862
+                    return false;
863
+                }
864
+            }
865
+        }
866
+        return true;
867
+    }
868
+
869
+
870
+    public static function GetAllFilesInSubfolders($dirname) {
871
+        $AllFiles = array();
872
+        $dirname = rtrim(realpath($dirname), '/\\');
873
+        if ($dirhandle = @opendir($dirname)) {
874
+            while (($file = readdir($dirhandle)) !== false) {
875
+                $fullfilename = $dirname.DIRECTORY_SEPARATOR.$file;
876
+                if (is_file($fullfilename)) {
877
+                    $AllFiles[] = $fullfilename;
878
+                } elseif (is_dir($fullfilename)) {
879
+                    switch ($file) {
880
+                        case '.':
881
+                        case '..':
882
+                            break;
883
+
884
+                        default:
885
+                            $AllFiles[] = $fullfilename;
886
+                            $subfiles = self::GetAllFilesInSubfolders($fullfilename);
887
+                            foreach ($subfiles as $filename) {
888
+                                $AllFiles[] = $filename;
889
+                            }
890
+                            break;
891
+                    }
892
+                } else {
893
+                    // ignore?
894
+                }
895
+            }
896
+            closedir($dirhandle);
897
+        }
898
+        sort($AllFiles);
899
+        return array_unique($AllFiles);
900
+    }
901
+
902
+
903
+    public static function SanitizeFilename($filename) {
904
+        $filename = preg_replace('/[^'.preg_quote(' !#$%^()+,-.;<>=@[]_{}').'a-zA-Z0-9]/', '_', $filename);
905
+        if (self::version_compare_replacement(PHP_VERSION, '4.1.0', '>=')) {
906
+            $filename = trim($filename, '.');
907
+        }
908
+        return $filename;
909
+    }
910
+
911
+    public static function PasswordStrength($password) {
912
+        $strength = 0;
913
+        $strength += strlen(preg_replace('#[^a-z]#',       '', $password)) * 0.5; // lowercase characters are weak
914
+        $strength += strlen(preg_replace('#[^A-Z]#',       '', $password)) * 0.8; // uppercase characters are somewhat better
915
+        $strength += strlen(preg_replace('#[^0-9]#',       '', $password)) * 1.0; // numbers are somewhat better
916
+        $strength += strlen(preg_replace('#[a-zA-Z0-9]#',  '', $password)) * 2.0; // other non-alphanumeric characters are best
917
+        return $strength;
918
+    }
919 919
 
920 920
 }
921 921
 
@@ -924,147 +924,147 @@  discard block
 block discarded – undo
924 924
 
925 925
 
926 926
 if (!function_exists('gd_info')) {
927
-	// built into PHP v4.3.0+ (with bundled GD2 library)
928
-	function gd_info() {
929
-		static $gd_info = array();
930
-		if (empty($gd_info)) {
931
-			// based on code by johnschaefer at gmx dot de
932
-			// from PHP help on gd_info()
933
-			$gd_info = array(
934
-				'GD Version'         => '',
935
-				'FreeType Support'   => false,
936
-				'FreeType Linkage'   => '',
937
-				'T1Lib Support'      => false,
938
-				'GIF Read Support'   => false,
939
-				'GIF Create Support' => false,
940
-				'JPG Support'        => false,
941
-				'PNG Support'        => false,
942
-				'WBMP Support'       => false,
943
-				'XBM Support'        => false
944
-			);
945
-			$phpinfo_array = phpthumb_functions::phpinfo_array();
946
-			foreach ($phpinfo_array as $line) {
947
-				$line = trim(strip_tags($line));
948
-				foreach ($gd_info as $key => $value) {
949
-					//if (strpos($line, $key) !== false) {
950
-					if (strpos($line, $key) === 0) {
951
-						$newvalue = trim(str_replace($key, '', $line));
952
-						$gd_info[$key] = $newvalue;
953
-					}
954
-				}
955
-			}
956
-			if (empty($gd_info['GD Version'])) {
957
-				// probable cause: "phpinfo() disabled for security reasons"
958
-				if (function_exists('imagetypes')) {
959
-					$imagetypes = imagetypes();
960
-					if ($imagetypes & IMG_PNG) {
961
-						$gd_info['PNG Support'] = true;
962
-					}
963
-					if ($imagetypes & IMG_GIF) {
964
-						$gd_info['GIF Create Support'] = true;
965
-					}
966
-					if ($imagetypes & IMG_JPG) {
967
-						$gd_info['JPG Support'] = true;
968
-					}
969
-					if ($imagetypes & IMG_WBMP) {
970
-						$gd_info['WBMP Support'] = true;
971
-					}
972
-				}
973
-				// to determine capability of GIF creation, try to use imagecreatefromgif on a 1px GIF
974
-				if (function_exists('imagecreatefromgif')) {
975
-					if ($tempfilename = phpthumb::phpThumb_tempnam()) {
976
-						if ($fp_tempfile = @fopen($tempfilename, 'wb')) {
977
-							fwrite($fp_tempfile, base64_decode('R0lGODlhAQABAIAAAH//AP///ywAAAAAAQABAAACAUQAOw==')); // very simple 1px GIF file base64-encoded as string
978
-							fclose($fp_tempfile);
979
-							@chmod($tempfilename, $this->getParameter('config_file_create_mask'));
980
-
981
-							// if we can convert the GIF file to a GD image then GIF create support must be enabled, otherwise it's not
982
-							$gd_info['GIF Read Support'] = (bool) @imagecreatefromgif($tempfilename);
983
-						}
984
-						unlink($tempfilename);
985
-					}
986
-				}
987
-				if (function_exists('imagecreatetruecolor') && @imagecreatetruecolor(1, 1)) {
988
-					$gd_info['GD Version'] = '2.0.1 or higher (assumed)';
989
-				} elseif (function_exists('imagecreate') && @imagecreate(1, 1)) {
990
-					$gd_info['GD Version'] = '1.6.0 or higher (assumed)';
991
-				}
992
-			}
993
-		}
994
-		return $gd_info;
995
-	}
927
+    // built into PHP v4.3.0+ (with bundled GD2 library)
928
+    function gd_info() {
929
+        static $gd_info = array();
930
+        if (empty($gd_info)) {
931
+            // based on code by johnschaefer at gmx dot de
932
+            // from PHP help on gd_info()
933
+            $gd_info = array(
934
+                'GD Version'         => '',
935
+                'FreeType Support'   => false,
936
+                'FreeType Linkage'   => '',
937
+                'T1Lib Support'      => false,
938
+                'GIF Read Support'   => false,
939
+                'GIF Create Support' => false,
940
+                'JPG Support'        => false,
941
+                'PNG Support'        => false,
942
+                'WBMP Support'       => false,
943
+                'XBM Support'        => false
944
+            );
945
+            $phpinfo_array = phpthumb_functions::phpinfo_array();
946
+            foreach ($phpinfo_array as $line) {
947
+                $line = trim(strip_tags($line));
948
+                foreach ($gd_info as $key => $value) {
949
+                    //if (strpos($line, $key) !== false) {
950
+                    if (strpos($line, $key) === 0) {
951
+                        $newvalue = trim(str_replace($key, '', $line));
952
+                        $gd_info[$key] = $newvalue;
953
+                    }
954
+                }
955
+            }
956
+            if (empty($gd_info['GD Version'])) {
957
+                // probable cause: "phpinfo() disabled for security reasons"
958
+                if (function_exists('imagetypes')) {
959
+                    $imagetypes = imagetypes();
960
+                    if ($imagetypes & IMG_PNG) {
961
+                        $gd_info['PNG Support'] = true;
962
+                    }
963
+                    if ($imagetypes & IMG_GIF) {
964
+                        $gd_info['GIF Create Support'] = true;
965
+                    }
966
+                    if ($imagetypes & IMG_JPG) {
967
+                        $gd_info['JPG Support'] = true;
968
+                    }
969
+                    if ($imagetypes & IMG_WBMP) {
970
+                        $gd_info['WBMP Support'] = true;
971
+                    }
972
+                }
973
+                // to determine capability of GIF creation, try to use imagecreatefromgif on a 1px GIF
974
+                if (function_exists('imagecreatefromgif')) {
975
+                    if ($tempfilename = phpthumb::phpThumb_tempnam()) {
976
+                        if ($fp_tempfile = @fopen($tempfilename, 'wb')) {
977
+                            fwrite($fp_tempfile, base64_decode('R0lGODlhAQABAIAAAH//AP///ywAAAAAAQABAAACAUQAOw==')); // very simple 1px GIF file base64-encoded as string
978
+                            fclose($fp_tempfile);
979
+                            @chmod($tempfilename, $this->getParameter('config_file_create_mask'));
980
+
981
+                            // if we can convert the GIF file to a GD image then GIF create support must be enabled, otherwise it's not
982
+                            $gd_info['GIF Read Support'] = (bool) @imagecreatefromgif($tempfilename);
983
+                        }
984
+                        unlink($tempfilename);
985
+                    }
986
+                }
987
+                if (function_exists('imagecreatetruecolor') && @imagecreatetruecolor(1, 1)) {
988
+                    $gd_info['GD Version'] = '2.0.1 or higher (assumed)';
989
+                } elseif (function_exists('imagecreate') && @imagecreate(1, 1)) {
990
+                    $gd_info['GD Version'] = '1.6.0 or higher (assumed)';
991
+                }
992
+            }
993
+        }
994
+        return $gd_info;
995
+    }
996 996
 }
997 997
 
998 998
 
999 999
 if (!function_exists('is_executable')) {
1000
-	// in PHP v3+, but v5.0+ for Windows
1001
-	function is_executable($filename) {
1002
-		// poor substitute, but better than nothing
1003
-		return file_exists($filename);
1004
-	}
1000
+    // in PHP v3+, but v5.0+ for Windows
1001
+    function is_executable($filename) {
1002
+        // poor substitute, but better than nothing
1003
+        return file_exists($filename);
1004
+    }
1005 1005
 }
1006 1006
 
1007 1007
 
1008 1008
 if (!function_exists('preg_quote')) {
1009
-	// included in PHP v3.0.9+, but may be unavailable if not compiled in
1010
-	function preg_quote($string, $delimiter='\\') {
1011
-		static $preg_quote_array = array();
1012
-		if (empty($preg_quote_array)) {
1013
-			$escapeables = '.\\+*?[^]$(){}=!<>|:';
1014
-			for ($i = 0, $iMax = strlen($escapeables); $i < $iMax; $i++) {
1015
-				$strtr_preg_quote[$escapeables{$i}] = $delimiter.$escapeables{$i};
1016
-			}
1017
-		}
1018
-		return strtr($string, $strtr_preg_quote);
1019
-	}
1009
+    // included in PHP v3.0.9+, but may be unavailable if not compiled in
1010
+    function preg_quote($string, $delimiter='\\') {
1011
+        static $preg_quote_array = array();
1012
+        if (empty($preg_quote_array)) {
1013
+            $escapeables = '.\\+*?[^]$(){}=!<>|:';
1014
+            for ($i = 0, $iMax = strlen($escapeables); $i < $iMax; $i++) {
1015
+                $strtr_preg_quote[$escapeables{$i}] = $delimiter.$escapeables{$i};
1016
+            }
1017
+        }
1018
+        return strtr($string, $strtr_preg_quote);
1019
+    }
1020 1020
 }
1021 1021
 
1022 1022
 if (!function_exists('file_get_contents')) {
1023
-	// included in PHP v4.3.0+
1024
-	function file_get_contents($filename) {
1025
-		if (preg_match('#^(f|ht)tp\://#i', $filename)) {
1026
-			return SafeURLread($filename, $error);
1027
-		}
1028
-		if ($fp = @fopen($filename, 'rb')) {
1029
-			$rawData = '';
1030
-			do {
1031
-				$buffer = fread($fp, 8192);
1032
-				$rawData .= $buffer;
1033
-			} while (strlen($buffer) > 0);
1034
-			fclose($fp);
1035
-			return $rawData;
1036
-		}
1037
-		return false;
1038
-	}
1023
+    // included in PHP v4.3.0+
1024
+    function file_get_contents($filename) {
1025
+        if (preg_match('#^(f|ht)tp\://#i', $filename)) {
1026
+            return SafeURLread($filename, $error);
1027
+        }
1028
+        if ($fp = @fopen($filename, 'rb')) {
1029
+            $rawData = '';
1030
+            do {
1031
+                $buffer = fread($fp, 8192);
1032
+                $rawData .= $buffer;
1033
+            } while (strlen($buffer) > 0);
1034
+            fclose($fp);
1035
+            return $rawData;
1036
+        }
1037
+        return false;
1038
+    }
1039 1039
 }
1040 1040
 
1041 1041
 
1042 1042
 if (!function_exists('file_put_contents')) {
1043
-	// included in PHP v5.0.0+
1044
-	function file_put_contents($filename, $filedata) {
1045
-		if ($fp = @fopen($filename, 'wb')) {
1046
-			fwrite($fp, $filedata);
1047
-			fclose($fp);
1048
-			return true;
1049
-		}
1050
-		return false;
1051
-	}
1043
+    // included in PHP v5.0.0+
1044
+    function file_put_contents($filename, $filedata) {
1045
+        if ($fp = @fopen($filename, 'wb')) {
1046
+            fwrite($fp, $filedata);
1047
+            fclose($fp);
1048
+            return true;
1049
+        }
1050
+        return false;
1051
+    }
1052 1052
 }
1053 1053
 
1054 1054
 if (!function_exists('imagealphablending')) {
1055
-	// built-in function requires PHP v4.0.6+ *and* GD v2.0.1+
1056
-	function imagealphablending(&$img, $blendmode=true) {
1057
-		// do nothing, this function is declared here just to
1058
-		// prevent runtime errors if GD2 is not available
1059
-		return true;
1060
-	}
1055
+    // built-in function requires PHP v4.0.6+ *and* GD v2.0.1+
1056
+    function imagealphablending(&$img, $blendmode=true) {
1057
+        // do nothing, this function is declared here just to
1058
+        // prevent runtime errors if GD2 is not available
1059
+        return true;
1060
+    }
1061 1061
 }
1062 1062
 
1063 1063
 if (!function_exists('imagesavealpha')) {
1064
-	// built-in function requires PHP v4.3.2+ *and* GD v2.0.1+
1065
-	function imagesavealpha(&$img, $blendmode=true) {
1066
-		// do nothing, this function is declared here just to
1067
-		// prevent runtime errors if GD2 is not available
1068
-		return true;
1069
-	}
1064
+    // built-in function requires PHP v4.3.2+ *and* GD v2.0.1+
1065
+    function imagesavealpha(&$img, $blendmode=true) {
1066
+        // do nothing, this function is declared here just to
1067
+        // prevent runtime errors if GD2 is not available
1068
+        return true;
1069
+    }
1070 1070
 }
Please login to merge, or discard this patch.
Spacing   +84 added lines, -84 removed lines patch added patch discarded remove patch
@@ -35,7 +35,7 @@  discard block
 block discarded – undo
35 35
 	}
36 36
 
37 37
 
38
-	public static function version_compare_replacement_sub($version1, $version2, $operator='') {
38
+	public static function version_compare_replacement_sub($version1, $version2, $operator = '') {
39 39
 		// If you specify the third optional operator argument, you can test for a particular relationship.
40 40
 		// The possible operators are: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne respectively.
41 41
 		// Using this argument, the function will return 1 if the relationship is the one specified by the operator, 0 otherwise.
@@ -61,29 +61,29 @@  discard block
 block discarded – undo
61 61
 		switch ($operator) {
62 62
 			case '<':
63 63
 			case 'lt':
64
-				return (int) ($version1 < $version2);
64
+				return (int)($version1 < $version2);
65 65
 				break;
66 66
 			case '<=':
67 67
 			case 'le':
68
-				return (int) ($version1 <= $version2);
68
+				return (int)($version1 <= $version2);
69 69
 				break;
70 70
 			case '>':
71 71
 			case 'gt':
72
-				return (int) ($version1 > $version2);
72
+				return (int)($version1 > $version2);
73 73
 				break;
74 74
 			case '>=':
75 75
 			case 'ge':
76
-				return (int) ($version1 >= $version2);
76
+				return (int)($version1 >= $version2);
77 77
 				break;
78 78
 			case '==':
79 79
 			case '=':
80 80
 			case 'eq':
81
-				return (int) ($version1 == $version2);
81
+				return (int)($version1 == $version2);
82 82
 				break;
83 83
 			case '!=':
84 84
 			case '<>':
85 85
 			case 'ne':
86
-				return (int) ($version1 != $version2);
86
+				return (int)($version1 != $version2);
87 87
 				break;
88 88
 		}
89 89
 		if ($version1 == $version2) {
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
 	}
96 96
 
97 97
 
98
-	public static function version_compare_replacement($version1, $version2, $operator='') {
98
+	public static function version_compare_replacement($version1, $version2, $operator = '') {
99 99
 		if (function_exists('version_compare')) {
100 100
 			// built into PHP v4.1.0+
101 101
 			return version_compare($version1, $version2, $operator);
@@ -174,28 +174,28 @@  discard block
 block discarded – undo
174 174
 			return image_type_to_mime_type($imagetype);
175 175
 		}
176 176
 		static $image_type_to_mime_type = array(
177
-			1  => 'image/gif',                     // IMAGETYPE_GIF
178
-			2  => 'image/jpeg',                    // IMAGETYPE_JPEG
179
-			3  => 'image/png',                     // IMAGETYPE_PNG
177
+			1  => 'image/gif', // IMAGETYPE_GIF
178
+			2  => 'image/jpeg', // IMAGETYPE_JPEG
179
+			3  => 'image/png', // IMAGETYPE_PNG
180 180
 			4  => 'application/x-shockwave-flash', // IMAGETYPE_SWF
181
-			5  => 'image/psd',                     // IMAGETYPE_PSD
182
-			6  => 'image/bmp',                     // IMAGETYPE_BMP
183
-			7  => 'image/tiff',                    // IMAGETYPE_TIFF_II (intel byte order)
184
-			8  => 'image/tiff',                    // IMAGETYPE_TIFF_MM (motorola byte order)
185
-			9  => 'application/octet-stream',      // IMAGETYPE_JPC
186
-			10 => 'image/jp2',                     // IMAGETYPE_JP2
187
-			11 => 'application/octet-stream',      // IMAGETYPE_JPX
188
-			12 => 'application/octet-stream',      // IMAGETYPE_JB2
181
+			5  => 'image/psd', // IMAGETYPE_PSD
182
+			6  => 'image/bmp', // IMAGETYPE_BMP
183
+			7  => 'image/tiff', // IMAGETYPE_TIFF_II (intel byte order)
184
+			8  => 'image/tiff', // IMAGETYPE_TIFF_MM (motorola byte order)
185
+			9  => 'application/octet-stream', // IMAGETYPE_JPC
186
+			10 => 'image/jp2', // IMAGETYPE_JP2
187
+			11 => 'application/octet-stream', // IMAGETYPE_JPX
188
+			12 => 'application/octet-stream', // IMAGETYPE_JB2
189 189
 			13 => 'application/x-shockwave-flash', // IMAGETYPE_SWC
190
-			14 => 'image/iff',                     // IMAGETYPE_IFF
191
-			15 => 'image/vnd.wap.wbmp',            // IMAGETYPE_WBMP
192
-			16 => 'image/xbm',                     // IMAGETYPE_XBM
193
-
194
-			'gif'  => 'image/gif',                 // IMAGETYPE_GIF
195
-			'jpg'  => 'image/jpeg',                // IMAGETYPE_JPEG
196
-			'jpeg' => 'image/jpeg',                // IMAGETYPE_JPEG
197
-			'png'  => 'image/png',                 // IMAGETYPE_PNG
198
-			'bmp'  => 'image/bmp',                 // IMAGETYPE_BMP
190
+			14 => 'image/iff', // IMAGETYPE_IFF
191
+			15 => 'image/vnd.wap.wbmp', // IMAGETYPE_WBMP
192
+			16 => 'image/xbm', // IMAGETYPE_XBM
193
+
194
+			'gif'  => 'image/gif', // IMAGETYPE_GIF
195
+			'jpg'  => 'image/jpeg', // IMAGETYPE_JPEG
196
+			'jpeg' => 'image/jpeg', // IMAGETYPE_JPEG
197
+			'png'  => 'image/png', // IMAGETYPE_PNG
198
+			'bmp'  => 'image/bmp', // IMAGETYPE_BMP
199 199
 			'ico'  => 'image/x-icon',
200 200
 		);
201 201
 
@@ -208,7 +208,7 @@  discard block
 block discarded – undo
208 208
 			return array($width, $height);
209 209
 		}
210 210
 		$newwidth  = (abs(sin(deg2rad($angle))) * $height) + (abs(cos(deg2rad($angle))) * $width);
211
-		$newheight = (abs(sin(deg2rad($angle))) * $width)  + (abs(cos(deg2rad($angle))) * $height);
211
+		$newheight = (abs(sin(deg2rad($angle))) * $width) + (abs(cos(deg2rad($angle))) * $height);
212 212
 		return array($newwidth, $newheight);
213 213
 	}
214 214
 
@@ -227,15 +227,15 @@  discard block
 block discarded – undo
227 227
 	}
228 228
 
229 229
 
230
-	public static function ImageColorAllocateAlphaSafe(&$gdimg_hexcolorallocate, $R, $G, $B, $alpha=false) {
230
+	public static function ImageColorAllocateAlphaSafe(&$gdimg_hexcolorallocate, $R, $G, $B, $alpha = false) {
231 231
 		if (self::version_compare_replacement(PHP_VERSION, '4.3.2', '>=') && ($alpha !== false)) {
232
-			return imagecolorallocatealpha($gdimg_hexcolorallocate, $R, $G, $B, (int) $alpha);
232
+			return imagecolorallocatealpha($gdimg_hexcolorallocate, $R, $G, $B, (int)$alpha);
233 233
 		} else {
234 234
 			return imagecolorallocate($gdimg_hexcolorallocate, $R, $G, $B);
235 235
 		}
236 236
 	}
237 237
 
238
-	public static function ImageHexColorAllocate(&$gdimg_hexcolorallocate, $HexColorString, $dieOnInvalid=false, $alpha=false) {
238
+	public static function ImageHexColorAllocate(&$gdimg_hexcolorallocate, $HexColorString, $dieOnInvalid = false, $alpha = false) {
239 239
 		if (!is_resource($gdimg_hexcolorallocate)) {
240 240
 			die('$gdimg_hexcolorallocate is not a GD resource in ImageHexColorAllocate()');
241 241
 		}
@@ -279,21 +279,21 @@  discard block
 block discarded – undo
279 279
 
280 280
 
281 281
 	public static function GrayscalePixel($OriginalPixel) {
282
-		$gray = self::GrayscaleValue($OriginalPixel[ 'red'], $OriginalPixel[ 'green'], $OriginalPixel[ 'blue']);
282
+		$gray = self::GrayscaleValue($OriginalPixel['red'], $OriginalPixel['green'], $OriginalPixel['blue']);
283 283
 		return array('red'=>$gray, 'green'=>$gray, 'blue'=>$gray);
284 284
 	}
285 285
 
286 286
 
287 287
 	public static function GrayscalePixelRGB($rgb) {
288 288
 		$r = ($rgb >> 16) & 0xFF;
289
-		$g = ($rgb >>  8) & 0xFF;
290
-		$b =  $rgb        & 0xFF;
289
+		$g = ($rgb >> 8) & 0xFF;
290
+		$b = $rgb & 0xFF;
291 291
 		return ($r * 0.299) + ($g * 0.587) + ($b * 0.114);
292 292
 	}
293 293
 
294 294
 
295
-	public static function ScaleToFitInBox($width, $height, $maxwidth=null, $maxheight=null, $allow_enlarge=true, $allow_reduce=true) {
296
-		$maxwidth  = (null === $maxwidth  ? $width  : $maxwidth);
295
+	public static function ScaleToFitInBox($width, $height, $maxwidth = null, $maxheight = null, $allow_enlarge = true, $allow_reduce = true) {
296
+		$maxwidth  = (null === $maxwidth ? $width : $maxwidth);
297 297
 		$maxheight = (null === $maxheight ? $height : $maxheight);
298 298
 		$scale_x = 1;
299 299
 		$scale_y = 1;
@@ -327,13 +327,13 @@  discard block
 block discarded – undo
327 327
 
328 328
 		for ($y = $src_y; $y < $src_y + $dst_h; $y++) {
329 329
 			$sY   = $y * $scaleY;
330
-			$siY  = (int) $sY;
331
-			$siY2 = (int) $sY + $scaleY2;
330
+			$siY  = (int)$sY;
331
+			$siY2 = (int)$sY + $scaleY2;
332 332
 
333 333
 			for ($x = $src_x; $x < $src_x + $dst_w; $x++) {
334 334
 				$sX   = $x * $scaleX;
335
-				$siX  = (int) $sX;
336
-				$siX2 = (int) $sX + $scaleX2;
335
+				$siX  = (int)$sX;
336
+				$siX2 = (int)$sX + $scaleX2;
337 337
 
338 338
 				if ($isTrueColor) {
339 339
 
@@ -342,7 +342,7 @@  discard block
 block discarded – undo
342 342
 					$c3 = imagecolorat($src_img, $siX2, $siY2);
343 343
 					$c4 = imagecolorat($src_img, $siX2, $siY);
344 344
 
345
-					$r = (( $c1             +  $c2             +  $c3             +  $c4            ) >> 2) & 0xFF0000;
345
+					$r = (($c1 + $c2 + $c3 + $c4) >> 2) & 0xFF0000;
346 346
 					$g = ((($c1 & 0x00FF00) + ($c2 & 0x00FF00) + ($c3 & 0x00FF00) + ($c4 & 0x00FF00)) >> 2) & 0x00FF00;
347 347
 					$b = ((($c1 & 0x0000FF) + ($c2 & 0x0000FF) + ($c3 & 0x0000FF) + ($c4 & 0x0000FF)) >> 2);
348 348
 
@@ -353,12 +353,12 @@  discard block
 block discarded – undo
353 353
 					$c3 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY2));
354 354
 					$c4 = imagecolorsforindex($src_img, imagecolorat($src_img, $siX2, $siY));
355 355
 
356
-					$r = ($c1['red']   + $c2['red']   + $c3['red']   + $c4['red'] )  << 14;
357
-					$g = ($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) <<  6;
358
-					$b = ($c1['blue']  + $c2['blue']  + $c3['blue']  + $c4['blue'] ) >>  2;
356
+					$r = ($c1['red'] + $c2['red'] + $c3['red'] + $c4['red']) << 14;
357
+					$g = ($c1['green'] + $c2['green'] + $c3['green'] + $c4['green']) << 6;
358
+					$b = ($c1['blue'] + $c2['blue'] + $c3['blue'] + $c4['blue']) >> 2;
359 359
 
360 360
 				}
361
-				imagesetpixel($dst_img, $dst_x + $x - $src_x, $dst_y + $y - $src_y, $r+$g+$b);
361
+				imagesetpixel($dst_img, $dst_x + $x - $src_x, $dst_y + $y - $src_y, $r + $g + $b);
362 362
 			}
363 363
 		}
364 364
 		return true;
@@ -380,7 +380,7 @@  discard block
 block discarded – undo
380 380
 	}
381 381
 
382 382
 
383
-	public static function ImageCopyRespectAlpha(&$dst_im, &$src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $opacity_pct=100) {
383
+	public static function ImageCopyRespectAlpha(&$dst_im, &$src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $opacity_pct = 100) {
384 384
 		$opacipct = $opacity_pct / 100;
385 385
 		for ($x = $src_x; $x < $src_w; $x++) {
386 386
 			for ($y = $src_y; $y < $src_h; $y++) {
@@ -391,9 +391,9 @@  discard block
 block discarded – undo
391 391
 
392 392
 				$newcolor = self::ImageColorAllocateAlphaSafe(
393 393
 					$dst_im,
394
-					round($RealPixel['red']   * (1 - $overlaypct)) + ($OverlayPixel['red']   * $overlaypct),
394
+					round($RealPixel['red'] * (1 - $overlaypct)) + ($OverlayPixel['red'] * $overlaypct),
395 395
 					round($RealPixel['green'] * (1 - $overlaypct)) + ($OverlayPixel['green'] * $overlaypct),
396
-					round($RealPixel['blue']  * (1 - $overlaypct)) + ($OverlayPixel['blue']  * $overlaypct),
396
+					round($RealPixel['blue'] * (1 - $overlaypct)) + ($OverlayPixel['blue'] * $overlaypct),
397 397
 					//$RealPixel['alpha']);
398 398
 					0);
399 399
 
@@ -404,7 +404,7 @@  discard block
 block discarded – undo
404 404
 	}
405 405
 
406 406
 
407
-	public static function ProportionalResize($old_width, $old_height, $new_width=false, $new_height=false) {
407
+	public static function ProportionalResize($old_width, $old_height, $new_width = false, $new_height = false) {
408 408
 		$old_aspect_ratio = $old_width / $old_height;
409 409
 		if (($new_width === false) && ($new_height === false)) {
410 410
 			return false;
@@ -424,8 +424,8 @@  discard block
 block discarded – undo
424 424
 			$new_width = $new_height * $old_aspect_ratio;
425 425
 		}
426 426
 		return array(
427
-			(int) round($new_width),
428
-			(int) round($new_height)
427
+			(int)round($new_width),
428
+			(int)round($new_height)
429 429
 		);
430 430
 	}
431 431
 
@@ -433,7 +433,7 @@  discard block
 block discarded – undo
433 433
 	public static function FunctionIsDisabled($function) {
434 434
 		static $DisabledFunctions = null;
435 435
 		if (null === $DisabledFunctions) {
436
-			$disable_functions_local  = explode(',',     strtolower(@ini_get('disable_functions')));
436
+			$disable_functions_local  = explode(',', strtolower(@ini_get('disable_functions')));
437 437
 			$disable_functions_global = explode(',', strtolower(@get_cfg_var('disable_functions')));
438 438
 			foreach ($disable_functions_local as $key => $value) {
439 439
 				$DisabledFunctions[trim($value)] = 'local';
@@ -518,23 +518,23 @@  discard block
 block discarded – undo
518 518
 	}
519 519
 
520 520
 
521
-	public static function gd_version($fullstring=false) {
521
+	public static function gd_version($fullstring = false) {
522 522
 		static $cache_gd_version = array();
523 523
 		if (empty($cache_gd_version)) {
524 524
 			$gd_info = gd_info();
525 525
 			if (preg_match('#bundled \((.+)\)$#i', $gd_info['GD Version'], $matches)) {
526
-				$cache_gd_version[1] = $gd_info['GD Version'];  // e.g. "bundled (2.0.15 compatible)"
527
-				$cache_gd_version[0] = (float) $matches[1];     // e.g. "2.0" (not "bundled (2.0.15 compatible)")
526
+				$cache_gd_version[1] = $gd_info['GD Version']; // e.g. "bundled (2.0.15 compatible)"
527
+				$cache_gd_version[0] = (float)$matches[1]; // e.g. "2.0" (not "bundled (2.0.15 compatible)")
528 528
 			} else {
529
-				$cache_gd_version[1] = $gd_info['GD Version'];                       // e.g. "1.6.2 or higher"
530
-				$cache_gd_version[0] = (float) substr($gd_info['GD Version'], 0, 3); // e.g. "1.6" (not "1.6.2 or higher")
529
+				$cache_gd_version[1] = $gd_info['GD Version']; // e.g. "1.6.2 or higher"
530
+				$cache_gd_version[0] = (float)substr($gd_info['GD Version'], 0, 3); // e.g. "1.6" (not "1.6.2 or higher")
531 531
 			}
532 532
 		}
533
-		return $cache_gd_version[ (int) $fullstring ];
533
+		return $cache_gd_version[(int)$fullstring];
534 534
 	}
535 535
 
536 536
 
537
-	public static function filesize_remote($remotefile, $timeout=10) {
537
+	public static function filesize_remote($remotefile, $timeout = 10) {
538 538
 		$size = false;
539 539
 		$url = self::ParseURLbetter($remotefile);
540 540
 		if ($fp = @fsockopen($url['host'], ($url['port'] ? $url['port'] : 80), $errno, $errstr, $timeout)) {
@@ -545,17 +545,17 @@  discard block
 block discarded – undo
545 545
 			while (!feof($fp)) {
546 546
 				$headerline = fgets($fp, 4096);
547 547
 				if (preg_match('#^Content-Length: (.*)#i', $headerline, $matches)) {
548
-					$size = (int) $matches[ 1];
548
+					$size = (int)$matches[1];
549 549
 					break;
550 550
 				}
551 551
 			}
552
-			fclose ($fp);
552
+			fclose($fp);
553 553
 		}
554 554
 		return $size;
555 555
 	}
556 556
 
557 557
 
558
-	public static function filedate_remote($remotefile, $timeout=10) {
558
+	public static function filedate_remote($remotefile, $timeout = 10) {
559 559
 		$date = false;
560 560
 		$url = self::ParseURLbetter($remotefile);
561 561
 		if ($fp = @fsockopen($url['host'], ($url['port'] ? $url['port'] : 80), $errno, $errstr, $timeout)) {
@@ -570,7 +570,7 @@  discard block
 block discarded – undo
570 570
 					break;
571 571
 				}
572 572
 			}
573
-			fclose ($fp);
573
+			fclose($fp);
574 574
 		}
575 575
 		return $date;
576 576
 	}
@@ -606,11 +606,11 @@  discard block
 block discarded – undo
606 606
 	}
607 607
 
608 608
 
609
-	public static function LittleEndian2String($number, $minbytes=1) {
609
+	public static function LittleEndian2String($number, $minbytes = 1) {
610 610
 		$intstring = '';
611 611
 		while ($number > 0) {
612 612
 			$intstring .= chr($number & 255);
613
-			$number    >>= 8;
613
+			$number >>= 8;
614 614
 		}
615 615
 		return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
616 616
 	}
@@ -638,7 +638,7 @@  discard block
 block discarded – undo
638 638
 		return false;
639 639
 	}
640 640
 
641
-	public static function URLreadFsock($host, $file, &$errstr, $successonly=true, $port=80, $timeout=10) {
641
+	public static function URLreadFsock($host, $file, &$errstr, $successonly = true, $port = 80, $timeout = 10) {
642 642
 		if (!function_exists('fsockopen') || self::FunctionIsDisabled('fsockopen')) {
643 643
 			$errstr = 'fsockopen() unavailable';
644 644
 			return false;
@@ -662,8 +662,8 @@  discard block
 block discarded – undo
662 662
 					$Data_body .= $line;
663 663
 				}
664 664
 				if (preg_match('#^HTTP/[\\.0-9]+ ([0-9]+) (.+)$#i', rtrim($line), $matches)) {
665
-					list( , $errno, $errstr) = $matches;
666
-					$errno = (int) $errno;
665
+					list(, $errno, $errstr) = $matches;
666
+					$errno = (int)$errno;
667 667
 				} elseif (preg_match('#^Location: (.*)$#i', rtrim($line), $matches)) {
668 668
 					$header_newlocation = $matches[1];
669 669
 				}
@@ -690,7 +690,7 @@  discard block
 block discarded – undo
690 690
 		return null;
691 691
 	}
692 692
 
693
-	public static function CleanUpURLencoding($url, $queryseperator='&') {
693
+	public static function CleanUpURLencoding($url, $queryseperator = '&') {
694 694
 		if (!preg_match('#^http#i', $url)) {
695 695
 			return $url;
696 696
 		}
@@ -746,7 +746,7 @@  discard block
 block discarded – undo
746 746
 		return $parsedURL;
747 747
 	}
748 748
 
749
-	public static function SafeURLread($url, &$error, $timeout=10, $followredirects=true) {
749
+	public static function SafeURLread($url, &$error, $timeout = 10, $followredirects = true) {
750 750
 		$error   = '';
751 751
 		$errstr  = '';
752 752
 		$rawData = '';
@@ -756,7 +756,7 @@  discard block
 block discarded – undo
756 756
 
757 757
 		while (true) {
758 758
 			$tryagain = false;
759
-			$rawData = self::URLreadFsock(@$parsed_url[ 'host'], @$parsed_url[ 'path'].'?'.@$parsed_url[ 'query'], $errstr, true, (@$parsed_url[ 'port'] ? @$parsed_url[ 'port'] : 80), $timeout);
759
+			$rawData = self::URLreadFsock(@$parsed_url['host'], @$parsed_url['path'].'?'.@$parsed_url['query'], $errstr, true, (@$parsed_url['port'] ? @$parsed_url['port'] : 80), $timeout);
760 760
 			if ($followredirects && preg_match('#302 [a-z ]+; Location\\: (http.*)#i', $errstr, $matches)) {
761 761
 				$matches[1] = trim(@$matches[1]);
762 762
 				if (!@$alreadyLookedAtURLs[$matches[1]]) {
@@ -765,7 +765,7 @@  discard block
 block discarded – undo
765 765
 
766 766
 					$tryagain = true;
767 767
 					$alreadyLookedAtURLs[$matches[1]] = true;
768
-					$parsed_url = self::ParseURLbetter($matches[ 1]);
768
+					$parsed_url = self::ParseURLbetter($matches[1]);
769 769
 				}
770 770
 			}
771 771
 			if (!$tryagain) {
@@ -791,7 +791,7 @@  discard block
 block discarded – undo
791 791
 			curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
792 792
 			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
793 793
 			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
794
-			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, (bool) $followredirects);
794
+			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, (bool)$followredirects);
795 795
 			curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
796 796
 			$rawData = curl_exec($ch);
797 797
 			curl_close($ch);
@@ -806,7 +806,7 @@  discard block
 block discarded – undo
806 806
 
807 807
 		$BrokenURLfopenPHPversions = array('4.4.2');
808 808
 		if (in_array(PHP_VERSION, $BrokenURLfopenPHPversions)) {
809
-			$error .= 'fopen(URL) broken in PHP v'. PHP_VERSION .'; ';
809
+			$error .= 'fopen(URL) broken in PHP v'.PHP_VERSION.'; ';
810 810
 		} elseif (@ini_get('allow_url_fopen')) {
811 811
 			$rawData = '';
812 812
 			$error_fopen = '';
@@ -836,7 +836,7 @@  discard block
 block discarded – undo
836 836
 
837 837
 	public static function EnsureDirectoryExists($dirname, $mask = 0755) {
838 838
 		$directory_elements = explode(DIRECTORY_SEPARATOR, $dirname);
839
-		$startoffset = (!$directory_elements[0] ? 2 : 1);  // unix with leading "/" then start with 2nd element; Windows with leading "c:\" then start with 1st element
839
+		$startoffset = (!$directory_elements[0] ? 2 : 1); // unix with leading "/" then start with 2nd element; Windows with leading "c:\" then start with 1st element
840 840
 		$open_basedirs = preg_split('#[;:]#', ini_get('open_basedir'));
841 841
 		foreach ($open_basedirs as $key => $open_basedir) {
842 842
 			if (preg_match('#^'.preg_quote($open_basedir).'#', $dirname) && (strlen($dirname) > strlen($open_basedir))) {
@@ -910,10 +910,10 @@  discard block
 block discarded – undo
910 910
 
911 911
 	public static function PasswordStrength($password) {
912 912
 		$strength = 0;
913
-		$strength += strlen(preg_replace('#[^a-z]#',       '', $password)) * 0.5; // lowercase characters are weak
914
-		$strength += strlen(preg_replace('#[^A-Z]#',       '', $password)) * 0.8; // uppercase characters are somewhat better
915
-		$strength += strlen(preg_replace('#[^0-9]#',       '', $password)) * 1.0; // numbers are somewhat better
916
-		$strength += strlen(preg_replace('#[a-zA-Z0-9]#',  '', $password)) * 2.0; // other non-alphanumeric characters are best
913
+		$strength += strlen(preg_replace('#[^a-z]#', '', $password)) * 0.5; // lowercase characters are weak
914
+		$strength += strlen(preg_replace('#[^A-Z]#', '', $password)) * 0.8; // uppercase characters are somewhat better
915
+		$strength += strlen(preg_replace('#[^0-9]#', '', $password)) * 1.0; // numbers are somewhat better
916
+		$strength += strlen(preg_replace('#[a-zA-Z0-9]#', '', $password)) * 2.0; // other non-alphanumeric characters are best
917 917
 		return $strength;
918 918
 	}
919 919
 
@@ -979,7 +979,7 @@  discard block
 block discarded – undo
979 979
 							@chmod($tempfilename, $this->getParameter('config_file_create_mask'));
980 980
 
981 981
 							// if we can convert the GIF file to a GD image then GIF create support must be enabled, otherwise it's not
982
-							$gd_info['GIF Read Support'] = (bool) @imagecreatefromgif($tempfilename);
982
+							$gd_info['GIF Read Support'] = (bool)@imagecreatefromgif($tempfilename);
983 983
 						}
984 984
 						unlink($tempfilename);
985 985
 					}
@@ -1007,7 +1007,7 @@  discard block
 block discarded – undo
1007 1007
 
1008 1008
 if (!function_exists('preg_quote')) {
1009 1009
 	// included in PHP v3.0.9+, but may be unavailable if not compiled in
1010
-	function preg_quote($string, $delimiter='\\') {
1010
+	function preg_quote($string, $delimiter = '\\') {
1011 1011
 		static $preg_quote_array = array();
1012 1012
 		if (empty($preg_quote_array)) {
1013 1013
 			$escapeables = '.\\+*?[^]$(){}=!<>|:';
@@ -1053,7 +1053,7 @@  discard block
 block discarded – undo
1053 1053
 
1054 1054
 if (!function_exists('imagealphablending')) {
1055 1055
 	// built-in function requires PHP v4.0.6+ *and* GD v2.0.1+
1056
-	function imagealphablending(&$img, $blendmode=true) {
1056
+	function imagealphablending(&$img, $blendmode = true) {
1057 1057
 		// do nothing, this function is declared here just to
1058 1058
 		// prevent runtime errors if GD2 is not available
1059 1059
 		return true;
@@ -1062,7 +1062,7 @@  discard block
 block discarded – undo
1062 1062
 
1063 1063
 if (!function_exists('imagesavealpha')) {
1064 1064
 	// built-in function requires PHP v4.3.2+ *and* GD v2.0.1+
1065
-	function imagesavealpha(&$img, $blendmode=true) {
1065
+	function imagesavealpha(&$img, $blendmode = true) {
1066 1066
 		// do nothing, this function is declared here just to
1067 1067
 		// prevent runtime errors if GD2 is not available
1068 1068
 		return true;
Please login to merge, or discard this patch.