image_gd::imageCopyResampled()   A
last analyzed

Complexity

Conditions 6
Paths 17

Size

Total Lines 32
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 6
eloc 13
c 1
b 1
f 0
nc 17
nop 9
dl 0
loc 32
rs 9.2222

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/** This file is part of KCFinder project
4
 *
5
 * @desc      GD image driver class
6
 * @package   KCFinder
7
 * @version   3.12
8
 * @author    Pavel Tzonkov <[email protected]>
9
 * @copyright 2010-2014 KCFinder Project
10
 * @license   http://opensource.org/licenses/GPL-3.0 GPLv3
11
 * @license   http://opensource.org/licenses/LGPL-3.0 LGPLv3
12
 * @link      http://kcfinder.sunhater.com
13
 */
14
15
namespace kcfinder;
16
17
class image_gd extends image
18
{
19
20
    // ABSTRACT PUBLIC METHODS
21
22
    public function resize($width, $height)
23
    {
24
        if (!$width) {
25
            $width = 1;
26
        }
27
        if (!$height) {
28
            $height = 1;
29
        }
30
        return ((false !== ($img = new image_gd([$width, $height]))) && $img->imageCopyResampled($this) && (false !== ($this->image = $img->image)) && (false !== ($this->width = $img->width)) && (false !== ($this->height = $img->height)));
31
    }
32
33
    public function resizeFit($width, $height, $background = false)
34
    {
35
        if ((!$width && !$height) || (($width == $this->width) && ($height == $this->height))) {
36
            return true;
37
        }
38
        if (!$width || (($height / $width) < ($this->height / $this->width))) {
39
            $h = $height;
40
            $w = round(($this->width * $h) / $this->height);
41
        } elseif (!$height || (($width / $height) < ($this->width / $this->height))) {
42
            $w = $width;
43
            $h = round(($this->height * $w) / $this->width);
44
        } else {
45
            $w = $width;
46
            $h = $height;
47
        }
48
        if (!$w) {
49
            $w = 1;
50
        }
51
        if (!$h) {
52
            $h = 1;
53
        }
54
55
        if (false === $background) {
56
            return $this->resize($w, $h);
57
        } else {
58
            $img = new image_gd([$width, $height]);
59
            $x   = round(($width - $w) / 2);
60
            $y   = round(($height - $h) / 2);
61
62
            if ((false === $this->resize($w, $h)) || (false === $img->imageFilledRectangle(0, 0, $width, $height, $background)) || (false === $img->imageCopyResampled($this->image, $x, $y, 0, 0, $w, $h))) {
63
                return false;
64
            }
65
66
            $this->image  = $img->image;
67
            $this->width  = $width;
68
            $this->height = $height;
69
70
            return true;
71
        }
72
    }
73
74
    public function resizeCrop($width, $height, $offset = false)
75
    {
76
        if (($this->width / $this->height) > ($width / $height)) {
77
            $h = $height;
78
            $w = ($this->width * $h) / $this->height;
79
            $y = 0;
80
            if (false !== $offset) {
81
                if ($offset > 0) {
82
                    $offset = -$offset;
83
                }
84
                if (($w + $offset) <= $width) {
85
                    $offset = $width - $w;
86
                }
87
                $x = $offset;
88
            } else {
89
                $x = ($width - $w) / 2;
90
            }
91
        } else {
92
            $w = $width;
93
            $h = ($this->height * $w) / $this->width;
94
            $x = 0;
95
            if (false !== $offset) {
96
                if ($offset > 0) {
97
                    $offset = -$offset;
98
                }
99
                if (($h + $offset) <= $height) {
100
                    $offset = $height - $h;
101
                }
102
                $y = $offset;
103
            } else {
104
                $y = ($height - $h) / 2;
105
            }
106
        }
107
108
        $x = round($x);
109
        $y = round($y);
110
        $w = round($w);
111
        $h = round($h);
112
        if (!$w) {
113
            $w = 1;
114
        }
115
        if (!$h) {
116
            $h = 1;
117
        }
118
119
        $return = ((false !== ($img = new image_gd([$width, $height])))) && (false !== ($img->imageCopyResampled($this->image, $x, $y, 0, 0, $w, $h)));
120
121
        if ($return) {
122
            $this->image  = $img->image;
123
            $this->width  = $w;
124
            $this->height = $h;
125
        }
126
127
        return $return;
128
    }
129
130
    public function rotate($angle, $background = '#000000')
131
    {
132
        $angle = -$angle;
133
        $img   = @imagerotate($this->image, $angle, $this->gdColor($background));
0 ignored issues
show
Bug introduced by
It seems like $this->gdColor($background) can also be of type false; however, parameter $bgd_color of imagerotate() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

133
        $img   = @imagerotate($this->image, $angle, /** @scrutinizer ignore-type */ $this->gdColor($background));
Loading history...
134
        if (false === $img) {
135
            return false;
136
        }
137
        $this->width  = imagesx($img);
138
        $this->height = imagesy($img);
139
        $this->image  = $img;
140
        return true;
141
    }
142
143
    public function flipHorizontal()
144
    {
145
        $img = imagecreatetruecolor($this->width, $this->height);
146
        if (imagecopyresampled($img, $this->image, 0, 0, ($this->width - 1), 0, $this->width, $this->height, -$this->width, $this->height)) {
147
            $this->image = $img;
148
        } else {
149
            return false;
150
        }
151
        return true;
152
    }
153
154
    public function flipVertical()
155
    {
156
        $img = imagecreatetruecolor($this->width, $this->height);
157
        if (imagecopyresampled($img, $this->image, 0, 0, 0, ($this->height - 1), $this->width, $this->height, $this->width, -$this->height)) {
158
            $this->image = $img;
159
        } else {
160
            return false;
161
        }
162
        return true;
163
    }
164
165
    public function watermark($file, $left = false, $top = false)
166
    {
167
        $info = getimagesize($file);
168
        list($w, $h, $t) = $info;
169
        if (!in_array($t, [IMAGETYPE_PNG, IMAGETYPE_GIF])) {
170
            return false;
171
        }
172
        $imagecreate = (IMAGETYPE_PNG == $t) ? 'imagecreatefrompng' : 'imagecreatefromgif';
173
174
        if (!@imagealphablending($this->image, true) || (false === ($wm = @$imagecreate($file)))) {
175
            return false;
176
        }
177
178
        $w = imagesx($wm);
179
        $h = imagesy($wm);
180
        $x = (true === $left) ? 0 : ((null === $left) ? round(($this->width - $w) / 2) : (((false === $left) || !preg_match('/^\d+$/', $left)) ? ($this->width - $w) : $left));
181
        $y = (true === $top) ? 0 : ((null === $top) ? round(($this->height - $h) / 2) : (((false === $top) || !preg_match('/^\d+$/', $top)) ? ($this->height - $h) : $top));
182
183
        if ((($x + $w) > $this->width) || (($y + $h) > $this->height) || ($x < 0) || ($y < 0)) {
184
            return false;
185
        }
186
187
        if ((false === $wm) || !@imagecopy($this->image, $wm, $x, $y, 0, 0, $w, $h)) {
0 ignored issues
show
Bug introduced by
It seems like $y can also be of type double; however, parameter $dst_y of imagecopy() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

187
        if ((false === $wm) || !@imagecopy($this->image, $wm, $x, /** @scrutinizer ignore-type */ $y, 0, 0, $w, $h)) {
Loading history...
Bug introduced by
It seems like $x can also be of type double; however, parameter $dst_x of imagecopy() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

187
        if ((false === $wm) || !@imagecopy($this->image, $wm, /** @scrutinizer ignore-type */ $x, $y, 0, 0, $w, $h)) {
Loading history...
188
            return false;
189
        }
190
191
        @imagealphablending($this->image, false);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagealphablending(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

191
        /** @scrutinizer ignore-unhandled */ @imagealphablending($this->image, false);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
192
        @imagesavealpha($this->image, true);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagesavealpha(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

192
        /** @scrutinizer ignore-unhandled */ @imagesavealpha($this->image, true);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
193
        return true;
194
    }
195
196
    public function output($type = 'jpeg', array $options = [])
197
    {
198
        $method = "output_$type";
199
        if (!method_exists($this, $method)) {
200
            return false;
201
        }
202
        return $this->$method($options);
203
    }
204
205
    // ABSTRACT PROTECTED METHODS
206
207
    protected function getBlankImage($width, $height)
208
    {
209
        $image = imagecreatetruecolor($width, $height);
210
        imagealphablending($image, false);
211
        imagesavealpha($image, true);
212
        return $image;
213
    }
214
215
    protected function getImage($image, &$width, &$height)
216
    {
217
        if (is_resource($image) && ('gd' == get_resource_type($image))) {
218
            $width  = @imagesx($image);
219
            $height = @imagesy($image);
220
            imagealphablending($image, false);
221
            imagesavealpha($image, true);
222
            return $image;
223
        } elseif (is_string($image) && (false !== (list($width, $height, $t) = @getimagesize($image)))) {
224
            $image = (IMAGETYPE_GIF == $t) ? @imagecreatefromgif($image) : ((IMAGETYPE_WBMP == $t) ? @imagecreatefromwbmp($image) : ((IMAGETYPE_JPEG == $t) ? @imagecreatefromjpeg($image) : ((IMAGETYPE_PNG == $t) ? @imagecreatefrompng($image) : ((IMAGETYPE_XBM == $t) ? @imagecreatefromxbm(
225
                $image
226
            ) : false))));
227
228
            if (IMAGETYPE_PNG == $t) {
229
                imagealphablending($image, false);
0 ignored issues
show
Bug introduced by
It seems like $image can also be of type false; however, parameter $image of imagealphablending() does only seem to accept GdImage|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

229
                imagealphablending(/** @scrutinizer ignore-type */ $image, false);
Loading history...
230
                imagesavealpha($image, true);
0 ignored issues
show
Bug introduced by
It seems like $image can also be of type false; however, parameter $image of imagesavealpha() does only seem to accept GdImage|resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

230
                imagesavealpha(/** @scrutinizer ignore-type */ $image, true);
Loading history...
231
            }
232
            return $image;
233
        } else {
234
            return false;
235
        }
236
    }
237
238
    // PSEUDO-ABSTRACT STATIC METHODS
239
240
    public static function available()
241
    {
242
        return function_exists('imagecreatefromjpeg');
243
    }
244
245
    public static function checkImage($file)
246
    {
247
        if (!is_string($file) || ((false === (list($width, $height, $t) = @getimagesize($file))))) {
248
            return false;
249
        }
250
251
        $img = (IMAGETYPE_GIF == $t) ? @imagecreatefromgif($file) : ((IMAGETYPE_WBMP == $t) ? @imagecreatefromwbmp($file) : ((IMAGETYPE_JPEG == $t) ? @imagecreatefromjpeg($file) : ((IMAGETYPE_PNG == $t) ? @imagecreatefrompng($file) : ((IMAGETYPE_XBM == $t) ? @imagecreatefromxbm($file) : false))));
252
253
        return (false !== $img);
254
    }
255
256
    // OWN METHODS
257
258
    protected function output_png(array $options = [])
259
    {
260
        $file    = isset($options['file']) ? $options['file'] : null;
261
        $quality = isset($options['quality']) ? $options['quality'] : null;
262
        $filters = isset($options['filters']) ? $options['filters'] : null;
263
        if ((null === $file) && !headers_sent()) {
264
            header('Content-Type: image/png');
265
        }
266
        return imagepng($this->image, $file, $quality, $filters);
267
    }
268
269
    protected function output_jpeg(array $options = [])
270
    {
271
        $file    = isset($options['file']) ? $options['file'] : null;
272
        $quality = isset($options['quality']) ? $options['quality'] : self::DEFAULT_JPEG_QUALITY;
273
        if ((null === $file) && !headers_sent()) {
274
            header('Content-Type: image/jpeg');
275
        }
276
        return imagejpeg($this->image, $file, $quality);
277
    }
278
279
    protected function output_gif(array $options = [])
280
    {
281
        $file = isset($options['file']) ? $options['file'] : null;
282
        if (isset($options['file']) && !headers_sent()) {
283
            header('Content-Type: image/gif');
284
        }
285
        return imagegif($this->image, $file);
286
    }
287
288
    protected function gdColor()
289
    {
290
        $args = func_get_args();
291
292
        $exprRGB  = '/^rgb\(\s*(\d{1,3})\s*\,\s*(\d{1,3})\s*\,\s*(\d{1,3})\s*\)$/i';
293
        $exprHex1 = '/^\#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i';
294
        $exprHex2 = '/^\#?([0-9a-f])([0-9a-f])([0-9a-f])$/i';
295
        $exprByte = '/^([01]?\d?\d|2[0-4]\d|25[0-5])$/';
296
297
        if (!isset($args[0])) {
298
            return false;
299
        }
300
301
        if (3 == count($args[0])) {
302
            list($r, $g, $b) = $args[0];
303
        } elseif (preg_match($exprRGB, $args[0], $match)) {
304
            list($tmp, $r, $g, $b) = $match;
305
        } elseif (preg_match($exprHex1, $args[0], $match)) {
306
            list($tmp, $r, $g, $b) = $match;
307
            $r = hexdec($r);
308
            $g = hexdec($g);
309
            $b = hexdec($b);
310
        } elseif (preg_match($exprHex2, $args[0], $match)) {
311
            list($tmp, $r, $g, $b) = $match;
312
            $r = hexdec("$r$r");
313
            $g = hexdec("$g$g");
314
            $b = hexdec("$b$b");
315
        } elseif ((3 == count($args)) && preg_match($exprByte, $args[0]) && preg_match($exprByte, $args[1]) && preg_match($exprByte, $args[2])) {
316
            list($r, $g, $b) = $args;
317
        } else {
318
            return false;
319
        }
320
321
        return imagecolorallocate($this->image, $r, $g, $b);
322
    }
323
324
    protected function imageFilledRectangle($x1, $y1, $x2, $y2, $color)
325
    {
326
        $color = $this->gdColor($color);
327
        if (false === $color) {
328
            return false;
329
        }
330
        return imageFilledRectangle($this->image, $x1, $y1, $x2, $y2, $color);
331
    }
332
333
    protected function imageCopyResampled(
334
        $src,
335
        $dstX = 0,
336
        $dstY = 0,
337
        $srcX = 0,
338
        $srcY = 0,
339
        $dstW = null,
340
        $dstH = null,
341
        $srcW = null,
342
        $srcH = null
343
    ) {
344
        $imageDetails = $this->buildImage($src);
345
346
        if (false === $imageDetails) {
0 ignored issues
show
introduced by
The condition false === $imageDetails is always false.
Loading history...
347
            return false;
348
        }
349
350
        list($src, $srcWidth, $srcHeight) = $imageDetails;
351
352
        if (is_null($dstW)) {
353
            $dstW = $this->width - $dstW;
354
        }
355
        if (is_null($dstH)) {
356
            $dstH = $this->height - $dstY;
357
        }
358
        if (is_null($srcW)) {
359
            $srcW = $srcWidth - $srcX;
360
        }
361
        if (is_null($srcH)) {
362
            $srcH = $srcHeight - $srcY;
363
        }
364
        return imageCopyResampled($this->image, $src, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH);
365
    }
366
}
367