Completed
Push — master ( 312aa1...eb49de )
by Paul
9s
created

Ico   C

Complexity

Total Complexity 71

Size/Duplication

Total Lines 521
Duplicated Lines 12.28 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 97.39%

Importance

Changes 6
Bugs 1 Features 0
Metric Value
wmc 71
lcom 1
cbo 0
dl 64
loc 521
ccs 299
cts 307
cp 0.9739
rs 5.5904
c 6
b 1
f 0

24 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
A loadFile() 0 5 1
A extractPng() 0 6 1
A getTotalIcons() 0 4 1
A getIconInfo() 0 8 2
A setBackgroundTransparent() 0 4 1
A getImage() 0 12 3
A getPngImage() 0 5 1
A allocateColor() 9 9 2
B loadData() 0 25 3
B extractIconDirEntries() 0 21 5
B extractBmp() 0 27 6
A extractTrueColorImageData() 0 11 1
B extractPaletteImageData() 0 28 2
B extractMonoImageData() 0 28 1
A setBackground() 0 10 3
C getBmpImage() 0 38 7
B render32bit() 13 24 4
B render24bit() 11 25 4
B buildMaskBits() 8 24 4
A render8bit() 9 19 4
A buildPalette() 0 17 3
B render4bit() 3 27 5
B render1bit() 11 24 5

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Ico 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 Ico, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Elphin\IcoFileLoader;
4
5
/**
6
 * Open ICO files and extract any size/depth to PNG format.
7
 */
