Completed
Push — master ( 8ccb48...fb1a92 )
by Lukas
65:04 queued 48:40
created
lib/private/legacy/image.php 1 patch
Indentation   +1057 added lines, -1057 removed lines patch added patch discarded remove patch
@@ -43,549 +43,549 @@  discard block
 block discarded – undo
43 43
  * Class for basic image manipulation
44 44
  */
45 45
 class OC_Image implements \OCP\IImage {
46
-	/** @var false|resource */
47
-	protected $resource = false; // tmp resource.
48
-	/** @var int */
49
-	protected $imageType = IMAGETYPE_PNG; // Default to png if file type isn't evident.
50
-	/** @var string */
51
-	protected $mimeType = 'image/png'; // Default to png
52
-	/** @var int */
53
-	protected $bitDepth = 24;
54
-	/** @var null|string */
55
-	protected $filePath = null;
56
-	/** @var finfo */
57
-	private $fileInfo;
58
-	/** @var \OCP\ILogger */
59
-	private $logger;
60
-	/** @var \OCP\IConfig */
61
-	private $config;
62
-	/** @var array */
63
-	private $exif;
46
+    /** @var false|resource */
47
+    protected $resource = false; // tmp resource.
48
+    /** @var int */
49
+    protected $imageType = IMAGETYPE_PNG; // Default to png if file type isn't evident.
50
+    /** @var string */
51
+    protected $mimeType = 'image/png'; // Default to png
52
+    /** @var int */
53
+    protected $bitDepth = 24;
54
+    /** @var null|string */
55
+    protected $filePath = null;
56
+    /** @var finfo */
57
+    private $fileInfo;
58
+    /** @var \OCP\ILogger */
59
+    private $logger;
60
+    /** @var \OCP\IConfig */
61
+    private $config;
62
+    /** @var array */
63
+    private $exif;
64 64
 
65
-	/**
66
-	 * Constructor.
67
-	 *
68
-	 * @param resource|string $imageRef The path to a local file, a base64 encoded string or a resource created by
69
-	 * an imagecreate* function.
70
-	 * @param \OCP\ILogger $logger
71
-	 * @param \OCP\IConfig $config
72
-	 */
73
-	public function __construct($imageRef = null, \OCP\ILogger $logger = null, \OCP\IConfig $config = null) {
74
-		$this->logger = $logger;
75
-		if ($logger === null) {
76
-			$this->logger = \OC::$server->getLogger();
77
-		}
78
-		$this->config = $config;
79
-		if ($config === null) {
80
-			$this->config = \OC::$server->getConfig();
81
-		}
65
+    /**
66
+     * Constructor.
67
+     *
68
+     * @param resource|string $imageRef The path to a local file, a base64 encoded string or a resource created by
69
+     * an imagecreate* function.
70
+     * @param \OCP\ILogger $logger
71
+     * @param \OCP\IConfig $config
72
+     */
73
+    public function __construct($imageRef = null, \OCP\ILogger $logger = null, \OCP\IConfig $config = null) {
74
+        $this->logger = $logger;
75
+        if ($logger === null) {
76
+            $this->logger = \OC::$server->getLogger();
77
+        }
78
+        $this->config = $config;
79
+        if ($config === null) {
80
+            $this->config = \OC::$server->getConfig();
81
+        }
82 82
 
83
-		if (\OC_Util::fileInfoLoaded()) {
84
-			$this->fileInfo = new finfo(FILEINFO_MIME_TYPE);
85
-		}
83
+        if (\OC_Util::fileInfoLoaded()) {
84
+            $this->fileInfo = new finfo(FILEINFO_MIME_TYPE);
85
+        }
86 86
 
87
-		if ($imageRef !== null) {
88
-			$this->load($imageRef);
89
-		}
90
-	}
87
+        if ($imageRef !== null) {
88
+            $this->load($imageRef);
89
+        }
90
+    }
91 91
 
92
-	/**
93
-	 * Determine whether the object contains an image resource.
94
-	 *
95
-	 * @return bool
96
-	 */
97
-	public function valid() { // apparently you can't name a method 'empty'...
98
-		return is_resource($this->resource);
99
-	}
92
+    /**
93
+     * Determine whether the object contains an image resource.
94
+     *
95
+     * @return bool
96
+     */
97
+    public function valid() { // apparently you can't name a method 'empty'...
98
+        return is_resource($this->resource);
99
+    }
100 100
 
101
-	/**
102
-	 * Returns the MIME type of the image or an empty string if no image is loaded.
103
-	 *
104
-	 * @return string
105
-	 */
106
-	public function mimeType() {
107
-		return $this->valid() ? $this->mimeType : '';
108
-	}
101
+    /**
102
+     * Returns the MIME type of the image or an empty string if no image is loaded.
103
+     *
104
+     * @return string
105
+     */
106
+    public function mimeType() {
107
+        return $this->valid() ? $this->mimeType : '';
108
+    }
109 109
 
110
-	/**
111
-	 * Returns the width of the image or -1 if no image is loaded.
112
-	 *
113
-	 * @return int
114
-	 */
115
-	public function width() {
116
-		return $this->valid() ? imagesx($this->resource) : -1;
117
-	}
110
+    /**
111
+     * Returns the width of the image or -1 if no image is loaded.
112
+     *
113
+     * @return int
114
+     */
115
+    public function width() {
116
+        return $this->valid() ? imagesx($this->resource) : -1;
117
+    }
118 118
 
119
-	/**
120
-	 * Returns the height of the image or -1 if no image is loaded.
121
-	 *
122
-	 * @return int
123
-	 */
124
-	public function height() {
125
-		return $this->valid() ? imagesy($this->resource) : -1;
126
-	}
119
+    /**
120
+     * Returns the height of the image or -1 if no image is loaded.
121
+     *
122
+     * @return int
123
+     */
124
+    public function height() {
125
+        return $this->valid() ? imagesy($this->resource) : -1;
126
+    }
127 127
 
128
-	/**
129
-	 * Returns the width when the image orientation is top-left.
130
-	 *
131
-	 * @return int
132
-	 */
133
-	public function widthTopLeft() {
134
-		$o = $this->getOrientation();
135
-		$this->logger->debug('OC_Image->widthTopLeft() Orientation: ' . $o, array('app' => 'core'));
136
-		switch ($o) {
137
-			case -1:
138
-			case 1:
139
-			case 2: // Not tested
140
-			case 3:
141
-			case 4: // Not tested
142
-				return $this->width();
143
-			case 5: // Not tested
144
-			case 6:
145
-			case 7: // Not tested
146
-			case 8:
147
-				return $this->height();
148
-		}
149
-		return $this->width();
150
-	}
128
+    /**
129
+     * Returns the width when the image orientation is top-left.
130
+     *
131
+     * @return int
132
+     */
133
+    public function widthTopLeft() {
134
+        $o = $this->getOrientation();
135
+        $this->logger->debug('OC_Image->widthTopLeft() Orientation: ' . $o, array('app' => 'core'));
136
+        switch ($o) {
137
+            case -1:
138
+            case 1:
139
+            case 2: // Not tested
140
+            case 3:
141
+            case 4: // Not tested
142
+                return $this->width();
143
+            case 5: // Not tested
144
+            case 6:
145
+            case 7: // Not tested
146
+            case 8:
147
+                return $this->height();
148
+        }
149
+        return $this->width();
150
+    }
151 151
 
152
-	/**
153
-	 * Returns the height when the image orientation is top-left.
154
-	 *
155
-	 * @return int
156
-	 */
157
-	public function heightTopLeft() {
158
-		$o = $this->getOrientation();
159
-		$this->logger->debug('OC_Image->heightTopLeft() Orientation: ' . $o, array('app' => 'core'));
160
-		switch ($o) {
161
-			case -1:
162
-			case 1:
163
-			case 2: // Not tested
164
-			case 3:
165
-			case 4: // Not tested
166
-				return $this->height();
167
-			case 5: // Not tested
168
-			case 6:
169
-			case 7: // Not tested
170
-			case 8:
171
-				return $this->width();
172
-		}
173
-		return $this->height();
174
-	}
152
+    /**
153
+     * Returns the height when the image orientation is top-left.
154
+     *
155
+     * @return int
156
+     */
157
+    public function heightTopLeft() {
158
+        $o = $this->getOrientation();
159
+        $this->logger->debug('OC_Image->heightTopLeft() Orientation: ' . $o, array('app' => 'core'));
160
+        switch ($o) {
161
+            case -1:
162
+            case 1:
163
+            case 2: // Not tested
164
+            case 3:
165
+            case 4: // Not tested
166
+                return $this->height();
167
+            case 5: // Not tested
168
+            case 6:
169
+            case 7: // Not tested
170
+            case 8:
171
+                return $this->width();
172
+        }
173
+        return $this->height();
174
+    }
175 175
 
176
-	/**
177
-	 * Outputs the image.
178
-	 *
179
-	 * @param string $mimeType
180
-	 * @return bool
181
-	 */
182
-	public function show($mimeType = null) {
183
-		if ($mimeType === null) {
184
-			$mimeType = $this->mimeType();
185
-		}
186
-		header('Content-Type: ' . $mimeType);
187
-		return $this->_output(null, $mimeType);
188
-	}
176
+    /**
177
+     * Outputs the image.
178
+     *
179
+     * @param string $mimeType
180
+     * @return bool
181
+     */
182
+    public function show($mimeType = null) {
183
+        if ($mimeType === null) {
184
+            $mimeType = $this->mimeType();
185
+        }
186
+        header('Content-Type: ' . $mimeType);
187
+        return $this->_output(null, $mimeType);
188
+    }
189 189
 
190
-	/**
191
-	 * Saves the image.
192
-	 *
193
-	 * @param string $filePath
194
-	 * @param string $mimeType
195
-	 * @return bool
196
-	 */
190
+    /**
191
+     * Saves the image.
192
+     *
193
+     * @param string $filePath
194
+     * @param string $mimeType
195
+     * @return bool
196
+     */
197 197
 
198
-	public function save($filePath = null, $mimeType = null) {
199
-		if ($mimeType === null) {
200
-			$mimeType = $this->mimeType();
201
-		}
202
-		if ($filePath === null) {
203
-			if ($this->filePath === null) {
204
-				$this->logger->error(__METHOD__ . '(): called with no path.', array('app' => 'core'));
205
-				return false;
206
-			} else {
207
-				$filePath = $this->filePath;
208
-			}
209
-		}
210
-		return $this->_output($filePath, $mimeType);
211
-	}
198
+    public function save($filePath = null, $mimeType = null) {
199
+        if ($mimeType === null) {
200
+            $mimeType = $this->mimeType();
201
+        }
202
+        if ($filePath === null) {
203
+            if ($this->filePath === null) {
204
+                $this->logger->error(__METHOD__ . '(): called with no path.', array('app' => 'core'));
205
+                return false;
206
+            } else {
207
+                $filePath = $this->filePath;
208
+            }
209
+        }
210
+        return $this->_output($filePath, $mimeType);
211
+    }
212 212
 
213
-	/**
214
-	 * Outputs/saves the image.
215
-	 *
216
-	 * @param string $filePath
217
-	 * @param string $mimeType
218
-	 * @return bool
219
-	 * @throws Exception
220
-	 */
221
-	private function _output($filePath = null, $mimeType = null) {
222
-		if ($filePath) {
223
-			if (!file_exists(dirname($filePath))) {
224
-				mkdir(dirname($filePath), 0777, true);
225
-			}
226
-			$isWritable = is_writable(dirname($filePath));
227
-			if (!$isWritable) {
228
-				$this->logger->error(__METHOD__ . '(): Directory \'' . dirname($filePath) . '\' is not writable.', array('app' => 'core'));
229
-				return false;
230
-			} elseif ($isWritable && file_exists($filePath) && !is_writable($filePath)) {
231
-				$this->logger->error(__METHOD__ . '(): File \'' . $filePath . '\' is not writable.', array('app' => 'core'));
232
-				return false;
233
-			}
234
-		}
235
-		if (!$this->valid()) {
236
-			return false;
237
-		}
213
+    /**
214
+     * Outputs/saves the image.
215
+     *
216
+     * @param string $filePath
217
+     * @param string $mimeType
218
+     * @return bool
219
+     * @throws Exception
220
+     */
221
+    private function _output($filePath = null, $mimeType = null) {
222
+        if ($filePath) {
223
+            if (!file_exists(dirname($filePath))) {
224
+                mkdir(dirname($filePath), 0777, true);
225
+            }
226
+            $isWritable = is_writable(dirname($filePath));
227
+            if (!$isWritable) {
228
+                $this->logger->error(__METHOD__ . '(): Directory \'' . dirname($filePath) . '\' is not writable.', array('app' => 'core'));
229
+                return false;
230
+            } elseif ($isWritable && file_exists($filePath) && !is_writable($filePath)) {
231
+                $this->logger->error(__METHOD__ . '(): File \'' . $filePath . '\' is not writable.', array('app' => 'core'));
232
+                return false;
233
+            }
234
+        }
235
+        if (!$this->valid()) {
236
+            return false;
237
+        }
238 238
 
239
-		$imageType = $this->imageType;
240
-		if ($mimeType !== null) {
241
-			switch ($mimeType) {
242
-				case 'image/gif':
243
-					$imageType = IMAGETYPE_GIF;
244
-					break;
245
-				case 'image/jpeg':
246
-					$imageType = IMAGETYPE_JPEG;
247
-					break;
248
-				case 'image/png':
249
-					$imageType = IMAGETYPE_PNG;
250
-					break;
251
-				case 'image/x-xbitmap':
252
-					$imageType = IMAGETYPE_XBM;
253
-					break;
254
-				case 'image/bmp':
255
-				case 'image/x-ms-bmp':
256
-					$imageType = IMAGETYPE_BMP;
257
-					break;
258
-				default:
259
-					throw new Exception('\OC_Image::_output(): "' . $mimeType . '" is not supported when forcing a specific output format');
260
-			}
261
-		}
239
+        $imageType = $this->imageType;
240
+        if ($mimeType !== null) {
241
+            switch ($mimeType) {
242
+                case 'image/gif':
243
+                    $imageType = IMAGETYPE_GIF;
244
+                    break;
245
+                case 'image/jpeg':
246
+                    $imageType = IMAGETYPE_JPEG;
247
+                    break;
248
+                case 'image/png':
249
+                    $imageType = IMAGETYPE_PNG;
250
+                    break;
251
+                case 'image/x-xbitmap':
252
+                    $imageType = IMAGETYPE_XBM;
253
+                    break;
254
+                case 'image/bmp':
255
+                case 'image/x-ms-bmp':
256
+                    $imageType = IMAGETYPE_BMP;
257
+                    break;
258
+                default:
259
+                    throw new Exception('\OC_Image::_output(): "' . $mimeType . '" is not supported when forcing a specific output format');
260
+            }
261
+        }
262 262
 
263
-		switch ($imageType) {
264
-			case IMAGETYPE_GIF:
265
-				$retVal = imagegif($this->resource, $filePath);
266
-				break;
267
-			case IMAGETYPE_JPEG:
268
-				$retVal = imagejpeg($this->resource, $filePath, $this->getJpegQuality());
269
-				break;
270
-			case IMAGETYPE_PNG:
271
-				$retVal = imagepng($this->resource, $filePath);
272
-				break;
273
-			case IMAGETYPE_XBM:
274
-				if (function_exists('imagexbm')) {
275
-					$retVal = imagexbm($this->resource, $filePath);
276
-				} else {
277
-					throw new Exception('\OC_Image::_output(): imagexbm() is not supported.');
278
-				}
263
+        switch ($imageType) {
264
+            case IMAGETYPE_GIF:
265
+                $retVal = imagegif($this->resource, $filePath);
266
+                break;
267
+            case IMAGETYPE_JPEG:
268
+                $retVal = imagejpeg($this->resource, $filePath, $this->getJpegQuality());
269
+                break;
270
+            case IMAGETYPE_PNG:
271
+                $retVal = imagepng($this->resource, $filePath);
272
+                break;
273
+            case IMAGETYPE_XBM:
274
+                if (function_exists('imagexbm')) {
275
+                    $retVal = imagexbm($this->resource, $filePath);
276
+                } else {
277
+                    throw new Exception('\OC_Image::_output(): imagexbm() is not supported.');
278
+                }
279 279
 
280
-				break;
281
-			case IMAGETYPE_WBMP:
282
-				$retVal = imagewbmp($this->resource, $filePath);
283
-				break;
284
-			case IMAGETYPE_BMP:
285
-				$retVal = imagebmp($this->resource, $filePath, $this->bitDepth);
286
-				break;
287
-			default:
288
-				$retVal = imagepng($this->resource, $filePath);
289
-		}
290
-		return $retVal;
291
-	}
280
+                break;
281
+            case IMAGETYPE_WBMP:
282
+                $retVal = imagewbmp($this->resource, $filePath);
283
+                break;
284
+            case IMAGETYPE_BMP:
285
+                $retVal = imagebmp($this->resource, $filePath, $this->bitDepth);
286
+                break;
287
+            default:
288
+                $retVal = imagepng($this->resource, $filePath);
289
+        }
290
+        return $retVal;
291
+    }
292 292
 
293
-	/**
294
-	 * Prints the image when called as $image().
295
-	 */
296
-	public function __invoke() {
297
-		return $this->show();
298
-	}
293
+    /**
294
+     * Prints the image when called as $image().
295
+     */
296
+    public function __invoke() {
297
+        return $this->show();
298
+    }
299 299
 
300
-	/**
301
-	 * @return resource Returns the image resource in any.
302
-	 */
303
-	public function resource() {
304
-		return $this->resource;
305
-	}
300
+    /**
301
+     * @return resource Returns the image resource in any.
302
+     */
303
+    public function resource() {
304
+        return $this->resource;
305
+    }
306 306
 
307
-	/**
308
-	 * @return null|string Returns the raw image data.
309
-	 */
310
-	public function data() {
311
-		if (!$this->valid()) {
312
-			return null;
313
-		}
314
-		ob_start();
315
-		switch ($this->mimeType) {
316
-			case "image/png":
317
-				$res = imagepng($this->resource);
318
-				break;
319
-			case "image/jpeg":
320
-				$quality = $this->getJpegQuality();
321
-				if ($quality !== null) {
322
-					$res = imagejpeg($this->resource, null, $quality);
323
-				} else {
324
-					$res = imagejpeg($this->resource);
325
-				}
326
-				break;
327
-			case "image/gif":
328
-				$res = imagegif($this->resource);
329
-				break;
330
-			default:
331
-				$res = imagepng($this->resource);
332
-				$this->logger->info('OC_Image->data. Could not guess mime-type, defaulting to png', array('app' => 'core'));
333
-				break;
334
-		}
335
-		if (!$res) {
336
-			$this->logger->error('OC_Image->data. Error getting image data.', array('app' => 'core'));
337
-		}
338
-		return ob_get_clean();
339
-	}
307
+    /**
308
+     * @return null|string Returns the raw image data.
309
+     */
310
+    public function data() {
311
+        if (!$this->valid()) {
312
+            return null;
313
+        }
314
+        ob_start();
315
+        switch ($this->mimeType) {
316
+            case "image/png":
317
+                $res = imagepng($this->resource);
318
+                break;
319
+            case "image/jpeg":
320
+                $quality = $this->getJpegQuality();
321
+                if ($quality !== null) {
322
+                    $res = imagejpeg($this->resource, null, $quality);
323
+                } else {
324
+                    $res = imagejpeg($this->resource);
325
+                }
326
+                break;
327
+            case "image/gif":
328
+                $res = imagegif($this->resource);
329
+                break;
330
+            default:
331
+                $res = imagepng($this->resource);
332
+                $this->logger->info('OC_Image->data. Could not guess mime-type, defaulting to png', array('app' => 'core'));
333
+                break;
334
+        }
335
+        if (!$res) {
336
+            $this->logger->error('OC_Image->data. Error getting image data.', array('app' => 'core'));
337
+        }
338
+        return ob_get_clean();
339
+    }
340 340
 
341
-	/**
342
-	 * @return string - base64 encoded, which is suitable for embedding in a VCard.
343
-	 */
344
-	public function __toString() {
345
-		return base64_encode($this->data());
346
-	}
341
+    /**
342
+     * @return string - base64 encoded, which is suitable for embedding in a VCard.
343
+     */
344
+    public function __toString() {
345
+        return base64_encode($this->data());
346
+    }
347 347
 
348
-	/**
349
-	 * @return int|null
350
-	 */
351
-	protected function getJpegQuality() {
352
-		$quality = $this->config->getAppValue('preview', 'jpeg_quality', 90);
353
-		if ($quality !== null) {
354
-			$quality = min(100, max(10, (int) $quality));
355
-		}
356
-		return $quality;
357
-	}
348
+    /**
349
+     * @return int|null
350
+     */
351
+    protected function getJpegQuality() {
352
+        $quality = $this->config->getAppValue('preview', 'jpeg_quality', 90);
353
+        if ($quality !== null) {
354
+            $quality = min(100, max(10, (int) $quality));
355
+        }
356
+        return $quality;
357
+    }
358 358
 
359
-	/**
360
-	 * (I'm open for suggestions on better method name ;)
361
-	 * Get the orientation based on EXIF data.
362
-	 *
363
-	 * @return int The orientation or -1 if no EXIF data is available.
364
-	 */
365
-	public function getOrientation() {
366
-		if ($this->exif !== null) {
367
-			return $this->exif['Orientation'];
368
-		}
359
+    /**
360
+     * (I'm open for suggestions on better method name ;)
361
+     * Get the orientation based on EXIF data.
362
+     *
363
+     * @return int The orientation or -1 if no EXIF data is available.
364
+     */
365
+    public function getOrientation() {
366
+        if ($this->exif !== null) {
367
+            return $this->exif['Orientation'];
368
+        }
369 369
 
370
-		if ($this->imageType !== IMAGETYPE_JPEG) {
371
-			$this->logger->debug('OC_Image->fixOrientation() Image is not a JPEG.', array('app' => 'core'));
372
-			return -1;
373
-		}
374
-		if (!is_callable('exif_read_data')) {
375
-			$this->logger->debug('OC_Image->fixOrientation() Exif module not enabled.', array('app' => 'core'));
376
-			return -1;
377
-		}
378
-		if (!$this->valid()) {
379
-			$this->logger->debug('OC_Image->fixOrientation() No image loaded.', array('app' => 'core'));
380
-			return -1;
381
-		}
382
-		if (is_null($this->filePath) || !is_readable($this->filePath)) {
383
-			$this->logger->debug('OC_Image->fixOrientation() No readable file path set.', array('app' => 'core'));
384
-			return -1;
385
-		}
386
-		$exif = @exif_read_data($this->filePath, 'IFD0');
387
-		if (!$exif) {
388
-			return -1;
389
-		}
390
-		if (!isset($exif['Orientation'])) {
391
-			return -1;
392
-		}
393
-		$this->exif = $exif;
394
-		return $exif['Orientation'];
395
-	}
370
+        if ($this->imageType !== IMAGETYPE_JPEG) {
371
+            $this->logger->debug('OC_Image->fixOrientation() Image is not a JPEG.', array('app' => 'core'));
372
+            return -1;
373
+        }
374
+        if (!is_callable('exif_read_data')) {
375
+            $this->logger->debug('OC_Image->fixOrientation() Exif module not enabled.', array('app' => 'core'));
376
+            return -1;
377
+        }
378
+        if (!$this->valid()) {
379
+            $this->logger->debug('OC_Image->fixOrientation() No image loaded.', array('app' => 'core'));
380
+            return -1;
381
+        }
382
+        if (is_null($this->filePath) || !is_readable($this->filePath)) {
383
+            $this->logger->debug('OC_Image->fixOrientation() No readable file path set.', array('app' => 'core'));
384
+            return -1;
385
+        }
386
+        $exif = @exif_read_data($this->filePath, 'IFD0');
387
+        if (!$exif) {
388
+            return -1;
389
+        }
390
+        if (!isset($exif['Orientation'])) {
391
+            return -1;
392
+        }
393
+        $this->exif = $exif;
394
+        return $exif['Orientation'];
395
+    }
396 396
 
397
-	public function readExif($data) {
398
-		if (!is_callable('exif_read_data')) {
399
-			$this->logger->debug('OC_Image->fixOrientation() Exif module not enabled.', array('app' => 'core'));
400
-			return;
401
-		}
402
-		if (!$this->valid()) {
403
-			$this->logger->debug('OC_Image->fixOrientation() No image loaded.', array('app' => 'core'));
404
-			return;
405
-		}
397
+    public function readExif($data) {
398
+        if (!is_callable('exif_read_data')) {
399
+            $this->logger->debug('OC_Image->fixOrientation() Exif module not enabled.', array('app' => 'core'));
400
+            return;
401
+        }
402
+        if (!$this->valid()) {
403
+            $this->logger->debug('OC_Image->fixOrientation() No image loaded.', array('app' => 'core'));
404
+            return;
405
+        }
406 406
 
407
-		$exif = @exif_read_data('data://image/jpeg;base64,' . base64_encode($data));
408
-		if (!$exif) {
409
-			return;
410
-		}
411
-		if (!isset($exif['Orientation'])) {
412
-			return;
413
-		}
414
-		$this->exif = $exif;
415
-	}
407
+        $exif = @exif_read_data('data://image/jpeg;base64,' . base64_encode($data));
408
+        if (!$exif) {
409
+            return;
410
+        }
411
+        if (!isset($exif['Orientation'])) {
412
+            return;
413
+        }
414
+        $this->exif = $exif;
415
+    }
416 416
 
417
-	/**
418
-	 * (I'm open for suggestions on better method name ;)
419
-	 * Fixes orientation based on EXIF data.
420
-	 *
421
-	 * @return bool
422
-	 */
423
-	public function fixOrientation() {
424
-		$o = $this->getOrientation();
425
-		$this->logger->debug('OC_Image->fixOrientation() Orientation: ' . $o, array('app' => 'core'));
426
-		$rotate = 0;
427
-		$flip = false;
428
-		switch ($o) {
429
-			case -1:
430
-				return false; //Nothing to fix
431
-			case 1:
432
-				$rotate = 0;
433
-				break;
434
-			case 2:
435
-				$rotate = 0;
436
-				$flip = true;
437
-				break;
438
-			case 3:
439
-				$rotate = 180;
440
-				break;
441
-			case 4:
442
-				$rotate = 180;
443
-				$flip = true;
444
-				break;
445
-			case 5:
446
-				$rotate = 90;
447
-				$flip = true;
448
-				break;
449
-			case 6:
450
-				$rotate = 270;
451
-				break;
452
-			case 7:
453
-				$rotate = 270;
454
-				$flip = true;
455
-				break;
456
-			case 8:
457
-				$rotate = 90;
458
-				break;
459
-		}
460
-		if($flip && function_exists('imageflip')) {
461
-			imageflip($this->resource, IMG_FLIP_HORIZONTAL);
462
-		}
463
-		if ($rotate) {
464
-			$res = imagerotate($this->resource, $rotate, 0);
465
-			if ($res) {
466
-				if (imagealphablending($res, true)) {
467
-					if (imagesavealpha($res, true)) {
468
-						imagedestroy($this->resource);
469
-						$this->resource = $res;
470
-						return true;
471
-					} else {
472
-						$this->logger->debug('OC_Image->fixOrientation() Error during alpha-saving', array('app' => 'core'));
473
-						return false;
474
-					}
475
-				} else {
476
-					$this->logger->debug('OC_Image->fixOrientation() Error during alpha-blending', array('app' => 'core'));
477
-					return false;
478
-				}
479
-			} else {
480
-				$this->logger->debug('OC_Image->fixOrientation() Error during orientation fixing', array('app' => 'core'));
481
-				return false;
482
-			}
483
-		}
484
-		return false;
485
-	}
417
+    /**
418
+     * (I'm open for suggestions on better method name ;)
419
+     * Fixes orientation based on EXIF data.
420
+     *
421
+     * @return bool
422
+     */
423
+    public function fixOrientation() {
424
+        $o = $this->getOrientation();
425
+        $this->logger->debug('OC_Image->fixOrientation() Orientation: ' . $o, array('app' => 'core'));
426
+        $rotate = 0;
427
+        $flip = false;
428
+        switch ($o) {
429
+            case -1:
430
+                return false; //Nothing to fix
431
+            case 1:
432
+                $rotate = 0;
433
+                break;
434
+            case 2:
435
+                $rotate = 0;
436
+                $flip = true;
437
+                break;
438
+            case 3:
439
+                $rotate = 180;
440
+                break;
441
+            case 4:
442
+                $rotate = 180;
443
+                $flip = true;
444
+                break;
445
+            case 5:
446
+                $rotate = 90;
447
+                $flip = true;
448
+                break;
449
+            case 6:
450
+                $rotate = 270;
451
+                break;
452
+            case 7:
453
+                $rotate = 270;
454
+                $flip = true;
455
+                break;
456
+            case 8:
457
+                $rotate = 90;
458
+                break;
459
+        }
460
+        if($flip && function_exists('imageflip')) {
461
+            imageflip($this->resource, IMG_FLIP_HORIZONTAL);
462
+        }
463
+        if ($rotate) {
464
+            $res = imagerotate($this->resource, $rotate, 0);
465
+            if ($res) {
466
+                if (imagealphablending($res, true)) {
467
+                    if (imagesavealpha($res, true)) {
468
+                        imagedestroy($this->resource);
469
+                        $this->resource = $res;
470
+                        return true;
471
+                    } else {
472
+                        $this->logger->debug('OC_Image->fixOrientation() Error during alpha-saving', array('app' => 'core'));
473
+                        return false;
474
+                    }
475
+                } else {
476
+                    $this->logger->debug('OC_Image->fixOrientation() Error during alpha-blending', array('app' => 'core'));
477
+                    return false;
478
+                }
479
+            } else {
480
+                $this->logger->debug('OC_Image->fixOrientation() Error during orientation fixing', array('app' => 'core'));
481
+                return false;
482
+            }
483
+        }
484
+        return false;
485
+    }
486 486
 
487
-	/**
488
-	 * Loads an image from a local file, a base64 encoded string or a resource created by an imagecreate* function.
489
-	 *
490
-	 * @param resource|string $imageRef The path to a local file, a base64 encoded string or a resource created by an imagecreate* function or a file resource (file handle    ).
491
-	 * @return resource|false An image resource or false on error
492
-	 */
493
-	public function load($imageRef) {
494
-		if (is_resource($imageRef)) {
495
-			if (get_resource_type($imageRef) === 'gd') {
496
-				$this->resource = $imageRef;
497
-				return $this->resource;
498
-			} elseif (in_array(get_resource_type($imageRef), array('file', 'stream'))) {
499
-				return $this->loadFromFileHandle($imageRef);
500
-			}
501
-		} elseif ($this->loadFromBase64($imageRef) !== false) {
502
-			return $this->resource;
503
-		} elseif ($this->loadFromFile($imageRef) !== false) {
504
-			return $this->resource;
505
-		} elseif ($this->loadFromData($imageRef) !== false) {
506
-			return $this->resource;
507
-		}
508
-		$this->logger->debug(__METHOD__ . '(): could not load anything. Giving up!', array('app' => 'core'));
509
-		return false;
510
-	}
487
+    /**
488
+     * Loads an image from a local file, a base64 encoded string or a resource created by an imagecreate* function.
489
+     *
490
+     * @param resource|string $imageRef The path to a local file, a base64 encoded string or a resource created by an imagecreate* function or a file resource (file handle    ).
491
+     * @return resource|false An image resource or false on error
492
+     */
493
+    public function load($imageRef) {
494
+        if (is_resource($imageRef)) {
495
+            if (get_resource_type($imageRef) === 'gd') {
496
+                $this->resource = $imageRef;
497
+                return $this->resource;
498
+            } elseif (in_array(get_resource_type($imageRef), array('file', 'stream'))) {
499
+                return $this->loadFromFileHandle($imageRef);
500
+            }
501
+        } elseif ($this->loadFromBase64($imageRef) !== false) {
502
+            return $this->resource;
503
+        } elseif ($this->loadFromFile($imageRef) !== false) {
504
+            return $this->resource;
505
+        } elseif ($this->loadFromData($imageRef) !== false) {
506
+            return $this->resource;
507
+        }
508
+        $this->logger->debug(__METHOD__ . '(): could not load anything. Giving up!', array('app' => 'core'));
509
+        return false;
510
+    }
511 511
 
512
-	/**
513
-	 * Loads an image from an open file handle.
514
-	 * It is the responsibility of the caller to position the pointer at the correct place and to close the handle again.
515
-	 *
516
-	 * @param resource $handle
517
-	 * @return resource|false An image resource or false on error
518
-	 */
519
-	public function loadFromFileHandle($handle) {
520
-		$contents = stream_get_contents($handle);
521
-		if ($this->loadFromData($contents)) {
522
-			return $this->resource;
523
-		}
524
-		return false;
525
-	}
512
+    /**
513
+     * Loads an image from an open file handle.
514
+     * It is the responsibility of the caller to position the pointer at the correct place and to close the handle again.
515
+     *
516
+     * @param resource $handle
517
+     * @return resource|false An image resource or false on error
518
+     */
519
+    public function loadFromFileHandle($handle) {
520
+        $contents = stream_get_contents($handle);
521
+        if ($this->loadFromData($contents)) {
522
+            return $this->resource;
523
+        }
524
+        return false;
525
+    }
526 526
 
527
-	/**
528
-	 * Loads an image from a local file.
529
-	 *
530
-	 * @param bool|string $imagePath The path to a local file.
531
-	 * @return bool|resource An image resource or false on error
532
-	 */
533
-	public function loadFromFile($imagePath = false) {
534
-		// exif_imagetype throws "read error!" if file is less than 12 byte
535
-		if (!@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) {
536
-			return false;
537
-		}
538
-		$iType = exif_imagetype($imagePath);
539
-		switch ($iType) {
540
-			case IMAGETYPE_GIF:
541
-				if (imagetypes() & IMG_GIF) {
542
-					$this->resource = imagecreatefromgif($imagePath);
543
-					// Preserve transparency
544
-					imagealphablending($this->resource, true);
545
-					imagesavealpha($this->resource, true);
546
-				} else {
547
-					$this->logger->debug('OC_Image->loadFromFile, GIF images not supported: ' . $imagePath, array('app' => 'core'));
548
-				}
549
-				break;
550
-			case IMAGETYPE_JPEG:
551
-				if (imagetypes() & IMG_JPG) {
552
-					if (getimagesize($imagePath) !== false) {
553
-						$this->resource = @imagecreatefromjpeg($imagePath);
554
-					} else {
555
-						$this->logger->debug('OC_Image->loadFromFile, JPG image not valid: ' . $imagePath, array('app' => 'core'));
556
-					}
557
-				} else {
558
-					$this->logger->debug('OC_Image->loadFromFile, JPG images not supported: ' . $imagePath, array('app' => 'core'));
559
-				}
560
-				break;
561
-			case IMAGETYPE_PNG:
562
-				if (imagetypes() & IMG_PNG) {
563
-					$this->resource = @imagecreatefrompng($imagePath);
564
-					// Preserve transparency
565
-					imagealphablending($this->resource, true);
566
-					imagesavealpha($this->resource, true);
567
-				} else {
568
-					$this->logger->debug('OC_Image->loadFromFile, PNG images not supported: ' . $imagePath, array('app' => 'core'));
569
-				}
570
-				break;
571
-			case IMAGETYPE_XBM:
572
-				if (imagetypes() & IMG_XPM) {
573
-					$this->resource = @imagecreatefromxbm($imagePath);
574
-				} else {
575
-					$this->logger->debug('OC_Image->loadFromFile, XBM/XPM images not supported: ' . $imagePath, array('app' => 'core'));
576
-				}
577
-				break;
578
-			case IMAGETYPE_WBMP:
579
-				if (imagetypes() & IMG_WBMP) {
580
-					$this->resource = @imagecreatefromwbmp($imagePath);
581
-				} else {
582
-					$this->logger->debug('OC_Image->loadFromFile, WBMP images not supported: ' . $imagePath, array('app' => 'core'));
583
-				}
584
-				break;
585
-			case IMAGETYPE_BMP:
586
-				$this->resource = $this->imagecreatefrombmp($imagePath);
587
-				break;
588
-			/*
527
+    /**
528
+     * Loads an image from a local file.
529
+     *
530
+     * @param bool|string $imagePath The path to a local file.
531
+     * @return bool|resource An image resource or false on error
532
+     */
533
+    public function loadFromFile($imagePath = false) {
534
+        // exif_imagetype throws "read error!" if file is less than 12 byte
535
+        if (!@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) {
536
+            return false;
537
+        }
538
+        $iType = exif_imagetype($imagePath);
539
+        switch ($iType) {
540
+            case IMAGETYPE_GIF:
541
+                if (imagetypes() & IMG_GIF) {
542
+                    $this->resource = imagecreatefromgif($imagePath);
543
+                    // Preserve transparency
544
+                    imagealphablending($this->resource, true);
545
+                    imagesavealpha($this->resource, true);
546
+                } else {
547
+                    $this->logger->debug('OC_Image->loadFromFile, GIF images not supported: ' . $imagePath, array('app' => 'core'));
548
+                }
549
+                break;
550
+            case IMAGETYPE_JPEG:
551
+                if (imagetypes() & IMG_JPG) {
552
+                    if (getimagesize($imagePath) !== false) {
553
+                        $this->resource = @imagecreatefromjpeg($imagePath);
554
+                    } else {
555
+                        $this->logger->debug('OC_Image->loadFromFile, JPG image not valid: ' . $imagePath, array('app' => 'core'));
556
+                    }
557
+                } else {
558
+                    $this->logger->debug('OC_Image->loadFromFile, JPG images not supported: ' . $imagePath, array('app' => 'core'));
559
+                }
560
+                break;
561
+            case IMAGETYPE_PNG:
562
+                if (imagetypes() & IMG_PNG) {
563
+                    $this->resource = @imagecreatefrompng($imagePath);
564
+                    // Preserve transparency
565
+                    imagealphablending($this->resource, true);
566
+                    imagesavealpha($this->resource, true);
567
+                } else {
568
+                    $this->logger->debug('OC_Image->loadFromFile, PNG images not supported: ' . $imagePath, array('app' => 'core'));
569
+                }
570
+                break;
571
+            case IMAGETYPE_XBM:
572
+                if (imagetypes() & IMG_XPM) {
573
+                    $this->resource = @imagecreatefromxbm($imagePath);
574
+                } else {
575
+                    $this->logger->debug('OC_Image->loadFromFile, XBM/XPM images not supported: ' . $imagePath, array('app' => 'core'));
576
+                }
577
+                break;
578
+            case IMAGETYPE_WBMP:
579
+                if (imagetypes() & IMG_WBMP) {
580
+                    $this->resource = @imagecreatefromwbmp($imagePath);
581
+                } else {
582
+                    $this->logger->debug('OC_Image->loadFromFile, WBMP images not supported: ' . $imagePath, array('app' => 'core'));
583
+                }
584
+                break;
585
+            case IMAGETYPE_BMP:
586
+                $this->resource = $this->imagecreatefrombmp($imagePath);
587
+                break;
588
+            /*
589 589
 			case IMAGETYPE_TIFF_II: // (intel byte order)
590 590
 				break;
591 591
 			case IMAGETYPE_TIFF_MM: // (motorola byte order)
@@ -609,581 +609,581 @@  discard block
 block discarded – undo
609 609
 			case IMAGETYPE_PSD:
610 610
 				break;
611 611
 			*/
612
-			default:
612
+            default:
613 613
 
614
-				// this is mostly file created from encrypted file
615
-				$this->resource = imagecreatefromstring(\OC\Files\Filesystem::file_get_contents(\OC\Files\Filesystem::getLocalPath($imagePath)));
616
-				$iType = IMAGETYPE_PNG;
617
-				$this->logger->debug('OC_Image->loadFromFile, Default', array('app' => 'core'));
618
-				break;
619
-		}
620
-		if ($this->valid()) {
621
-			$this->imageType = $iType;
622
-			$this->mimeType = image_type_to_mime_type($iType);
623
-			$this->filePath = $imagePath;
624
-		}
625
-		return $this->resource;
626
-	}
614
+                // this is mostly file created from encrypted file
615
+                $this->resource = imagecreatefromstring(\OC\Files\Filesystem::file_get_contents(\OC\Files\Filesystem::getLocalPath($imagePath)));
616
+                $iType = IMAGETYPE_PNG;
617
+                $this->logger->debug('OC_Image->loadFromFile, Default', array('app' => 'core'));
618
+                break;
619
+        }
620
+        if ($this->valid()) {
621
+            $this->imageType = $iType;
622
+            $this->mimeType = image_type_to_mime_type($iType);
623
+            $this->filePath = $imagePath;
624
+        }
625
+        return $this->resource;
626
+    }
627 627
 
628
-	/**
629
-	 * Loads an image from a string of data.
630
-	 *
631
-	 * @param string $str A string of image data as read from a file.
632
-	 * @return bool|resource An image resource or false on error
633
-	 */
634
-	public function loadFromData($str) {
635
-		if (is_resource($str)) {
636
-			return false;
637
-		}
638
-		$this->resource = @imagecreatefromstring($str);
639
-		if ($this->fileInfo) {
640
-			$this->mimeType = $this->fileInfo->buffer($str);
641
-		}
642
-		if (is_resource($this->resource)) {
643
-			imagealphablending($this->resource, false);
644
-			imagesavealpha($this->resource, true);
645
-		}
628
+    /**
629
+     * Loads an image from a string of data.
630
+     *
631
+     * @param string $str A string of image data as read from a file.
632
+     * @return bool|resource An image resource or false on error
633
+     */
634
+    public function loadFromData($str) {
635
+        if (is_resource($str)) {
636
+            return false;
637
+        }
638
+        $this->resource = @imagecreatefromstring($str);
639
+        if ($this->fileInfo) {
640
+            $this->mimeType = $this->fileInfo->buffer($str);
641
+        }
642
+        if (is_resource($this->resource)) {
643
+            imagealphablending($this->resource, false);
644
+            imagesavealpha($this->resource, true);
645
+        }
646 646
 
647
-		if (!$this->resource) {
648
-			$this->logger->debug('OC_Image->loadFromFile, could not load', array('app' => 'core'));
649
-			return false;
650
-		}
651
-		return $this->resource;
652
-	}
647
+        if (!$this->resource) {
648
+            $this->logger->debug('OC_Image->loadFromFile, could not load', array('app' => 'core'));
649
+            return false;
650
+        }
651
+        return $this->resource;
652
+    }
653 653
 
654
-	/**
655
-	 * Loads an image from a base64 encoded string.
656
-	 *
657
-	 * @param string $str A string base64 encoded string of image data.
658
-	 * @return bool|resource An image resource or false on error
659
-	 */
660
-	public function loadFromBase64($str) {
661
-		if (!is_string($str)) {
662
-			return false;
663
-		}
664
-		$data = base64_decode($str);
665
-		if ($data) { // try to load from string data
666
-			$this->resource = @imagecreatefromstring($data);
667
-			if ($this->fileInfo) {
668
-				$this->mimeType = $this->fileInfo->buffer($data);
669
-			}
670
-			if (!$this->resource) {
671
-				$this->logger->debug('OC_Image->loadFromBase64, could not load', array('app' => 'core'));
672
-				return false;
673
-			}
674
-			return $this->resource;
675
-		} else {
676
-			return false;
677
-		}
678
-	}
654
+    /**
655
+     * Loads an image from a base64 encoded string.
656
+     *
657
+     * @param string $str A string base64 encoded string of image data.
658
+     * @return bool|resource An image resource or false on error
659
+     */
660
+    public function loadFromBase64($str) {
661
+        if (!is_string($str)) {
662
+            return false;
663
+        }
664
+        $data = base64_decode($str);
665
+        if ($data) { // try to load from string data
666
+            $this->resource = @imagecreatefromstring($data);
667
+            if ($this->fileInfo) {
668
+                $this->mimeType = $this->fileInfo->buffer($data);
669
+            }
670
+            if (!$this->resource) {
671
+                $this->logger->debug('OC_Image->loadFromBase64, could not load', array('app' => 'core'));
672
+                return false;
673
+            }
674
+            return $this->resource;
675
+        } else {
676
+            return false;
677
+        }
678
+    }
679 679
 
680
-	/**
681
-	 * Create a new image from file or URL
682
-	 *
683
-	 * @link http://www.programmierer-forum.de/function-imagecreatefrombmp-laeuft-mit-allen-bitraten-t143137.htm
684
-	 * @version 1.00
685
-	 * @param string $fileName <p>
686
-	 * Path to the BMP image.
687
-	 * </p>
688
-	 * @return bool|resource an image resource identifier on success, <b>FALSE</b> on errors.
689
-	 */
690
-	private function imagecreatefrombmp($fileName) {
691
-		if (!($fh = fopen($fileName, 'rb'))) {
692
-			$this->logger->warning('imagecreatefrombmp: Can not open ' . $fileName, array('app' => 'core'));
693
-			return false;
694
-		}
695
-		// read file header
696
-		$meta = unpack('vtype/Vfilesize/Vreserved/Voffset', fread($fh, 14));
697
-		// check for bitmap
698
-		if ($meta['type'] != 19778) {
699
-			fclose($fh);
700
-			$this->logger->warning('imagecreatefrombmp: Can not open ' . $fileName . ' is not a bitmap!', array('app' => 'core'));
701
-			return false;
702
-		}
703
-		// read image header
704
-		$meta += unpack('Vheadersize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vcolors/Vimportant', fread($fh, 40));
705
-		// read additional 16bit header
706
-		if ($meta['bits'] == 16) {
707
-			$meta += unpack('VrMask/VgMask/VbMask', fread($fh, 12));
708
-		}
709
-		// set bytes and padding
710
-		$meta['bytes'] = $meta['bits'] / 8;
711
-		$this->bitDepth = $meta['bits']; //remember the bit depth for the imagebmp call
712
-		$meta['decal'] = 4 - (4 * (($meta['width'] * $meta['bytes'] / 4) - floor($meta['width'] * $meta['bytes'] / 4)));
713
-		if ($meta['decal'] == 4) {
714
-			$meta['decal'] = 0;
715
-		}
716
-		// obtain imagesize
717
-		if ($meta['imagesize'] < 1) {
718
-			$meta['imagesize'] = $meta['filesize'] - $meta['offset'];
719
-			// in rare cases filesize is equal to offset so we need to read physical size
720
-			if ($meta['imagesize'] < 1) {
721
-				$meta['imagesize'] = @filesize($fileName) - $meta['offset'];
722
-				if ($meta['imagesize'] < 1) {
723
-					fclose($fh);
724
-					$this->logger->warning('imagecreatefrombmp: Can not obtain file size of ' . $fileName . ' is not a bitmap!', array('app' => 'core'));
725
-					return false;
726
-				}
727
-			}
728
-		}
729
-		// calculate colors
730
-		$meta['colors'] = !$meta['colors'] ? pow(2, $meta['bits']) : $meta['colors'];
731
-		// read color palette
732
-		$palette = array();
733
-		if ($meta['bits'] < 16) {
734
-			$palette = unpack('l' . $meta['colors'], fread($fh, $meta['colors'] * 4));
735
-			// in rare cases the color value is signed
736
-			if ($palette[1] < 0) {
737
-				foreach ($palette as $i => $color) {
738
-					$palette[$i] = $color + 16777216;
739
-				}
740
-			}
741
-		}
742
-		// create gd image
743
-		$im = imagecreatetruecolor($meta['width'], $meta['height']);
744
-		if ($im == false) {
745
-			fclose($fh);
746
-			$this->logger->warning(
747
-				'imagecreatefrombmp: imagecreatetruecolor failed for file "' . $fileName . '" with dimensions ' . $meta['width'] . 'x' . $meta['height'],
748
-				array('app' => 'core'));
749
-			return false;
750
-		}
680
+    /**
681
+     * Create a new image from file or URL
682
+     *
683
+     * @link http://www.programmierer-forum.de/function-imagecreatefrombmp-laeuft-mit-allen-bitraten-t143137.htm
684
+     * @version 1.00
685
+     * @param string $fileName <p>
686
+     * Path to the BMP image.
687
+     * </p>
688
+     * @return bool|resource an image resource identifier on success, <b>FALSE</b> on errors.
689
+     */
690
+    private function imagecreatefrombmp($fileName) {
691
+        if (!($fh = fopen($fileName, 'rb'))) {
692
+            $this->logger->warning('imagecreatefrombmp: Can not open ' . $fileName, array('app' => 'core'));
693
+            return false;
694
+        }
695
+        // read file header
696
+        $meta = unpack('vtype/Vfilesize/Vreserved/Voffset', fread($fh, 14));
697
+        // check for bitmap
698
+        if ($meta['type'] != 19778) {
699
+            fclose($fh);
700
+            $this->logger->warning('imagecreatefrombmp: Can not open ' . $fileName . ' is not a bitmap!', array('app' => 'core'));
701
+            return false;
702
+        }
703
+        // read image header
704
+        $meta += unpack('Vheadersize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vcolors/Vimportant', fread($fh, 40));
705
+        // read additional 16bit header
706
+        if ($meta['bits'] == 16) {
707
+            $meta += unpack('VrMask/VgMask/VbMask', fread($fh, 12));
708
+        }
709
+        // set bytes and padding
710
+        $meta['bytes'] = $meta['bits'] / 8;
711
+        $this->bitDepth = $meta['bits']; //remember the bit depth for the imagebmp call
712
+        $meta['decal'] = 4 - (4 * (($meta['width'] * $meta['bytes'] / 4) - floor($meta['width'] * $meta['bytes'] / 4)));
713
+        if ($meta['decal'] == 4) {
714
+            $meta['decal'] = 0;
715
+        }
716
+        // obtain imagesize
717
+        if ($meta['imagesize'] < 1) {
718
+            $meta['imagesize'] = $meta['filesize'] - $meta['offset'];
719
+            // in rare cases filesize is equal to offset so we need to read physical size
720
+            if ($meta['imagesize'] < 1) {
721
+                $meta['imagesize'] = @filesize($fileName) - $meta['offset'];
722
+                if ($meta['imagesize'] < 1) {
723
+                    fclose($fh);
724
+                    $this->logger->warning('imagecreatefrombmp: Can not obtain file size of ' . $fileName . ' is not a bitmap!', array('app' => 'core'));
725
+                    return false;
726
+                }
727
+            }
728
+        }
729
+        // calculate colors
730
+        $meta['colors'] = !$meta['colors'] ? pow(2, $meta['bits']) : $meta['colors'];
731
+        // read color palette
732
+        $palette = array();
733
+        if ($meta['bits'] < 16) {
734
+            $palette = unpack('l' . $meta['colors'], fread($fh, $meta['colors'] * 4));
735
+            // in rare cases the color value is signed
736
+            if ($palette[1] < 0) {
737
+                foreach ($palette as $i => $color) {
738
+                    $palette[$i] = $color + 16777216;
739
+                }
740
+            }
741
+        }
742
+        // create gd image
743
+        $im = imagecreatetruecolor($meta['width'], $meta['height']);
744
+        if ($im == false) {
745
+            fclose($fh);
746
+            $this->logger->warning(
747
+                'imagecreatefrombmp: imagecreatetruecolor failed for file "' . $fileName . '" with dimensions ' . $meta['width'] . 'x' . $meta['height'],
748
+                array('app' => 'core'));
749
+            return false;
750
+        }
751 751
 
752
-		$data = fread($fh, $meta['imagesize']);
753
-		$p = 0;
754
-		$vide = chr(0);
755
-		$y = $meta['height'] - 1;
756
-		$error = 'imagecreatefrombmp: ' . $fileName . ' has not enough data!';
757
-		// loop through the image data beginning with the lower left corner
758
-		while ($y >= 0) {
759
-			$x = 0;
760
-			while ($x < $meta['width']) {
761
-				switch ($meta['bits']) {
762
-					case 32:
763
-					case 24:
764
-						if (!($part = substr($data, $p, 3))) {
765
-							$this->logger->warning($error, array('app' => 'core'));
766
-							return $im;
767
-						}
768
-						$color = @unpack('V', $part . $vide);
769
-						break;
770
-					case 16:
771
-						if (!($part = substr($data, $p, 2))) {
772
-							fclose($fh);
773
-							$this->logger->warning($error, array('app' => 'core'));
774
-							return $im;
775
-						}
776
-						$color = @unpack('v', $part);
777
-						$color[1] = (($color[1] & 0xf800) >> 8) * 65536 + (($color[1] & 0x07e0) >> 3) * 256 + (($color[1] & 0x001f) << 3);
778
-						break;
779
-					case 8:
780
-						$color = @unpack('n', $vide . substr($data, $p, 1));
781
-						$color[1] = (isset($palette[$color[1] + 1])) ? $palette[$color[1] + 1] : $palette[1];
782
-						break;
783
-					case 4:
784
-						$color = @unpack('n', $vide . substr($data, floor($p), 1));
785
-						$color[1] = ($p * 2) % 2 == 0 ? $color[1] >> 4 : $color[1] & 0x0F;
786
-						$color[1] = (isset($palette[$color[1] + 1])) ? $palette[$color[1] + 1] : $palette[1];
787
-						break;
788
-					case 1:
789
-						$color = @unpack('n', $vide . substr($data, floor($p), 1));
790
-						switch (($p * 8) % 8) {
791
-							case 0:
792
-								$color[1] = $color[1] >> 7;
793
-								break;
794
-							case 1:
795
-								$color[1] = ($color[1] & 0x40) >> 6;
796
-								break;
797
-							case 2:
798
-								$color[1] = ($color[1] & 0x20) >> 5;
799
-								break;
800
-							case 3:
801
-								$color[1] = ($color[1] & 0x10) >> 4;
802
-								break;
803
-							case 4:
804
-								$color[1] = ($color[1] & 0x8) >> 3;
805
-								break;
806
-							case 5:
807
-								$color[1] = ($color[1] & 0x4) >> 2;
808
-								break;
809
-							case 6:
810
-								$color[1] = ($color[1] & 0x2) >> 1;
811
-								break;
812
-							case 7:
813
-								$color[1] = ($color[1] & 0x1);
814
-								break;
815
-						}
816
-						$color[1] = (isset($palette[$color[1] + 1])) ? $palette[$color[1] + 1] : $palette[1];
817
-						break;
818
-					default:
819
-						fclose($fh);
820
-						$this->logger->warning('imagecreatefrombmp: ' . $fileName . ' has ' . $meta['bits'] . ' bits and this is not supported!', array('app' => 'core'));
821
-						return false;
822
-				}
823
-				imagesetpixel($im, $x, $y, $color[1]);
824
-				$x++;
825
-				$p += $meta['bytes'];
826
-			}
827
-			$y--;
828
-			$p += $meta['decal'];
829
-		}
830
-		fclose($fh);
831
-		return $im;
832
-	}
752
+        $data = fread($fh, $meta['imagesize']);
753
+        $p = 0;
754
+        $vide = chr(0);
755
+        $y = $meta['height'] - 1;
756
+        $error = 'imagecreatefrombmp: ' . $fileName . ' has not enough data!';
757
+        // loop through the image data beginning with the lower left corner
758
+        while ($y >= 0) {
759
+            $x = 0;
760
+            while ($x < $meta['width']) {
761
+                switch ($meta['bits']) {
762
+                    case 32:
763
+                    case 24:
764
+                        if (!($part = substr($data, $p, 3))) {
765
+                            $this->logger->warning($error, array('app' => 'core'));
766
+                            return $im;
767
+                        }
768
+                        $color = @unpack('V', $part . $vide);
769
+                        break;
770
+                    case 16:
771
+                        if (!($part = substr($data, $p, 2))) {
772
+                            fclose($fh);
773
+                            $this->logger->warning($error, array('app' => 'core'));
774
+                            return $im;
775
+                        }
776
+                        $color = @unpack('v', $part);
777
+                        $color[1] = (($color[1] & 0xf800) >> 8) * 65536 + (($color[1] & 0x07e0) >> 3) * 256 + (($color[1] & 0x001f) << 3);
778
+                        break;
779
+                    case 8:
780
+                        $color = @unpack('n', $vide . substr($data, $p, 1));
781
+                        $color[1] = (isset($palette[$color[1] + 1])) ? $palette[$color[1] + 1] : $palette[1];
782
+                        break;
783
+                    case 4:
784
+                        $color = @unpack('n', $vide . substr($data, floor($p), 1));
785
+                        $color[1] = ($p * 2) % 2 == 0 ? $color[1] >> 4 : $color[1] & 0x0F;
786
+                        $color[1] = (isset($palette[$color[1] + 1])) ? $palette[$color[1] + 1] : $palette[1];
787
+                        break;
788
+                    case 1:
789
+                        $color = @unpack('n', $vide . substr($data, floor($p), 1));
790
+                        switch (($p * 8) % 8) {
791
+                            case 0:
792
+                                $color[1] = $color[1] >> 7;
793
+                                break;
794
+                            case 1:
795
+                                $color[1] = ($color[1] & 0x40) >> 6;
796
+                                break;
797
+                            case 2:
798
+                                $color[1] = ($color[1] & 0x20) >> 5;
799
+                                break;
800
+                            case 3:
801
+                                $color[1] = ($color[1] & 0x10) >> 4;
802
+                                break;
803
+                            case 4:
804
+                                $color[1] = ($color[1] & 0x8) >> 3;
805
+                                break;
806
+                            case 5:
807
+                                $color[1] = ($color[1] & 0x4) >> 2;
808
+                                break;
809
+                            case 6:
810
+                                $color[1] = ($color[1] & 0x2) >> 1;
811
+                                break;
812
+                            case 7:
813
+                                $color[1] = ($color[1] & 0x1);
814
+                                break;
815
+                        }
816
+                        $color[1] = (isset($palette[$color[1] + 1])) ? $palette[$color[1] + 1] : $palette[1];
817
+                        break;
818
+                    default:
819
+                        fclose($fh);
820
+                        $this->logger->warning('imagecreatefrombmp: ' . $fileName . ' has ' . $meta['bits'] . ' bits and this is not supported!', array('app' => 'core'));
821
+                        return false;
822
+                }
823
+                imagesetpixel($im, $x, $y, $color[1]);
824
+                $x++;
825
+                $p += $meta['bytes'];
826
+            }
827
+            $y--;
828
+            $p += $meta['decal'];
829
+        }
830
+        fclose($fh);
831
+        return $im;
832
+    }
833 833
 
834
-	/**
835
-	 * Resizes the image preserving ratio.
836
-	 *
837
-	 * @param integer $maxSize The maximum size of either the width or height.
838
-	 * @return bool
839
-	 */
840
-	public function resize($maxSize) {
841
-		if (!$this->valid()) {
842
-			$this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
843
-			return false;
844
-		}
845
-		$widthOrig = imagesx($this->resource);
846
-		$heightOrig = imagesy($this->resource);
847
-		$ratioOrig = $widthOrig / $heightOrig;
834
+    /**
835
+     * Resizes the image preserving ratio.
836
+     *
837
+     * @param integer $maxSize The maximum size of either the width or height.
838
+     * @return bool
839
+     */
840
+    public function resize($maxSize) {
841
+        if (!$this->valid()) {
842
+            $this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
843
+            return false;
844
+        }
845
+        $widthOrig = imagesx($this->resource);
846
+        $heightOrig = imagesy($this->resource);
847
+        $ratioOrig = $widthOrig / $heightOrig;
848 848
 
849
-		if ($ratioOrig > 1) {
850
-			$newHeight = round($maxSize / $ratioOrig);
851
-			$newWidth = $maxSize;
852
-		} else {
853
-			$newWidth = round($maxSize * $ratioOrig);
854
-			$newHeight = $maxSize;
855
-		}
849
+        if ($ratioOrig > 1) {
850
+            $newHeight = round($maxSize / $ratioOrig);
851
+            $newWidth = $maxSize;
852
+        } else {
853
+            $newWidth = round($maxSize * $ratioOrig);
854
+            $newHeight = $maxSize;
855
+        }
856 856
 
857
-		$this->preciseResize(round($newWidth), round($newHeight));
858
-		return true;
859
-	}
857
+        $this->preciseResize(round($newWidth), round($newHeight));
858
+        return true;
859
+    }
860 860
 
861
-	/**
862
-	 * @param int $width
863
-	 * @param int $height
864
-	 * @return bool
865
-	 */
866
-	public function preciseResize($width, $height) {
867
-		if (!$this->valid()) {
868
-			$this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
869
-			return false;
870
-		}
871
-		$widthOrig = imagesx($this->resource);
872
-		$heightOrig = imagesy($this->resource);
873
-		$process = imagecreatetruecolor($width, $height);
861
+    /**
862
+     * @param int $width
863
+     * @param int $height
864
+     * @return bool
865
+     */
866
+    public function preciseResize($width, $height) {
867
+        if (!$this->valid()) {
868
+            $this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
869
+            return false;
870
+        }
871
+        $widthOrig = imagesx($this->resource);
872
+        $heightOrig = imagesy($this->resource);
873
+        $process = imagecreatetruecolor($width, $height);
874 874
 
875
-		if ($process == false) {
876
-			$this->logger->error(__METHOD__ . '(): Error creating true color image', array('app' => 'core'));
877
-			imagedestroy($process);
878
-			return false;
879
-		}
875
+        if ($process == false) {
876
+            $this->logger->error(__METHOD__ . '(): Error creating true color image', array('app' => 'core'));
877
+            imagedestroy($process);
878
+            return false;
879
+        }
880 880
 
881
-		// preserve transparency
882
-		if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
883
-			imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127));
884
-			imagealphablending($process, false);
885
-			imagesavealpha($process, true);
886
-		}
881
+        // preserve transparency
882
+        if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
883
+            imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127));
884
+            imagealphablending($process, false);
885
+            imagesavealpha($process, true);
886
+        }
887 887
 
