Issues (992)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class/pear/Image/Transform/Driver/NetPBM.php (7 issues)

1
<?php
2
3
/* vim: set expandtab tabstop=4 shiftwidth=4: */
4
5
/**
6
 * NetPBM implementation for Image_Transform package
7
 *
8
 * PHP versions 4 and 5
9
 *
10
 * LICENSE: This source file is subject to version 3.0 of the PHP license
11
 * that is available through the world-wide-web at the following URI:
12
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
13
 * the PHP License and are unable to obtain it through the web, please
14
 * send a note to [email protected] so we can mail you a copy immediately.
15
 *
16
 * @category   Image
17
 * @package    Image_Transform
18
 * @author     Peter Bowyer <[email protected]>
19
 * @author     Philippe Jausions <[email protected]>
20
 * @copyright  2002-2005 The PHP Group
21
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
22
 * @version    CVS: $Id: NetPBM.php 236527 2007-05-28 16:36:09Z dufuz $
23
 * @link       http://pear.php.net/package/Image_Transform
24
 */
25
26
//require_once __DIR__ . '/Image/Transform.php';
27
//require_once __DIR__ . '/System.php';
28
require_once XOOPS_ROOT_PATH . '/modules/extgallery/class/pear/Image/Transform.php';
29
require_once XOOPS_ROOT_PATH . '/modules/extgallery/class/pear/System.php';
30
31
/**
32
 * NetPBM implementation for Image_Transform package
33
 *
34
 * @category   Image
35
 * @package    Image_Transform
36
 * @subpackage Image_Transform_Driver_NetPBM
37
 * @author     Peter Bowyer <[email protected]>
38
 * @author     Philippe Jausions <[email protected]>
39
 * @copyright  2002-2005 The PHP Group
40
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
41
 * @version    Release: @package_version@
42
 * @link       http://pear.php.net/package/Image_Transform
43
 * @link       http://netpbm.sourceforge.net/
44
 */