8
class Ico
9
{
10
    /**
11
     * Background color on icon extraction.
12
     * @var array(R, G, B) = array(255, 255, 255)
13
     */
14
    public $bgcolor = [255, 255, 255];
15
16
    /**
17
     * @var bool Is background color transparent?
18
     */
19
    public $bgcolorTransparent = false;
20
21
    private $filename;
22
    private $ico;
23
    private $iconDirEntry;
24
25
    /**
26
     * Constructor
27
     *
28
     * @param string $path optional path to ICO file
29
     */
30 8
    public function __construct($path = '')
31
    {
32 8
        if (strlen($path) > 0) {
33 7
            $this->loadFile($path);
34 7
        }
35 8
    }
36
37
    /**
38
     * Load an ICO file (don't need to call this is if fill the
39
     * parameter in the class constructor).
40
     *
41
     * @param string $path Path to ICO file
42
     *
43
     * @return bool Success
44
     */
45 8
    public function loadFile($path)
46
    {
47 8
        $this->filename = $path;
48 8
        return $this->loadData(file_get_contents($path));
49
    }
50
51
    /**
52
     * Load an ICO data. If you prefer to open the file
53
     * and return the binary data you can use this function
54
     * directly. Otherwise use loadFile() instead.
55
     *
56
     * @param string $data Binary data of ICO file
57
     *
58
     * @return bool Success
59
     */
60 8
    public function loadData($data)
61
    {
62 8
        $this->iconDirEntry = [];
63
64
        //extract ICONDIR header
65 8
        $icodata = unpack('SReserved/SType/SCount', $data);
66 8
        $this->ico = $icodata;
67 8
        $data = substr($data, 6);
68
69
        //extract ICONDIRENTRY structures
70 8
        $data = $this->extractIconDirEntries($data);
71
72
        // Extract additional headers for each extracted ICONDIRENTRY
73 8
        $iconCount = count($this->iconDirEntry);
74 8
        for ($i = 0; $i < $iconCount; ++$i) {
75 8
            $signature = unpack('LFourCC', substr($data, $this->iconDirEntry[$i]['FileOffset'], 4));
76
77 8
            if ($signature['FourCC'] == 0x474e5089) {
78 2
                $this->extractPng($i, $data);
79 2
            } else {
80 8
                $this->extractBmp($i, $data);
81
            }
82 8
        }
83 8
        return true;
84
    }
85
86 8
    private function extractIconDirEntries($data)
87
    {
88 8
        for ($i = 0; $i < $this->ico['Count']; ++$i) {
89 8
            $icodata = unpack('CWidth/CHeight/CColorCount/CReserved/SPlanes/SBitCount/LSizeInBytes/LFileOffset', $data);
90 8
            $icodata['FileOffset'] -= ($this->ico['Count'] * 16) + 6;
91 8
            if ($icodata['ColorCount'] == 0) {
92 6
                $icodata['ColorCount'] = 256;
93 6
            }
94 8
            if ($icodata['Width'] == 0) {
95 2
                $icodata['Width'] = 256;
96 2
            }
97 8
            if ($icodata['Height'] == 0) {
98 2
                $icodata['Height'] = 256;
99 2
            }
100 8
            $this->iconDirEntry[] = $icodata;
101
102 8
            $data = substr($data, 16);
103 8
        }
104
105 8
        return $data;
106
    }
107
108 2
    private function extractPng($i, $data)
109
    {
110
        //a png icon contains a complete png image at the file offset
111 2
        $this->iconDirEntry[$i]['png'] =
112 2
            substr($data, $this->iconDirEntry[$i]['FileOffset'], $this->iconDirEntry[$i]['SizeInBytes']);
113 2
    }
114
115 8
    private function extractBmp($i, $data)
116
    {
117 8
        $bitmapInfoHeader = unpack(
118
            'LSize/LWidth/LHeight/SPlanes/SBitCount/LCompression/LImageSize/' .
119 8
            'LXpixelsPerM/LYpixelsPerM/LColorsUsed/LColorsImportant',
120 8
            substr($data, $this->iconDirEntry[$i]['FileOffset'])
121 8
        );
122
123 8
        $this->iconDirEntry[$i]['header'] = $bitmapInfoHeader;
124 8
        $this->iconDirEntry[$i]['colors'] = [];
125 8
        $this->iconDirEntry[$i]['BitCount'] = $this->iconDirEntry[$i]['header']['BitCount'];
126
127 8
        switch ($this->iconDirEntry[$i]['BitCount']) {
128 8
            case 32:
129 8
            case 24:
130 5
                $this->extractTrueColorImageData($i, $data);
131 5
                break;
132 5
            case 8:
133 5
            case 4:
134 4
                $this->extractPaletteImageData($i, $data);
135 4
                break;
136 1
            case 1:
137 1
                $this->extractMonoImageData($i, $data);
138 1
                break;
139 8
        }
140 8
        $this->iconDirEntry[$i]['data_length'] = strlen($this->iconDirEntry[$i]['data']);
141 8
    }
142
143 5
    private function extractTrueColorImageData($i, $data)
144
    {
145 5
        $length = $this->iconDirEntry[$i]['header']['Width'] *
146 5
            $this->iconDirEntry[$i]['header']['Height'] *
147 5
            ($this->iconDirEntry[$i]['BitCount'] / 8);
148 5
        $this->iconDirEntry[$i]['data'] = substr(
149 5
            $data,
150 5
            $this->iconDirEntry[$i]['FileOffset'] + $this->iconDirEntry[$i]['header']['Size'],
151
            $length
152 5
        );
153 5
    }
154
155 4
    private function extractPaletteImageData($i, $data)
156
    {
157 4
        $icodata = substr(
158 4
            $data,
159 4
            $this->iconDirEntry[$i]['FileOffset'] + $this->iconDirEntry[$i]['header']['Size'],
160 4
            $this->iconDirEntry[$i]['ColorCount'] * 4
161 4
        );
162 4
        $offset = 0;
163 4
        for ($j = 0; $j < $this->iconDirEntry[$i]['ColorCount']; ++$j) {
164 4
            $this->iconDirEntry[$i]['colors'][] = [
165 4
                'blue' => ord($icodata[$offset]),
166 4
                'green' => ord($icodata[$offset + 1]),
167 4
                'red' => ord($icodata[$offset + 2]),
168 4
                'reserved' => ord($icodata[$offset + 3]),
169
            ];
170 4
            $offset += 4;
171 4
        }
172 4
        $length = $this->iconDirEntry[$i]['header']['Width'] *
173 4
            $this->iconDirEntry[$i]['header']['Height'] *
174 4
            (1 + $this->iconDirEntry[$i]['BitCount']) / $this->iconDirEntry[$i]['BitCount'];
175 4
        $this->iconDirEntry[$i]['data'] = substr(
176 4
            $data,
177 4
            $this->iconDirEntry[$i]['FileOffset'] +
178 4
            ($this->iconDirEntry[$i]['ColorCount'] * 4) +
179 4
            $this->iconDirEntry[$i]['header']['Size'],
180
            $length
181 4
        );
182 4
    }
183
184 1
    private function extractMonoImageData($i, $data)
185
    {
186 1
        $icodata = substr(
187 1
            $data,
188 1
            $this->iconDirEntry[$i]['FileOffset'] + $this->iconDirEntry[$i]['header']['Size'],
189 1
            $this->iconDirEntry[$i]['ColorCount'] * 4
190 1
        );
191
192 1
        $this->iconDirEntry[$i]['colors'][] = [
193 1
            'blue' => ord($icodata[0]),
194 1
            'green' => ord($icodata[1]),
195 1
            'red' => ord($icodata[2]),
196 1
            'reserved' => ord($icodata[3]),
197
        ];
198 1
        $this->iconDirEntry[$i]['colors'][] = [
199 1
            'blue' => ord($icodata[4]),
200 1
            'green' => ord($icodata[5]),
201 1
            'red' => ord($icodata[6]),
202 1
            'reserved' => ord($icodata[7]),
203
        ];
204
205 1
        $length = $this->iconDirEntry[$i]['header']['Width'] * $this->iconDirEntry[$i]['header']['Height'] / 8;
206 1
        $this->iconDirEntry[$i]['data'] = substr(
207 1
            $data,
208 1
            $this->iconDirEntry[$i]['FileOffset'] + $this->iconDirEntry[$i]['header']['Size'] + 8,
209
            $length
210 1
        );
211 1
    }
212
213
    /**
214
     * Return the total icons extracted at the moment.
215
     *
216
     * @return int Total icons
217
     */
218 7
    public function getTotalIcons()
219
    {
220 7
        return count($this->iconDirEntry);
221
    }
222
223
    /**
224
     * Return the icon header corresponding to that index.
225
     *
226
     * @param int $index Icon index
227
     *
228
     * @return resource|bool Icon header or false
229
     */
230 8
    public function getIconInfo($index)
231
    {
232 8
        if (isset($this->iconDirEntry[$index])) {
233 8
            return $this->iconDirEntry[$index];
234
        }
235
236 1
        return false;
237
    }
238
239
    /**
240
     * Changes background color of extraction. You can set
241
     * the 3 color components or set $red = '#xxxxxx' (HTML format)
242
     * and leave all other blanks.
243
     *
244
     * @param int $red Red component
245
     * @param int $green Green component
246
     * @param int $blue Blue component
247
     */
248 6
    public function setBackground($red = 255, $green = 255, $blue = 255)
249
    {
250 6
        if (is_string($red) && preg_match('/^\#[0-9a-f]{6}$/', $red)) {
251 6
            $green = hexdec($red[3] . $red[4]);
252 6
            $blue = hexdec($red[5] . $red[6]);
253 6
            $red = hexdec($red[1] . $red[2]);
254 6
        }
255
256 6
        $this->bgcolor = [$red, $green, $blue];
257 6
    }
258
259
    /**
260
     * Set background color to be saved as transparent.
261
     *
262
     * @param bool $transparent Is Transparent or not
263
     *
264
     * @return bool Is Transparent or not
265
     */
266 3
    public function setBackgroundTransparent($transparent = true)
267
    {
268 3
        return $this->bgcolorTransparent = $transparent;
269
    }
270
271
    /**
272
     * Return an image resource with the icon stored
273
     * on the $index position of the ICO file.
274
     *
275
     * @param int $index Position of the icon inside ICO
276
     *
277
     * @return resource|bool Image resource
278
     **/
279 8
    public function getImage($index)
280
    {
281 8
        if (!isset($this->iconDirEntry[$index])) {
282
            return false;
283
        }
284
285 8
        if (isset($this->iconDirEntry[$index]['png'])) {
286
            return $this->getPngImage($index);
287
        } else {
288 8
            return $this->getBmpImage($index);
289
        }
290
    }
291
292
    private function getPngImage($index)
293
    {
294
        $im = imagecreatefromstring($this->iconDirEntry[$index]['png']);
295
        return $im;
296
    }
297
298 8
    private function getBmpImage($index)
299
    {
300
        // create image filled with desired background color
301 8
        $w=$this->iconDirEntry[$index]['Width'];
302 8
        $h=$this->iconDirEntry[$index]['Height'];
303 8
        $im = imagecreatetruecolor($w, $h);
304
305 8
        if ($this->bgcolorTransparent) {
306 3
            imagealphablending($im, false);
307 3
            $bgcolor=$this->allocateColor($im, $this->bgcolor[0], $this->bgcolor[1], $this->bgcolor[2], 127);
308 3
            imagefilledrectangle($im, 0, 0, $w, $h, $bgcolor);
309 3
            imagesavealpha($im, true);
310 3
        } else {
311 5
            $bgcolor = $this->allocateColor($im, $this->bgcolor[0], $this->bgcolor[1], $this->bgcolor[2]);
312 5
            imagefilledrectangle($im, 0, 0, $w, $h, $bgcolor);
313
        }
314
315
        // now paint pixels based on bit count
316 8
        switch ($this->iconDirEntry[$index]['BitCount']) {
317 8
            case 32:
318 3
                $this->render32bit($this->iconDirEntry[$index], $im);
319 3
                break;
320 5
            case 24:
321 1
                $this->render24bit($this->iconDirEntry[$index], $im);
322 1
                break;
323 4
            case 8:
324 2
                $this->render8bit($this->iconDirEntry[$index], $im);
325 2
                break;
326 2
            case 4:
327 1
                $this->render4bit($this->iconDirEntry[$index], $im);
328 1
                break;
329 1
            case 1:
330 1
                $this->render1bit($this->iconDirEntry[$index], $im);
331 1
                break;
332 8
        }
333
334 8
        return $im;
335
    }
336
337
    /**
338
     * Allocate a color on $im resource. This function prevents
339
     * from allocating same colors on the same pallete. Instead
340
     * if it finds that the color is already allocated, it only
341
     * returns the index to that color.
342
     * It supports alpha channel.
343
     *
344
     * @param resource $im Image resource
345
     * @param int $red Red component
346
     * @param int $green Green component
347
     * @param int $blue Blue component
348
     * @param int $alpha Alpha channel
349
     *
350
     * @return int Color index
351
     */
352 8 View Code Duplication
    private function allocateColor($im, $red, $green, $blue, $alpha = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
353
    {
354 8
        $c = imagecolorexactalpha($im, $red, $green, $blue, $alpha);
355 8
        if ($c >= 0) {
356 8
            return $c;
357
        }
358
359
        return imagecolorallocatealpha($im, $red, $green, $blue, $alpha);
360
    }
361
362 3
    private function render32bit($metadata, $im)
363
    {
364
        /**
365
         * 32 bits: 4 bytes per pixel [ B | G | R | ALPHA ].
366
         **/
367 3
        $offset = 0;
368 3
        $binary = $metadata['data'];
369
370 3
        for ($i = $metadata['Height'] - 1; $i >= 0; --$i) {
371 3 View Code Duplication
            for ($j = 0; $j < $metadata['Width']; ++$j) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
372
                //we translate the BGRA to aRGB ourselves, which is twice as fast
373
                //as calling imagecolorallocatealpha
374 3
                $alpha7 = ((~ord($binary[$offset + 3])) & 0xff) >> 1;
375 3
                if ($alpha7 < 127) {
376 3
                    $col = ($alpha7 << 24) |
377 3
                        (ord($binary[$offset + 2]) << 16) |
378 3
                        (ord($binary[$offset + 1]) << 8) |
379 3
                        (ord($binary[$offset]));
380 3
                    imagesetpixel($im, $j, $i, $col);
381 3
                }
382 3
                $offset += 4;
383 3
            }
384 3
        }
385 3
    }
386
387 1
    private function render24bit($metadata, $im)
388
    {
389 1
        $maskBits = $this->buildMaskBits($metadata);
390
391
        /**
392
         * 24 bits: 3 bytes per pixel [ B | G | R ].
393
         **/
394 1
        $offset = 0;
395 1
        $bitoffset = 0;
396 1
        $binary = $metadata['data'];
397
398 1
        for ($i = $metadata['Height'] - 1; $i >= 0; --$i) {
399 1 View Code Duplication
            for ($j = 0; $j < $metadata['Width']; ++$j) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
400 1
                if ($maskBits[$bitoffset] == 0) {
401
                    //translate BGR to RGB
402 1
                    $col = (ord($binary[$offset + 2]) << 16) |
403 1
                        (ord($binary[$offset + 1]) << 8) |
404 1
                        (ord($binary[$offset]));
405 1
                    imagesetpixel($im, $j, $i, $col);
406 1
                }
407 1
                $offset += 3;
408 1
                ++$bitoffset;
409 1
            }
410 1
        }
411 1
    }
