Completed
Pull Request — master (#76)
by Roberto
07:14
created

Graphics::convertBW()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1.644

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 23
ccs 3
cts 22
cp 0.1364
rs 9.0856
cc 1
eloc 20
nc 1
nop 0
crap 1.644
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\ErrorCorrectionLevel;
18
use Endroid\QrCode\Writer\PngWriter;
19
use Endroid\QrCode\QrCode;
20
use RuntimeException;
21
use InvalidArgumentException;
22
23
class Graphics extends Basic
24
{
25
    /**
26
     * Image prixels in BW
27
     *
28
     * @var string
29
     */
30
    protected $imgData = null;
31
    /**
32
     * Image Raster bit
33
     *
34
     * @var string
35
     */
36
    protected $imgRasterData = null;
37
  
38
    /**
39
     * Constructor
40
     * Load a image, if passed a path to file and adjust dimentions
41
     *
42
     * @param  string $filename
43
     * @param  int    $width
44
     * @param  int    $height
45
     * @throws RuntimeException
46
     */
47 12
    public function __construct($filename = null, $width = null, $height = null)
48
    {
49 12
        if (! $this->isGdSupported()) {
50
            throw new RuntimeException("GD module not found.");
51
        }
52 12
        $this->imgHeight = 0;
53 12
        $this->imgWidth = 0;
54 12
        $this->imgData = null;
55 12
        $this->imgRasterData = null;
56
        // Load the image, if the patch was passed
57 12
        if (! is_null($filename)) {
58 9
            $this->load($filename, $width, $height);
59 7
        }
60 10
    }
61
    
62
    /**
63
     * Return a string of bytes
64
     * for inclusion on printer commands
65
     * This method change image to Black and White and
66
     * reducing the color resolution of 1 bit per pixel
67
     *
68
     * @return string
69
     */
70 2
    public function getRasterImage()
71
    {
72 2
        $this->resizeImage($this->imgWidth);
73 2
        $this->convertPixelBW();
74 2
        $this->convertRaster();
75 2
        return $this->imgRasterData;
76
    }
77
78
    /**
79
     * load
80
     * Load image file and adjust dimentions
81
     *
82
     * @param  string $filename path to image file
83
     * @param  float  $width
84
     * @param  float  $height
85
     * @throws InvalidArgumentException
86
     * @throws RuntimeException
87
     */
88 9
    public function load($filename, $width = null, $height = null)
89
    {
90 9
        if (! is_file($filename)) {
91 1
            throw new InvalidArgumentException("Image file not found.");
92
        }
93 8
        if (! is_readable($filename)) {
94
            throw new RuntimeException("The file can not be read due to lack of permissions.");
95
        }
96
        //identify type of image and load with GD
97 8
        $tipo = $this->identifyImg($filename);
98 8
        if ($tipo == 'BMP') {
99
            $img = $this->loadBMP($filename);
100
            if ($img === false) {
101
                throw new InvalidArgumentException("Image file is not a BMP");
102
            }
103
        } else {
104 8
            $func = 'imagecreatefrom' . strtolower($tipo);
105 8
            if (! function_exists($func)) {
106 1
                throw new RuntimeException("It is not possible to use or handle this type of image with GD");
107
            }
108 7
            $this->img = $func($filename);
109
        }
110 7
        if (! $this->img) {
111
            throw new RuntimeException("Failed to load image '$filename'.");
112
        }
113
        //get image dimentions
114 7
        $this->getDimImage();
115 7
        if ($width != null || $height != null) {
116
            $this->resizeImage($width, $height);
117
        }
118 7
    }
119
    
120
    /**
121
     * Converts a true color image to Black and white
122
     * even if the image have transparency (alpha channel)
123
     */
124 1
    public function convertBW()
125
    {
126
        $newimg = imagecreatetruecolor($this->imgWidth, $this->imgHeight);
127
        imagealphablending($newimg, false);
128
        imagesavealpha($newimg, true);
129
        imagecopyresampled(
130 1
            $newimg,
131 1
            $this->img,
132
            0,
133
            0,
134
            0,
135
            0,
136
            $this->imgWidth,
137
            $this->imgHeight,
138
            $this->imgWidth,
139
            $this->imgHeight
140
        );
141
        $bcg = imagecolorallocate($newimg, 255, 255, 255);
142
        imagefill($newimg, 0, 0, $bcg);
143
        imagefilter($newimg, IMG_FILTER_GRAYSCALE);
144
        imagefilter($newimg, IMG_FILTER_CONTRAST, -1000);
145
        $this->img = $newimg;
146
    }
147
    
148
    /**
149
     * Save image to file
150
     *
151
     * @param string $filename
152
     * @param string $type  PNG, JPG, GIF, BMP
153
     * @param integer $quality 0 - 100 default 75
154
     * @return boolean
155
     */
156 4
    public function save($filename = null, $type = 'PNG', $quality = 75)
157
    {
158 4
        $type = strtoupper($type);
159 4
        if ($type == 'BMP') {
160 2
            $this->saveBMP($filename);
161 1
            return true;
162
        }
163 2
        $aTypes = ['PNG', 'JPG', 'JPEG',  'GIF'];
164 2
        if (! in_array($type, $aTypes)) {
165
            throw InvalidArgumentException('This file type is not supported.');
166
        }
167 2
        return $this->saveImage($filename, $this->img, $type, $quality);
168
    }
169
    
170
    /**
171
     * resizeImage
172
     * Resize an image
173
     * NOTE: the width is always set to the multiple of 8 more
174
     * next, why? printers have a resolution of 8 dots per mm
175
     *
176
     * @param  float $width
177
     * @param  float $height
178
     * @throws InvalidArgumentException
179
     */
180 3
    public function resizeImage($width = null, $height = null)
181
    {
182 3
        if ($width == null && $height == null) {
183 1
            throw new InvalidArgumentException("No dimensions was passed.");
184
        }
185 2
        if ($width != null) {
186 1
            $width = $this->closestMultiple($width);
187 1
            $razao = $width / $this->imgWidth;
188 1
            $height = (int) round($razao * $this->imgHeight);
189 2
        } elseif ($width == null && $height != null) {
190 1
            $razao = $height / $this->imgHeight;
191 1
            $width = (int) round($razao * $this->imgWidth);
192 1
            $width = $this->closestMultiple($width);
193 1
        }
194 2
        $tempimg = imagecreatetruecolor($width, $height);
195 2
        imagecopyresampled($tempimg, $this->img, 0, 0, 0, 0, $width, $height, $this->imgWidth, $this->imgHeight);
196 2
        $this->img = $tempimg;
197 2
        $this->getDimImage();
198 2
    }
199
    
200
    /**
201
     * Creates a  GD QRCode image
202
     *
203
     * @param string $dataText
204
     * @param int    $width
205
     * @param int    $padding
206
     * @param string $errCorretion  LOW, MEDIUM, QUARTILE, HIGH
207
     * @return void
208
     */
209 1
    public function imageQRCode(
210
        $dataText = 'NADA NADA NADA NADA NADA NADA NADA NADA NADA NADA NADA NADA',
211
        $width = 200,
212
        $padding = 10,
213
        $errCorretion = 'MEDIUM'
214
    ) {
215
        //adjust width for a closest multiple of 8
216 1
        $width = $this->closestMultiple($width, 8);
217
        //create image
218
        try {
219 1
            $qrCode = new QrCode($dataText);
220 1
            $qrCode->setMargin($padding);
221 1
            $qrCode->setSize($width);
222 1
            $qrCode->setEncoding('UTF-8');
223 1
            $qrCode->setErrorCorrectionLevel(strtolower($errCorretion));
224 1
            $qrCode->setForegroundColor(['r' => 0, 'g' => 0, 'b' => 0]);
225 1
            $qrCode->setBackgroundColor(['r' => 255, 'g' => 255, 'b' => 255]);
226 1
            $qrCode->setValidateResult(true);
227
            //write PNG image
228 1
            $this->img = $qrCode->writeString(PngWriter::class);
0 ignored issues
show
Documentation Bug introduced by
It seems like $qrCode->writeString(\En...riter\PngWriter::class) of type string is incompatible with the declared type resource of property $img.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
229 1
            $this->getDimImage();
230 1
        } catch (\Exception $e) {
231
            throw new \RuntimeException(
232
                "ERROR. Falha de validação Ajuste o tamanho do codigo "
233
                    . "para permitir legibilidade. [" . $e->getMessage() . ']');
234
        }
235 1
    }
236
    
237
    /**
238
     * loadBMP
239
     * Create a GD image from BMP file
240
     *
241
     * @param  string $filename
242
     * @return boolean
243
     */
244 1
    protected function loadBMP($filename)
245
    {
246
        //open file as binary
247 1
        if (! $f1 = fopen($filename, "rb")) {
248
            throw InvalidArgumentException('Can not open file.');
249
        }
250
        //get properties from image file
251 1
        $file = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1, 14));
252 1
        if ($file['file_type'] != 19778) {
253
            throw InvalidArgumentException('This file is not a BMP image.');
254
        }
255
        //get properties form image
256 1
        $bmp = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
257 1
           '/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
258 1
           '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1, 40));
259
        //check deep of colors
260 1
        $bmp['colors'] = pow(2, $bmp['bits_per_pixel']);
261 1
        if ($bmp['size_bitmap'] == 0) {
262 1
            $bmp['size_bitmap'] = $file['file_size'] - $file['bitmap_offset'];
263 1
        }
264 1
        $bmp['bytes_per_pixel'] = $bmp['bits_per_pixel']/8;
265 1
        $bmp['bytes_per_pixel2'] = ceil($bmp['bytes_per_pixel']);
266 1
        $bmp['decal'] = ($bmp['width']*$bmp['bytes_per_pixel']/4);
267 1
        $bmp['decal'] -= floor($bmp['width']*$bmp['bytes_per_pixel']/4);
268 1
        $bmp['decal'] = 4-(4*$bmp['decal']);
269 1
        if ($bmp['decal'] == 4) {
270
            $bmp['decal'] = 0;
271
        }
272 1
        $palette = array();
273 1
        if ($bmp['colors'] < 16777216) {
274
            $palette = unpack('V'.$bmp['colors'], fread($f1, $bmp['colors']*4));
275
        }
276
        //read all data form image but not the header
277 1
        $img = fread($f1, $bmp['size_bitmap']);
278 1
        fclose($f1);
279
        //create a true color GD resource
280 1
        $vide = chr(0);
281 1
        $res = imagecreatetruecolor($bmp['width'], $bmp['height']);
282 1
        $p = 0;
283 1
        $y = $bmp['height']-1;
284
        //read all bytes form original file
285 1
        while ($y >= 0) {
286 1
            $x=0;
287 1
            while ($x < $bmp['width']) {
288
                //get byte color from BMP
289 1
                $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...
290 1
                if ($color === false) {
291
                    throw RuntimeException('Fail during conversion from BMP number bit per pixel incorrect!');
292
                }
293 1
                imagesetpixel($res, $x, $y, $color[1]);
294 1
                $x++;
295 1
                $p += $bmp['bytes_per_pixel'];
296 1
            }
297 1
            $y--;
298 1
            $p += $bmp['decal'];
299 1
        }
300 1
        $this->img = $res;
301 1
        return true;
302
    }