45
class Image_Transform_Driver_NetPBM extends Image_Transform
46
{
47
    /**
48
     * associative array commands to be executed
49
     * @var array
50
     */
51
    public $command = [];
52
53
    /**
54
     * Class Constructor
55
     */
56
    public function Image_Transform_Driver_NetPBM()
57
    {
58
        $this->__construct();
59
    }
60
61
    // End function Image_NetPBM
62
63
    /**
64
     * Class Constructor
65
     */
66
    public function __construct()
67
    {
68
        if (!defined('IMAGE_TRANSFORM_NETPBM_PATH')) {
69
            $path = \dirname(System::which('pnmscale')) . DIRECTORY_SEPARATOR;
0 ignored issues
show
It seems like System::which('pnmscale') can also be of type false; however, parameter $path of dirname() does only seem to accept string, 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

69
            $path = \dirname(/** @scrutinizer ignore-type */ System::which('pnmscale')) . DIRECTORY_SEPARATOR;
Loading history...
70
            define('IMAGE_TRANSFORM_NETPBM_PATH', $path);
71
        }
72
        if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'pnmscale' . (OS_WINDOWS ? '.exe' : ''))) {
73
            $this->isError(PEAR::raiseError('Couldn\'t find "pnmscale" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED));
0 ignored issues
show
The method raiseError() does not exist on PEAR. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

73
            $this->isError(PEAR::/** @scrutinizer ignore-call */ raiseError('Couldn\'t find "pnmscale" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED));
Loading history...
74
        }
75
    }
76
77
    // End function Image_NetPBM
78
79
    /**
80
     * Load image
81
     *
82
     * @param mixed $image
83
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
84
     * @access public
85
     */
86
    public function load($image)
87
    {
88
        $this->image = $image;
89
        $result      = $this->_get_image_details($image);
90
        if (PEAR::isError($result)) {
91
            return $result;
92
        }
93
94
        return true;
95
    }
96
97
    // End load
98
99
    /**
100
     * Resize the image.
101
     *
102
     * @access private
103
     *
104
     * @param int   $new_x   New width
105
     * @param int   $new_y   New height
106
     * @param mixed $options Optional parameters
107
     *
108
     * @return true on success or PEAR Error object on error
109
     * @see    PEAR::isError()
110
     */
111
    public function _resize($new_x, $new_y, $options = null)
112
    {
113
        // there's no technical reason why resize can't be called multiple
114
        // times...it's just silly to do so
115
        $scaleMethod = $this->_getOption('scaleMethod', $options, 'smooth');
116
        switch ($scaleMethod) {
117
            case 'pixel':
118
                $scale_x = $new_x / $this->img_x;
119
                if ($scale_x == $new_y / $this->img_x
120
                    && $scale_x > 1
121
                    && floor($scale_x) == $scale_x) {
122
                    if (System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'pnmenlarge' . (OS_WINDOWS ? '.exe' : ''))) {
123
                        $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pnmenlarge', $scale_x);
124
                    } else {
125
                        return PEAR::raiseError('Couldn\'t find "pnmenlarge" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
126
                    }
127
                } else {
128
                    $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pnmscale', '-nomix -width ' . ((int)$new_x) . ' -height ' . ((int)$new_y));
129
                }
130
                break;
131
            case 'smooth':
132
            default:
133
                $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pnmscale', '-width ' . ((int)$new_x) . ' -height ' . ((int)$new_y));
134
                // Smooth things if scaling by a factor more than 3
135
                // (see pnmscale man page)
136
                if ($new_x / $this->img_x > 3
137
                    || $new_y / $this->img_y > 3) {
138
                    if (System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'pnmsmooth' . (OS_WINDOWS ? '.exe' : ''))) {
139
                        $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pnmsmooth');
140
                    } else {
141
                        return PEAR::raiseError('Couldn\'t find "pnmsmooth" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
142
                    }
143
                }
144
        } // End [SWITCH]
145
146
        $this->_set_new_x($new_x);
147
        $this->_set_new_y($new_y);
148
149
        return true;
150
    }
151
152
    // End resize
153
154
    /**
155
     * Rotates the image
156
     *
157
     * @param int   $angle The angle to rotate the image through
158
     * @param array $options
159
     * @return bool|PEAR_Error TRUE on success, PEAR_Error object on error
160
     */
161
    public function rotate($angle, $options = null)
162
    {
163
        if (!($angle == $this->_rotation_angle($angle))) {
164
            // No rotation needed
165
            return true;
166
        }
167
168
        // For pnmrotate, we want to limit rotations from -45 to +45 degrees
169
        // even if acceptable range is -90 to +90 (see pnmrotate man page)
170
        // Bring image to that range by using pamflip
171
        if ($angle > 45 && $angle < 315) {
172
            if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'pamflip' . (OS_WINDOWS ? '.exe' : ''))) {
173
                return PEAR::raiseError('Couldn\'t find "pamflip" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
174
            }
175
176
            $quarters        = floor(ceil($angle / 45) / 2);
177
            $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pamflip', '-rotate' . (360 - $quarters * 90));
178
            $angle           -= $quarters * 90;
179
        }
180
181
        if (0 != $angle) {
182
            if ($angle > 45) {
183
                $angle -= 360;
184
            }
185
186
            if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'pnmrotate' . (OS_WINDOWS ? '.exe' : ''))) {
187
                return PEAR::raiseError('Couldn\'t find "pnmrotate" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
188
            }
189
190
            $bgcolor = $this->_getColor('canvasColor', $options, [255, 255, 255]);
191
            $bgcolor = $this->colorarray2colorhex($bgcolor);
192
193
            $scaleMethod = $this->_getOption('scaleMethod', $options, 'smooth');
194
            if ('pixel' != $scaleMethod) {
195
                $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pnmrotate', '-background=' . $bgcolor . ' -' . (float)$angle);
0 ignored issues
show
Are you sure $bgcolor of type false|string can be used in concatenation? ( Ignorable by Annotation )

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

195
                $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pnmrotate', '-background=' . /** @scrutinizer ignore-type */ $bgcolor . ' -' . (float)$angle);
Loading history...
196
            } else {
197
                $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pnmrotate', '-background=' . $bgcolor . ' -noantialias -' . (float)$angle);
198
            }
199
        }
200
201
        return true;
202
    }
203
204
    // End rotate
205
206
    /**
207
     * Crop an image
208
     *
209
     * @param int $width  Cropped image width
210
     * @param int $height Cropped image height
211
     * @param int $x      positive X-coordinate to crop at
212
     * @param int $y      positive Y-coordinate to crop at
213
     *
214
     * @return mixed TRUE or a PEAR error object on error
215
     * @todo keep track of the new cropped size
216
     **/
217
    public function crop($width, $height, $x = 0, $y = 0)
218
    {
219
        // Sanity check
220
        if (!$this->intersects($width, $height, $x, $y)) {
221
            return PEAR::raiseError('Nothing to crop', IMAGE_TRANSFORM_ERROR_OUTOFBOUND);
222
        }
223
        if (0 != $x || 0 != $y
224
            || $width != $this->img_x
225
            || $height != $this->img_y) {
226
            if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'pnmcut' . (OS_WINDOWS ? '.exe' : ''))) {
227
                return PEAR::raiseError('Couldn\'t find "pnmcut" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
228
            }
229
230
            $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pnmcut', '-left ' . ((int)$x) . ' -top ' . ((int)$y) . ' -width ' . ((int)$width) . ' -height ' . ((int)$height));
231
        }
232
233
        return true;
234
    }
