Completed
Push — master ( 5bc85f...14d91c )
by Roberto
06:34 queued 03:37
created

Graphics   D

Complexity

Total Complexity 80

Size/Duplication

Total Lines 568
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 71.24%

Importance

Changes 9
Bugs 0 Features 0
Metric Value
wmc 80
c 9
b 0
f 0
lcom 1
cbo 2
dl 0
loc 568
ccs 218
cts 306
cp 0.7124
rs 4.8717

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 3
A getRasterImage() 0 7 1
D load() 0 31 9
A convertBW() 0 23 1
A save() 0 13 3
B resizeImage() 0 19 6
A imageQRCode() 0 21 1
C loadBMP() 0 59 9
B saveBMP() 0 44 5
A convertPixelBW() 0 18 3
C convertRaster() 0 48 9
D saveImage() 0 35 10
C getBMPColor() 0 55 15
A littleEndian2String() 0 9 2
A getPixelColor() 0 4 1
A closestMultiple() 0 8 2

How to fix   Complexity   

Complex Class

Complex classes like Graphics often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Graphics, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Posprint\Graphics;
4
5
/**
6
 * Classe Graphics
7
 *
8
 * @category  NFePHP
9
 * @package   Posprint
10
 * @copyright Copyright (c) 2016
11
 * @license   http://www.gnu.org/licenses/lesser.html LGPL v3
12
 * @author    Roberto L. Machado <linux dot rlm at gmail dot com>
13
 * @link      http://github.com/nfephp-org/posprint for the canonical source repository
14
 */