303
304
    /**
305
     * Convert a GD image into a BMP string representation
306
     *
307
     * @param string $filename
308
     * @return string
309
     */
310 2
    protected function saveBMP($filename = null)
311
    {
312 2
        if (! is_resource($this->img)) {
313
            return '';
314
        }
315
        //to remove alpha color and put white instead
316 2
        $img = $this->img;
317 2
        $imageX = imagesx($img);
318 2
        $imageY = imagesy($img);
319 2
        $bmp = '';
320 2
        for ($yInd = ($imageY - 1); $yInd >= 0; $yInd--) {
321 2
            $thisline = '';
322 2
            for ($xInd = 0; $xInd < $imageX; $xInd++) {
323 2
                $argb = self::getPixelColor($img, $xInd, $yInd);
324 2
                $thisline .= chr($argb['blue']).chr($argb['green']).chr($argb['red']);
325 2
            }
326 2
            while (strlen($thisline) % 4) {
327 2
                $thisline .= "\x00";
328 2
            }
329 2
            $bmp .= $thisline;
330 2
        }
331 2
        $bmpSize = strlen($bmp) + 14 + 40;
332
        // bitMapHeader [14 bytes] - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_62uq.asp
333 2
        $bitMapHeader  = 'BM'; // WORD bfType;
334 2
        $bitMapHeader .= self::littleEndian2String($bmpSize, 4); // DWORD bfSize;
335 2
        $bitMapHeader .= self::littleEndian2String(0, 2); // WORD bfReserved1;
336 2
        $bitMapHeader .= self::littleEndian2String(0, 2); // WORD bfReserved2;
337 2
        $bitMapHeader .= self::littleEndian2String(54, 4); // DWORD bfOffBits;
338
        // bitMapInfoHeader - [40 bytes] http://msdn.microsoft.com/library/en-us/gdi/bitmaps_1rw2.asp
339 2
        $bitMapInfoHeader  = self::littleEndian2String(40, 4); // DWORD biSize;
340 2
        $bitMapInfoHeader .= self::littleEndian2String($imageX, 4); // LONG biWidth;
341 2
        $bitMapInfoHeader .= self::littleEndian2String($imageY, 4); // LONG biHeight;
342 2
        $bitMapInfoHeader .= self::littleEndian2String(1, 2); // WORD biPlanes;
343 2
        $bitMapInfoHeader .= self::littleEndian2String(24, 2); // WORD biBitCount;
344 2
        $bitMapInfoHeader .= self::littleEndian2String(0, 4); // DWORD biCompression;
345 2
        $bitMapInfoHeader .= self::littleEndian2String(0, 4); // DWORD biSizeImage;
346 2
        $bitMapInfoHeader .= self::littleEndian2String(2835, 4); // LONG biXPelsPerMeter;
347 2
        $bitMapInfoHeader .= self::littleEndian2String(2835, 4); // LONG biYPelsPerMeter;
348 2
        $bitMapInfoHeader .= self::littleEndian2String(0, 4); // DWORD biClrUsed;
349 2
        $bitMapInfoHeader .= self::littleEndian2String(0, 4); // DWORD biClrImportant;
350 2
        $data = $bitMapHeader.$bitMapInfoHeader.$bmp;
351 2
        $this->saveImage($filename, $data);
352 1
        return $data;
353
    }