235
236
    // End crop
237
238
    /**
239
     * Adjust the image gamma
240
     *
241
     * @param float $outputgamma
242
     *
243
     * @return mixed TRUE or a PEAR error object on error
244
     */
245
    public function gamma($outputgamma = 1.0)
246
    {
247
        if (1.0 != $outputgamme) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $outputgamme does not exist. Did you maybe mean $outputgamma?
Loading history...
248
            if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'pnmgamma' . (OS_WINDOWS ? '.exe' : ''))) {
249
                return PEAR::raiseError('Couldn\'t find "pnmgamma" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
250
            }
251
            $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pnmgamma', (float)$outputgamma);
252
        }
253
254
        return true;
255
    }
256
257
    /**
258
     * Vertical mirroring
259
     *
260
     * @return true or PEAR Error object on error
261
     **@see mirror()
262
     */
263
    public function flip()
264
    {
265
        if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'pamflip' . (OS_WINDOWS ? '.exe' : ''))) {
266
            return PEAR::raiseError('Couldn\'t find "pamflip" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
267
        }
268
        $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pamflip', '-topbottom');
269
270
        return true;
271
    }
272
273
    /**
274
     * Horizontal mirroring
275
     *
276
     * @return true or PEAR Error object on error
277
     **@see flip()
278
     */
279
    public function mirror()
280
    {
281
        if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'pamflip' . (OS_WINDOWS ? '.exe' : ''))) {
282
            return PEAR::raiseError('Couldn\'t find "pamflip" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
283
        }
284
        $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'pamflip', '-leftright');
285
286
        return true;
287
    }
288
289
    /**
290
     * Converts an image into greyscale colors
291
     *
292
     * @access public
293
     * @return mixed TRUE or a PEAR error object on error
294
     **/
295
    public function greyscale()
296
    {
297
        if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'ppmtopgm' . (OS_WINDOWS ? '.exe' : ''))) {
298
            return PEAR::raiseError('Couldn\'t find "ppmtopgm" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
299
        }
300
        $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'ppmtopgm');
301
302
        return true;
303
    }
304
305
    /**
306
     * adds text to an image
307
     *
308
     * @param mixed $params
309
     *
310
     * @return object
311
     */
