Passed
Push — 1.11.x ( f30747...d96de9 )
by Angel Fernando Quiroz
11:28
created

GDWrapper::get_image_size()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
/**
5
 * Image class
6
 * This class provides a layer to manage images.
7
 *
8
 * @author Julio Montoya <[email protected]>
9
 *
10
 * @todo move in a DB configuration setting
11
 */
12
class Image
13
{
14
    public $image_wrapper = null;
15
16
    /**
17
     * Image constructor.
18
     *
19
     * @param string $path
20
     */
21
    public function __construct($path)
22
    {
23
        if (IMAGE_PROCESSOR == 'gd') {
24
            $this->image_wrapper = new GDWrapper($path);
25
        } else {
26
            if (class_exists('Imagick')) {
27
                $this->image_wrapper = new ImagickWrapper($path);
28
            } else {
29
                echo Display::return_message(
30
                    'Class Imagick not found',
31
                    'warning'
32
                );
33
                exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
34
            }
35
        }
36
37
        $this->image_wrapper->reencode();
38
    }
39
40
    public function resize($max_size_for_picture)
41
    {
42
        $image_size = $this->get_image_size($this->image_wrapper->path);
43
        $width = $image_size['width'];
44
        $height = $image_size['height'];
45
        if ($width >= $height) {
46
            if ($width >= $max_size_for_picture) {
47
                // scale height
48
                $new_height = round($height * ($max_size_for_picture / $width));
49
                $this->image_wrapper->resize(
50
                    $max_size_for_picture,
51
                    $new_height,
52
                    0
53
                );
54
            }
55
        } else { // height > $width
56
            if ($height >= $max_size_for_picture) {
57
                // scale width
58
                $new_width = round($width * ($max_size_for_picture / $height));
59
                $this->image_wrapper->resize(
60
                    $new_width,
61
                    $max_size_for_picture,
62
                    0
63
                );
64
            }
65
        }
66
    }
67
68
    /**
69
     * @param string $cropParameters
70
     *
71
     * @return bool
72
     */
73
    public function crop($cropParameters)
74
    {
75
        $image_size = $this->get_image_size($this->image_wrapper->path);
76
        $src_width = $image_size['width'];
77
        $src_height = $image_size['height'];
78
        $cropParameters = explode(',', $cropParameters);
79
80
        if (isset($cropParameters[0]) && isset($cropParameters[1])) {
81
            $x = intval($cropParameters[0]);
82
            $y = intval($cropParameters[1]);
83
            $width = intval($cropParameters[2]);
84
            $height = intval($cropParameters[3]);
85
86
            $image = $this->image_wrapper->crop(
87
                $x,
88
                $y,
89
                $width,
90
                $height,
91
                $src_width,
92
                $src_height
93
            );
94
95
            return $image;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $image also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
96
        }
97
98
        return false;
99
    }
100
101
    /**
102
     * @param string $file
103
     * @param int    $compress
104
     * @param null   $convert_file_to
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $convert_file_to is correct as it would always require null to be passed?
Loading history...
105
     *
106
     * @return bool
107
     */
108
    public function send_image(
109
        $file = '',
110
        $compress = -1,
111
        $convert_file_to = null
112
    ) {
113
        return $this->image_wrapper->send_image(
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->image_wrap...ress, $convert_file_to) also could return the type integer which is incompatible with the documented return type boolean.
Loading history...
114
            $file,
115
            $compress,
116
            $convert_file_to
117
        );
118
    }
119
120
    /**
121
     * @return array
122
     */
123
    public function get_image_size()
124
    {
125
        return $this->image_wrapper->get_image_size();
126
    }
127
128
    /**
129
     * @return array
130
     */
131
    public function get_image_info()
132
    {
133
        return $this->image_wrapper->get_image_info();
134
    }
135
136
    public function convert2bw()
137
    {
138
        $this->image_wrapper->convert2bw();
139
    }
140
}
141
142
/**
143
 * Image wrapper class.
144
 */