354
    
355
    /**
356
     * Convert image from GD resource
357
     * into Black and White pixels image
358
     *
359
     * @return string Representation of bytes image in BW
360
     */
361 1
    protected function convertPixelBW()
362
    {
363
        // Make a string of 1's and 0's
364 1
        $this->imgData = str_repeat("\0", $this->imgHeight * $this->imgWidth);
365 1
        for ($yInd = 0; $yInd < $this->imgHeight; $yInd++) {
366 1
            for ($xInd = 0; $xInd < $this->imgWidth; $xInd++) {
367
                //get colors from byte image
368 1
                $cols = imagecolorsforindex($this->img, imagecolorat($this->img, $xInd, $yInd));
369
                //convert to greyness color 1 for white, 0 for black
370 1
                $greyness = (int)(($cols['red'] + $cols['green'] + $cols['blue']) / 3) >> 7;
371
                //switch to Black and white
372
                //1 for black, 0 for white, taking into account transparency color
373 1
                $black = (1 - $greyness) >> ($cols['alpha'] >> 6);
374 1
                $this->imgData[$yInd * $this->imgWidth + $xInd] = $black;
375 1
            }
376 1
        }
377 1
        return $this->imgData;
378
    }
379
380
    /**
381
     * Output the image in raster (row) format.
382
     * This can result in padding on the right of the image,
383
     * if its width is not divisible by 8.
384
     *
385
     * @throws RuntimeException Where the generated data is
386
     *         unsuitable for the printer (indicates a bug or oversized image).
387
     * @return string The image in raster format.
388
     */