888
-		imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $widthOrig, $heightOrig);
889
-		if ($process == false) {
890
-			$this->logger->error(__METHOD__ . '(): Error re-sampling process image', array('app' => 'core'));
891
-			imagedestroy($process);
892
-			return false;
893
-		}
894
-		imagedestroy($this->resource);
895
-		$this->resource = $process;
896
-		return true;
897
-	}
888
+        imagecopyresampled($process, $this->resource, 0, 0, 0, 0, $width, $height, $widthOrig, $heightOrig);
889
+        if ($process == false) {
890
+            $this->logger->error(__METHOD__ . '(): Error re-sampling process image', array('app' => 'core'));
891
+            imagedestroy($process);
892
+            return false;
893
+        }
894
+        imagedestroy($this->resource);
895
+        $this->resource = $process;
896
+        return true;
897
+    }
898 898
 
899
-	/**
900
-	 * Crops the image to the middle square. If the image is already square it just returns.
901
-	 *
902
-	 * @param int $size maximum size for the result (optional)
903
-	 * @return bool for success or failure
904
-	 */
905
-	public function centerCrop($size = 0) {
906
-		if (!$this->valid()) {
907
-			$this->logger->error('OC_Image->centerCrop, No image loaded', array('app' => 'core'));
908
-			return false;
909
-		}
910
-		$widthOrig = imagesx($this->resource);
911
-		$heightOrig = imagesy($this->resource);
912
-		if ($widthOrig === $heightOrig and $size == 0) {
913
-			return true;
914
-		}
915
-		$ratioOrig = $widthOrig / $heightOrig;
916
-		$width = $height = min($widthOrig, $heightOrig);
899
+    /**
900
+     * Crops the image to the middle square. If the image is already square it just returns.
901
+     *
902
+     * @param int $size maximum size for the result (optional)
903
+     * @return bool for success or failure
904
+     */
905
+    public function centerCrop($size = 0) {
906
+        if (!$this->valid()) {
907
+            $this->logger->error('OC_Image->centerCrop, No image loaded', array('app' => 'core'));
908
+            return false;
909
+        }
910
+        $widthOrig = imagesx($this->resource);
911
+        $heightOrig = imagesy($this->resource);
912
+        if ($widthOrig === $heightOrig and $size == 0) {
913
+            return true;
914
+        }
915
+        $ratioOrig = $widthOrig / $heightOrig;
916
+        $width = $height = min($widthOrig, $heightOrig);
917 917
 
918
-		if ($ratioOrig > 1) {
919
-			$x = ($widthOrig / 2) - ($width / 2);
920
-			$y = 0;
921
-		} else {
922
-			$y = ($heightOrig / 2) - ($height / 2);
923
-			$x = 0;
924
-		}
925
-		if ($size > 0) {
926
-			$targetWidth = $size;
927
-			$targetHeight = $size;
928
-		} else {
929
-			$targetWidth = $width;
930
-			$targetHeight = $height;
931
-		}
932
-		$process = imagecreatetruecolor($targetWidth, $targetHeight);
933
-		if ($process == false) {
934
-			$this->logger->error('OC_Image->centerCrop, Error creating true color image', array('app' => 'core'));
935
-			imagedestroy($process);
936
-			return false;
937
-		}
918
+        if ($ratioOrig > 1) {
919
+            $x = ($widthOrig / 2) - ($width / 2);
920
+            $y = 0;
921
+        } else {
922
+            $y = ($heightOrig / 2) - ($height / 2);
923
+            $x = 0;
924
+        }
925
+        if ($size > 0) {
926
+            $targetWidth = $size;
927
+            $targetHeight = $size;
928
+        } else {
929
+            $targetWidth = $width;
930
+            $targetHeight = $height;
931
+        }
932
+        $process = imagecreatetruecolor($targetWidth, $targetHeight);
933
+        if ($process == false) {
934
+            $this->logger->error('OC_Image->centerCrop, Error creating true color image', array('app' => 'core'));
935
+            imagedestroy($process);
936
+            return false;
937
+        }
938 938
 
939
-		// preserve transparency
940
-		if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
941
-			imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127));
942
-			imagealphablending($process, false);
943
-			imagesavealpha($process, true);
944
-		}
939
+        // preserve transparency
940
+        if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
941
+            imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127));
942
+            imagealphablending($process, false);
943
+            imagesavealpha($process, true);
944
+        }
945 945
 