15
16
use Posprint\Graphics\Basic;
17
use Endroid\QrCode\QrCode;
18
use RuntimeException;
19
use InvalidArgumentException;
20
21
class Graphics extends Basic
22
{
23
    /**
24
     * Image prixels in BW
25
     *
26
     * @var string
27
     */
28
    protected $imgData = null;
29
    /**
30
     * Image Raster bit
31
     *
32
     * @var string
33
     */
34
    protected $imgRasterData = null;
35
  
36
    /**
37
     * Constructor
38
     * Load a image, if passed a path to file and adjust dimentions
39
     *
40
     * @param  string $filename
41
     * @param  int    $width
42
     * @param  int    $height
43
     * @throws RuntimeException
44
     */
45 12
    public function __construct($filename = null, $width = null, $height = null)
46
    {
47 12
        if (! $this->isGdSupported()) {
48
            throw new RuntimeException("GD module not found.");
49
        }
50 12
        $this->imgHeight = 0;
51 12
        $this->imgWidth = 0;
52 12
        $this->imgData = null;
53 12
        $this->imgRasterData = null;
54
        // Load the image, if the patch was passed
55 12
        if (! is_null($filename)) {
56 9
            $this->load($filename, $width, $height);
57 7
        }
58 10
    }
59
    
60
    /**
61
     * Return a string of bytes
62
     * for inclusion on printer commands
63
     * This method change image to Black and White and
64
     * reducing the color resolution of 1 bit per pixel
65
     *
66
     * @return string
67
     */
68 2
    public function getRasterImage()
69
    {
70 2
        $this->resizeImage($this->imgWidth);
71 2
        $this->convertPixelBW();
72 2
        $this->convertRaster();
73 2
        return $this->imgRasterData;
74
    }
75
76
    /**
77
     * load
78
     * Load image file and adjust dimentions
79
     *
80
     * @param  string $filename path to image file
81
     * @param  float  $width
82
     * @param  float  $height
83
     * @throws InvalidArgumentException
84
     * @throws RuntimeException
85
     */
86 9
    public function load($filename, $width = null, $height = null)
87
    {
88 9
        if (! is_file($filename)) {
89 1
            throw new InvalidArgumentException("Image file not found.");
90
        }
91 8
        if (! is_readable($filename)) {
92
            throw new RuntimeException("The file can not be read due to lack of permissions.");
93
        }
94
        //identify type of image and load with GD
95 8
        $tipo = $this->identifyImg($filename);
96 8
        if ($tipo == 'BMP') {
97
            $img = $this->loadBMP($filename);
98
            if ($img === false) {
99
                throw new InvalidArgumentException("Image file is not a BMP");
100
            }
101
        } else {
102 8
            $func = 'imagecreatefrom' . strtolower($tipo);
103 8
            if (! function_exists($func)) {
104 1
                throw new RuntimeException("It is not possible to use or handle this type of image with GD");
105
            }
106 7
            $this->img = $func($filename);
107
        }
108 7
        if (! $this->img) {
109
            throw new RuntimeException("Failed to load image '$filename'.");
110
        }
111
        //get image dimentions
112 7
        $this->getDimImage();
113 7
        if ($width != null || $height != null) {
114
            $this->resizeImage($width, $height);
115
        }
116 7
    }
117
    
118
    /**
119
     * Converts a true color image to Black and white
120
     * even if the image have transparency (alpha channel)
121
     */
122
    public function convertBW()
123
    {
124
        $newimg = imagecreatetruecolor($this->imgWidth, $this->imgHeight);
125
        imagealphablending($newimg, false);
126
        imagesavealpha($newimg, true);
127
        imagecopyresampled(
128
            $newimg,
129
            $this->img,
130
            0,
131
            0,
132
            0,
133
            0,
134
            $this->imgWidth,
135
            $this->imgHeight,
136
            $this->imgWidth,
137
            $this->imgHeight
138
        );
139
        $bcg = imagecolorallocate($newimg, 255, 255, 255);
140
        imagefill($newimg, 0, 0, $bcg);
141
        imagefilter($newimg, IMG_FILTER_GRAYSCALE);
142 2
        imagefilter($newimg, IMG_FILTER_CONTRAST, -1000);
143
        $this->img = $newimg;
144 2
    }
145 2
    
146
    /**
147
     * Save image to file
148
     *
149 2
     * @param string $filename
150 2
     * @param string $type  PNG, JPG, GIF, BMP
151
     * @param integer $quality 0 - 100 default 75
152
     * @return boolean
153 2
     */
154
    public function save($filename = null, $type = 'PNG', $quality = 75)
155
    {
156
        $type = strtoupper($type);
157
        if ($type == 'BMP') {
158
            $this->saveBMP($filename);
159
            return true;
160
        }
161
        $aTypes = ['PNG', 'JPG', 'JPEG',  'GIF'];
162 3
        if (! in_array($type, $aTypes)) {
163
            throw InvalidArgumentException('This file type is not supported.');
164 3
        }
165
        return $this->saveImage($filename, $this->img, $type, $quality);
166
    }
167
    
168 3
    /**
169 3
     * resizeImage
170 3
     * Resize an image
171 3
     * NOTE: the width is always set to the multiple of 8 more
172 3
     * next, why? printers have a resolution of 8 dots per mm
173 3
     *
174 3
     * @param  float $width
175 3
     * @param  float $height
176 3
     * @throws InvalidArgumentException
177 3
     */
178 3
    public function resizeImage($width = null, $height = null)
179 3
    {
180 3
        if ($width == null && $height == null) {
181 3
            throw new InvalidArgumentException("No dimensions was passed.");
182 3
        }
183 3
        if ($width != null) {
184
            $width = $this->closestMultiple($width);
185 3
            $razao = $width / $this->imgWidth;
186 3
            $height = (int) round($razao * $this->imgHeight);
187 3
        } elseif ($width == null && $height != null) {
188 3
            $razao = $height / $this->imgHeight;
189 3
            $width = (int) round($razao * $this->imgWidth);
190
            $width = $this->closestMultiple($width);
191 3
        }
192 3
        $tempimg = imagecreatetruecolor($width, $height);
193 3
        imagecopyresampled($tempimg, $this->img, 0, 0, 0, 0, $width, $height, $this->imgWidth, $this->imgHeight);
194 3
        $this->img = $tempimg;
195 3
        $this->getDimImage();
196 3
    }
197 3
    
198 3
    /**
199 3
     * Creates a  GD QRCode image
200 3
     *
201 3
     * @param string $dataText
202 3
     * @param int    $width
203 3
     * @param int    $padding
204 2
     * @param string $errCorretion  LOW, MEDIUM, QUARTILE, HIGH
205
     * @return void
206
     */
207
    public function imageQRCode(
208
        $dataText = 'NADA NADA NADA NADA NADA NADA NADA NADA NADA NADA NADA NADA',
209
        $width = 200,
210
        $padding = 10,
211
        $errCorretion = 'MEDIUM'
212
    ) {
213
        //adjust width for a closest multiple of 8
214 1
        $width = $this->closestMultiple($width, 8);
215
        $qrCode = new QrCode();
216
        $qrCode->setText($dataText)
217 1
            ->setImageType('png')
218
            ->setSize($width)
219
            ->setPadding($padding)
220
            ->setErrorCorrection($errCorretion)
221 1
            ->setForegroundColor(array('r' => 0, 'g' => 0, 'b' => 0, 'a' => 0))
222 1
            ->setBackgroundColor(array('r' => 255, 'g' => 255, 'b' => 255, 'a' => 0))
223
            ->setLabel('')
224
            ->setLabelFontSize(8);
225
        $this->img = $qrCode->getImage();
226 1
        $this->getDimImage();
227 1
    }
228 1
    
229
    /**
230 1
     * loadBMP
231 1
     * Create a GD image from BMP file
232 1
     *
233 1
     * @param  string $filename
234 1
     * @return boolean
235 1
     */
236 1
    protected function loadBMP($filename)
237 1
    {
238 1
        //open file as binary
239 1
        if (! $f1 = fopen($filename, "rb")) {
240
            throw InvalidArgumentException('Can not open file.');
241
        }
242 1
        //get properties from image file
243 1
        $file = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1, 14));