312
    public function addText($params)
313
    {
314
        if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'ppmlabel' . (OS_WINDOWS ? '.exe' : ''))) {
315
            return PEAR::raiseError('Couldn\'t find "ppmlabel" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
316
        }
317
318
        // we ignore 'resize_first' since the more logical approach would be
319
        // for the user to just call $this->_resize() _first_ ;)
320
        extract(array_merge($this->_get_default_text_params(), $params));
321
322
        $options = ['colorFont' => $color];
323
        $color   = $this->_getColor('colorFont', $options, [0, 0, 0]);
324
        $color   = $this->colorarray2colorhex($color);
325
326
        $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'ppmlabel', '-angle ' . ((int)$angle) . ' -colour ' . escapeshellarg($color) . ' -size ' . ((float)$size) . ' -x ' . ((int)$x) . ' -y ' . $y + $size . ' -text ' . escapeshellarg($text));
0 ignored issues
show
It seems like $color can also be of type false; however, parameter $arg of escapeshellarg() does only seem to accept string, 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

326
        $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'ppmlabel', '-angle ' . ((int)$angle) . ' -colour ' . escapeshellarg(/** @scrutinizer ignore-type */ $color) . ' -size ' . ((float)$size) . ' -x ' . ((int)$x) . ' -y ' . $y + $size . ' -text ' . escapeshellarg($text));
Loading history...
327
    }
328
329
    // End addText
330
331
    /**
332
     * Image_Transform_Driver_NetPBM::_postProcess()
333
     *
334
     * @param $type
335
     * @param $quality
336
     * @return string A chain of shell command
337
     * @link http://netpbm.sourceforge.net/doc/directory.html
338
     */
339
    public function _postProcess($type, $quality)
340
    {
341
        array_unshift($this->command, $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, mb_strtolower($this->type) . 'topnm', escapeshellarg($this->image)));
342
        $arg     = '';
0 ignored issues
show
The assignment to $arg is dead and can be removed.
Loading history...
343
        $type    = mb_strtolower($type);
344
        $program = '';
345
        switch ($type) {
346
            // ppmto* converters
347
            case 'gif':
348
                if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . 'ppmquant' . (OS_WINDOWS ? '.exe' : ''))) {
349
                    return PEAR::raiseError('Couldn\'t find "ppmquant" binary', IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
350
                }
351
                $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, 'ppmquant', 256);
352
            // no break
353
            case 'acad':
354
            case 'bmp':
355
            case 'eyuv':
356
            case 'ilbm':
357
            case 'leaf':
358
            case 'lj':
359
            case 'mitsu':
360
            case 'mpeg':
361
            case 'neo':
362
            case 'pcx':
363
            case 'pi1':
364
            case 'pict':
365
            case 'pj':
366
            case 'pjxl':
367
            case 'puzz':
368
            case 'sixel':
369
            case 'tga':
370
            case 'uil':
371
            case 'xpm':
372
            case 'yuv':
373
                $program = 'ppmto' . $type;
374
                break;
375
            // Windows icon
376
            case 'winicon':
377
            case 'ico':
378
                $type    = 'winicon';
379
                $program = 'ppmto' . $type;
380
                break;
381
            // pbmto* converters
382
            case 'ascii':
383
            case 'text':
384
            case 'txt':
385
                $type = 'ascii';
386
            // no break
387
            case 'atk':
388
            case 'bbubg':
389
            case 'epsi':
390
            case 'epson':
391
            case 'escp2':
392
            case 'icon':    // Sun icon
393
            case 'gem':
394
            case 'go':
395
            case 'lj':
396
            case 'ln03':
397
            case 'lps':
398
            case 'macp':
399
            case 'mda':
400
            case 'mgr':
401
            case 'pi3':
402
            case 'pk':
403
            case 'plot':
404
            case 'ptx':
405
            case 'wbp':
406
            case 'xbm':