946
-		imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $targetWidth, $targetHeight, $width, $height);
947
-		if ($process == false) {
948
-			$this->logger->error('OC_Image->centerCrop, Error re-sampling process image ' . $width . 'x' . $height, array('app' => 'core'));
949
-			imagedestroy($process);
950
-			return false;
951
-		}
952
-		imagedestroy($this->resource);
953
-		$this->resource = $process;
954
-		return true;
955
-	}
946
+        imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $targetWidth, $targetHeight, $width, $height);
947
+        if ($process == false) {
948
+            $this->logger->error('OC_Image->centerCrop, Error re-sampling process image ' . $width . 'x' . $height, array('app' => 'core'));
949
+            imagedestroy($process);
950
+            return false;
951
+        }
952
+        imagedestroy($this->resource);
953
+        $this->resource = $process;
954
+        return true;
955
+    }
956 956
 
957
-	/**
958
-	 * Crops the image from point $x$y with dimension $wx$h.
959
-	 *
960
-	 * @param int $x Horizontal position
961
-	 * @param int $y Vertical position
962
-	 * @param int $w Width
963
-	 * @param int $h Height
964
-	 * @return bool for success or failure
965
-	 */
966
-	public function crop($x, $y, $w, $h) {
967
-		if (!$this->valid()) {
968
-			$this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
969
-			return false;
970
-		}
971
-		$process = imagecreatetruecolor($w, $h);
972
-		if ($process == false) {
973
-			$this->logger->error(__METHOD__ . '(): Error creating true color image', array('app' => 'core'));
974
-			imagedestroy($process);
975
-			return false;
976
-		}
957
+    /**
958
+     * Crops the image from point $x$y with dimension $wx$h.
959
+     *
960
+     * @param int $x Horizontal position
961
+     * @param int $y Vertical position
962
+     * @param int $w Width
963
+     * @param int $h Height
964
+     * @return bool for success or failure
965
+     */
966
+    public function crop($x, $y, $w, $h) {
967
+        if (!$this->valid()) {
968
+            $this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
969
+            return false;
970
+        }
971
+        $process = imagecreatetruecolor($w, $h);
972
+        if ($process == false) {
973
+            $this->logger->error(__METHOD__ . '(): Error creating true color image', array('app' => 'core'));
974
+            imagedestroy($process);
975
+            return false;
976
+        }
977 977
 
978
-		// preserve transparency
979
-		if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
980
-			imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127));
981
-			imagealphablending($process, false);
982
-			imagesavealpha($process, true);
983
-		}
978
+        // preserve transparency
979
+        if ($this->imageType == IMAGETYPE_GIF or $this->imageType == IMAGETYPE_PNG) {
980
+            imagecolortransparent($process, imagecolorallocatealpha($process, 0, 0, 0, 127));
981
+            imagealphablending($process, false);
982
+            imagesavealpha($process, true);
983
+        }
984 984
 