412
413 5
    private function buildMaskBits($metadata)
414
    {
415 5
        $width = $metadata['Width'];
416 5
        if (($width % 32) > 0) {
417
            $width += (32 - ($metadata['Width'] % 32));
418
        }
419 5
        $offset = $metadata['Width'] *
420 5
            $metadata['Height'] *
421 5
            $metadata['BitCount'] / 8;
422 5
        $total_bytes = ($width * $metadata['Height']) / 8;
423 5
        $maskBits = '';
424 5
        $bytes = 0;
425 5
        $bytes_per_line = ($metadata['Width'] / 8);
426 5
        $bytes_to_remove = (($width - $metadata['Width']) / 8);
427 5 View Code Duplication
        for ($i = 0; $i < $total_bytes; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
428 5
            $maskBits .= str_pad(decbin(ord($metadata['data'][$offset + $i])), 8, '0', STR_PAD_LEFT);
429 5
            ++$bytes;
430 5
            if ($bytes == $bytes_per_line) {
431 5
                $i += $bytes_to_remove;
432 5
                $bytes = 0;
433 5
            }
434 5
        }
435 5
        return $maskBits;
436
    }
437
438 2
    private function render8bit($metadata, $im)
439
    {
440 2
        $palette = $this->buildPalette($metadata, $im);
441 2
        $maskBits = $this->buildMaskBits($metadata);
442
443
        /**
444
         * 8 bits: 1 byte per pixel [ COLOR INDEX ].
445
         **/
446 2
        $offset = 0;
447 2 View Code Duplication
        for ($i = $metadata['Height'] - 1; $i >= 0; --$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
448 2
            for ($j = 0; $j < $metadata['Width']; ++$j) {
449 2
                if ($maskBits[$offset] == 0) {
450 2
                    $color = ord($metadata['data'][$offset]);
451 2
                    imagesetpixel($im, $j, $i, $palette[$color]);
452 2
                }
453 2
                ++$offset;
454 2
            }
455 2
        }
456 2
    }