407
            case 'x10bm':
408
            case 'ybm':
409
            case 'zinc':
410
            case '10x':
411
                $program = 'pbmto' . $type;
412
                break;
413
            // pamto* converters
414
            case 'jpc':
415
                $type = 'jpeg2k';
416
            // no break
417
            case 'html':
418
            case 'pfm':
419
            case 'tga':
420
                $program = 'pamto' . $type;
421
                break;
422
            // pnmto* converters
423
            case 'jpc':
424
                $type = 'jpeg2k';
425
                break;
426
            case 'wfa':
427
                $type = 'fiasco';
428
                break;
429
            case 'jpg':
430
                $type = 'jpeg';
431
            // no break
432
            case 'jpeg':
433
                $arg = '--quality=' . $quality;
434
            // no break
435
            case 'jbig':
436
            case 'fits':
437
            case 'palm':
438
            case 'pclxl':
439
            case 'png':
440
            case 'ps':
441
            case 'rast':
442
            case 'rle':
443
            case 'sgi':
444
            case 'sir':
445
            case 'tiff':
446
            case 'xwd':
447
                $program = 'pnmto' . $type;
448
                break;
449
        } // switch
450
451
        if ('' == $program) {
452
            $program = 'pnmto' . $type;
453
        }
454
455
        if (!System::which(IMAGE_TRANSFORM_NETPBM_PATH . $program . (OS_WINDOWS ? '.exe' : ''))) {
456
            return PEAR::raiseError("Couldn't find \"$program\" binary", IMAGE_TRANSFORM_ERROR_UNSUPPORTED);
457
        }
458
        $this->command[] = $this->_prepare_cmd(IMAGE_TRANSFORM_NETPBM_PATH, $program);
459
460
        return implode('|', $this->command);
461
    }
462
463
    /**
464
     * Save the image file
465
     *
466
     * @param string $filename the name of the file to write to
467
     * @param string $type     (jpeg,png...);
468
     * @param int    $quality  75
469
     * @return true or PEAR Error object on error
470
     */
471
    public function save($filename, $type = null, $quality = 75)
472
    {
473
        $type    = $type ?? $this->type;
474
        $options = [];
475
        if (null !== $quality) {
0 ignored issues
show
The condition null !== $quality is always true.
Loading history...
476
            $options['quality'] = $quality;
477
        }
478
        $quality = $this->_getOption('quality', $options, $quality);
479
480
        $nullDevice = OS_WINDOWS ? 'nul' : '/dev/null';
481
482
        $cmd = $this->_postProcess($type, $quality) . '> "' . $filename . '"';
483
        exec($cmd . ' 2>  ' . $nullDevice, $res, $exit);
484
        if (!$this->keep_settings_on_save) {
485
            $this->free();
486
        }
487
488
        return (0 == $exit) ? true : PEAR::raiseError(implode('. ', $res), IMAGE_TRANSFORM_ERROR_IO);
489
    }
490
491
    // End save
492
493
    /**
494
     * Display image without saving and lose changes
495
     *
496
     * @param string $type    (jpeg,png...);
497
     * @param int    $quality 75
498
     * @return true or PEAR Error object on error
499
     */
500
    public function display($type = null, $quality = null)
501
    {
502
        $type    = $type ?? $this->type;
503
        $options = [];
504
        if (null !== $quality) {
505
            $options['quality'] = $quality;
506
        }
507
        $quality = $this->_getOption('quality', $options, 75);
508
509
        header('Content-type: ' . $this->getMimeType($type));
510
        $cmd = $this->_postProcess($type, $quality);
511
        passthru($cmd . ' 2>&1');
512
        if (!$this->keep_settings_on_save) {
513
            $this->free();
514
        }
515
516
        return true;
517
    }
518
519
    /**
520
     * Destroy image handle
521
     */
522
    public function free()
523
    {
524
        $this->command = [];
525
    }
526
} // End class ImageIM
527