145
abstract class ImageWrapper
146
{
147
    public $debug = true;
148
    public $path;
149
    public $width;
150
    public $height;
151
    public $type;
152
    public $allowed_extensions = ['jpeg', 'jpg', 'png', 'gif'];
153
    public $image_validated = false;
154
155
    public function __construct($path)
156
    {
157
        if (empty($path)) {
158
            return false;
159
        }
160
        $this->path = $path;
161
        $this->set_image_wrapper(); //Creates image obj
162
        $this->reencode();
163
    }
164
165
    abstract public function set_image_wrapper();
166
167
    abstract public function fill_image_info();
168
169
    abstract public function get_image_size();
170
171
    abstract public function resize($thumbw, $thumbh, $border, $specific_size = false);
172
173
    abstract public function crop($x, $y, $width, $height, $src_width, $src_height);
174
175
    abstract public function reencode(): void;
176
177
    abstract public function send_image($file = '', $compress = -1, $convert_file_to = null);
178
179
    /**
180
     * @return array
181
     */
182
    public function get_image_info()
183
    {
184
        return [
185
            'width' => $this->width,
186
            'height' => $this->height,
187
            'type' => $this->type,
188
        ];
189
    }
190
}
191
192
/**
193
 * Imagick Chamilo wrapper.
194
 *
195
 * @author jmontoya
196
 */
197
class ImagickWrapper extends ImageWrapper
198
{
199
    public $image;
200
    public $filter = Imagick::FILTER_LANCZOS;
201
202
    /**
203
     * ImagickWrapper constructor.
204
     *
205
     * @param $path
206
     */
207
    public function __construct($path)
208
    {
209
        parent::__construct($path);
210
    }
211
212
    public function set_image_wrapper()
213
    {
214
        if ($this->debug) {
215
            error_log('Image::set_image_wrapper loaded');
216
        }
217
        try {
218
            if (file_exists($this->path)) {
219
                $this->image = new Imagick($this->path);
220
221
                if ($this->image) {
222
                    $this->fill_image_info(); //Fills height, width and type
223
                }
224
            } else {
225
                if ($this->debug) {
226
                    error_log('Image::image does not exist');
227
                }
228
            }
229
        } catch (ImagickException $e) {
230
            if ($this->debug) {
231
                error_log($e->getMessage());
232
            }
233
        }
234
    }
235
236
    public function fill_image_info()
237
    {
238
        $image_info = $this->image->identifyImage();
239
        $this->width = $image_info['geometry']['width'];
240
        $this->height = $image_info['geometry']['height'];
241
        $this->type = strtolower($this->image->getImageFormat());
242
243
        if (in_array($this->type, $this->allowed_extensions)) {
244
            $this->image_validated = true;
245
            if ($this->debug) {
246
                error_log('image_validated true');
247
            }
248
        }
249
    }
250
251
    public function get_image_size()
252
    {
253
        $imagesize = ['width' => 0, 'height' => 0];
254
        if ($this->image_validated) {
255
            $imagesize = $this->image->getImageGeometry();
256
        }
257
258
        return $imagesize;
259
    }
260
261
    //@todo implement border logic case for Imagick
262
    public function resize($thumbw, $thumbh, $border, $specific_size = false)
263
    {
264
        if (!$this->image_validated) {
265
            return false;
266
        }
267
268
        if ($specific_size) {
269
            $width = $thumbw;
270
            $height = $thumbh;
271
        } else {
272
            $scale = ($this->width > 0 && $this->height > 0) ? min($thumbw / $this->width, $thumbh / $this->height) : 0;
273
            $width = (int) ($this->width * $scale);
274
            $height = (int) ($this->height * $scale);
275
        }
276
        $result = $this->image->resizeImage($width, $height, $this->filter, 1);
277
        $this->width = $thumbw;
278
        $this->height = $thumbh;
279
    }
280
281
    /**
282
     * @author José Loguercio <[email protected]>
283
     *
284
     * @param int $x          coordinate of the cropped region top left corner
285
     * @param int $y          coordinate of the cropped region top left corner
286
     * @param int $width      the width of the crop
287
     * @param int $height     the height of the crop
288
     * @param int $src_width  the source width of the original image
289
     * @param int $src_height the source height of the original image
290
     *
291
     * @return bool
292
     */
293
    public function crop($x, $y, $width, $height, $src_width, $src_height)
294
    {
295
        if (!$this->image_validated) {
296
            return false;
297
        }
298
        $this->image->cropimage($width, $height, $x, $y);
299
        $this->width = $width;
300
        $this->height = $height;
301
302
        return true;
303
    }
304
305
    public function send_image(
306
        $file = '',
307
        $compress = -1,
308
        $convert_file_to = null
309
    ) {
310
        if (!$this->image_validated) {
311
            return false;
312
        }
313
        $type = $this->type;
314
        if (!empty($convert_file_to) && in_array($convert_file_to, $this->allowed_extensions)) {
315
            $type = $convert_file_to;
316
        }
317
        switch ($type) {
318
            case 'jpeg':
319
            case 'jpg':
320
                if (!$file) {
321
                    header("Content-type: image/jpeg");
322
                }
323
                break;
324
            case 'png':
325
                if (!$file) {
326
                    header("Content-type: image/png");
327
                }
328
                break;
329
            case 'gif':
330
                if (!$file) {
331
                    header("Content-type: image/gif");
332
                }
333
                break;
334
        }
335
        $result = false;
336
        try {
337
            $result = $this->image->writeImage($file);
338
        } catch (ImagickException $e) {
339
            if ($this->debug) {
340
                error_log($e->getMessage());
341
            }
342
        }
343
344
        if (!$file) {
345
            echo $this->image;
346
            $this->image->clear();
347
            $this->image->destroy();
348
        } else {
349
            $this->image->clear();
350
            $this->image->destroy();
351
352
            return $result;
353
        }
354
    }
355
356
    /**
357
     * @throws Exception
358
     */
359
    public function reencode(): void
360
    {
361
        if ($this->image_validated) {
362
            try {
363
                $this->image->setImageFormat($this->type);
364
                $this->image->writeImage($this->path);
365
            } catch (ImagickException $e) {
366
                throw new Exception;
367
            }
368
369
            $this->image->clear();
370
371
            return;
372
        }
373
374
        throw new Exception;
375
    }
376
}
377
378
/**
379
 * php-gd wrapper.
380
 */