389 2
    protected function convertRaster()
390
    {
391 2
        if (! is_null($this->imgRasterData)) {
392 1
             return $this->imgRasterData;
393
        }
394 2
        if (is_null($this->imgData)) {
395
            $this->convertPixelBW();
396
        }
397
        //get width in Pixels
398 2
        $widthPixels = $this->getWidth();
399
        //get heightin in Pixels
400 2
        $heightPixels = $this->getHeight();
401
        //get width in Bytes
402 2
        $widthBytes = $this->getWidthBytes();
403
        //initialize vars
404 2
        $xCount = $yCount = $bit = $byte = $byteVal = 0;
405
        //create a string for converted bytes
406 2
        $data = str_repeat("\0", $widthBytes * $heightPixels);
407 2
        if (strlen($data) == 0) {
408
            return $data;
409
        }
410
        /* Loop through and convert format */
411
        do {
412 2
            $num = $yCount * $widthPixels + $xCount;
413 2
            $byteVal |= (int) $this->imgData[$num] << (7 - $bit);
414 2
            $xCount++;
415 2
            $bit++;
416 2
            if ($xCount >= $widthPixels) {
417 2
                $xCount = 0;
418 2
                $yCount++;
419 2
                $bit = 8;
420 2
                if ($yCount >= $heightPixels) {
421 2
                    $data[$byte] = chr($byteVal);
422 2
                    break;
423
                }
424 2
            }
425 2
            if ($bit >= 8) {
426 2
                $data[$byte] = chr($byteVal);
427 2
                $byteVal = 0;
428 2
                $bit = 0;
429 2
                $byte++;
430 2
            }
431 2
        } while (true);
432 2
        if (strlen($data) != ($this->getWidthBytes() * $this->getHeight())) {
433
            throw new RuntimeException("Bug in " . __FUNCTION__ . ", wrong number of bytes.");
434
        }
435 2
         $this->imgRasterData = $data;
436 2
         return $this->imgRasterData;
437
    }