244
        if ($file['file_type'] != 19778) {
245
            throw InvalidArgumentException('This file is not a BMP image.');
246
        }
247 1
        //get properties form image
248 1
        $bmp = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
249
           '/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
250 1
           '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1, 40));
251 1
        //check deep of colors
252 1
        $bmp['colors'] = pow(2, $bmp['bits_per_pixel']);
253 1
        if ($bmp['size_bitmap'] == 0) {
254
            $bmp['size_bitmap'] = $file['file_size'] - $file['bitmap_offset'];
255 1
        }
256 1
        $bmp['bytes_per_pixel'] = $bmp['bits_per_pixel']/8;
257 1
        $bmp['bytes_per_pixel2'] = ceil($bmp['bytes_per_pixel']);
258
        $bmp['decal'] = ($bmp['width']*$bmp['bytes_per_pixel']/4);
259 1
        $bmp['decal'] -= floor($bmp['width']*$bmp['bytes_per_pixel']/4);
260 1
        $bmp['decal'] = 4-(4*$bmp['decal']);
261
        if ($bmp['decal'] == 4) {
262
            $bmp['decal'] = 0;
263 1
        }
264 1
        $palette = array();
265 1
        if ($bmp['colors'] < 16777216) {
266 1
            $palette = unpack('V'.$bmp['colors'], fread($f1, $bmp['colors']*4));
267 1
        }
268 1
        //read all data form image but not the header
269 1
        $img = fread($f1, $bmp['size_bitmap']);
270 1
        fclose($f1);
271 1
        //create a true color GD resource
272
        $vide = chr(0);
273
        $res = imagecreatetruecolor($bmp['width'], $bmp['height']);
274
        $p = 0;
275
        $y = $bmp['height']-1;
276
        //read all bytes form original file
277
        while ($y >= 0) {
278
            $x=0;
279
            while ($x < $bmp['width']) {
280
                //get byte color from BMP
281
                $color = $this->getBMPColor($bmp['bits_per_pixel'], $img, $vide, $p, $palette);
0 ignored issues
show
Documentation introduced by
$palette is of type array, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
282
                if ($color === false) {
283
                    throw RuntimeException('Fail during conversion from BMP number bit per pixel incorrect!');
284
                }
285
                imagesetpixel($res, $x, $y, $color[1]);
286
                $x++;
287
                $p += $bmp['bytes_per_pixel'];
288
            }
289
            $y--;
290
            $p += $bmp['decal'];
291
        }
292
        $this->img = $res;
293
        return true;
294
    }