381
class GDWrapper extends ImageWrapper
382
{
383
    public $bg;
384
385
    /**
386
     * GDWrapper constructor.
387
     *
388
     * @param $path
389
     */
390
    public function __construct($path)
391
    {
392
        parent::__construct($path);
393
    }
394
395
    public function set_image_wrapper()
396
    {
397
        $handler = null;
398
        $this->fill_image_info();
399
400
        switch ($this->type) {
401
            case 0:
402
                $handler = false;
403
                break;
404
            case 1:
405
                $handler = @imagecreatefromgif($this->path);
406
                $this->type = 'gif';
407
                break;
408
            case 2:
409
                $handler = @imagecreatefromjpeg($this->path);
410
                $this->type = 'jpg';
411
                break;
412
            case 3:
413
                $handler = @imagecreatefrompng($this->path);
414
                $this->type = 'png';
415
                break;
416
        }
417
        if ($handler) {
418
            $this->image_validated = true;
419
            $this->bg = $handler;
420
            @imagealphablending($this->bg, 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

420
            /** @scrutinizer ignore-unhandled */ @imagealphablending($this->bg, 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...
421
            @imagesavealpha($this->bg, 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

421
            /** @scrutinizer ignore-unhandled */ @imagesavealpha($this->bg, 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...
422
        }
423
    }
424
425
    /**
426
     * @return array
427
     */
428
    public function get_image_size()
429
    {
430
        $return_array = ['width' => 0, 'height' => 0];
431
        if ($this->image_validated) {
432
            $return_array = ['width' => $this->width, 'height' => $this->height];
433
        }
434
435
        return $return_array;
436
    }
437
438
    public function fill_image_info()
439
    {
440
        if (file_exists($this->path)) {
441
            $image_info = getimagesize($this->path);
442
            $this->width = $image_info[0];
443
            $this->height = $image_info[1];
444
            $this->type = $image_info[2];
445
        } else {
446
            $this->width = 0;
447
            $this->height = 0;
448
            $this->type = 0;
449
        }
450
    }
451
452
    public function resize($thumbw, $thumbh, $border, $specific_size = false)
453
    {
454
        if (!$this->image_validated) {
455
            return false;
456
        }
457
        if (1 == $border) {
458
            if ($specific_size) {
459
                $width = $thumbw;
460
                $height = $thumbh;
461
            } else {
462
                $scale = min($thumbw / $this->width, $thumbh / $this->height);
463
                $width = (int) ($this->width * $scale);
464
                $height = (int) ($this->height * $scale);
465
            }
466
            $deltaw = (int) (($thumbw - $width) / 2);
467
            $deltah = (int) (($thumbh - $height) / 2);
468
            $dst_img = @imagecreatetruecolor($thumbw, $thumbh);
469
            @imagealphablending($dst_img, 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

469
            /** @scrutinizer ignore-unhandled */ @imagealphablending($dst_img, 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...
470
            @imagesavealpha($dst_img, 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

470
            /** @scrutinizer ignore-unhandled */ @imagesavealpha($dst_img, 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...
471
472
            if (!empty($this->color)) {
473
                @imagefill($dst_img, 0, 0, $this->color);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagefill(). 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

473
                /** @scrutinizer ignore-unhandled */ @imagefill($dst_img, 0, 0, $this->color);

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...
Bug Best Practice introduced by
The property color does not exist on GDWrapper. Did you maybe forget to declare it?
Loading history...
474
            }
475
            $this->width = $thumbw;
476
            $this->height = $thumbh;
477
        } elseif (0 == $border) {
478
            if ($specific_size) {
479
                $width = $thumbw;
480
                $height = $thumbh;
481
            } else {
482
                $scale = ($this->width > 0 && $this->height > 0) ? min($thumbw / $this->width, $thumbh / $this->height) : 0;
483
                $width = (int) ($this->width * $scale);
484
                $height = (int) ($this->height * $scale);
485
            }
486
            $deltaw = 0;
487
            $deltah = 0;
488
            $dst_img = @imagecreatetruecolor($width, $height);
489
            @imagealphablending($dst_img, false);
490
            @imagesavealpha($dst_img, true);
491
            $this->width = $width;
492
            $this->height = $height;
493
        }
494
        $src_img = $this->bg;
495
        @imagecopyresampled(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagecopyresampled(). 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

495
        /** @scrutinizer ignore-unhandled */ @imagecopyresampled(

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...
496
            $dst_img,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $dst_img does not seem to be defined for all execution paths leading up to this point.
Loading history...
497
            $src_img,
498
            $deltaw,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $deltaw does not seem to be defined for all execution paths leading up to this point.
Loading history...
499
            $deltah,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $deltah does not seem to be defined for all execution paths leading up to this point.
Loading history...
500
            0,
501
            0,
502
            $width,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $width does not seem to be defined for all execution paths leading up to this point.
Loading history...
503
            $height,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $height does not seem to be defined for all execution paths leading up to this point.
Loading history...
504
            imagesx($src_img),
505
            imagesy($src_img)
506
        );
507
        $this->bg = $dst_img;
508
        @imagedestroy($src_img);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagedestroy(). 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

508
        /** @scrutinizer ignore-unhandled */ @imagedestroy($src_img);

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...
509
    }
510
511
    /**
512
     * @throws Exception
513
     */
514
    public function reencode(): void
515
    {
516
        if ($this->image_validated) {
517
            switch ($this->type) {
518
                case 'jpeg':
519
                case 'jpg':
520
                    imagejpeg($this->bg, $this->path);
521
                    break;
522
523
                case 'png':
524
                    imagepng($this->bg, $this->path);
525
                    break;
526
527
                case 'gif':
528
                    imagegif($this->bg, $this->path);
529
                    break;
530
            }
531
532
            return;
533
        }
534
535
        throw new Exception;
536
    }
537
538
    /**
539
     * @author José Loguercio <[email protected]>
540
     *
541
     * @param int $x          coordinate of the cropped region top left corner
542
     * @param int $y          coordinate of the cropped region top left corner
543
     * @param int $width      the width of the crop
544
     * @param int $height     the height of the crop
545
     * @param int $src_width  the source width of the original image
546
     * @param int $src_height the source height of the original image
547
     */
548
    public function crop($x, $y, $width, $height, $src_width, $src_height)
549
    {
550
        if (!$this->image_validated) {
551
            return false;
552
        }
553
        $this->width = $width;
554
        $this->height = $height;
555
        $src = null;
556
        $dest = @imagecreatetruecolor($width, $height);
557
        $type = $this->type;
558
        switch ($type) {
559
            case 'jpeg':
560
            case 'jpg':
561
                $src = @imagecreatefromjpeg($this->path);
562
                @imagecopy($dest, $src, 0, 0, $x, $y, $src_width, $src_height);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagecopy(). 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

562
                /** @scrutinizer ignore-unhandled */ @imagecopy($dest, $src, 0, 0, $x, $y, $src_width, $src_height);

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...
563
                @imagejpeg($dest, $this->path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagejpeg(). 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

563
                /** @scrutinizer ignore-unhandled */ @imagejpeg($dest, $this->path);

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...
564
                break;
565
            case 'png':
566
                $src = @imagecreatefrompng($this->path);
567
                @imagealphablending($dest, 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

567
                /** @scrutinizer ignore-unhandled */ @imagealphablending($dest, 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...
568
                @imagesavealpha($dest, 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

568
                /** @scrutinizer ignore-unhandled */ @imagesavealpha($dest, 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...
569
                @imagecopy($dest, $src, 0, 0, $x, $y, $src_width, $src_height);
570
                @imagepng($dest, $this->path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagepng(). 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

570
                /** @scrutinizer ignore-unhandled */ @imagepng($dest, $this->path);

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...
571
                break;
572
            case 'gif':
573
                $src = @imagecreatefromgif($this->path);
574
                @imagecopy($dest, $src, 0, 0, $x, $y, $src_width, $src_height);
575
                @imagegif($dest, $this->path);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagegif(). 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

575
                /** @scrutinizer ignore-unhandled */ @imagegif($dest, $this->path);

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...
576
                break;
577
            default:
578
                return 0;
579
        }
580
        @imagedestroy($dest);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagedestroy(). 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

580
        /** @scrutinizer ignore-unhandled */ @imagedestroy($dest);

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...
581
        @imagedestroy($src);
582
    }
583
584
    /**
585
     * @param string $file
586
     * @param int    $compress
587
     * @param null   $convert_file_to
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $convert_file_to is correct as it would always require null to be passed?
Loading history...
588
     *
589
     * @return bool|int
590
     */
591
    public function send_image($file = '', $compress = -1, $convert_file_to = null)
592
    {
593
        if (!$this->image_validated) {
594
            return false;
595
        }
596
        $compress = (int) $compress;
597
        $type = $this->type;
598
        if (!empty($convert_file_to) && in_array($convert_file_to, $this->allowed_extensions)) {
599
            $type = $convert_file_to;
600
        }
601
        switch ($type) {
602
            case 'jpeg':
603
            case 'jpg':
604
                if (!$file) {
605
                    header("Content-type: image/jpeg");
606
                }
607
                if (-1 == $compress) {
608
                    $compress = 100;
609
                }
610
611
                return imagejpeg($this->bg, $file, $compress);
612
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
613
            case 'png':
614
                if (!$file) {
615
                    header("Content-type: image/png");
616
                }
617
                if (-1 != $compress) {
618
                    @imagetruecolortopalette($this->bg, true, $compress);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for imagetruecolortopalette(). 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

618
                    /** @scrutinizer ignore-unhandled */ @imagetruecolortopalette($this->bg, true, $compress);

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...
619
                }
620
621
                return imagepng($this->bg, $file, $compress);
622
                break;
623
            case 'gif':
624
                if (!$file) {
625
                    header("Content-type: image/gif");
626
                }
627
                if (-1 != $compress) {
628
                    @imagetruecolortopalette($this->bg, true, $compress);
629
                }
630
631
                return imagegif($this->bg, $file);
632
                break;
633
            default:
634
                return 0;
635
        }
636
        // TODO: Occupied memory is not released, because the following fragment of code is actually dead.
637
        @imagedestroy($this->bg);
0 ignored issues
show
Unused Code introduced by
@imagedestroy($this->bg) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for imagedestroy(). 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

637
        /** @scrutinizer ignore-unhandled */ @imagedestroy($this->bg);

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...
638
    }
639
640
    /**
641
     * Convert image to black & white.
642
     */
643
    public function convert2bw()
644
    {
645
        if (!$this->image_validated) {
646
            return false;
647
        }
648
649
        $dest_img = imagecreatetruecolor(imagesx($this->bg), imagesy($this->bg));
650
        /* copy ignore the transparent color
651
         * so that we can use black (0,0,0) as transparent, which is what
652
         * the image is filled with when created.
653
         */
654
        $transparent = imagecolorallocate($dest_img, 0, 0, 0);
655
        imagealphablending($dest_img, false);
656
        imagesavealpha($dest_img, true);
657
        imagecolortransparent($dest_img, $transparent);
658
        imagecopy(
659
            $dest_img,
660
            $this->bg,
661
            0,
662
            0,
663
            0,
664
            0,
665
            imagesx($this->bg),
666
            imagesx($this->bg)
667
        );
668
        imagefilter($dest_img, IMG_FILTER_GRAYSCALE);
669
        $this->bg = $dest_img;
670
671
        return true;
672
    }
673
}
674