438
    
439
    /**
440
     * Save safety binary image file
441
     *
442
     * @param string               $filename
443
     * @param resource|string|null $data
444
     * @param string $type PNG, JPG, GIF, BMP
445
     * @param integer $quality
446
     * @return boolean
447
     * @throws InvalidArgumentException
448
     * @throws RuntimeException
449
     */
450 4
    protected function saveImage($filename = null, $data = null, $type = 'PNG', $quality = 75)
451
    {
452 4
        if (empty($filename) || empty($data)) {
453
            return false;
454
        }
455 4
        if (is_resource($data)) {
456
            //use GD to save image to file
457
            switch ($type) {
458 1
                case 'JPG':
459 1
                case 'JPEG':
460
                    $result = imagejpeg($data, $filename, $quality);
461
                    break;
462 1
                case 'GIF':
463
                    $result = imagegif($data, $filename);
464
                    break;
465 1
                default:
466 1
                    $result = imagepng($data, $filename);
467 1
                    break;
468 1
            }
469 1
            if (!$result) {
470
                throw new InvalidArgumentException("Fail to write in $filename.");
471
            }
472 1
            return true;
473
        }
474 3
        $handle = @fopen($filename, 'w');
475 3
        if (!is_resource($handle)) {
476 1
            throw new InvalidArgumentException("Cant open file $filename. Check permissions.");
477
        }
478 2
        $nbytes = fwrite($handle, $data);
479 2
        fclose($handle);
480 2
        if (!$nbytes) {
481
            throw new RuntimeException("Fail to write in $filename.");
482
        }
483 2
        return true;
484
    }