295
296
    /**
297
     * Convert a GD image into a BMP string representation
298
     *
299
     * @param string $filename
300
     * @return string
301
     */
302
    protected function saveBMP($filename = null)
303
    {
304
        if (! is_resource($this->img)) {
305
            return '';
306
        }
307
        //to remove alpha color and put white instead
308
        $img = $this->img;
309
        $imageX = imagesx($img);
310
        $imageY = imagesy($img);
311
        $bmp = '';
312
        for ($yInd = ($imageY - 1); $yInd >= 0; $yInd--) {
313
            $thisline = '';
314
            for ($xInd = 0; $xInd < $imageX; $xInd++) {
315
                $argb = self::getPixelColor($img, $xInd, $yInd);
316
                $thisline .= chr($argb['blue']).chr($argb['green']).chr($argb['red']);
317
            }
318
            while (strlen($thisline) % 4) {
319
                $thisline .= "\x00";
320
            }
321
            $bmp .= $thisline;
322
        }
323
        $bmpSize = strlen($bmp) + 14 + 40;
324
        // bitMapHeader [14 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_62uq.asp
325
        $bitMapHeader  = 'BM'; // WORD bfType;
326
        $bitMapHeader .= self::littleEndian2String($bmpSize, 4); // DWORD bfSize;
327
        $bitMapHeader .= self::littleEndian2String(0, 2); // WORD bfReserved1;
328
        $bitMapHeader .= self::littleEndian2String(0, 2); // WORD bfReserved2;
329
        $bitMapHeader .= self::littleEndian2String(54, 4); // DWORD bfOffBits;
330
        // bitMapInfoHeader - [40 bytes] http://msdn.microsoft.com/library/en-us/gdi/bitmaps_1rw2.asp
331
        $bitMapInfoHeader  = self::littleEndian2String(40, 4); // DWORD biSize;
332
        $bitMapInfoHeader .= self::littleEndian2String($imageX, 4); // LONG biWidth;
333
        $bitMapInfoHeader .= self::littleEndian2String($imageY, 4); // LONG biHeight;
334
        $bitMapInfoHeader .= self::littleEndian2String(1, 2); // WORD biPlanes;
335
        $bitMapInfoHeader .= self::littleEndian2String(24, 2); // WORD biBitCount;
336
        $bitMapInfoHeader .= self::littleEndian2String(0, 4); // DWORD biCompression;
337
        $bitMapInfoHeader .= self::littleEndian2String(0, 4); // DWORD biSizeImage;
338
        $bitMapInfoHeader .= self::littleEndian2String(2835, 4); // LONG biXPelsPerMeter;
339
        $bitMapInfoHeader .= self::littleEndian2String(2835, 4); // LONG biYPelsPerMeter;
340
        $bitMapInfoHeader .= self::littleEndian2String(0, 4); // DWORD biClrUsed;
341
        $bitMapInfoHeader .= self::littleEndian2String(0, 4); // DWORD biClrImportant;
342
        $data = $bitMapHeader.$bitMapInfoHeader.$bmp;
343
        $this->saveImage($filename, $data);
344
        return $data;
345
    }
346
    
347
    /**
348
     * Convert image from GD resource
349
     * into Black and White pixels image
350
     *
351 3
     * @return string Representation of bytes image in BW
352
     */
353 3
    protected function convertPixelBW()
354 1
    {
355
        // Make a string of 1's and 0's
356 2
        $this->imgData = str_repeat("\0", $this->imgHeight * $this->imgWidth);
357 1
        for ($yInd = 0; $yInd < $this->imgHeight; $yInd++) {
358 1
            for ($xInd = 0; $xInd < $this->imgWidth; $xInd++) {
359 1
                //get colors from byte image
360 2
                $cols = imagecolorsforindex($this->img, imagecolorat($this->img, $xInd, $yInd));
361 1
                //convert to greyness color 1 for white, 0 for black
362 1
                $greyness = (int)(($cols['red'] + $cols['green'] + $cols['blue']) / 3) >> 7;
363 1
                //switch to Black and white
364 1
                //1 for black, 0 for white, taking into account transparency color
365 2
                $black = (1 - $greyness) >> ($cols['alpha'] >> 6);
366 2
                $this->imgData[$yInd * $this->imgWidth + $xInd] = $black;
367 2
            }
368 2
        }
369 2
        return $this->imgData;
370
    }