985
-		imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $w, $h, $w, $h);
986
-		if ($process == false) {
987
-			$this->logger->error(__METHOD__ . '(): Error re-sampling process image ' . $w . 'x' . $h, array('app' => 'core'));
988
-			imagedestroy($process);
989
-			return false;
990
-		}
991
-		imagedestroy($this->resource);
992
-		$this->resource = $process;
993
-		return true;
994
-	}
985
+        imagecopyresampled($process, $this->resource, 0, 0, $x, $y, $w, $h, $w, $h);
986
+        if ($process == false) {
987
+            $this->logger->error(__METHOD__ . '(): Error re-sampling process image ' . $w . 'x' . $h, array('app' => 'core'));
988
+            imagedestroy($process);
989
+            return false;
990
+        }
991
+        imagedestroy($this->resource);
992
+        $this->resource = $process;
993
+        return true;
994
+    }
995 995
 
996
-	/**
997
-	 * Resizes the image to fit within a boundary while preserving ratio.
998
-	 *
999
-	 * Warning: Images smaller than $maxWidth x $maxHeight will end up being scaled up
1000
-	 *
1001
-	 * @param integer $maxWidth
1002
-	 * @param integer $maxHeight
1003
-	 * @return bool
1004
-	 */
1005
-	public function fitIn($maxWidth, $maxHeight) {
1006
-		if (!$this->valid()) {
1007
-			$this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
1008
-			return false;
1009
-		}
1010
-		$widthOrig = imagesx($this->resource);
1011
-		$heightOrig = imagesy($this->resource);
1012
-		$ratio = $widthOrig / $heightOrig;
996
+    /**
997
+     * Resizes the image to fit within a boundary while preserving ratio.
998
+     *
999
+     * Warning: Images smaller than $maxWidth x $maxHeight will end up being scaled up
1000
+     *
1001
+     * @param integer $maxWidth
1002
+     * @param integer $maxHeight
1003
+     * @return bool
1004
+     */
1005
+    public function fitIn($maxWidth, $maxHeight) {
1006
+        if (!$this->valid()) {
1007
+            $this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
1008
+            return false;
1009
+        }
1010
+        $widthOrig = imagesx($this->resource);
1011
+        $heightOrig = imagesy($this->resource);
1012
+        $ratio = $widthOrig / $heightOrig;
1013 1013
 
1014
-		$newWidth = min($maxWidth, $ratio * $maxHeight);
1015
-		$newHeight = min($maxHeight, $maxWidth / $ratio);
1014
+        $newWidth = min($maxWidth, $ratio * $maxHeight);
1015
+        $newHeight = min($maxHeight, $maxWidth / $ratio);
1016 1016
 
1017
-		$this->preciseResize(round($newWidth), round($newHeight));
1018
-		return true;
1019
-	}
1017
+        $this->preciseResize(round($newWidth), round($newHeight));
1018
+        return true;
1019
+    }
1020 1020
 