457
458 4
    private function buildPalette($metadata, $im)
459
    {
460 4
        $palette = [];
461 4
        if ($metadata['BitCount'] != 24) {
462 4
            $palette = [];
463 4
            for ($i = 0; $i < $metadata['ColorCount']; ++$i) {
464 4
                $palette[$i] = $this->allocateColor(
465 4
                    $im,
466 4
                    $metadata['colors'][$i]['red'],
467 4
                    $metadata['colors'][$i]['green'],
468 4
                    $metadata['colors'][$i]['blue'],
469 4
                    round($metadata['colors'][$i]['reserved'] / 255 * 127)
470 4
                );
471 4
            }
472 4
        }
473 4
        return $palette;
474
    }
475
476 1
    private function render4bit($metadata, $im)
477
    {
478 1
        $palette = $this->buildPalette($metadata, $im);
479 1
        $maskBits = $this->buildMaskBits($metadata);
480
481
        /**
482
         * 4 bits: half byte/nibble per pixel [ COLOR INDEX ].
483
         **/
484 1
        $offset = 0;
485 1
        $maskoffset = 0;
486 1
        for ($i = $metadata['Height'] - 1; $i >= 0; --$i) {
487 1
            for ($j = 0; $j < $metadata['Width']; $j += 2) {
488 1
                $colorByte = ord($metadata['data'][$offset]);
489 1
                $lowNibble = $colorByte & 0x0f;
490 1
                $highNibble = ($colorByte & 0xf0) >> 4;
491
492 1
                if ($maskBits[$maskoffset++] == 0) {
493 1
                    imagesetpixel($im, $j, $i, $palette[$highNibble]);
494 1
                }
495
496 1 View Code Duplication
                if ($maskBits[$maskoffset++] == 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
497 1
                    imagesetpixel($im, $j + 1, $i, $palette[$lowNibble]);
498 1
                }
499 1
                $offset++;
500 1
            }
501 1
        }
502 1
    }
503
504 1
    private function render1bit($metadata, $im)
505
    {
506 1
        $palette = $this->buildPalette($metadata, $im);
507 1
        $maskBits = $this->buildMaskBits($metadata);
508
509
        /**
510
         * 1 bit: 1 bit per pixel (2 colors, usually black&white) [ COLOR INDEX ].
511
         **/
512 1
        $colorbits = '';
513 1
        $total = strlen($metadata['data']);
514 1 View Code Duplication
        for ($i = 0; $i < $total; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
515 1
            $colorbits .= str_pad(decbin(ord($metadata['data'][$i])), 8, '0', STR_PAD_LEFT);
516 1
        }
517
518 1
        $offset = 0;
519 1 View Code Duplication
        for ($i = $metadata['Height'] - 1; $i >= 0; --$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
520 1
            for ($j = 0; $j < $metadata['Width']; ++$j) {
521 1
                if ($maskBits[$offset] == 0) {
522 1
                    imagesetpixel($im, $j, $i, $palette[$colorbits[$offset]]);
523 1
                }
524 1
                ++$offset;
525 1
            }
526 1
        }
527 1
    }
528
}
529