371
372
    /**
373
     * Output the image in raster (row) format.
374
     * This can result in padding on the right of the image,
375
     * if its width is not divisible by 8.
376
     *
377
     * @throws RuntimeException Where the generated data is
378
     *         unsuitable for the printer (indicates a bug or oversized image).
379
     * @return string The image in raster format.
380 1
     */
381
    protected function convertRaster()
382
    {
383
        if (! is_null($this->imgRasterData)) {
384
             return $this->imgRasterData;
385
        }
386
        if (is_null($this->imgData)) {
387 1
            $this->convertPixelBW();
388 1
        }
389 1
        //get width in Pixels
390 1
        $widthPixels = $this->getWidth();
391 1
        //get heightin in Pixels
392 1
        $heightPixels = $this->getHeight();
393 1
        //get width in Bytes
394 1
        $widthBytes = $this->getWidthBytes();
395 1
        //initialize vars
396 1
        $xCount = $yCount = $bit = $byte = $byteVal = 0;
397 1
        //create a string for converted bytes
398 1
        $data = str_repeat("\0", $widthBytes * $heightPixels);
399 1
        if (strlen($data) == 0) {
400 1
            return $data;
401
        }
402
        /* Loop through and convert format */
403
        do {
404
            $byteVal |= (int) $this->imgData[$yCount * $widthPixels + $xCount] << (7 - $bit);
405
            $xCount++;
406
            $bit++;
407
            if ($xCount >= $widthPixels) {
408 1
                $xCount = 0;
409
                $yCount++;
410
                $bit = 8;
411 1
                if ($yCount >= $heightPixels) {
412 1
                    $data[$byte] = chr($byteVal);
413 1
                    break;
414
                }
415 1
            }
416
            if ($bit >= 8) {
417 1
                $data[$byte] = chr($byteVal);
418
                $byteVal = 0;
419
                $bit = 0;
420 1
                $byte++;
421 1
            }
422 1
        } while (true);
423 1
        if (strlen($data) != ($this->getWidthBytes() * $this->getHeight())) {
424 1
            throw new RuntimeException("Bug in " . __FUNCTION__ . ", wrong number of bytes.");
425
        }
426
         $this->imgRasterData = $data;
427
         return $this->imgRasterData;
428
    }
429
    
430
    /**
431
     * Save safety binary image file
432
     *
433
     * @param string               $filename
434
     * @param resource|string|null $data
435
     * @param string $type PNG, JPG, GIF, BMP
436 2
     * @param integer $quality
437
     * @return boolean
438 2
     * @throws InvalidArgumentException
439 1
     * @throws RuntimeException
440
     */
441 2
    protected function saveImage($filename = null, $data = null, $type = 'PNG', $quality = 75)
442
    {
443
        if (empty($filename) || empty($data)) {
444
            return false;
445 2
        }
446
        if (is_resource($data)) {
447 2
            //use GD to save image to file
448
            switch ($type) {
449 2
                case 'JPG':
450
                case 'JPEG':
451 2
                    $result = imagejpeg($data, $filename, $quality);
452
                    break;
453 2
                case 'GIF':
454 2
                    $result = imagegif($data, $filename);
455
                    break;
456
                default:
457
                    $result = imagepng($data, $filename);
458
                    break;
459 2
            }
460 2
            if (!$result) {
461 2
                throw new InvalidArgumentException("Fail to write in $filename.");
462 2
            }
463 2
            return true;
464 2
        }
465 2
        $handle = @fopen($filename, 'w');
466 2
        if (!is_resource($handle)) {
467 2
            throw new InvalidArgumentException("Cant open file $filename. Check permissions.");
468 2
        }
469
        $nbytes = fwrite($handle, $data);
470 2
        fclose($handle);
471 2
        if (!$nbytes) {
472 2
            throw new RuntimeException("Fail to write in $filename.");
473 2
        }
474 2
        return true;
475 2
    }