1021
-	/**
1022
-	 * Shrinks larger images to fit within specified boundaries while preserving ratio.
1023
-	 *
1024
-	 * @param integer $maxWidth
1025
-	 * @param integer $maxHeight
1026
-	 * @return bool
1027
-	 */
1028
-	public function scaleDownToFit($maxWidth, $maxHeight) {
1029
-		if (!$this->valid()) {
1030
-			$this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
1031
-			return false;
1032
-		}
1033
-		$widthOrig = imagesx($this->resource);
1034
-		$heightOrig = imagesy($this->resource);
1021
+    /**
1022
+     * Shrinks larger images to fit within specified boundaries while preserving ratio.
1023
+     *
1024
+     * @param integer $maxWidth
1025
+     * @param integer $maxHeight
1026
+     * @return bool
1027
+     */
1028
+    public function scaleDownToFit($maxWidth, $maxHeight) {
1029
+        if (!$this->valid()) {
1030
+            $this->logger->error(__METHOD__ . '(): No image loaded', array('app' => 'core'));
1031
+            return false;
1032
+        }
1033
+        $widthOrig = imagesx($this->resource);
1034
+        $heightOrig = imagesy($this->resource);
1035 1035
 
1036
-		if ($widthOrig > $maxWidth || $heightOrig > $maxHeight) {
1037
-			return $this->fitIn($maxWidth, $maxHeight);
1038
-		}
1036
+        if ($widthOrig > $maxWidth || $heightOrig > $maxHeight) {
1037
+            return $this->fitIn($maxWidth, $maxHeight);
1038
+        }
1039 1039
 
1040
-		return false;
1041
-	}
1040
+        return false;
1041
+    }
1042 1042
 