485
486
    /**
487
     * Get byte color form BMP
488
     *
489
     * @param integer $bpp bytes_per_pixel
490
     * @param string $img bytes read of file
491
     * @param string $vide
492
     * @param integer $p
493
     * @param integer $palette
494
     * @return integer|boolean
495
     */
496
    private function getBMPColor($bpp, $img, $vide, $p, $palette)
497
    {
498
        switch ($bpp) {
499
            case 24:
500
                return unpack("V", substr($img, $p, 3).$vide);
501
                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...
502
            case 16:
503
                $color = unpack("v", substr($img, $p, 2));
504
                $blue = ($color[1] & 0x001f) << 3;
505
                $green = ($color[1] & 0x07e0) >> 3;
506
                $red = ($color[1] & 0xf800) >> 8;
507
                $color[1] = $red * 65536 + $green * 256 + $blue;
508
                return $color;
509
                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...
510
            case 8:
511
                $color = unpack("n", $vide.substr($img, $p, 1));
512
                $color[1] = $palette[$color[1]+1];
513
                return $color;
514
                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...
515
            case 4:
516
                $color = unpack("n", $vide.substr($img, floor($p), 1));
517
                if (($p*2)%2 == 0) {
518
                    $color[1] = ($color[1] >> 4) ;
519
                } else {
520
                    $color[1] = ($color[1] & 0x0F);
521
                }
522
                $color[1] = $palette[$color[1]+1];
523
                return $color;
524
                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...
525
            case 1:
526
                $color = unpack("n", $vide.substr($img, floor($p), 1));
527
                if (($p*8)%8 == 0) {
528
                    $color[1] = $color[1]>>7;
529
                } elseif (($p*8)%8 == 1) {
530
                    $color[1] = ($color[1] & 0x40)>>6;
531
                } elseif (($p*8)%8 == 2) {
532
                    $color[1] = ($color[1] & 0x20)>>5;
533
                } elseif (($p*8)%8 == 3) {
534
                    $color[1] = ($color[1] & 0x10)>>4;
535
                } 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...
536
                    $color[1] = ($color[1] & 0x8)>>3;
537
                } elseif (($p*8)%8 == 5) {
538
                    $color[1] = ($color[1] & 0x4)>>2;
539
                } elseif (($p*8)%8 == 6) {
540
                    $color[1] = ($color[1] & 0x2)>>1;
541
                } elseif (($p*8)%8 == 7) {
542
                    $color[1] = ($color[1] & 0x1);
543
                }
544
                $color[1] = $palette[$color[1]+1];
545
                return $color;
546
                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...
547
            default:
548
                return false;
549
        }
550
    }
551
    
552
    /**
553
     * Converts Litte Endian Bytes do String
554
     *
555
     * @param  int $number
556
     * @param  int $minbytes
557
     * @return string
558
     */
559 2
    private static function littleEndian2String($number, $minbytes = 1)
560
    {
561 2
        $intstring = '';
562 2
        while ($number > 0) {
563 2
            $intstring = $intstring.chr($number & 255);
564 2
            $number >>= 8;
565 2
        }
566 2
        return str_pad($intstring, $minbytes, "\x00", STR_PAD_RIGHT);
567
    }
568
    
569
    /**
570
     * Get pixel colors
571
     *
572
     * @param  resource $img
573
     * @param  int      $x
574
     * @param  int      $y
575
     * @return array
576
     */
577 2
    private static function getPixelColor($img, $x, $y)
578
    {
579 2
        return imageColorsForIndex($img, imageColorAt($img, $x, $y));
580
    }
581
    
582
    /**
583
     * Ajusta o numero para o multiplo mais proximo de base
584
     *
585
     * @param  float $num
586
     * @param  int   $num
587
     * @return int
588
     */
589 3
    private function closestMultiple($num = 0, $base = 8)
590
    {
591 3
        $iNum = ceil($num);
592 3
        if (($iNum % $base) === 0) {
593 1
            return $iNum;
594
        }
595 2
        return round($num/$base) * $base;
596
    }
597
}
598