476 2
477 2
    /**
478 2
     * Get byte color form BMP
479
     *
480
     * @param integer $bpp bytes_per_pixel
481 2
     * @param string $img bytes read of file
482 2
     * @param string $vide
483
     * @param integer $p
484
     * @param integer $palette
485
     * @return integer|boolean
486
     */
487
    private function getBMPColor($bpp, $img, $vide, $p, $palette)
488
    {
489
        switch ($bpp) {
490
            case 24:
491
                return unpack("V", substr($img, $p, 3).$vide);
492
                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...
493
            case 16:
494
                $color = unpack("v", substr($img, $p, 2));
495
                $blue = ($color[1] & 0x001f) << 3;
496 4
                $green = ($color[1] & 0x07e0) >> 3;
497
                $red = ($color[1] & 0xf800) >> 8;
498 4
                $color[1] = $red * 65536 + $green * 256 + $blue;
499
                return $color;
500
                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...
501 4
            case 8:
502
                $color = unpack("n", $vide.substr($img, $p, 1));
503
                $color[1] = $palette[$color[1]+1];
504 2
                return $color;
505 2
                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...
506
            case 4:
507
                $color = unpack("n", $vide.substr($img, floor($p), 1));
508 2
                if (($p*2)%2 == 0) {
509
                    $color[1] = ($color[1] >> 4) ;
510
                } else {
511 2
                    $color[1] = ($color[1] & 0x0F);
512 2
                }
513 2
                $color[1] = $palette[$color[1]+1];
514 2
                return $color;
515 2
                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...
516
            case 1:
517
                $color = unpack("n", $vide.substr($img, floor($p), 1));
518 2
                if (($p*8)%8 == 0) {
519
                    $color[1] = $color[1]>>7;
520 2
                } elseif (($p*8)%8 == 1) {
521 2
                    $color[1] = ($color[1] & 0x40)>>6;
522 1
                } elseif (($p*8)%8 == 2) {
523
                    $color[1] = ($color[1] & 0x20)>>5;
524 1
                } elseif (($p*8)%8 == 3) {
525 1
                    $color[1] = ($color[1] & 0x10)>>4;
526 1
                } elseif (($P*8)%8 == 4) {
0 ignored issues
show
Bug introduced by
The variable $P does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
527
                    $color[1] = ($color[1] & 0x8)>>3;
528
                } elseif (($p*8)%8 == 5) {
529 1
                    $color[1] = ($color[1] & 0x4)>>2;
530
                } elseif (($p*8)%8 == 6) {
531
                    $color[1] = ($color[1] & 0x2)>>1;
532
                } elseif (($p*8)%8 == 7) {
533
                    $color[1] = ($color[1] & 0x1);
534
                }
535
                $color[1] = $palette[$color[1]+1];
536
                return $color;
537
                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...
538
            default:
539 2
                return false;
540
        }
541 2
    }
542 2
    
543 2
    /**
544 2
     * Converts Litte Endian Bytes do String
545 2
     *
546 2
     * @param  int $number
547
     * @param  int $minbytes
548
     * @return string
549
     */
550
    private static function littleEndian2String($number, $minbytes = 1)
551
    {
552
        $intstring = '';
553
        while ($number > 0) {
554
            $intstring = $intstring.chr($number & 255);
555
            $number >>= 8;
556
        }
557 2
        return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
558
    }
559 2
    
560
    /**
561
     * Get pixel colors
562
     *
563
     * @param  resource $img
564
     * @param  int      $x
565
     * @param  int      $y
566
     * @return array
567
     */
568
    private static function getPixelColor($img, $x, $y)
569 3
    {
570
        return imageColorsForIndex($img, imageColorAt($img, $x, $y));
571 3
    }
572 3
    
573 1
    /**
574
     * Ajusta o numero para o multiplo mais proximo de base
575 2
     *
576
     * @param  float $num
577
     * @param  int   $num
578
     * @return int
579
     */
580
    private function closestMultiple($num = 0, $base = 8)
581
    {
582
        $iNum = ceil($num);
583
        if (($iNum % $base) === 0) {
584
            return $iNum;
585
        }
586
        return round($num/$base) * $base;
587
    }
588
}
589