1043
-	/**
1044
-	 * Destroys the current image and resets the object
1045
-	 */
1046
-	public function destroy() {
1047
-		if ($this->valid()) {
1048
-			imagedestroy($this->resource);
1049
-		}
1050
-		$this->resource = null;
1051
-	}
1043
+    /**
1044
+     * Destroys the current image and resets the object
1045
+     */
1046
+    public function destroy() {
1047
+        if ($this->valid()) {
1048
+            imagedestroy($this->resource);
1049
+        }
1050
+        $this->resource = null;
1051
+    }
1052 1052
 
1053
-	public function __destruct() {
1054
-		$this->destroy();
1055
-	}
1053
+    public function __destruct() {
1054
+        $this->destroy();
1055
+    }
1056 1056
 }
1057 1057
 
1058 1058
 if (!function_exists('imagebmp')) {
1059
-	/**
1060
-	 * Output a BMP image to either the browser or a file
1061
-	 *
1062
-	 * @link http://www.ugia.cn/wp-data/imagebmp.php
1063
-	 * @author legend <[email protected]>
1064
-	 * @link http://www.programmierer-forum.de/imagebmp-gute-funktion-gefunden-t143716.htm
1065
-	 * @author mgutt <[email protected]>
1066
-	 * @version 1.00
1067
-	 * @param resource $im
1068
-	 * @param string $fileName [optional] <p>The path to save the file to.</p>
1069
-	 * @param int $bit [optional] <p>Bit depth, (default is 24).</p>
1070
-	 * @param int $compression [optional]
1071
-	 * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
1072
-	 */
1073
-	function imagebmp($im, $fileName = '', $bit = 24, $compression = 0) {
1074
-		if (!in_array($bit, array(1, 4, 8, 16, 24, 32))) {
1075
-			$bit = 24;
1076
-		} else if ($bit == 32) {
1077
-			$bit = 24;
1078
-		}
1079
-		$bits = pow(2, $bit);
1080
-		imagetruecolortopalette($im, true, $bits);
1081
-		$width = imagesx($im);
1082
-		$height = imagesy($im);
1083
-		$colorsNum = imagecolorstotal($im);
1084
-		$rgbQuad = '';
1085
-		if ($bit <= 8) {
1086
-			for ($i = 0; $i < $colorsNum; $i++) {
1087
-				$colors = imagecolorsforindex($im, $i);
1088
-				$rgbQuad .= chr($colors['blue']) . chr($colors['green']) . chr($colors['red']) . "\0";
1089
-			}
1090
-			$bmpData = '';
1091
-			if ($compression == 0 || $bit < 8) {
1092
-				$compression = 0;
1093
-				$extra = '';
1094
-				$padding = 4 - ceil($width / (8 / $bit)) % 4;
1095
-				if ($padding % 4 != 0) {
1096
-					$extra = str_repeat("\0", $padding);
1097
-				}
1098
-				for ($j = $height - 1; $j >= 0; $j--) {
1099
-					$i = 0;
1100
-					while ($i < $width) {
1101
-						$bin = 0;
1102
-						$limit = $width - $i < 8 / $bit ? (8 / $bit - $width + $i) * $bit : 0;
1103
-						for ($k = 8 - $bit; $k >= $limit; $k -= $bit) {
1104
-							$index = imagecolorat($im, $i, $j);
1105
-							$bin |= $index << $k;
1106
-							$i++;
1107
-						}
1108
-						$bmpData .= chr($bin);
1109
-					}
1110
-					$bmpData .= $extra;
1111
-				}
1112
-			} // RLE8
1113
-			else if ($compression == 1 && $bit == 8) {
1114
-				for ($j = $height - 1; $j >= 0; $j--) {
1115
-					$lastIndex = "\0";
1116
-					$sameNum = 0;
1117
-					for ($i = 0; $i <= $width; $i++) {
1118
-						$index = imagecolorat($im, $i, $j);
1119
-						if ($index !== $lastIndex || $sameNum > 255) {
1120
-							if ($sameNum != 0) {
1121
-								$bmpData .= chr($sameNum) . chr($lastIndex);
1122
-							}
1123
-							$lastIndex = $index;
1124
-							$sameNum = 1;
1125
-						} else {
1126
-							$sameNum++;
1127
-						}
1128
-					}
1129
-					$bmpData .= "\0\0";
1130
-				}
1131
-				$bmpData .= "\0\1";
1132
-			}
1133
-			$sizeQuad = strlen($rgbQuad);
1134
-			$sizeData = strlen($bmpData);
1135
-		} else {
1136
-			$extra = '';
1137
-			$padding = 4 - ($width * ($bit / 8)) % 4;
1138
-			if ($padding % 4 != 0) {
1139
-				$extra = str_repeat("\0", $padding);
1140
-			}
1141
-			$bmpData = '';
1142
-			for ($j = $height - 1; $j >= 0; $j--) {
1143
-				for ($i = 0; $i < $width; $i++) {
1144
-					$index = imagecolorat($im, $i, $j);
1145
-					$colors = imagecolorsforindex($im, $index);
1146
-					if ($bit == 16) {
1147
-						$bin = 0 << $bit;
1148
-						$bin |= ($colors['red'] >> 3) << 10;
1149
-						$bin |= ($colors['green'] >> 3) << 5;
1150
-						$bin |= $colors['blue'] >> 3;
1151
-						$bmpData .= pack("v", $bin);
1152
-					} else {
1153
-						$bmpData .= pack("c*", $colors['blue'], $colors['green'], $colors['red']);
1154
-					}
1155
-				}
1156
-				$bmpData .= $extra;
1157
-			}
1158
-			$sizeQuad = 0;
1159
-			$sizeData = strlen($bmpData);
1160
-			$colorsNum = 0;
1161
-		}
1162
-		$fileHeader = 'BM' . pack('V3', 54 + $sizeQuad + $sizeData, 0, 54 + $sizeQuad);
1163
-		$infoHeader = pack('V3v2V*', 0x28, $width, $height, 1, $bit, $compression, $sizeData, 0, 0, $colorsNum, 0);
1164
-		if ($fileName != '') {
1165
-			$fp = fopen($fileName, 'wb');
1166
-			fwrite($fp, $fileHeader . $infoHeader . $rgbQuad . $bmpData);
1167
-			fclose($fp);
1168
-			return true;
1169
-		}
1170
-		echo $fileHeader . $infoHeader . $rgbQuad . $bmpData;
1171
-		return true;
1172
-	}
1059
+    /**
1060
+     * Output a BMP image to either the browser or a file
1061
+     *
1062
+     * @link http://www.ugia.cn/wp-data/imagebmp.php
1063
+     * @author legend <[email protected]>
1064
+     * @link http://www.programmierer-forum.de/imagebmp-gute-funktion-gefunden-t143716.htm
1065
+     * @author mgutt <[email protected]>
1066
+     * @version 1.00
1067
+     * @param resource $im
1068
+     * @param string $fileName [optional] <p>The path to save the file to.</p>
1069
+     * @param int $bit [optional] <p>Bit depth, (default is 24).</p>
1070
+     * @param int $compression [optional]
1071
+     * @return bool <b>TRUE</b> on success or <b>FALSE</b> on failure.
1072
+     */
1073
+    function imagebmp($im, $fileName = '', $bit = 24, $compression = 0) {
1074
+        if (!in_array($bit, array(1, 4, 8, 16, 24, 32))) {
1075
+            $bit = 24;
1076
+        } else if ($bit == 32) {
1077
+            $bit = 24;
1078
+        }
1079
+        $bits = pow(2, $bit);
1080
+        imagetruecolortopalette($im, true, $bits);
1081
+        $width = imagesx($im);
1082
+        $height = imagesy($im);
1083
+        $colorsNum = imagecolorstotal($im);
1084
+        $rgbQuad = '';
1085
+        if ($bit <= 8) {
1086
+            for ($i = 0; $i < $colorsNum; $i++) {
1087
+                $colors = imagecolorsforindex($im, $i);
1088
+                $rgbQuad .= chr($colors['blue']) . chr($colors['green']) . chr($colors['red']) . "\0";
1089
+            }
1090
+            $bmpData = '';
1091
+            if ($compression == 0 || $bit < 8) {
1092
+                $compression = 0;
1093
+                $extra = '';
1094
+                $padding = 4 - ceil($width / (8 / $bit)) % 4;
1095
+                if ($padding % 4 != 0) {
1096
+                    $extra = str_repeat("\0", $padding);
1097
+                }
1098
+                for ($j = $height - 1; $j >= 0; $j--) {
1099
+                    $i = 0;
1100
+                    while ($i < $width) {
1101
+                        $bin = 0;
1102
+                        $limit = $width - $i < 8 / $bit ? (8 / $bit - $width + $i) * $bit : 0;
1103
+                        for ($k = 8 - $bit; $k >= $limit; $k -= $bit) {
1104
+                            $index = imagecolorat($im, $i, $j);
1105
+                            $bin |= $index << $k;
1106
+                            $i++;
1107
+                        }
1108
+                        $bmpData .= chr($bin);
1109
+                    }
1110
+                    $bmpData .= $extra;
1111
+                }
1112
+            } // RLE8
1113
+            else if ($compression == 1 && $bit == 8) {
1114
+                for ($j = $height - 1; $j >= 0; $j--) {
1115
+                    $lastIndex = "\0";
1116
+                    $sameNum = 0;
1117
+                    for ($i = 0; $i <= $width; $i++) {
1118
+                        $index = imagecolorat($im, $i, $j);
1119
+                        if ($index !== $lastIndex || $sameNum > 255) {
1120
+                            if ($sameNum != 0) {
1121
+                                $bmpData .= chr($sameNum) . chr($lastIndex);
1122
+                            }
1123
+                            $lastIndex = $index;
1124
+                            $sameNum = 1;
1125
+                        } else {
1126
+                            $sameNum++;
1127
+                        }
1128
+                    }
1129
+                    $bmpData .= "\0\0";
1130
+                }
1131
+                $bmpData .= "\0\1";
1132
+            }
1133
+            $sizeQuad = strlen($rgbQuad);
1134
+            $sizeData = strlen($bmpData);
1135
+        } else {
1136
+            $extra = '';
1137
+            $padding = 4 - ($width * ($bit / 8)) % 4;
1138
+            if ($padding % 4 != 0) {
1139
+                $extra = str_repeat("\0", $padding);
1140
+            }
1141
+            $bmpData = '';
1142
+            for ($j = $height - 1; $j >= 0; $j--) {
1143
+                for ($i = 0; $i < $width; $i++) {
1144
+                    $index = imagecolorat($im, $i, $j);
1145
+                    $colors = imagecolorsforindex($im, $index);
1146
+                    if ($bit == 16) {
1147
+                        $bin = 0 << $bit;
1148
+                        $bin |= ($colors['red'] >> 3) << 10;
1149
+                        $bin |= ($colors['green'] >> 3) << 5;
1150
+                        $bin |= $colors['blue'] >> 3;
1151
+                        $bmpData .= pack("v", $bin);
1152
+                    } else {
1153
+                        $bmpData .= pack("c*", $colors['blue'], $colors['green'], $colors['red']);
1154
+                    }
1155
+                }
1156
+                $bmpData .= $extra;
1157
+            }
1158
+            $sizeQuad = 0;
1159
+            $sizeData = strlen($bmpData);
1160
+            $colorsNum = 0;
1161
+        }
1162
+        $fileHeader = 'BM' . pack('V3', 54 + $sizeQuad + $sizeData, 0, 54 + $sizeQuad);
1163
+        $infoHeader = pack('V3v2V*', 0x28, $width, $height, 1, $bit, $compression, $sizeData, 0, 0, $colorsNum, 0);
1164
+        if ($fileName != '') {
1165
+            $fp = fopen($fileName, 'wb');
1166
+            fwrite($fp, $fileHeader . $infoHeader . $rgbQuad . $bmpData);
1167
+            fclose($fp);
1168
+            return true;
1169
+        }
1170
+        echo $fileHeader . $infoHeader . $rgbQuad . $bmpData;
1171
+        return true;
1172
+    }
1173 1173
 }
1174 1174
 
1175 1175
 if (!function_exists('exif_imagetype')) {
1176
-	/**
1177
-	 * Workaround if exif_imagetype does not exist
1178
-	 *
1179
-	 * @link http://www.php.net/manual/en/function.exif-imagetype.php#80383
1180
-	 * @param string $fileName
1181
-	 * @return string|boolean
1182
-	 */
1183
-	function exif_imagetype($fileName) {
1184
-		if (($info = getimagesize($fileName)) !== false) {
1185
-			return $info[2];
1186
-		}
1187
-		return false;
1188
-	}
1176
+    /**
1177
+     * Workaround if exif_imagetype does not exist
1178
+     *
1179
+     * @link http://www.php.net/manual/en/function.exif-imagetype.php#80383
1180
+     * @param string $fileName
1181
+     * @return string|boolean
1182
+     */
1183
+    function exif_imagetype($fileName) {
1184
+        if (($info = getimagesize($fileName)) !== false) {
1185
+            return $info[2];
1186
+        }
1187
+        return false;
1188
+    }
1189 1189
 }
Please login to merge, or discard this patch.