Issues (1270)

lib/phpqrcode/phpqrcode.php (50 issues)

1
<?php
2
3
/*
4
 * PHP QR Code encoder
5
 *
6
 * This file contains MERGED version of PHP QR Code library.
7
 * It was auto-generated from full version for your convenience.
8
 *
9
 * This merged version was configured to not requre any external files,
10
 * with disabled cache, error loging and weker but faster mask matching.
11
 * If you need tune it up please use non-merged version.
12
 *
13
 * For full version, documentation, examples of use please visit:
14
 *
15
 *    http://phpqrcode.sourceforge.net/
16
 *    https://sourceforge.net/projects/phpqrcode/
17
 *
18
 * PHP QR Code is distributed under LGPL 3
19
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
20
 *
21
 * This library is free software; you can redistribute it and/or
22
 * modify it under the terms of the GNU Lesser General Public
23
 * License as published by the Free Software Foundation; either
24
 * version 3 of the License, or any later version.
25
 *
26
 * This library is distributed in the hope that it will be useful,
27
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29
 * Lesser General Public License for more details.
30
 *
31
 * You should have received a copy of the GNU Lesser General Public
32
 * License along with this library; if not, write to the Free Software
33
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34
 */
35
 
36
 
37
38
/*
39
 * Version: 1.1.4
40
 * Build: 2010100721
41
 */
42
43
44
45
//---- qrconst.php -----------------------------
46
47
48
49
50
51
/*
52
 * PHP QR Code encoder
53
 *
54
 * Common constants
55
 *
56
 * Based on libqrencode C library distributed under LGPL 2.1
57
 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <[email protected]>
58
 *
59
 * PHP QR Code is distributed under LGPL 3
60
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
61
 *
62
 * This library is free software; you can redistribute it and/or
63
 * modify it under the terms of the GNU Lesser General Public
64
 * License as published by the Free Software Foundation; either
65
 * version 3 of the License, or any later version.
66
 *
67
 * This library is distributed in the hope that it will be useful,
68
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
69
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
70
 * Lesser General Public License for more details.
71
 *
72
 * You should have received a copy of the GNU Lesser General Public
73
 * License along with this library; if not, write to the Free Software
74
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
75
 */
76
 
77
    // Encoding modes
78
	 
79
    define('QR_MODE_NUL', -1);
80
    define('QR_MODE_NUM', 0);
81
    define('QR_MODE_AN', 1);
82
    define('QR_MODE_8', 2);
83
    define('QR_MODE_KANJI', 3);
84
    define('QR_MODE_STRUCTURE', 4);
85
86
    // Levels of error correction.
87
88
    define('QR_ECLEVEL_L', 0);
89
    define('QR_ECLEVEL_M', 1);
90
    define('QR_ECLEVEL_Q', 2);
91
    define('QR_ECLEVEL_H', 3);
92
	
93
    // Supported output formats
94
	
95
    define('QR_FORMAT_TEXT', 0);
96
    define('QR_FORMAT_PNG', 1);
97
	
98
    class qrstr {
99
        public static function set(&$srctab, $x, $y, $repl, $replLen = false) {
100
            $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false) ?substr($repl, 0, $replLen) : $repl, $x, ($replLen !== false) ? $replLen : strlen($repl));
101
        }
102
    }	
103
104
105
106
//---- merged_config.php -----------------------------
107
108
109
110
111
/*
112
 * PHP QR Code encoder
113
 *
114
 * Config file, tuned-up for merged verion
115
 */
116
     
117
    define('QR_CACHEABLE', false); // use cache - more disk reads but less CPU power, masks and format templates are stored there
118
    define('QR_CACHE_DIR', false); // used when QR_CACHEABLE === true
119
    define('QR_LOG_DIR', false); // default error logs dir   
120
    
121
    define('QR_FIND_BEST_MASK', true); // if true, estimates best mask (spec. default, but extremally slow; set to false to significant performance boost but (propably) worst quality code
122
    define('QR_FIND_FROM_RANDOM', 2); // if false, checks all masks available, otherwise value tells count of masks need to be checked, mask id are got randomly
123
    define('QR_DEFAULT_MASK', 2); // when QR_FIND_BEST_MASK === false
124
                                                  
125
    define('QR_PNG_MAXIMUM_SIZE', 1024); // maximum allowed png image width (in pixels), tune to make sure GD and PHP can handle such big images
126
                                                  
127
128
129
130
//---- qrtools.php -----------------------------
131
132
133
134
135
/*
136
 * PHP QR Code encoder
137
 *
138
 * Toolset, handy and debug utilites.
139
 *
140
 * PHP QR Code is distributed under LGPL 3
141
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
142
 *
143
 * This library is free software; you can redistribute it and/or
144
 * modify it under the terms of the GNU Lesser General Public
145
 * License as published by the Free Software Foundation; either
146
 * version 3 of the License, or any later version.
147
 *
148
 * This library is distributed in the hope that it will be useful,
149
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
150
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
151
 * Lesser General Public License for more details.
152
 *
153
 * You should have received a copy of the GNU Lesser General Public
154
 * License along with this library; if not, write to the Free Software
155
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
156
 */
157
158
    class QRtools {
159
    
160
        //----------------------------------------------------------------------
161
        public static function binarize($frame)
162
        {
163
            $len = count($frame);
164
            foreach ($frame as &$frameLine) {
165
                
166
                for ($i = 0; $i < $len; $i++) {
167
                    $frameLine[$i] = (ord($frameLine[$i]) & 1) ? '1' : '0';
168
                }
169
            }
170
            
171
            return $frame;
172
        }
173
        
174
        //----------------------------------------------------------------------
175
        public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037')
0 ignored issues
show
The parameter $tcPdfVersion is not used and could be removed. ( Ignorable by Annotation )

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

175
        public static function tcpdfBarcodeArray($code, $mode = 'QR,L', /** @scrutinizer ignore-unused */ $tcPdfVersion = '4.5.037')

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
176
        {
177
            $barcode_array = array();
178
            
179
            if (!is_array($mode)) {
180
                            $mode = explode(',', $mode);
181
            }
182
                
183
            $eccLevel = 'L';
184
                
185
            if (count($mode) > 1) {
186
                $eccLevel = $mode[1];
187
            }
188
                
189
            $qrTab = QRcode::text($code, false, $eccLevel);
190
            $size = count($qrTab);
191
                
192
            $barcode_array['num_rows'] = $size;
193
            $barcode_array['num_cols'] = $size;
194
            $barcode_array['bcode'] = array();
195
                
196
            foreach ($qrTab as $line) {
197
                $arrAdd = array();
198
                foreach (str_split($line) as $char) {
199
                                    $arrAdd[] = ($char == '1') ? 1 : 0;
200
                }
201
                $barcode_array['bcode'][] = $arrAdd;
202
            }
203
                    
204
            return $barcode_array;
205
        }
206
        
207
        //----------------------------------------------------------------------
208
        public static function clearCache()
209
        {
210
            self::$frames = array();
0 ignored issues
show
Bug Best Practice introduced by
The property frames does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
211
        }
212
        
213
        //----------------------------------------------------------------------
214
        public static function buildCache()
215
        {
216
            QRtools::markTime('before_build_cache');
217
			
218
            $mask = new QRmask();
219
            for ($a = 1; $a <= QRSPEC_VERSION_MAX; $a++) {
220
                $frame = QRspec::newFrame($a);
221
                if (QR_IMAGE) {
222
                    $fileName = QR_CACHE_DIR.'frame_'.$a.'.png';
223
                    QRimage::png(self::binarize($frame), $fileName, 1, 0);
224
                }
225
				
226
                $width = count($frame);
227
                $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
228
                for ($maskNo = 0; $maskNo < 8; $maskNo++) {
229
                                    $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true);
230
                }
231
            }
232
			
233
            QRtools::markTime('after_build_cache');
234
        }
235
236
        //----------------------------------------------------------------------
237
        public static function log($outfile, $err)
238
        {
239
            if (QR_LOG_DIR !== false) {
240
                if ($err != '') {
241
                    if ($outfile !== false) {
242
                        file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
243
                    } else {
244
                        file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);
245
                    }
246
                }    
247
            }
248
        }
249
        
250
        //----------------------------------------------------------------------
251
        public static function dumpMask($frame) 
252
        {
253
            $width = count($frame);
254
            for ($y = 0; $y < $width; $y++) {
255
                for ($x = 0; $x < $width; $x++) {
256
                    echo ord($frame[$y][$x]).',';
257
                }
258
            }
259
        }
260
        
261
        //----------------------------------------------------------------------
262
        public static function markTime($markerId)
263
        {
264
            list($usec, $sec) = explode(" ", microtime());
265
            $time = ((float) $usec + (float) $sec);
266
            
267
            if (!isset($GLOBALS['qr_time_bench'])) {
268
                            $GLOBALS['qr_time_bench'] = array();
269
            }
270
            
271
            $GLOBALS['qr_time_bench'][$markerId] = $time;
272
        }
273
        
274
        //----------------------------------------------------------------------
275
        public static function timeBenchmark()
276
        {
277
            self::markTime('finish');
278
        
279
            $lastTime = 0;
280
            $startTime = 0;
281
            $p = 0;
282
283
            echo '<table cellpadding="3" cellspacing="1">
284
                    <thead><tr style="border-bottom:1px solid silver"><td colspan="2" style="text-align:center">BENCHMARK</td></tr></thead>
285
                    <tbody>';
286
287
            foreach ($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) {
288
                if ($p > 0) {
289
                    echo '<tr><th style="text-align:right">till '.$markerId.': </th><td>'.number_format($thisTime - $lastTime, 6).'s</td></tr>';
290
                } else {
291
                    $startTime = $thisTime;
292
                }
293
                
294
                $p++;
295
                $lastTime = $thisTime;
296
            }
297
            
298
            echo '</tbody><tfoot>
299
                <tr style="border-top:2px solid black"><th style="text-align:right">TOTAL: </th><td>'.number_format($lastTime - $startTime, 6).'s</td></tr>
300
            </tfoot>
301
            </table>';
302
        }
303
        
304
    }
305
    
306
    //##########################################################################
307
    
308
    QRtools::markTime('start');
309
    
310
311
312
313
//---- qrspec.php -----------------------------
314
315
316
317
318
/*
319
 * PHP QR Code encoder
320
 *
321
 * QR Code specifications
322
 *
323
 * Based on libqrencode C library distributed under LGPL 2.1
324
 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <[email protected]>
325
 *
326
 * PHP QR Code is distributed under LGPL 3
327
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
328
 *
329
 * The following data / specifications are taken from
330
 * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
331
 *  or
332
 * "Automatic identification and data capture techniques -- 
333
 *  QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
334
 *
335
 * This library is free software; you can redistribute it and/or
336
 * modify it under the terms of the GNU Lesser General Public
337
 * License as published by the Free Software Foundation; either
338
 * version 3 of the License, or any later version.
339
 *
340
 * This library is distributed in the hope that it will be useful,
341
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
342
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
343
 * Lesser General Public License for more details.
344
 *
345
 * You should have received a copy of the GNU Lesser General Public
346
 * License along with this library; if not, write to the Free Software
347
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
348
 */
349
 
350
    define('QRSPEC_VERSION_MAX', 40);
351
    define('QRSPEC_WIDTH_MAX', 177);
352
353
    define('QRCAP_WIDTH', 0);
354
    define('QRCAP_WORDS', 1);
355
    define('QRCAP_REMINDER', 2);
356
    define('QRCAP_EC', 3);
357
358
    class QRspec {
359
    
360
        public static $capacity = array(
361
            array(0, 0, 0, array(0, 0, 0, 0)),
362
            array(21, 26, 0, array(7, 10, 13, 17)), // 1
363
            array(25, 44, 7, array(10, 16, 22, 28)),
364
            array(29, 70, 7, array(15, 26, 36, 44)),
365
            array(33, 100, 7, array(20, 36, 52, 64)),
366
            array(37, 134, 7, array(26, 48, 72, 88)), // 5
367
            array(41, 172, 7, array(36, 64, 96, 112)),
368
            array(45, 196, 0, array(40, 72, 108, 130)),
369
            array(49, 242, 0, array(48, 88, 132, 156)),
370
            array(53, 292, 0, array(60, 110, 160, 192)),
371
            array(57, 346, 0, array(72, 130, 192, 224)), //10
372
            array(61, 404, 0, array(80, 150, 224, 264)),
373
            array(65, 466, 0, array(96, 176, 260, 308)),
374
            array(69, 532, 0, array(104, 198, 288, 352)),
375
            array(73, 581, 3, array(120, 216, 320, 384)),
376
            array(77, 655, 3, array(132, 240, 360, 432)), //15
377
            array(81, 733, 3, array(144, 280, 408, 480)),
378
            array(85, 815, 3, array(168, 308, 448, 532)),
379
            array(89, 901, 3, array(180, 338, 504, 588)),
380
            array(93, 991, 3, array(196, 364, 546, 650)),
381
            array(97, 1085, 3, array(224, 416, 600, 700)), //20
382
            array(101, 1156, 4, array(224, 442, 644, 750)),
383
            array(105, 1258, 4, array(252, 476, 690, 816)),
384
            array(109, 1364, 4, array(270, 504, 750, 900)),
385
            array(113, 1474, 4, array(300, 560, 810, 960)),
386
            array(117, 1588, 4, array(312, 588, 870, 1050)), //25
387
            array(121, 1706, 4, array(336, 644, 952, 1110)),
388
            array(125, 1828, 4, array(360, 700, 1020, 1200)),
389
            array(129, 1921, 3, array(390, 728, 1050, 1260)),
390
            array(133, 2051, 3, array(420, 784, 1140, 1350)),
391
            array(137, 2185, 3, array(450, 812, 1200, 1440)), //30
392
            array(141, 2323, 3, array(480, 868, 1290, 1530)),
393
            array(145, 2465, 3, array(510, 924, 1350, 1620)),
394
            array(149, 2611, 3, array(540, 980, 1440, 1710)),
395
            array(153, 2761, 3, array(570, 1036, 1530, 1800)),
396
            array(157, 2876, 0, array(570, 1064, 1590, 1890)), //35
397
            array(161, 3034, 0, array(600, 1120, 1680, 1980)),
398
            array(165, 3196, 0, array(630, 1204, 1770, 2100)),
399
            array(169, 3362, 0, array(660, 1260, 1860, 2220)),
400
            array(173, 3532, 0, array(720, 1316, 1950, 2310)),
401
            array(177, 3706, 0, array(750, 1372, 2040, 2430)) //40
402
        );
403
        
404
        //----------------------------------------------------------------------
405
        public static function getDataLength($version, $level)
406
        {
407
            return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];
408
        }
409
        
410
        //----------------------------------------------------------------------
411
        public static function getECCLength($version, $level)
412
        {
413
            return self::$capacity[$version][QRCAP_EC][$level];
414
        }
415
        
416
        //----------------------------------------------------------------------
417
        public static function getWidth($version)
418
        {
419
            return self::$capacity[$version][QRCAP_WIDTH];
420
        }
421
        
422
        //----------------------------------------------------------------------
423
        public static function getRemainder($version)
424
        {
425
            return self::$capacity[$version][QRCAP_REMINDER];
426
        }
427
        
428
        //----------------------------------------------------------------------
429
        public static function getMinimumVersion($size, $level)
430
        {
431
432
            for ($i = 1; $i <= QRSPEC_VERSION_MAX; $i++) {
433
                $words = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];
434
                if ($words >= $size) {
435
                                    return $i;
436
                }
437
            }
438
439
            return -1;
440
        }
441
    
442
        //######################################################################
443
        
444
        public static $lengthTableBits = array(
445
            array(10, 12, 14),
446
            array(9, 11, 13),
447
            array(8, 16, 16),
448
            array(8, 10, 12)
449
        );
450
        
451
        //----------------------------------------------------------------------
452
        public static function lengthIndicator($mode, $version)
453
        {
454
            if ($mode == QR_MODE_STRUCTURE) {
455
                            return 0;
456
            }
457
                
458
            if ($version <= 9) {
459
                $l = 0;
460
            } else if ($version <= 26) {
461
                $l = 1;
462
            } else {
463
                $l = 2;
464
            }
465
466
            return self::$lengthTableBits[$mode][$l];
467
        }
468
        
469
        //----------------------------------------------------------------------
470
        public static function maximumWords($mode, $version)
471
        {
472
            if ($mode == QR_MODE_STRUCTURE) {
473
                            return 3;
474
            }
475
                
476
            if ($version <= 9) {
477
                $l = 0;
478
            } else if ($version <= 26) {
479
                $l = 1;
480
            } else {
481
                $l = 2;
482
            }
483
484
            $bits = self::$lengthTableBits[$mode][$l];
485
            $words = (1 << $bits) - 1;
486
            
487
            if ($mode == QR_MODE_KANJI) {
488
                $words *= 2; // the number of bytes is required
489
            }
490
491
            return $words;
492
        }
493
494
        // Error correction code -----------------------------------------------
495
        // Table of the error correction code (Reed-Solomon block)
496
        // See Table 12-16 (pp.30-36), JIS X0510:2004.
497
498
        public static $eccTable = array(
499
            array(array(0, 0), array(0, 0), array(0, 0), array(0, 0)),
500
            array(array(1, 0), array(1, 0), array(1, 0), array(1, 0)), // 1
501
            array(array(1, 0), array(1, 0), array(1, 0), array(1, 0)),
502
            array(array(1, 0), array(1, 0), array(2, 0), array(2, 0)),
503
            array(array(1, 0), array(2, 0), array(2, 0), array(4, 0)),
504
            array(array(1, 0), array(2, 0), array(2, 2), array(2, 2)), // 5
505
            array(array(2, 0), array(4, 0), array(4, 0), array(4, 0)),
506
            array(array(2, 0), array(4, 0), array(2, 4), array(4, 1)),
507
            array(array(2, 0), array(2, 2), array(4, 2), array(4, 2)),
508
            array(array(2, 0), array(3, 2), array(4, 4), array(4, 4)),
509
            array(array(2, 2), array(4, 1), array(6, 2), array(6, 2)), //10
510
            array(array(4, 0), array(1, 4), array(4, 4), array(3, 8)),
511
            array(array(2, 2), array(6, 2), array(4, 6), array(7, 4)),
512
            array(array(4, 0), array(8, 1), array(8, 4), array(12, 4)),
513
            array(array(3, 1), array(4, 5), array(11, 5), array(11, 5)),
514
            array(array(5, 1), array(5, 5), array(5, 7), array(11, 7)), //15
515
            array(array(5, 1), array(7, 3), array(15, 2), array(3, 13)),
516
            array(array(1, 5), array(10, 1), array(1, 15), array(2, 17)),
517
            array(array(5, 1), array(9, 4), array(17, 1), array(2, 19)),
518
            array(array(3, 4), array(3, 11), array(17, 4), array(9, 16)),
519
            array(array(3, 5), array(3, 13), array(15, 5), array(15, 10)), //20
520
            array(array(4, 4), array(17, 0), array(17, 6), array(19, 6)),
521
            array(array(2, 7), array(17, 0), array(7, 16), array(34, 0)),
522
            array(array(4, 5), array(4, 14), array(11, 14), array(16, 14)),
523
            array(array(6, 4), array(6, 14), array(11, 16), array(30, 2)),
524
            array(array(8, 4), array(8, 13), array(7, 22), array(22, 13)), //25
525
            array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)),
526
            array(array(8, 4), array(22, 3), array(8, 26), array(12, 28)),
527
            array(array(3, 10), array(3, 23), array(4, 31), array(11, 31)),
528
            array(array(7, 7), array(21, 7), array(1, 37), array(19, 26)),
529
            array(array(5, 10), array(19, 10), array(15, 25), array(23, 25)), //30
530
            array(array(13, 3), array(2, 29), array(42, 1), array(23, 28)),
531
            array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)),
532
            array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)),
533
            array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)),
534
            array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35
535
            array(array(6, 14), array(6, 34), array(46, 10), array(2, 64)),
536
            array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)),
537
            array(array(4, 18), array(13, 32), array(48, 14), array(42, 32)),
538
            array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)),
539
            array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)), //40
540
        );                                                                       
541
542
        //----------------------------------------------------------------------
543
        // CACHEABLE!!!
544
        
545
        public static function getEccSpec($version, $level, array &$spec)
546
        {
547
            if (count($spec) < 5) {
548
                $spec = array(0, 0, 0, 0, 0);
549
            }
550
551
            $b1   = self::$eccTable[$version][$level][0];
552
            $b2   = self::$eccTable[$version][$level][1];
553
            $data = self::getDataLength($version, $level);
554
            $ecc  = self::getECCLength($version, $level);
555
556
            if ($b2 == 0) {
557
                $spec[0] = $b1;
558
                $spec[1] = (int) ($data / $b1);
559
                $spec[2] = (int) ($ecc / $b1);
560
                $spec[3] = 0; 
561
                $spec[4] = 0;
562
            } else {
563
                $spec[0] = $b1;
564
                $spec[1] = (int) ($data / ($b1 + $b2));
565
                $spec[2] = (int) ($ecc / ($b1 + $b2));
566
                $spec[3] = $b2;
567
                $spec[4] = $spec[1] + 1;
568
            }
569
        }
570
571
        // Alignment pattern ---------------------------------------------------
572
573
        // Positions of alignment patterns.
574
        // This array includes only the second and the third position of the 
575
        // alignment patterns. Rest of them can be calculated from the distance 
576
        // between them.
577
         
578
        // See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
579
         
580
        public static $alignmentPattern = array(      
581
            array(0, 0),
582
            array(0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5
583
            array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10
584
            array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15
585
            array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20
586
            array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25
587
            array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30
588
            array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35
589
            array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40
590
        );                                                                                  
591
592
        
593
        /** --------------------------------------------------------------------
594
         * Put an alignment marker.
595
         * @param frame
596
         * @param width
597
         * @param ox,oy center coordinate of the pattern
0 ignored issues
show
The type center was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
598
         */
599
        public static function putAlignmentMarker(array &$frame, $ox, $oy)
600
        {
601
            $finder = array(
602
                "\xa1\xa1\xa1\xa1\xa1",
603
                "\xa1\xa0\xa0\xa0\xa1",
604
                "\xa1\xa0\xa1\xa0\xa1",
605
                "\xa1\xa0\xa0\xa0\xa1",
606
                "\xa1\xa1\xa1\xa1\xa1"
607
            );                        
608
            
609
            $yStart = $oy - 2;         
610
            $xStart = $ox - 2;
611
            
612
            for ($y = 0; $y < 5; $y++) {
613
                QRstr::set($frame, $xStart, $yStart + $y, $finder[$y]);
614
            }
615
        }
616
617
        //----------------------------------------------------------------------
618
        public static function putAlignmentPattern($version, &$frame, $width)
619
        {
620
            if ($version < 2) {
621
                            return;
622
            }
623
624
            $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];
625
            if ($d < 0) {
626
                $w = 2;
627
            } else {
628
                $w = (int) (($width - self::$alignmentPattern[$version][0]) / $d + 2);
629
            }
630
631
            if ($w * $w - 3 == 1) {
632
                $x = self::$alignmentPattern[$version][0];
633
                $y = self::$alignmentPattern[$version][0];
634
                self::putAlignmentMarker($frame, $x, $y);
635
                return;
636
            }
637
638
            $cx = self::$alignmentPattern[$version][0];
639
            for ($x = 1; $x < $w - 1; $x++) {
640
                self::putAlignmentMarker($frame, 6, $cx);
641
                self::putAlignmentMarker($frame, $cx, 6);
642
                $cx += $d;
643
            }
644
645
            $cy = self::$alignmentPattern[$version][0];
646
            for ($y = 0; $y < $w - 1; $y++) {
647
                $cx = self::$alignmentPattern[$version][0];
648
                for ($x = 0; $x < $w - 1; $x++) {
649
                    self::putAlignmentMarker($frame, $cx, $cy);
650
                    $cx += $d;
651
                }
652
                $cy += $d;
653
            }
654
        }
655
656
        // Version information pattern -----------------------------------------
657
658
        // Version information pattern (BCH coded).
659
        // See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
660
        
661
        // size: [QRSPEC_VERSION_MAX - 6]
662
		
663
        public static $versionPattern = array(
664
            0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
665
            0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
666
            0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
667
            0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
668
            0x27541, 0x28c69
669
        );
670
671
        //----------------------------------------------------------------------
672
        public static function getVersionPattern($version)
673
        {
674
            if ($version < 7 || $version > QRSPEC_VERSION_MAX) {
675
                            return 0;
676
            }
677
678
            return self::$versionPattern[$version - 7];
679
        }
680
681
        // Format information --------------------------------------------------
682
        // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib)
683
        
684
        public static $formatInfo = array(
685
            array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),
686
            array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),
687
            array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),
688
            array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)
689
        );
690
691
        public static function getFormatInfo($mask, $level)
692
        {
693
            if ($mask < 0 || $mask > 7) {
694
                            return 0;
695
            }
696
                
697
            if ($level < 0 || $level > 3) {
698
                            return 0;
699
            }
700
701
            return self::$formatInfo[$level][$mask];
702
        }
703
704
        // Frame ---------------------------------------------------------------
705
        // Cache of initial frames.
706
         
707
        public static $frames = array();
708
709
        /** --------------------------------------------------------------------
710
         * Put a finder pattern.
711
         * @param frame
712
         * @param width
713
         * @param ox,oy upper-left coordinate of the pattern
0 ignored issues
show
Documentation Bug introduced by
The doc comment upper-left at position 0 could not be parsed: Unknown type name 'upper-left' at position 0 in upper-left.
Loading history...
714
         */
715
        public static function putFinderPattern(&$frame, $ox, $oy)
716
        {
717
            $finder = array(
718
                "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
719
                "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
720
                "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
721
                "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
722
                "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
723
                "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
724
                "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
725
            );                            
726
            
727
            for ($y = 0; $y < 7; $y++) {
728
                QRstr::set($frame, $ox, $oy + $y, $finder[$y]);
729
            }
730
        }
731
732
        //----------------------------------------------------------------------
733
        public static function createFrame($version)
734
        {
735
            $width = self::$capacity[$version][QRCAP_WIDTH];
736
            $frameLine = str_repeat("\0", $width);
737
            $frame = array_fill(0, $width, $frameLine);
738
739
            // Finder pattern
740
            self::putFinderPattern($frame, 0, 0);
741
            self::putFinderPattern($frame, $width - 7, 0);
742
            self::putFinderPattern($frame, 0, $width - 7);
743
            
744
            // Separator
745
            $yOffset = $width - 7;
746
            
747
            for ($y = 0; $y < 7; $y++) {
748
                $frame[$y][7] = "\xc0";
749
                $frame[$y][$width - 8] = "\xc0";
750
                $frame[$yOffset][7] = "\xc0";
751
                $yOffset++;
752
            }
753
            
754
            $setPattern = str_repeat("\xc0", 8);
755
            
756
            QRstr::set($frame, 0, 7, $setPattern);
757
            QRstr::set($frame, $width - 8, 7, $setPattern);
758
            QRstr::set($frame, 0, $width - 8, $setPattern);
759
        
760
            // Format info
761
            $setPattern = str_repeat("\x84", 9);
762
            QRstr::set($frame, 0, 8, $setPattern);
763
            QRstr::set($frame, $width - 8, 8, $setPattern, 8);
764
            
765
            $yOffset = $width - 8;
766
767
            for ($y = 0; $y < 8; $y++, $yOffset++) {
768
                $frame[$y][8] = "\x84";
769
                $frame[$yOffset][8] = "\x84";
770
            }
771
772
            // Timing pattern  
773
            
774
            for ($i = 1; $i < $width - 15; $i++) {
775
                $frame[6][7 + $i] = chr(0x90 | ($i & 1));
776
                $frame[7 + $i][6] = chr(0x90 | ($i & 1));
777
            }
778
            
779
            // Alignment pattern  
780
            self::putAlignmentPattern($version, $frame, $width);
781
            
782
            // Version information 
783
            if ($version >= 7) {
784
                $vinf = self::getVersionPattern($version);
785
786
                $v = $vinf;
787
                
788
                for ($x = 0; $x < 6; $x++) {
789
                    for ($y = 0; $y < 3; $y++) {
790
                        $frame[($width - 11) + $y][$x] = chr(0x88 | ($v & 1));
791
                        $v = $v >> 1;
792
                    }
793
                }
794
795
                $v = $vinf;
796
                for ($y = 0; $y < 6; $y++) {
797
                    for ($x = 0; $x < 3; $x++) {
798
                        $frame[$y][$x + ($width - 11)] = chr(0x88 | ($v & 1));
799
                        $v = $v >> 1;
800
                    }
801
                }
802
            }
803
    
804
            // and a little bit...  
805
            $frame[$width - 8][8] = "\x81";
806
            
807
            return $frame;
808
        }
809
810
        //----------------------------------------------------------------------
811
        public static function debug($frame, $binary_mode = false)
812
        {
813
            if ($binary_mode) {
814
            
815
                    foreach ($frame as &$frameLine) {
816
                        $frameLine = join('<span class="m">&nbsp;&nbsp;</span>', explode('0', $frameLine));
817
                        $frameLine = join('&#9608;&#9608;', explode('1', $frameLine));
818
                    }
819
                    
820
                    ?>
821
                <style>
822
                    .m { background-color: white; }
823
                </style>
824
                <?php
825
                    echo '<pre><tt><br/ ><br/ ><br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
826
                    echo join("<br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", $frame);
827
                    echo '</tt></pre><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >';
828
            
829
            } else {
830
            
831
                foreach ($frame as &$frameLine) {
832
                    $frameLine = join('<span class="m">&nbsp;</span>', explode("\xc0", $frameLine));
833
                    $frameLine = join('<span class="m">&#9618;</span>', explode("\xc1", $frameLine));
834
                    $frameLine = join('<span class="p">&nbsp;</span>', explode("\xa0", $frameLine));
835
                    $frameLine = join('<span class="p">&#9618;</span>', explode("\xa1", $frameLine));
836
                    $frameLine = join('<span class="s">&#9671;</span>', explode("\x84", $frameLine)); //format 0
837
                    $frameLine = join('<span class="s">&#9670;</span>', explode("\x85", $frameLine)); //format 1
838
                    $frameLine = join('<span class="x">&#9762;</span>', explode("\x81", $frameLine)); //special bit
839
                    $frameLine = join('<span class="c">&nbsp;</span>', explode("\x90", $frameLine)); //clock 0
840
                    $frameLine = join('<span class="c">&#9719;</span>', explode("\x91", $frameLine)); //clock 1
841
                    $frameLine = join('<span class="f">&nbsp;</span>', explode("\x88", $frameLine)); //version
842
                    $frameLine = join('<span class="f">&#9618;</span>', explode("\x89", $frameLine)); //version
843
                    $frameLine = join('&#9830;', explode("\x01", $frameLine));
844
                    $frameLine = join('&#8901;', explode("\0", $frameLine));
845
                }
846
                
847
                ?>
848
                <style>
849
                    .p { background-color: yellow; }
850
                    .m { background-color: #00FF00; }
851
                    .s { background-color: #FF0000; }
852
                    .c { background-color: aqua; }
853
                    .x { background-color: pink; }
854
                    .f { background-color: gold; }
855
                </style>
856
                <?php
857
                echo "<pre><tt>";
858
                echo join("<br/ >", $frame);
859
                echo "</tt></pre>";
860
            
861
            }
862
        }
863
864
        //----------------------------------------------------------------------
865
        public static function serial($frame)
866
        {
867
            return gzcompress(join("\n", $frame), 9);
868
        }
869
        
870
        //----------------------------------------------------------------------
871
        public static function unserial($code)
872
        {
873
            return explode("\n", gzuncompress($code));
874
        }
875
        
876
        //----------------------------------------------------------------------
877
        public static function newFrame($version)
878
        {
879
            if ($version < 1 || $version > QRSPEC_VERSION_MAX) {
880
                            return null;
881
            }
882
883
            if (!isset(self::$frames[$version])) {
884
                
885
                $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat';
886
                
887
                if (QR_CACHEABLE) {
888
                    if (file_exists($fileName)) {
889
                        self::$frames[$version] = self::unserial(file_get_contents($fileName));
890
                    } else {
891
                        self::$frames[$version] = self::createFrame($version);
892
                        file_put_contents($fileName, self::serial(self::$frames[$version]));
893
                    }
894
                } else {
895
                    self::$frames[$version] = self::createFrame($version);
896
                }
897
            }
898
            
899
            if (is_null(self::$frames[$version])) {
900
                            return null;
901
            }
902
903
            return self::$frames[$version];
904
        }
905
906
        //----------------------------------------------------------------------
907
        public static function rsBlockNum($spec) { return $spec[0] + $spec[3]; }
908
        public static function rsBlockNum1($spec) { return $spec[0]; }
909
        public static function rsDataCodes1($spec) { return $spec[1]; }
910
        public static function rsEccCodes1($spec) { return $spec[2]; }
911
        public static function rsBlockNum2($spec) { return $spec[3]; }
912
        public static function rsDataCodes2($spec) { return $spec[4]; }
913
        public static function rsEccCodes2($spec) { return $spec[2]; }
914
        public static function rsDataLength($spec) { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]); }
915
        public static function rsEccLength($spec) { return ($spec[0] + $spec[3]) * $spec[2]; }
916
        
917
    }
918
919
920
921
//---- qrimage.php -----------------------------
922
923
924
925
926
/*
927
 * PHP QR Code encoder
928
 *
929
 * Image output of code using GD2
930
 *
931
 * PHP QR Code is distributed under LGPL 3
932
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
933
 *
934
 * This library is free software; you can redistribute it and/or
935
 * modify it under the terms of the GNU Lesser General Public
936
 * License as published by the Free Software Foundation; either
937
 * version 3 of the License, or any later version.
938
 *
939
 * This library is distributed in the hope that it will be useful,
940
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
941
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
942
 * Lesser General Public License for more details.
943
 *
944
 * You should have received a copy of the GNU Lesser General Public
945
 * License along with this library; if not, write to the Free Software
946
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
947
 */
948
 
949
    define('QR_IMAGE', true);
950
951
    class QRimage {
952
    
953
        //----------------------------------------------------------------------
954
        public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4, $saveandprint = false) 
955
        {
956
            $image = self::image($frame, $pixelPerPoint, $outerFrame);
957
            
958
            if ($filename === false) {
959
                Header("Content-type: image/png");
960
                ImagePng($image);
0 ignored issues
show
It seems like $image can also be of type false; however, parameter $image of imagepng() does only seem to accept resource, 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

960
                ImagePng(/** @scrutinizer ignore-type */ $image);
Loading history...
961
            } else {
962
                if ($saveandprint === true) {
963
                    ImagePng($image, $filename);
964
                    header("Content-type: image/png");
965
                    ImagePng($image);
966
                } else {
967
                    ImagePng($image, $filename);
968
                }
969
            }
970
            
971
            ImageDestroy($image);
0 ignored issues
show
It seems like $image can also be of type false; however, parameter $image of imagedestroy() does only seem to accept resource, 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

971
            ImageDestroy(/** @scrutinizer ignore-type */ $image);
Loading history...
972
        }
973
    
974
        //----------------------------------------------------------------------
975
        public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85) 
976
        {
977
            $image = self::image($frame, $pixelPerPoint, $outerFrame);
978
            
979
            if ($filename === false) {
980
                Header("Content-type: image/jpeg");
981
                ImageJpeg($image, null, $q);
0 ignored issues
show
It seems like $image can also be of type false; however, parameter $image of imagejpeg() does only seem to accept resource, 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

981
                ImageJpeg(/** @scrutinizer ignore-type */ $image, null, $q);
Loading history...
982
            } else {
983
                ImageJpeg($image, $filename, $q);            
984
            }
985
            
986
            ImageDestroy($image);
0 ignored issues
show
It seems like $image can also be of type false; however, parameter $image of imagedestroy() does only seem to accept resource, 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

986
            ImageDestroy(/** @scrutinizer ignore-type */ $image);
Loading history...
987
        }
988
    
989
        //----------------------------------------------------------------------
990
        private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4) 
991
        {
992
            $h = count($frame);
993
            $w = strlen($frame[0]);
994
            
995
            $imgW = $w + 2 * $outerFrame;
996
            $imgH = $h + 2 * $outerFrame;
997
            
998
            $base_image = ImageCreate($imgW, $imgH);
999
            
1000
            $col[0] = ImageColorAllocate($base_image, 255, 255, 255);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$col was never initialized. Although not strictly required by PHP, it is generally a good practice to add $col = array(); before regardless.
Loading history...
It seems like $base_image can also be of type false; however, parameter $image of imagecolorallocate() does only seem to accept resource, 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

1000
            $col[0] = ImageColorAllocate(/** @scrutinizer ignore-type */ $base_image, 255, 255, 255);
Loading history...
1001
            $col[1] = ImageColorAllocate($base_image, 0, 0, 0);
1002
1003
            imagefill($base_image, 0, 0, $col[0]);
0 ignored issues
show
It seems like $base_image can also be of type false; however, parameter $image of imagefill() does only seem to accept resource, 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

1003
            imagefill(/** @scrutinizer ignore-type */ $base_image, 0, 0, $col[0]);
Loading history...
1004
1005
            for ($y = 0; $y < $h; $y++) {
1006
                for ($x = 0; $x < $w; $x++) {
1007
                    if ($frame[$y][$x] == '1') {
1008
                        ImageSetPixel($base_image, $x + $outerFrame, $y + $outerFrame, $col[1]); 
0 ignored issues
show
It seems like $base_image can also be of type false; however, parameter $image of imagesetpixel() does only seem to accept resource, 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

1008
                        ImageSetPixel(/** @scrutinizer ignore-type */ $base_image, $x + $outerFrame, $y + $outerFrame, $col[1]); 
Loading history...
1009
                    }
1010
                }
1011
            }
1012
            
1013
            $target_image = ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
1014
            ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
0 ignored issues
show
It seems like $base_image can also be of type false; however, parameter $src_image of imagecopyresized() does only seem to accept resource, 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

1014
            ImageCopyResized($target_image, /** @scrutinizer ignore-type */ $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
Loading history...
It seems like $target_image can also be of type false; however, parameter $dst_image of imagecopyresized() does only seem to accept resource, 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

1014
            ImageCopyResized(/** @scrutinizer ignore-type */ $target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
Loading history...
1015
            ImageDestroy($base_image);
0 ignored issues
show
It seems like $base_image can also be of type false; however, parameter $image of imagedestroy() does only seem to accept resource, 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

1015
            ImageDestroy(/** @scrutinizer ignore-type */ $base_image);
Loading history...
1016
            
1017
            return $target_image;
1018
        }
1019
    }
1020
1021
1022
1023
//---- qrinput.php -----------------------------
1024
1025
1026
1027
1028
/*
1029
 * PHP QR Code encoder
1030
 *
1031
 * Input encoding class
1032
 *
1033
 * Based on libqrencode C library distributed under LGPL 2.1
1034
 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <[email protected]>
1035
 *
1036
 * PHP QR Code is distributed under LGPL 3
1037
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
1038
 *
1039
 * This library is free software; you can redistribute it and/or
1040
 * modify it under the terms of the GNU Lesser General Public
1041
 * License as published by the Free Software Foundation; either
1042
 * version 3 of the License, or any later version.
1043
 *
1044
 * This library is distributed in the hope that it will be useful,
1045
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1046
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1047
 * Lesser General Public License for more details.
1048
 *
1049
 * You should have received a copy of the GNU Lesser General Public
1050
 * License along with this library; if not, write to the Free Software
1051
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1052
 */
1053
 
1054
    define('STRUCTURE_HEADER_BITS', 20);
1055
    define('MAX_STRUCTURED_SYMBOLS', 16);
1056
1057
    class QRinputItem {
1058
    
1059
        public $mode;
1060
        public $size;
1061
        public $data;
1062
        public $bstream;
1063
1064
        public function __construct($mode, $size, $data, $bstream = null) 
1065
        {
1066
            $setData = array_slice($data, 0, $size);
1067
            
1068
            if (count($setData) < $size) {
1069
                $setData = array_merge($setData, array_fill(0, $size - count($setData), 0));
1070
            }
1071
        
1072
            if (!QRinput::check($mode, $size, $setData)) {
1073
                throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',', $setData));
1074
                return null;
0 ignored issues
show
return null is not reachable.

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

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

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

    return false;
}

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

Loading history...
1075
            }
1076
            
1077
            $this->mode = $mode;
1078
            $this->size = $size;
1079
            $this->data = $setData;
1080
            $this->bstream = $bstream;
1081
        }
1082
        
1083
        //----------------------------------------------------------------------
1084
        public function encodeModeNum($version)
1085
        {
1086
            try {
1087
            
1088
                $words = (int) ($this->size / 3);
1089
                $bs = new QRbitstream();
1090
                
1091
                $val = 0x1;
1092
                $bs->appendNum(4, $val);
1093
                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size);
1094
1095
                for ($i = 0; $i < $words; $i++) {
1096
                    $val  = (ord($this->data[$i * 3]) - ord('0')) * 100;
1097
                    $val += (ord($this->data[$i * 3 + 1]) - ord('0')) * 10;
1098
                    $val += (ord($this->data[$i * 3 + 2]) - ord('0'));
1099
                    $bs->appendNum(10, $val);
1100
                }
1101
1102
                if ($this->size - $words * 3 == 1) {
1103
                    $val = ord($this->data[$words * 3]) - ord('0');
1104
                    $bs->appendNum(4, $val);
1105
                } else if ($this->size - $words * 3 == 2) {
1106
                    $val  = (ord($this->data[$words * 3]) - ord('0')) * 10;
1107
                    $val += (ord($this->data[$words * 3 + 1]) - ord('0'));
1108
                    $bs->appendNum(7, $val);
1109
                }
1110
1111
                $this->bstream = $bs;
1112
                return 0;
1113
                
1114
            } catch (Exception $e) {
1115
                return -1;
1116
            }
1117
        }
1118
        
1119
        //----------------------------------------------------------------------
1120
        public function encodeModeAn($version)
1121
        {
1122
            try {
1123
                $words = (int) ($this->size / 2);
1124
                $bs = new QRbitstream();
1125
                
1126
                $bs->appendNum(4, 0x02);
1127
                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size);
1128
1129
                for ($i = 0; $i < $words; $i++) {
1130
                    $val  = (int) QRinput::lookAnTable(ord($this->data[$i * 2])) * 45;
1131
                    $val += (int) QRinput::lookAnTable(ord($this->data[$i * 2 + 1]));
1132
1133
                    $bs->appendNum(11, $val);
1134
                }
1135
1136
                if ($this->size & 1) {
1137
                    $val = QRinput::lookAnTable(ord($this->data[$words * 2]));
1138
                    $bs->appendNum(6, $val);
1139
                }
1140
        
1141
                $this->bstream = $bs;
1142
                return 0;
1143
            
1144
            } catch (Exception $e) {
1145
                return -1;
1146
            }
1147
        }
1148
        
1149
        //----------------------------------------------------------------------
1150
        public function encodeMode8($version)
1151
        {
1152
            try {
1153
                $bs = new QRbitstream();
1154
1155
                $bs->appendNum(4, 0x4);
1156
                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size);
1157
1158
                for ($i = 0; $i < $this->size; $i++) {
1159
                    $bs->appendNum(8, ord($this->data[$i]));
1160
                }
1161
1162
                $this->bstream = $bs;
1163
                return 0;
1164
            
1165
            } catch (Exception $e) {
1166
                return -1;
1167
            }
1168
        }
1169
        
1170
        //----------------------------------------------------------------------
1171
        public function encodeModeKanji($version)
1172
        {
1173
            try {
1174
1175
                $bs = new QRbitrtream();
0 ignored issues
show
The type QRbitrtream was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1176
                
1177
                $bs->appendNum(4, 0x8);
1178
                $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int) ($this->size / 2));
1179
1180
                for ($i = 0; $i < $this->size; $i += 2) {
1181
                    $val = (ord($this->data[$i]) << 8) | ord($this->data[$i + 1]);
1182
                    if ($val <= 0x9ffc) {
1183
                        $val -= 0x8140;
1184
                    } else {
1185
                        $val -= 0xc140;
1186
                    }
1187
                    
1188
                    $h = ($val >> 8) * 0xc0;
1189
                    $val = ($val & 0xff) + $h;
1190
1191
                    $bs->appendNum(13, $val);
1192
                }
1193
1194
                $this->bstream = $bs;
1195
                return 0;
1196
            
1197
            } catch (Exception $e) {
1198
                return -1;
1199
            }
1200
        }
1201
1202
        //----------------------------------------------------------------------
1203
        public function encodeModeStructure()
1204
        {
1205
            try {
1206
                $bs = new QRbitstream();
1207
                
1208
                $bs->appendNum(4, 0x03);
1209
                $bs->appendNum(4, ord($this->data[1]) - 1);
1210
                $bs->appendNum(4, ord($this->data[0]) - 1);
1211
                $bs->appendNum(8, ord($this->data[2]));
1212
1213
                $this->bstream = $bs;
1214
                return 0;
1215
            
1216
            } catch (Exception $e) {
1217
                return -1;
1218
            }
1219
        }
1220
        
1221
        //----------------------------------------------------------------------
1222
        public function estimateBitStreamSizeOfEntry($version)
1223
        {
1224
            $bits = 0;
1225
1226
            if ($version == 0) {
1227
                            $version = 1;
1228
            }
1229
1230
            switch ($this->mode) {
1231
            case QR_MODE_NUM:        $bits = QRinput::estimateBitsModeNum($this->size); break;
1232
            case QR_MODE_AN:        $bits = QRinput::estimateBitsModeAn($this->size); break;
1233
            case QR_MODE_8:            $bits = QRinput::estimateBitsMode8($this->size); break;
1234
            case QR_MODE_KANJI:        $bits = QRinput::estimateBitsModeKanji($this->size); break;
0 ignored issues
show
Bug Best Practice introduced by
The method QRinput::estimateBitsModeKanji() is not static, but was called statically. ( Ignorable by Annotation )

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

1234
            case QR_MODE_KANJI:        /** @scrutinizer ignore-call */ $bits = QRinput::estimateBitsModeKanji($this->size); break;
Loading history...
1235
            case QR_MODE_STRUCTURE:    return STRUCTURE_HEADER_BITS;            
1236
            default:
1237
                return 0;
1238
            }
1239
1240
            $l = QRspec::lengthIndicator($this->mode, $version);
1241
            $m = 1 << $l;
1242
            $num = (int) (($this->size + $m - 1) / $m);
1243
1244
            $bits += $num * (4 + $l);
1245
1246
            return $bits;
1247
        }
1248
        
1249
        //----------------------------------------------------------------------
1250
        public function encodeBitStream($version)
1251
        {
1252
            try {
1253
            
1254
                unset($this->bstream);
1255
                $words = QRspec::maximumWords($this->mode, $version);
1256
                
1257
                if ($this->size > $words) {
1258
                
1259
                    $st1 = new QRinputItem($this->mode, $words, $this->data);
1260
                    $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words));
1261
1262
                    $st1->encodeBitStream($version);
1263
                    $st2->encodeBitStream($version);
1264
                    
1265
                    $this->bstream = new QRbitstream();
1266
                    $this->bstream->append($st1->bstream);
1267
                    $this->bstream->append($st2->bstream);
1268
                    
1269
                    unset($st1);
1270
                    unset($st2);
1271
                    
1272
                } else {
1273
                    
1274
                    $ret = 0;
1275
                    
1276
                    switch ($this->mode) {
1277
                    case QR_MODE_NUM:        $ret = $this->encodeModeNum($version); break;
1278
                    case QR_MODE_AN:        $ret = $this->encodeModeAn($version); break;
1279
                    case QR_MODE_8:            $ret = $this->encodeMode8($version); break;
1280
                    case QR_MODE_KANJI:        $ret = $this->encodeModeKanji($version); break;
1281
                    case QR_MODE_STRUCTURE:    $ret = $this->encodeModeStructure(); break;
1282
                        
1283
                    default:
1284
                        break;
1285
                    }
1286
                    
1287
                    if ($ret < 0) {
1288
                                            return -1;
1289
                    }
1290
                }
1291
1292
                return $this->bstream->size();
1293
            
1294
            } catch (Exception $e) {
1295
                return -1;
1296
            }
1297
        }
1298
    };
1299
    
1300
    //##########################################################################
1301
1302
    class QRinput {
1303
1304
        public $items;
1305
        
1306
        private $version;
1307
        private $level;
1308
        
1309
        //----------------------------------------------------------------------
1310
        public function __construct($version = 0, $level = QR_ECLEVEL_L)
1311
        {
1312
            if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) {
1313
                throw new Exception('Invalid version no');
1314
                return null;
0 ignored issues
show
return null is not reachable.

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

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

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

    return false;
}

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

Loading history...
1315
            }
1316
            
1317
            $this->version = $version;
1318
            $this->level = $level;
1319
        }
1320
        
1321
        //----------------------------------------------------------------------
1322
        public function getVersion()
1323
        {
1324
            return $this->version;
1325
        }
1326
        
1327
        //----------------------------------------------------------------------
1328
        public function setVersion($version)
1329
        {
1330
            if ($version < 0 || $version > QRSPEC_VERSION_MAX) {
1331
                throw new Exception('Invalid version no');
1332
                return -1;
0 ignored issues
show
return -1 is not reachable.

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

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

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

    return false;
}

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

Loading history...
1333
            }
1334
1335
            $this->version = $version;
1336
1337
            return 0;
1338
        }
1339
        
1340
        //----------------------------------------------------------------------
1341
        public function getErrorCorrectionLevel()
1342
        {
1343
            return $this->level;
1344
        }
1345
1346
        //----------------------------------------------------------------------
1347
        public function setErrorCorrectionLevel($level)
1348
        {
1349
            if ($level > QR_ECLEVEL_H) {
1350
                throw new Exception('Invalid ECLEVEL');
1351
                return -1;
0 ignored issues
show
return -1 is not reachable.

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

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

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

    return false;
}

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

Loading history...
1352
            }
1353
1354
            $this->level = $level;
1355
1356
            return 0;
1357
        }
1358
        
1359
        //----------------------------------------------------------------------
1360
        public function appendEntry(QRinputItem $entry)
1361
        {
1362
            $this->items[] = $entry;
1363
        }
1364
        
1365
        //----------------------------------------------------------------------
1366
        public function append($mode, $size, $data)
1367
        {
1368
            try {
1369
                $entry = new QRinputItem($mode, $size, $data);
1370
                $this->items[] = $entry;
1371
                return 0;
1372
            } catch (Exception $e) {
1373
                return -1;
1374
            }
1375
        }
1376
        
1377
        //----------------------------------------------------------------------
1378
        
1379
        public function insertStructuredAppendHeader($size, $index, $parity)
1380
        {
1381
            if ($size > MAX_STRUCTURED_SYMBOLS) {
1382
                throw new Exception('insertStructuredAppendHeader wrong size');
1383
            }
1384
            
1385
            if ($index <= 0 || $index > MAX_STRUCTURED_SYMBOLS) {
1386
                throw new Exception('insertStructuredAppendHeader wrong index');
1387
            }
1388
1389
            $buf = array($size, $index, $parity);
0 ignored issues
show
The assignment to $buf is dead and can be removed.
Loading history...
1390
            
1391
            try {
1392
                $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf);
0 ignored issues
show
The constant buf was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1393
                array_unshift($this->items, $entry);
1394
                return 0;
1395
            } catch (Exception $e) {
1396
                return -1;
1397
            }
1398
        }
1399
1400
        //----------------------------------------------------------------------
1401
        public function calcParity()
1402
        {
1403
            $parity = 0;
1404
            
1405
            foreach ($this->items as $item) {
1406
                if ($item->mode != QR_MODE_STRUCTURE) {
1407
                    for ($i = $item->size - 1; $i >= 0; $i--) {
1408
                        $parity ^= $item->data[$i];
1409
                    }
1410
                }
1411
            }
1412
1413
            return $parity;
1414
        }
1415
        
1416
        //----------------------------------------------------------------------
1417
        public static function checkModeNum($size, $data)
1418
        {
1419
            for ($i = 0; $i < $size; $i++) {
1420
                if ((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))) {
1421
                    return false;
1422
                }
1423
            }
1424
1425
            return true;
1426
        }
1427
1428
        //----------------------------------------------------------------------
1429
        public static function estimateBitsModeNum($size)
1430
        {
1431
            $w = (int) $size / 3;
1432
            $bits = $w * 10;
1433
            
1434
            switch ($size - $w * 3) {
1435
            case 1:
1436
                $bits += 4;
1437
                break;
1438
            case 2:
1439
                $bits += 7;
1440
                break;
1441
            default:
1442
                break;
1443
            }
1444
1445
            return $bits;
1446
        }
1447
        
1448
        //----------------------------------------------------------------------
1449
        public static $anTable = array(
1450
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1451
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1452
            36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
1453
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
1454
            -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1455
            25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
1456
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1457
            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1458
        );
1459
        
1460
        //----------------------------------------------------------------------
1461
        public static function lookAnTable($c)
1462
        {
1463
            return (($c > 127) ?-1 : self::$anTable[$c]);
1464
        }
1465
        
1466
        //----------------------------------------------------------------------
1467
        public static function checkModeAn($size, $data)
1468
        {
1469
            for ($i = 0; $i < $size; $i++) {
1470
                if (self::lookAnTable(ord($data[$i])) == -1) {
1471
                    return false;
1472
                }
1473
            }
1474
1475
            return true;
1476
        }
1477
        
1478
        //----------------------------------------------------------------------
1479
        public static function estimateBitsModeAn($size)
1480
        {
1481
            $w = (int) ($size / 2);
1482
            $bits = $w * 11;
1483
            
1484
            if ($size & 1) {
1485
                $bits += 6;
1486
            }
1487
1488
            return $bits;
1489
        }
1490
    
1491
        //----------------------------------------------------------------------
1492
        public static function estimateBitsMode8($size)
1493
        {
1494
            return $size * 8;
1495
        }
1496
        
1497
        //----------------------------------------------------------------------
1498
        public function estimateBitsModeKanji($size)
1499
        {
1500
            return (int) (($size / 2) * 13);
1501
        }
1502
        
1503
        //----------------------------------------------------------------------
1504
        public static function checkModeKanji($size, $data)
1505
        {
1506
            if ($size & 1) {
1507
                            return false;
1508
            }
1509
1510
            for ($i = 0; $i < $size; $i += 2) {
1511
                $val = (ord($data[$i]) << 8) | ord($data[$i + 1]);
1512
                if ($val < 0x8140 
1513
                || ($val > 0x9ffc && $val < 0xe040) 
1514
                || $val > 0xebbf) {
1515
                    return false;
1516
                }
1517
            }
1518
1519
            return true;
1520
        }
1521
1522
        /***********************************************************************
1523
         * Validation
1524
         **********************************************************************/
1525
1526
        public static function check($mode, $size, $data)
1527
        {
1528
            if ($size <= 0) {
1529
                            return false;
1530
            }
1531
1532
            switch ($mode) {
1533
            case QR_MODE_NUM:       return self::checkModeNum($size, $data); break;
0 ignored issues
show
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...
1534
            case QR_MODE_AN:        return self::checkModeAn($size, $data); break;
1535
            case QR_MODE_KANJI:     return self::checkModeKanji($size, $data); break;
1536
            case QR_MODE_8:         return true; break;
1537
            case QR_MODE_STRUCTURE: return true; break;
1538
                
1539
            default:
1540
                break;
1541
            }
1542
1543
            return false;
1544
        }
1545
        
1546
        
1547
        //----------------------------------------------------------------------
1548
        public function estimateBitStreamSize($version)
1549
        {
1550
            $bits = 0;
1551
1552
            foreach ($this->items as $item) {
1553
                $bits += $item->estimateBitStreamSizeOfEntry($version);
1554
            }
1555
1556
            return $bits;
1557
        }
1558
        
1559
        //----------------------------------------------------------------------
1560
        public function estimateVersion()
1561
        {
1562
            $version = 0;
1563
            $prev = 0;
0 ignored issues
show
The assignment to $prev is dead and can be removed.
Loading history...
1564
            do {
1565
                $prev = $version;
1566
                $bits = $this->estimateBitStreamSize($prev);
1567
                $version = QRspec::getMinimumVersion((int) (($bits + 7) / 8), $this->level);
1568
                if ($version < 0) {
1569
                    return -1;
1570
                }
1571
            } while ($version > $prev);
1572
1573
            return $version;
1574
        }
1575
        
1576
        //----------------------------------------------------------------------
1577
        public static function lengthOfCode($mode, $version, $bits)
1578
        {
1579
            $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version);
1580
            switch ($mode) {
1581
            case QR_MODE_NUM:
1582
                $chunks = (int) ($payload / 10);
1583
                $remain = $payload - $chunks * 10;
1584
                $size = $chunks * 3;
1585
                if ($remain >= 7) {
1586
                    $size += 2;
1587
                } else if ($remain >= 4) {
1588
                    $size += 1;
1589
                }
1590
                break;
1591
            case QR_MODE_AN:
1592
                $chunks = (int) ($payload / 11);
1593
                $remain = $payload - $chunks * 11;
1594
                $size = $chunks * 2;
1595
                if ($remain >= 6) {
1596
                                    $size++;
1597
                }
1598
                break;
1599
            case QR_MODE_8:
1600
                $size = (int) ($payload / 8);
1601
                break;
1602
            case QR_MODE_KANJI:
1603
                $size = (int) (($payload / 13) * 2);
1604
                break;
1605
            case QR_MODE_STRUCTURE:
1606
                $size = (int) ($payload / 8);
1607
                break;
1608
            default:
1609
                $size = 0;
1610
                break;
1611
            }
1612
            
1613
            $maxsize = QRspec::maximumWords($mode, $version);
1614
            if ($size < 0) {
1615
                $size = 0;
1616
            }
1617
            if ($size > $maxsize) {
1618
                $size = $maxsize;
1619
            }
1620
1621
            return $size;
1622
        }
1623
        
1624
        //----------------------------------------------------------------------
1625
        public function createBitStream()
1626
        {
1627
            $total = 0;
1628
1629
            foreach ($this->items as $item) {
1630
                $bits = $item->encodeBitStream($this->version);
1631
                
1632
                if ($bits < 0) {
1633
                                    return -1;
1634
                }
1635
                    
1636
                $total += $bits;
1637
            }
1638
1639
            return $total;
1640
        }
1641
        
1642
        //----------------------------------------------------------------------
1643
        public function convertData()
1644
        {
1645
            $ver = $this->estimateVersion();
1646
            if ($ver > $this->getVersion()) {
1647
                $this->setVersion($ver);
1648
            }
1649
1650
            for (;;) {
1651
                $bits = $this->createBitStream();
1652
                
1653
                if ($bits < 0) {
1654
                                    return -1;
1655
                }
1656
                    
1657
                $ver = QRspec::getMinimumVersion((int) (($bits + 7) / 8), $this->level);
1658
                if ($ver < 0) {
1659
                    throw new Exception('WRONG VERSION');
1660
                    return -1;
0 ignored issues
show
return -1 is not reachable.

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

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

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

    return false;
}

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

Loading history...
1661
                } else if ($ver > $this->getVersion()) {
1662
                    $this->setVersion($ver);
1663
                } else {
1664
                    break;
1665
                }
1666
            }
1667
1668
            return 0;
1669
        }
1670
        
1671
        //----------------------------------------------------------------------
1672
        public function appendPaddingBit(&$bstream)
1673
        {
1674
            $bits = $bstream->size();
1675
            $maxwords = QRspec::getDataLength($this->version, $this->level);
1676
            $maxbits = $maxwords * 8;
1677
1678
            if ($maxbits == $bits) {
1679
                return 0;
1680
            }
1681
1682
            if ($maxbits - $bits < 5) {
1683
                return $bstream->appendNum($maxbits - $bits, 0);
1684
            }
1685
1686
            $bits += 4;
1687
            $words = (int) (($bits + 7) / 8);
1688
1689
            $padding = new QRbitstream();
1690
            $ret = $padding->appendNum($words * 8 - $bits + 4, 0);
1691
            
1692
            if ($ret < 0) {
1693
                            return $ret;
1694
            }
1695
1696
            $padlen = $maxwords - $words;
1697
            
1698
            if ($padlen > 0) {
1699
                
1700
                $padbuf = array();
1701
                for ($i = 0; $i < $padlen; $i++) {
1702
                    $padbuf[$i] = ($i & 1) ? 0x11 : 0xec;
1703
                }
1704
                
1705
                $ret = $padding->appendBytes($padlen, $padbuf);
1706
                
1707
                if ($ret < 0) {
1708
                                    return $ret;
1709
                }
1710
                
1711
            }
1712
1713
            $ret = $bstream->append($padding);
1714
            
1715
            return $ret;
1716
        }
1717
1718
        //----------------------------------------------------------------------
1719
        public function mergeBitStream()
1720
        {
1721
            if ($this->convertData() < 0) {
1722
                return null;
1723
            }
1724
1725
            $bstream = new QRbitstream();
1726
            
1727
            foreach ($this->items as $item) {
1728
                $ret = $bstream->append($item->bstream);
1729
                if ($ret < 0) {
1730
                    return null;
1731
                }
1732
            }
1733
1734
            return $bstream;
1735
        }
1736
1737
        //----------------------------------------------------------------------
1738
        public function getBitStream()
1739
        {
1740
1741
            $bstream = $this->mergeBitStream();
1742
            
1743
            if ($bstream == null) {
1744
                return null;
1745
            }
1746
            
1747
            $ret = $this->appendPaddingBit($bstream);
1748
            if ($ret < 0) {
1749
                return null;
1750
            }
1751
1752
            return $bstream;
1753
        }
1754
        
1755
        //----------------------------------------------------------------------
1756
        public function getByteStream()
1757
        {
1758
            $bstream = $this->getBitStream();
0 ignored issues
show
Are you sure the assignment to $bstream is correct as $this->getBitStream() targeting QRinput::getBitStream() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1759
            if ($bstream == null) {
0 ignored issues
show
The condition $bstream == null is always true.
Loading history...
1760
                return null;
1761
            }
1762
            
1763
            return $bstream->toByte();
1764
        }
1765
    }
1766
        
1767
        
1768
    
1769
1770
1771
1772
//---- qrbitstream.php -----------------------------
1773
1774
1775
1776
1777
/*
1778
 * PHP QR Code encoder
1779
 *
1780
 * Bitstream class
1781
 *
1782
 * Based on libqrencode C library distributed under LGPL 2.1
1783
 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <[email protected]>
1784
 *
1785
 * PHP QR Code is distributed under LGPL 3
1786
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
1787
 *
1788
 * This library is free software; you can redistribute it and/or
1789
 * modify it under the terms of the GNU Lesser General Public
1790
 * License as published by the Free Software Foundation; either
1791
 * version 3 of the License, or any later version.
1792
 *
1793
 * This library is distributed in the hope that it will be useful,
1794
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1795
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1796
 * Lesser General Public License for more details.
1797
 *
1798
 * You should have received a copy of the GNU Lesser General Public
1799
 * License along with this library; if not, write to the Free Software
1800
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1801
 */
1802
     
1803
    class QRbitstream {
1804
    
1805
        public $data = array();
1806
        
1807
        //----------------------------------------------------------------------
1808
        public function size()
1809
        {
1810
            return count($this->data);
1811
        }
1812
        
1813
        //----------------------------------------------------------------------
1814
        public function allocate($setLength)
1815
        {
1816
            $this->data = array_fill(0, $setLength, 0);
1817
            return 0;
1818
        }
1819
    
1820
        //----------------------------------------------------------------------
1821
        public static function newFromNum($bits, $num)
1822
        {
1823
            $bstream = new QRbitstream();
1824
            $bstream->allocate($bits);
1825
            
1826
            $mask = 1 << ($bits - 1);
1827
            for ($i = 0; $i < $bits; $i++) {
1828
                if ($num & $mask) {
1829
                    $bstream->data[$i] = 1;
1830
                } else {
1831
                    $bstream->data[$i] = 0;
1832
                }
1833
                $mask = $mask >> 1;
1834
            }
1835
1836
            return $bstream;
1837
        }
1838
        
1839
        //----------------------------------------------------------------------
1840
        public static function newFromBytes($size, $data)
1841
        {
1842
            $bstream = new QRbitstream();
1843
            $bstream->allocate($size * 8);
1844
            $p = 0;
1845
1846
            for ($i = 0; $i < $size; $i++) {
1847
                $mask = 0x80;
1848
                for ($j = 0; $j < 8; $j++) {
1849
                    if ($data[$i] & $mask) {
1850
                        $bstream->data[$p] = 1;
1851
                    } else {
1852
                        $bstream->data[$p] = 0;
1853
                    }
1854
                    $p++;
1855
                    $mask = $mask >> 1;
1856
                }
1857
            }
1858
1859
            return $bstream;
1860
        }
1861
        
1862
        //----------------------------------------------------------------------
1863
        public function append(QRbitstream $arg)
1864
        {
1865
            if (is_null($arg)) {
1866
                return -1;
1867
            }
1868
            
1869
            if ($arg->size() == 0) {
1870
                return 0;
1871
            }
1872
            
1873
            if ($this->size() == 0) {
1874
                $this->data = $arg->data;
1875
                return 0;
1876
            }
1877
            
1878
            $this->data = array_values(array_merge($this->data, $arg->data));
1879
1880
            return 0;
1881
        }
1882
        
1883
        //----------------------------------------------------------------------
1884
        public function appendNum($bits, $num)
1885
        {
1886
            if ($bits == 0) {
1887
                            return 0;
1888
            }
1889
1890
            $b = QRbitstream::newFromNum($bits, $num);
1891
            
1892
            if (is_null($b)) {
1893
                            return -1;
1894
            }
1895
1896
            $ret = $this->append($b);
1897
            unset($b);
1898
1899
            return $ret;
1900
        }
1901
1902
        //----------------------------------------------------------------------
1903
        public function appendBytes($size, $data)
1904
        {
1905
            if ($size == 0) {
1906
                            return 0;
1907
            }
1908
1909
            $b = QRbitstream::newFromBytes($size, $data);
1910
            
1911
            if (is_null($b)) {
1912
                            return -1;
1913
            }
1914
1915
            $ret = $this->append($b);
1916
            unset($b);
1917
1918
            return $ret;
1919
        }
1920
        
1921
        //----------------------------------------------------------------------
1922
        public function toByte()
1923
        {
1924
        
1925
            $size = $this->size();
1926
1927
            if ($size == 0) {
1928
                return array();
1929
            }
1930
            
1931
            $data = array_fill(0, (int) (($size + 7) / 8), 0);
1932
            $bytes = (int) ($size / 8);
1933
1934
            $p = 0;
1935
            
1936
            for ($i = 0; $i < $bytes; $i++) {
1937
                $v = 0;
1938
                for ($j = 0; $j < 8; $j++) {
1939
                    $v = $v << 1;
1940
                    $v |= $this->data[$p];
1941
                    $p++;
1942
                }
1943
                $data[$i] = $v;
1944
            }
1945
            
1946
            if ($size & 7) {
1947
                $v = 0;
1948
                for ($j = 0; $j < ($size & 7); $j++) {
1949
                    $v = $v << 1;
1950
                    $v |= $this->data[$p];
1951
                    $p++;
1952
                }
1953
                $data[$bytes] = $v;
1954
            }
1955
1956
            return $data;
1957
        }
1958
1959
    }
1960
1961
1962
1963
1964
//---- qrsplit.php -----------------------------
1965
1966
1967
1968
1969
/*
1970
 * PHP QR Code encoder
1971
 *
1972
 * Input splitting classes
1973
 *
1974
 * Based on libqrencode C library distributed under LGPL 2.1
1975
 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <[email protected]>
1976
 *
1977
 * PHP QR Code is distributed under LGPL 3
1978
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
1979
 *
1980
 * The following data / specifications are taken from
1981
 * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
1982
 *  or
1983
 * "Automatic identification and data capture techniques -- 
1984
 *  QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
1985
 *
1986
 * This library is free software; you can redistribute it and/or
1987
 * modify it under the terms of the GNU Lesser General Public
1988
 * License as published by the Free Software Foundation; either
1989
 * version 3 of the License, or any later version.
1990
 *
1991
 * This library is distributed in the hope that it will be useful,
1992
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1993
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1994
 * Lesser General Public License for more details.
1995
 *
1996
 * You should have received a copy of the GNU Lesser General Public
1997
 * License along with this library; if not, write to the Free Software
1998
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1999
 */
2000
    class QRsplit {
2001
2002
        public $dataStr = '';
2003
        public $input;
2004
        public $modeHint;
2005
2006
        //----------------------------------------------------------------------
2007
        public function __construct($dataStr, $input, $modeHint) 
2008
        {
2009
            $this->dataStr  = $dataStr;
2010
            $this->input    = $input;
2011
            $this->modeHint = $modeHint;
2012
        }
2013
        
2014
        //----------------------------------------------------------------------
2015
        public static function isdigitat($str, $pos)
2016
        {    
2017
            if ($pos >= strlen($str)) {
2018
                            return false;
2019
            }
2020
            
2021
            return ((ord($str[$pos]) >= ord('0')) && (ord($str[$pos]) <= ord('9')));
2022
        }
2023
        
2024
        //----------------------------------------------------------------------
2025
        public static function isalnumat($str, $pos)
2026
        {
2027
            if ($pos >= strlen($str)) {
2028
                            return false;
2029
            }
2030
                
2031
            return (QRinput::lookAnTable(ord($str[$pos])) >= 0);
2032
        }
2033
2034
        //----------------------------------------------------------------------
2035
        public function identifyMode($pos)
2036
        {
2037
            if ($pos >= strlen($this->dataStr)) {
2038
                            return QR_MODE_NUL;
2039
            }
2040
                
2041
            $c = $this->dataStr[$pos];
2042
            
2043
            if (self::isdigitat($this->dataStr, $pos)) {
2044
                return QR_MODE_NUM;
2045
            } else if (self::isalnumat($this->dataStr, $pos)) {
2046
                return QR_MODE_AN;
2047
            } else if ($this->modeHint == QR_MODE_KANJI) {
2048
            
2049
                if ($pos + 1 < strlen($this->dataStr)) 
2050
                {
2051
                    $d = $this->dataStr[$pos + 1];
2052
                    $word = (ord($c) << 8) | ord($d);
2053
                    if (($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) {
2054
                        return QR_MODE_KANJI;
2055
                    }
2056
                }
2057
            }
2058
2059
            return QR_MODE_8;
2060
        } 
2061
        
2062
        //----------------------------------------------------------------------
2063
        public function eatNum()
2064
        {
2065
            $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
2066
2067
            $p = 0;
2068
            while (self::isdigitat($this->dataStr, $p)) {
2069
                $p++;
2070
            }
2071
            
2072
            $run = $p;
2073
            $mode = $this->identifyMode($p);
2074
            
2075
            if ($mode == QR_MODE_8) {
2076
                $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
2077
                     + QRinput::estimateBitsMode8(1)         // + 4 + l8
2078
                     - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
2079
                if ($dif > 0) {
2080
                    return $this->eat8();
2081
                }
2082
            }
2083
            if ($mode == QR_MODE_AN) {
2084
                $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln
2085
                     + QRinput::estimateBitsModeAn(1)        // + 4 + la
2086
                     - QRinput::estimateBitsModeAn($run + 1); // - 4 - la
2087
                if ($dif > 0) {
2088
                    return $this->eatAn();
2089
                }
2090
            }
2091
            
2092
            $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));
2093
            if ($ret < 0) {
2094
                            return -1;
2095
            }
2096
2097
            return $run;
2098
        }
2099
        
2100
        //----------------------------------------------------------------------
2101
        public function eatAn()
2102
        {
2103
            $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
2104
            $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
2105
2106
            $p = 0;
2107
            
2108
            while (self::isalnumat($this->dataStr, $p)) {
2109
                if (self::isdigitat($this->dataStr, $p)) {
2110
                    $q = $p;
2111
                    while (self::isdigitat($this->dataStr, $q)) {
2112
                        $q++;
2113
                    }
2114
                    
2115
                    $dif = QRinput::estimateBitsModeAn($p) // + 4 + la
2116
                         + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
2117
                         - QRinput::estimateBitsModeAn($q); // - 4 - la
2118
                         
2119
                    if ($dif < 0) {
2120
                        break;
2121
                    } else {
2122
                        $p = $q;
2123
                    }
2124
                } else {
2125
                    $p++;
2126
                }
2127
            }
2128
2129
            $run = $p;
2130
2131
            if (!self::isalnumat($this->dataStr, $p)) {
2132
                $dif = QRinput::estimateBitsModeAn($run) + 4 + $la
2133
                     + QRinput::estimateBitsMode8(1) // + 4 + l8
2134
                      - QRinput::estimateBitsMode8($run + 1); // - 4 - l8
2135
                if ($dif > 0) {
2136
                    return $this->eat8();
2137
                }
2138
            }
2139
2140
            $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));
2141
            if ($ret < 0) {
2142
                            return -1;
2143
            }
2144
2145
            return $run;
2146
        }
2147
        
2148
        //----------------------------------------------------------------------
2149
        public function eatKanji()
2150
        {
2151
            $p = 0;
2152
            
2153
            while ($this->identifyMode($p) == QR_MODE_KANJI) {
2154
                $p += 2;
2155
            }
2156
            
2157
            $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));
2158
            if ($ret < 0) {
2159
                            return -1;
2160
            }
2161
2162
            return $run;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $run seems to be never defined.
Loading history...
2163
        }
2164
2165
        //----------------------------------------------------------------------
2166
        public function eat8()
2167
        {
2168
            $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());
2169
            $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());
2170
2171
            $p = 1;
2172
            $dataStrLen = strlen($this->dataStr);
2173
            
2174
            while ($p < $dataStrLen) {
2175
                
2176
                $mode = $this->identifyMode($p);
2177
                if ($mode == QR_MODE_KANJI) {
2178
                    break;
2179
                }
2180
                if ($mode == QR_MODE_NUM) {
2181
                    $q = $p;
2182
                    while (self::isdigitat($this->dataStr, $q)) {
2183
                        $q++;
2184
                    }
2185
                    $dif = QRinput::estimateBitsMode8($p) // + 4 + l8
2186
                         + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln
2187
                         - QRinput::estimateBitsMode8($q); // - 4 - l8
2188
                    if ($dif < 0) {
2189
                        break;
2190
                    } else {
2191
                        $p = $q;
2192
                    }
2193
                } else if ($mode == QR_MODE_AN) {
2194
                    $q = $p;
2195
                    while (self::isalnumat($this->dataStr, $q)) {
2196
                        $q++;
2197
                    }
2198
                    $dif = QRinput::estimateBitsMode8($p)  // + 4 + l8
2199
                         + QRinput::estimateBitsModeAn($q - $p) + 4 + $la
2200
                         - QRinput::estimateBitsMode8($q); // - 4 - l8
2201
                    if ($dif < 0) {
2202
                        break;
2203
                    } else {
2204
                        $p = $q;
2205
                    }
2206
                } else {
2207
                    $p++;
2208
                }
2209
            }
2210
2211
            $run = $p;
2212
            $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));
2213
            
2214
            if ($ret < 0) {
2215
                            return -1;
2216
            }
2217
2218
            return $run;
2219
        }
2220
2221
        //----------------------------------------------------------------------
2222
        public function splitString()
2223
        {
2224
            while (strlen($this->dataStr) > 0)
2225
            {
2226
                if ($this->dataStr == '') {
2227
                                    return 0;
2228
                }
2229
2230
                $mode = $this->identifyMode(0);
2231
                
2232
                switch ($mode) {
2233
                case QR_MODE_NUM: $length = $this->eatNum(); break;
2234
                case QR_MODE_AN:  $length = $this->eatAn(); break;
2235
                case QR_MODE_KANJI:
2236
                    if ($this->modeHint == QR_MODE_KANJI) {
2237
                                                $length = $this->eatKanji();
2238
                    } else {
2239
                        $length = $this->eat8();
2240
                    }
2241
                    break;
2242
                default: $length = $this->eat8(); break;
2243
                
2244
                }
2245
2246
                if ($length == 0) {
2247
                    return 0;
2248
                }
2249
                if ($length < 0) {
2250
                    return -1;
2251
                }
2252
                
2253
                $this->dataStr = substr($this->dataStr, $length);
2254
            }
2255
        }
2256
2257
        //----------------------------------------------------------------------
2258
        public function toUpper()
2259
        {
2260
            $stringLen = strlen($this->dataStr);
2261
            $p = 0;
2262
            
2263
            while ($p < $stringLen) {
2264
                $mode = self::identifyMode(substr($this->dataStr, $p));
0 ignored issues
show
Bug Best Practice introduced by
The method QRsplit::identifyMode() is not static, but was called statically. ( Ignorable by Annotation )

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

2264
                /** @scrutinizer ignore-call */ $mode = self::identifyMode(substr($this->dataStr, $p));
Loading history...
2265
                if ($mode == QR_MODE_KANJI) {
2266
                    $p += 2;
2267
                } else {
2268
                    if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) {
2269
                        $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);
2270
                    }
2271
                    $p++;
2272
                }
2273
            }
2274
2275
            return $this->dataStr;
2276
        }
2277
2278
        //----------------------------------------------------------------------
2279
        public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true)
2280
        {
2281
            if (is_null($string) || $string == '\0' || $string == '') {
2282
                throw new Exception('empty string!!!');
2283
            }
2284
2285
            $split = new QRsplit($string, $input, $modeHint);
2286
            
2287
            if (!$casesensitive) {
2288
                            $split->toUpper();
2289
            }
2290
                
2291
            return $split->splitString();
2292
        }
2293
    }
2294
2295
2296
2297
//---- qrrscode.php -----------------------------
2298
2299
2300
2301
2302
/*
2303
 * PHP QR Code encoder
2304
 *
2305
 * Reed-Solomon error correction support
2306
 * 
2307
 * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
2308
 * (libfec is released under the GNU Lesser General Public License.)
2309
 *
2310
 * Based on libqrencode C library distributed under LGPL 2.1
2311
 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <[email protected]>
2312
 *
2313
 * PHP QR Code is distributed under LGPL 3
2314
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
2315
 *
2316
 * This library is free software; you can redistribute it and/or
2317
 * modify it under the terms of the GNU Lesser General Public
2318
 * License as published by the Free Software Foundation; either
2319
 * version 3 of the License, or any later version.
2320
 *
2321
 * This library is distributed in the hope that it will be useful,
2322
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2323
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2324
 * Lesser General Public License for more details.
2325
 *
2326
 * You should have received a copy of the GNU Lesser General Public
2327
 * License along with this library; if not, write to the Free Software
2328
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2329
 */
2330
 
2331
    class QRrsItem {
2332
    
2333
        public $mm; // Bits per symbol 
2334
        public $nn; // Symbols per block (= (1<<mm)-1) 
2335
        public $alpha_to = array(); // log lookup table 
2336
        public $index_of = array(); // Antilog lookup table 
2337
        public $genpoly = array(); // Generator polynomial 
2338
        public $nroots; // Number of generator roots = number of parity symbols 
2339
        public $fcr; // First consecutive root, index form 
2340
        public $prim; // Primitive element, index form 
2341
        public $iprim; // prim-th root of 1, index form 
2342
        public $pad; // Padding bytes in shortened block 
2343
        public $gfpoly;
2344
    
2345
        //----------------------------------------------------------------------
2346
        public function modnn($x)
2347
        {
2348
            while ($x >= $this->nn) {
2349
                $x -= $this->nn;
2350
                $x = ($x >> $this->mm) + ($x & $this->nn);
2351
            }
2352
            
2353
            return $x;
2354
        }
2355
        
2356
        //----------------------------------------------------------------------
2357
        public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
2358
        {
2359
            // Common code for intializing a Reed-Solomon control block (char or int symbols)
2360
            // Copyright 2004 Phil Karn, KA9Q
2361
            // May be used under the terms of the GNU Lesser General Public License (LGPL)
2362
2363
            $rs = null;
2364
            
2365
            // Check parameter ranges
2366
            if ($symsize < 0 || $symsize > 8) {
2367
                return $rs;
2368
            }
2369
            if ($fcr < 0 || $fcr >= (1 << $symsize)) {
2370
                return $rs;
2371
            }
2372
            if ($prim <= 0 || $prim >= (1 << $symsize)) {
2373
                return $rs;
2374
            }
2375
            if ($nroots < 0 || $nroots >= (1 << $symsize)) {
2376
                return $rs;
2377
            }
2378
            // Can't have more roots than symbol values!
2379
            if ($pad < 0 || $pad >= ((1 << $symsize) - 1 - $nroots)) {
2380
                return $rs;
2381
            }
2382
            // Too much padding
2383
2384
            $rs = new QRrsItem();
2385
            $rs->mm = $symsize;
2386
            $rs->nn = (1 << $symsize) - 1;
2387
            $rs->pad = $pad;
2388
2389
            $rs->alpha_to = array_fill(0, $rs->nn + 1, 0);
2390
            $rs->index_of = array_fill(0, $rs->nn + 1, 0);
2391
          
2392
            // PHP style macro replacement ;)
2393
            $NN = & $rs->nn;
2394
            $A0 = & $NN;
2395
            
2396
            // Generate Galois field lookup tables
2397
            $rs->index_of[0] = $A0; // log(zero) = -inf
2398
            $rs->alpha_to[$A0] = 0; // alpha**-inf = 0
2399
            $sr = 1;
2400
          
2401
            for ($i = 0; $i < $rs->nn; $i++) {
2402
                $rs->index_of[$sr] = $i;
2403
                $rs->alpha_to[$i] = $sr;
2404
                $sr <<= 1;
2405
                if ($sr & (1 << $symsize)) {
2406
                    $sr ^= $gfpoly;
2407
                }
2408
                $sr &= $rs->nn;
2409
            }
2410
            
2411
            if ($sr != 1) {
2412
                // field generator polynomial is not primitive!
2413
                $rs = null;
2414
                return $rs;
2415
            }
2416
2417
            /* Form RS code generator polynomial from its roots */
2418
            $rs->genpoly = array_fill(0, $nroots + 1, 0);
2419
        
2420
            $rs->fcr = $fcr;
2421
            $rs->prim = $prim;
2422
            $rs->nroots = $nroots;
2423
            $rs->gfpoly = $gfpoly;
2424
2425
            /* Find prim-th root of 1, used in decoding */
2426
            for ($iprim = 1; ($iprim % $prim) != 0; $iprim += $rs->nn)
2427
            ; // intentional empty-body loop!
2428
            
2429
            $rs->iprim = (int) ($iprim / $prim);
2430
            $rs->genpoly[0] = 1;
2431
            
2432
            for ($i = 0, $root = $fcr * $prim; $i < $nroots; $i++, $root += $prim) {
2433
                $rs->genpoly[$i + 1] = 1;
2434
2435
                // Multiply rs->genpoly[] by  @**(root + x)
2436
                for ($j = $i; $j > 0; $j--) {
2437
                    if ($rs->genpoly[$j] != 0) {
2438
                        $rs->genpoly[$j] = $rs->genpoly[$j - 1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)];
2439
                    } else {
2440
                        $rs->genpoly[$j] = $rs->genpoly[$j - 1];
2441
                    }
2442
                }
2443
                // rs->genpoly[0] can never be zero
2444
                $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)];
2445
            }
2446
            
2447
            // convert rs->genpoly[] to index form for quicker encoding
2448
            for ($i = 0; $i <= $nroots; $i++) {
2449
                            $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]];
2450
            }
2451
2452
            return $rs;
2453
        }
2454
        
2455
        //----------------------------------------------------------------------
2456
        public function encode_rs_char($data, &$parity)
2457
        {
2458
            $MM       = & $this->mm;
0 ignored issues
show
The assignment to $MM is dead and can be removed.
Loading history...
2459
            $NN       = & $this->nn;
2460
            $ALPHA_TO = & $this->alpha_to;
2461
            $INDEX_OF = & $this->index_of;
2462
            $GENPOLY  = & $this->genpoly;
2463
            $NROOTS   = & $this->nroots;
2464
            $FCR      = & $this->fcr;
0 ignored issues
show
The assignment to $FCR is dead and can be removed.
Loading history...
2465
            $PRIM     = & $this->prim;
0 ignored issues
show
The assignment to $PRIM is dead and can be removed.
Loading history...
2466
            $IPRIM    = & $this->iprim;
0 ignored issues
show
The assignment to $IPRIM is dead and can be removed.
Loading history...
2467
            $PAD      = & $this->pad;
2468
            $A0       = & $NN;
2469
2470
            $parity = array_fill(0, $NROOTS, 0);
2471
2472
            for ($i = 0; $i < ($NN - $NROOTS - $PAD); $i++) {
2473
                
2474
                $feedback = $INDEX_OF[$data[$i] ^ $parity[0]];
2475
                if ($feedback != $A0) {      
2476
                    // feedback term is non-zero
2477
            
2478
                    // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
2479
                    // always be for the polynomials constructed by init_rs()
2480
                    $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback);
2481
            
2482
                    for ($j = 1; $j < $NROOTS; $j++) {
2483
                        $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS - $j])];
2484
                    }
2485
                }
2486
                
2487
                // Shift 
2488
                array_shift($parity);
2489
                if ($feedback != $A0) {
2490
                    array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]);
2491
                } else {
2492
                    array_push($parity, 0);
2493
                }
2494
            }
2495
        }
2496
    }
2497
    
2498
    //##########################################################################
2499
    
2500
    class QRrs {
2501
    
2502
        public static $items = array();
2503
        
2504
        //----------------------------------------------------------------------
2505
        public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
2506
        {
2507
            foreach (self::$items as $rs) {
2508
                if ($rs->pad != $pad) {
2509
                    continue;
2510
                }
2511
                if ($rs->nroots != $nroots) {
2512
                    continue;
2513
                }
2514
                if ($rs->mm != $symsize) {
2515
                    continue;
2516
                }
2517
                if ($rs->gfpoly != $gfpoly) {
2518
                    continue;
2519
                }
2520
                if ($rs->fcr != $fcr) {
2521
                    continue;
2522
                }
2523
                if ($rs->prim != $prim) {
2524
                    continue;
2525
                }
2526
2527
                return $rs;
2528
            }
2529
2530
            $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
2531
            array_unshift(self::$items, $rs);
2532
2533
            return $rs;
2534
        }
2535
    }
2536
2537
2538
2539
//---- qrmask.php -----------------------------
2540
2541
2542
2543
2544
/*
2545
 * PHP QR Code encoder
2546
 *
2547
 * Masking
2548
 *
2549
 * Based on libqrencode C library distributed under LGPL 2.1
2550
 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <[email protected]>
2551
 *
2552
 * PHP QR Code is distributed under LGPL 3
2553
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
2554
 *
2555
 * This library is free software; you can redistribute it and/or
2556
 * modify it under the terms of the GNU Lesser General Public
2557
 * License as published by the Free Software Foundation; either
2558
 * version 3 of the License, or any later version.
2559
 *
2560
 * This library is distributed in the hope that it will be useful,
2561
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2562
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2563
 * Lesser General Public License for more details.
2564
 *
2565
 * You should have received a copy of the GNU Lesser General Public
2566
 * License along with this library; if not, write to the Free Software
2567
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2568
 */
2569
 
2570
    define('N1', 3);
2571
    define('N2', 3);
2572
    define('N3', 40);
2573
    define('N4', 10);
2574
2575
    class QRmask {
2576
	
2577
        public $runLength = array();
2578
		
2579
        //----------------------------------------------------------------------
2580
        public function __construct() 
2581
        {
2582
            $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0);
2583
        }
2584
        
2585
        //----------------------------------------------------------------------
2586
        public function writeFormatInformation($width, &$frame, $mask, $level)
2587
        {
2588
            $blacks = 0;
2589
            $format = QRspec::getFormatInfo($mask, $level);
2590
2591
            for ($i = 0; $i < 8; $i++) {
2592
                if ($format & 1) {
2593
                    $blacks += 2;
2594
                    $v = 0x85;
2595
                } else {
2596
                    $v = 0x84;
2597
                }
2598
                
2599
                $frame[8][$width - 1 - $i] = chr($v);
2600
                if ($i < 6) {
2601
                    $frame[$i][8] = chr($v);
2602
                } else {
2603
                    $frame[$i + 1][8] = chr($v);
2604
                }
2605
                $format = $format >> 1;
2606
            }
2607
            
2608
            for ($i = 0; $i < 7; $i++) {
2609
                if ($format & 1) {
2610
                    $blacks += 2;
2611
                    $v = 0x85;
2612
                } else {
2613
                    $v = 0x84;
2614
                }
2615
                
2616
                $frame[$width - 7 + $i][8] = chr($v);
2617
                if ($i == 0) {
2618
                    $frame[8][7] = chr($v);
2619
                } else {
2620
                    $frame[8][6 - $i] = chr($v);
2621
                }
2622
                
2623
                $format = $format >> 1;
2624
            }
2625
2626
            return $blacks;
2627
        }
2628
        
2629
        //----------------------------------------------------------------------
2630
        public function mask0($x, $y) { return ($x + $y) & 1; }
2631
        public function mask1($x, $y) { return ($y & 1); }
2632
        public function mask2($x, $y) { return ($x % 3); }
2633
        public function mask3($x, $y) { return ($x + $y) % 3; }
2634
        public function mask4($x, $y) { return (((int) ($y / 2)) + ((int) ($x / 3))) & 1; }
2635
        public function mask5($x, $y) { return (($x * $y) & 1) + ($x * $y) % 3; }
2636
        public function mask6($x, $y) { return ((($x * $y) & 1) + ($x * $y) % 3) & 1; }
2637
        public function mask7($x, $y) { return ((($x * $y) % 3) + (($x + $y) & 1)) & 1; }
2638
        
2639
        //----------------------------------------------------------------------
2640
        private function generateMaskNo($maskNo, $width, $frame)
2641
        {
2642
            $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
2643
            
2644
            for ($y = 0; $y < $width; $y++) {
2645
                for ($x = 0; $x < $width; $x++) {
2646
                    if (ord($frame[$y][$x]) & 0x80) {
2647
                        $bitMask[$y][$x] = 0;
2648
                    } else {
2649
                        $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y);
2650
                        $bitMask[$y][$x] = ($maskFunc == 0) ? 1 : 0;
2651
                    }
2652
                    
2653
                }
2654
            }
2655
            
2656
            return $bitMask;
2657
        }
2658
        
2659
        //----------------------------------------------------------------------
2660
        public static function serial($bitFrame)
2661
        {
2662
            $codeArr = array();
2663
            
2664
            foreach ($bitFrame as $line) {
2665
                            $codeArr[] = join('', $line);
2666
            }
2667
                
2668
            return gzcompress(join("\n", $codeArr), 9);
2669
        }
2670
        
2671
        //----------------------------------------------------------------------
2672
        public static function unserial($code)
2673
        {
2674
            $codeArr = array();
2675
            
2676
            $codeLines = explode("\n", gzuncompress($code));
2677
            foreach ($codeLines as $line) {
2678
                            $codeArr[] = str_split($line);
2679
            }
2680
            
2681
            return $codeArr;
2682
        }
2683
        
2684
        //----------------------------------------------------------------------
2685
        public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false) 
2686
        {
2687
            $b = 0;
2688
            $bitMask = array();
2689
            
2690
            $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat';
2691
2692
            if (QR_CACHEABLE) {
2693
                if (file_exists($fileName)) {
2694
                    $bitMask = self::unserial(file_get_contents($fileName));
2695
                } else {
2696
                    $bitMask = $this->generateMaskNo($maskNo, $width, $s);
2697
                    if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo)) {
2698
                                            mkdir(QR_CACHE_DIR.'mask_'.$maskNo);
2699
                    }
2700
                    file_put_contents($fileName, self::serial($bitMask));
2701
                }
2702
            } else {
2703
                $bitMask = $this->generateMaskNo($maskNo, $width, $s);
2704
            }
2705
2706
            if ($maskGenOnly) {
2707
                            return;
2708
            }
2709
                
2710
            $d = $s;
2711
2712
            for ($y = 0; $y < $width; $y++) {
2713
                for ($x = 0; $x < $width; $x++) {
2714
                    if ($bitMask[$y][$x] == 1) {
2715
                        $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int) $bitMask[$y][$x]);
2716
                    }
2717
                    $b += (int) (ord($d[$y][$x]) & 1);
2718
                }
2719
            }
2720
2721
            return $b;
2722
        }
2723
        
2724
        //----------------------------------------------------------------------
2725
        public function makeMask($width, $frame, $maskNo, $level)
2726
        {
2727
            $masked = array_fill(0, $width, str_repeat("\0", $width));
2728
            $this->makeMaskNo($maskNo, $width, $frame, $masked);
2729
            $this->writeFormatInformation($width, $masked, $maskNo, $level);
2730
       
2731
            return $masked;
2732
        }
2733
        
2734
        //----------------------------------------------------------------------
2735
        public function calcN1N3($length)
2736
        {
2737
            $demerit = 0;
2738
2739
            for ($i = 0; $i < $length; $i++) {
2740
                
2741
                if ($this->runLength[$i] >= 5) {
2742
                    $demerit += (N1 + ($this->runLength[$i] - 5));
2743
                }
2744
                if ($i & 1) {
2745
                    if (($i >= 3) && ($i < ($length - 2)) && ($this->runLength[$i] % 3 == 0)) {
2746
                        $fact = (int) ($this->runLength[$i] / 3);
2747
                        if (($this->runLength[$i - 2] == $fact) &&
2748
                           ($this->runLength[$i - 1] == $fact) &&
2749
                           ($this->runLength[$i + 1] == $fact) &&
2750
                           ($this->runLength[$i + 2] == $fact)) {
2751
                            if (($this->runLength[$i - 3] < 0) || ($this->runLength[$i - 3] >= (4 * $fact))) {
2752
                                $demerit += N3;
2753
                            } else if ((($i + 3) >= $length) || ($this->runLength[$i + 3] >= (4 * $fact))) {
2754
                                $demerit += N3;
2755
                            }
2756
                        }
2757
                    }
2758
                }
2759
            }
2760
            return $demerit;
2761
        }
2762
        
2763
        //----------------------------------------------------------------------
2764
        public function evaluateSymbol($width, $frame)
2765
        {
2766
            $head = 0;
2767
            $demerit = 0;
2768
2769
            for ($y = 0; $y < $width; $y++) {
2770
                $head = 0;
2771
                $this->runLength[0] = 1;
2772
                
2773
                $frameY = $frame[$y];
2774
                
2775
                if ($y > 0) {
2776
                                    $frameYM = $frame[$y - 1];
2777
                }
2778
                
2779
                for ($x = 0; $x < $width; $x++) {
2780
                    if (($x > 0) && ($y > 0)) {
2781
                        $b22 = ord($frameY[$x]) & ord($frameY[$x - 1]) & ord($frameYM[$x]) & ord($frameYM[$x - 1]);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $frameYM does not seem to be defined for all execution paths leading up to this point.
Loading history...
2782
                        $w22 = ord($frameY[$x]) | ord($frameY[$x - 1]) | ord($frameYM[$x]) | ord($frameYM[$x - 1]);
2783
                        
2784
                        if (($b22 | ($w22 ^ 1)) & 1) {                                                                     
2785
                            $demerit += N2;
2786
                        }
2787
                    }
2788
                    if (($x == 0) && (ord($frameY[$x]) & 1)) {
2789
                        $this->runLength[0] = -1;
2790
                        $head = 1;
2791
                        $this->runLength[$head] = 1;
2792
                    } else if ($x > 0) {
2793
                        if ((ord($frameY[$x]) ^ ord($frameY[$x - 1])) & 1) {
2794
                            $head++;
2795
                            $this->runLength[$head] = 1;
2796
                        } else {
2797
                            $this->runLength[$head]++;
2798
                        }
2799
                    }
2800
                }
2801
    
2802
                $demerit += $this->calcN1N3($head + 1);
2803
            }
2804
2805
            for ($x = 0; $x < $width; $x++) {
2806
                $head = 0;
2807
                $this->runLength[0] = 1;
2808
                
2809
                for ($y = 0; $y < $width; $y++) {
2810
                    if ($y == 0 && (ord($frame[$y][$x]) & 1)) {
2811
                        $this->runLength[0] = -1;
2812
                        $head = 1;
2813
                        $this->runLength[$head] = 1;
2814
                    } else if ($y > 0) {
2815
                        if ((ord($frame[$y][$x]) ^ ord($frame[$y - 1][$x])) & 1) {
2816
                            $head++;
2817
                            $this->runLength[$head] = 1;
2818
                        } else {
2819
                            $this->runLength[$head]++;
2820
                        }
2821
                    }
2822
                }
2823
            
2824
                $demerit += $this->calcN1N3($head + 1);
2825
            }
2826
2827
            return $demerit;
2828
        }
2829
        
2830
        
2831
        //----------------------------------------------------------------------
2832
        public function mask($width, $frame, $level)
2833
        {
2834
            $minDemerit = PHP_INT_MAX;
2835
            $bestMaskNum = 0;
0 ignored issues
show
The assignment to $bestMaskNum is dead and can be removed.
Loading history...
2836
            $bestMask = array();
0 ignored issues
show
The assignment to $bestMask is dead and can be removed.
Loading history...
2837
            
2838
            $checked_masks = array(0, 1, 2, 3, 4, 5, 6, 7);
2839
            
2840
            if (QR_FIND_FROM_RANDOM !== false) {
0 ignored issues
show
The condition QR_FIND_FROM_RANDOM !== false is always false.
Loading history...
2841
            
2842
                $howManuOut = 8 - (QR_FIND_FROM_RANDOM % 9);
2843
                for ($i = 0; $i < $howManuOut; $i++) {
2844
                    $remPos = rand(0, count($checked_masks) - 1);
2845
                    unset($checked_masks[$remPos]);
2846
                    $checked_masks = array_values($checked_masks);
2847
                }
2848
            
2849
            }
2850
            
2851
            $bestMask = $frame;
2852
             
2853
            foreach ($checked_masks as $i) {
2854
                $mask = array_fill(0, $width, str_repeat("\0", $width));
2855
2856
                $demerit = 0;
0 ignored issues
show
The assignment to $demerit is dead and can be removed.
Loading history...
2857
                $blacks = 0;
0 ignored issues
show
The assignment to $blacks is dead and can be removed.
Loading history...
2858
                $blacks  = $this->makeMaskNo($i, $width, $frame, $mask);
2859
                $blacks += $this->writeFormatInformation($width, $mask, $i, $level);
2860
                $blacks  = (int) (100 * $blacks / ($width * $width));
2861
                $demerit = (int) ((int) (abs($blacks - 50) / 5) * N4);
2862
                $demerit += $this->evaluateSymbol($width, $mask);
2863
                
2864
                if ($demerit < $minDemerit) {
2865
                    $minDemerit = $demerit;
2866
                    $bestMask = $mask;
2867
                    $bestMaskNum = $i;
2868
                }
2869
            }
2870
            
2871
            return $bestMask;
2872
        }
2873
        
2874
        //----------------------------------------------------------------------
2875
    }
2876
2877
2878
2879
2880
//---- qrencode.php -----------------------------
2881
2882
2883
2884
2885
/*
2886
 * PHP QR Code encoder
2887
 *
2888
 * Main encoder classes.
2889
 *
2890
 * Based on libqrencode C library distributed under LGPL 2.1
2891
 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <[email protected]>
2892
 *
2893
 * PHP QR Code is distributed under LGPL 3
2894
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
2895
 *
2896
 * This library is free software; you can redistribute it and/or
2897
 * modify it under the terms of the GNU Lesser General Public
2898
 * License as published by the Free Software Foundation; either
2899
 * version 3 of the License, or any later version.
2900
 *
2901
 * This library is distributed in the hope that it will be useful,
2902
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2903
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2904
 * Lesser General Public License for more details.
2905
 *
2906
 * You should have received a copy of the GNU Lesser General Public
2907
 * License along with this library; if not, write to the Free Software
2908
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2909
 */
2910
 
2911
    class QRrsblock {
2912
        public $dataLength;
2913
        public $data = array();
2914
        public $eccLength;
2915
        public $ecc = array();
2916
        
2917
        public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs)
2918
        {
2919
            $rs->encode_rs_char($data, $ecc);
2920
        
2921
            $this->dataLength = $dl;
2922
            $this->data = $data;
2923
            $this->eccLength = $el;
2924
            $this->ecc = $ecc;
2925
        }
2926
    };
2927
    
2928
    //##########################################################################
2929
2930
    class QRrawcode {
2931
        public $version;
2932
        public $datacode = array();
2933
        public $ecccode = array();
2934
        public $blocks;
2935
        public $rsblocks = array(); //of RSblock
2936
        public $count;
2937
        public $dataLength;
2938
        public $eccLength;
2939
        public $b1;
2940
        
2941
        //----------------------------------------------------------------------
2942
        public function __construct(QRinput $input)
2943
        {
2944
            $spec = array(0, 0, 0, 0, 0);
2945
            
2946
            $this->datacode = $input->getByteStream();
0 ignored issues
show
Are you sure the assignment to $this->datacode is correct as $input->getByteStream() targeting QRinput::getByteStream() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
2947
            if (is_null($this->datacode)) {
0 ignored issues
show
The condition is_null($this->datacode) is always true.
Loading history...
2948
                throw new Exception('null imput string');
2949
            }
2950
2951
            QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);
2952
2953
            $this->version = $input->getVersion();
2954
            $this->b1 = QRspec::rsBlockNum1($spec);
2955
            $this->dataLength = QRspec::rsDataLength($spec);
2956
            $this->eccLength = QRspec::rsEccLength($spec);
2957
            $this->ecccode = array_fill(0, $this->eccLength, 0);
2958
            $this->blocks = QRspec::rsBlockNum($spec);
2959
            
2960
            $ret = $this->init($spec);
2961
            if ($ret < 0) {
2962
                throw new Exception('block alloc error');
2963
                return null;
0 ignored issues
show
return null is not reachable.

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

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

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

    return false;
}

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

Loading history...
2964
            }
2965
2966
            $this->count = 0;
2967
        }
2968
        
2969
        //----------------------------------------------------------------------
2970
        public function init(array $spec)
2971
        {
2972
            $dl = QRspec::rsDataCodes1($spec);
2973
            $el = QRspec::rsEccCodes1($spec);
2974
            $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
2975
            
2976
2977
            $blockNo = 0;
2978
            $dataPos = 0;
2979
            $eccPos = 0;
2980
            for ($i = 0; $i < QRspec::rsBlockNum1($spec); $i++) {
2981
                $ecc = array_slice($this->ecccode, $eccPos);
2982
                $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
0 ignored issues
show
It seems like $rs can also be of type null; however, parameter $rs of QRrsblock::__construct() does only seem to accept QRrsItem, 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

2982
                $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, /** @scrutinizer ignore-type */ $rs);
Loading history...
2983
                $this->ecccode = array_merge(array_slice($this->ecccode, 0, $eccPos), $ecc);
2984
                
2985
                $dataPos += $dl;
2986
                $eccPos += $el;
2987
                $blockNo++;
2988
            }
2989
2990
            if (QRspec::rsBlockNum2($spec) == 0) {
2991
                            return 0;
2992
            }
2993
2994
            $dl = QRspec::rsDataCodes2($spec);
2995
            $el = QRspec::rsEccCodes2($spec);
2996
            $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
2997
            
2998
            if ($rs == null) {
2999
                return -1;
3000
            }
3001
            
3002
            for ($i = 0; $i < QRspec::rsBlockNum2($spec); $i++) {
3003
                $ecc = array_slice($this->ecccode, $eccPos);
3004
                $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);
3005
                $this->ecccode = array_merge(array_slice($this->ecccode, 0, $eccPos), $ecc);
3006
                
3007
                $dataPos += $dl;
3008
                $eccPos += $el;
3009
                $blockNo++;
3010
            }
3011
3012
            return 0;
3013
        }
3014
        
3015
        //----------------------------------------------------------------------
3016
        public function getCode()
3017
        {
3018
            $ret = 0;
3019
3020
            if ($this->count < $this->dataLength) {
3021
                $row = $this->count % $this->blocks;
3022
                $col = $this->count / $this->blocks;
3023
                if ($col >= $this->rsblocks[0]->dataLength) {
3024
                    $row += $this->b1;
3025
                }
3026
                $ret = $this->rsblocks[$row]->data[$col];
3027
            } else if ($this->count < $this->dataLength + $this->eccLength) {
3028
                $row = ($this->count - $this->dataLength) % $this->blocks;
3029
                $col = ($this->count - $this->dataLength) / $this->blocks;
3030
                $ret = $this->rsblocks[$row]->ecc[$col];
3031
            } else {
3032
                return 0;
3033
            }
3034
            $this->count++;
3035
            
3036
            return $ret;
3037
        }
3038
    }
3039
3040
    //##########################################################################
3041
    
3042
    class QRcode {
3043
    
3044
        public $version;
3045
        public $width;
3046
        public $data; 
3047
        
3048
        //----------------------------------------------------------------------
3049
        public function encodeMask(QRinput $input, $mask)
3050
        {
3051
            if ($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) {
3052
                throw new Exception('wrong version');
3053
            }
3054
            if ($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) {
3055
                throw new Exception('wrong level');
3056
            }
3057
3058
            $raw = new QRrawcode($input);
3059
            
3060
            QRtools::markTime('after_raw');
3061
            
3062
            $version = $raw->version;
3063
            $width = QRspec::getWidth($version);
3064
            $frame = QRspec::newFrame($version);
3065
            
3066
            $filler = new FrameFiller($width, $frame);
3067
            if (is_null($filler)) {
3068
                return null;
3069
            }
3070
3071
            // inteleaved data and ecc codes
3072
            for ($i = 0; $i < $raw->dataLength + $raw->eccLength; $i++) {
3073
                $code = $raw->getCode();
3074
                $bit = 0x80;
3075
                for ($j = 0; $j < 8; $j++) {
3076
                    $addr = $filler->next();
3077
                    $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));
3078
                    $bit = $bit >> 1;
3079
                }
3080
            }
3081
            
3082
            QRtools::markTime('after_filler');
3083
            
3084
            unset($raw);
3085
            
3086
            // remainder bits
3087
            $j = QRspec::getRemainder($version);
3088
            for ($i = 0; $i < $j; $i++) {
3089
                $addr = $filler->next();
3090
                $filler->setFrameAt($addr, 0x02);
3091
            }
3092
            
3093
            $frame = $filler->frame;
3094
            unset($filler);
3095
            
3096
            
3097
            // masking
3098
            $maskObj = new QRmask();
3099
            if ($mask < 0) {
3100
            
3101
                if (QR_FIND_BEST_MASK) {
3102
                    $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());
3103
                } else {
3104
                    $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel());
3105
                }
3106
            } else {
3107
                $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());
3108
            }
3109
            
3110
            if ($masked == null) {
3111
                return null;
3112
            }
3113
            
3114
            QRtools::markTime('after_mask');
3115
            
3116
            $this->version = $version;
3117
            $this->width = $width;
3118
            $this->data = $masked;
3119
            
3120
            return $this;
3121
        }
3122
    
3123
        //----------------------------------------------------------------------
3124
        public function encodeInput(QRinput $input)
3125
        {
3126
            return $this->encodeMask($input, -1);
3127
        }
3128
        
3129
        //----------------------------------------------------------------------
3130
        public function encodeString8bit($string, $version, $level)
3131
        {
3132
            if (string == null) {
0 ignored issues
show
The constant string was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
3133
                throw new Exception('empty string!');
3134
                return null;
0 ignored issues
show
return null is not reachable.

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

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

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

    return false;
}

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

Loading history...
3135
            }
3136
3137
            $input = new QRinput($version, $level);
3138
            if ($input == null) {
3139
                return null;
3140
            }
3141
3142
            $ret = $input->append(QR_MODE_8, strlen($string), str_split($string));
3143
            if ($ret < 0) {
3144
                unset($input);
3145
                return null;
3146
            }
3147
            return $this->encodeInput($input);
3148
        }
3149
3150
        //----------------------------------------------------------------------
3151
        public function encodeString($string, $version, $level, $hint, $casesensitive)
3152
        {
3153
3154
            if ($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) {
3155
                throw new Exception('bad hint');
3156
                return null;
0 ignored issues
show
return null is not reachable.

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

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

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

    return false;
}

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

Loading history...
3157
            }
3158
3159
            $input = new QRinput($version, $level);
3160
            if ($input == null) {
3161
                return null;
3162
            }
3163
3164
            $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive);
3165
            if ($ret < 0) {
3166
                return null;
3167
            }
3168
3169
            return $this->encodeInput($input);
3170
        }
3171
        
3172
        //----------------------------------------------------------------------
3173
        public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint = false) 
0 ignored issues
show
The parameter $saveandprint is not used and could be removed. ( Ignorable by Annotation )

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

3173
        public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, /** @scrutinizer ignore-unused */ $saveandprint = false) 

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3174
        {
3175
            $enc = QRencode::factory($level, $size, $margin);
3176
            return $enc->encodePNG($text, $outfile, $saveandprint = false);
0 ignored issues
show
Are you sure the usage of $enc->encodePNG($text, $... $saveandprint = false) targeting QRencode::encodePNG() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
3177
        }
3178
3179
        //----------------------------------------------------------------------
3180
        public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) 
3181
        {
3182
            $enc = QRencode::factory($level, $size, $margin);
3183
            return $enc->encode($text, $outfile);
3184
        }
3185
3186
        //----------------------------------------------------------------------
3187
        public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) 
3188
        {
3189
            $enc = QRencode::factory($level, $size, $margin);
3190
            return $enc->encodeRAW($text, $outfile);
3191
        }
3192
    }
3193
    
3194
    //##########################################################################
3195
    
3196
    class FrameFiller {
3197
    
3198
        public $width;
3199
        public $frame;
3200
        public $x;
3201
        public $y;
3202
        public $dir;
3203
        public $bit;
3204
        
3205
        //----------------------------------------------------------------------
3206
        public function __construct($width, &$frame)
3207
        {
3208
            $this->width = $width;
3209
            $this->frame = $frame;
3210
            $this->x = $width - 1;
3211
            $this->y = $width - 1;
3212
            $this->dir = -1;
3213
            $this->bit = -1;
3214
        }
3215
        
3216
        //----------------------------------------------------------------------
3217
        public function setFrameAt($at, $val)
3218
        {
3219
            $this->frame[$at['y']][$at['x']] = chr($val);
3220
        }
3221
        
3222
        //----------------------------------------------------------------------
3223
        public function getFrameAt($at)
3224
        {
3225
            return ord($this->frame[$at['y']][$at['x']]);
3226
        }
3227
        
3228
        //----------------------------------------------------------------------
3229
        public function next()
3230
        {
3231
            do {
3232
            
3233
                if ($this->bit == -1) {
3234
                    $this->bit = 0;
3235
                    return array('x'=>$this->x, 'y'=>$this->y);
3236
                }
3237
3238
                $x = $this->x;
3239
                $y = $this->y;
3240
                $w = $this->width;
3241
3242
                if ($this->bit == 0) {
3243
                    $x--;
3244
                    $this->bit++;
3245
                } else {
3246
                    $x++;
3247
                    $y += $this->dir;
3248
                    $this->bit--;
3249
                }
3250
3251
                if ($this->dir < 0) {
3252
                    if ($y < 0) {
3253
                        $y = 0;
3254
                        $x -= 2;
3255
                        $this->dir = 1;
3256
                        if ($x == 6) {
3257
                            $x--;
3258
                            $y = 9;
3259
                        }
3260
                    }
3261
                } else {
3262
                    if ($y == $w) {
3263
                        $y = $w - 1;
3264
                        $x -= 2;
3265
                        $this->dir = -1;
3266
                        if ($x == 6) {
3267
                            $x--;
3268
                            $y -= 8;
3269
                        }
3270
                    }
3271
                }
3272
                if ($x < 0 || $y < 0) {
3273
                    return null;
3274
                }
3275
3276
                $this->x = $x;
3277
                $this->y = $y;
3278
3279
            } while (ord($this->frame[$y][$x]) & 0x80);
3280
                        
3281
            return array('x'=>$x, 'y'=>$y);
3282
        }
3283
        
3284
    } ;
3285
    
3286
    //##########################################################################    
3287
    
3288
    class QRencode {
3289
    
3290
        public $casesensitive = true;
3291
        public $eightbit = false;
3292
        
3293
        public $version = 0;
3294
        public $size = 3;
3295
        public $margin = 4;
3296
        
3297
        public $structured = 0; // not supported yet
3298
        
3299
        public $level = QR_ECLEVEL_L;
3300
        public $hint = QR_MODE_8;
3301
        
3302
        //----------------------------------------------------------------------
3303
        public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4)
3304
        {
3305
            $enc = new QRencode();
3306
            $enc->size = $size;
3307
            $enc->margin = $margin;
3308
            
3309
            switch ($level.'') {
3310
            case '0':
3311
            case '1':
3312
            case '2':
3313
            case '3':
3314
                    $enc->level = $level;
3315
                break;
3316
            case 'l':
3317
            case 'L':
3318
                    $enc->level = QR_ECLEVEL_L;
3319
                break;
3320
            case 'm':
3321
            case 'M':
3322
                    $enc->level = QR_ECLEVEL_M;
3323
                break;
3324
            case 'q':
3325
            case 'Q':
3326
                    $enc->level = QR_ECLEVEL_Q;
3327
                break;
3328
            case 'h':
3329
            case 'H':
3330
                    $enc->level = QR_ECLEVEL_H;
3331
                break;
3332
            }
3333
            
3334
            return $enc;
3335
        }
3336
        
3337
        //----------------------------------------------------------------------
3338
        public function encodeRAW($intext, $outfile = false) 
0 ignored issues
show
The parameter $outfile is not used and could be removed. ( Ignorable by Annotation )

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

3338
        public function encodeRAW($intext, /** @scrutinizer ignore-unused */ $outfile = false) 

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
3339
        {
3340
            $code = new QRcode();
3341
3342
            if ($this->eightbit) {
3343
                $code->encodeString8bit($intext, $this->version, $this->level);
3344
            } else {
3345
                $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
3346
            }
3347
            
3348
            return $code->data;
3349
        }
3350
3351
        //----------------------------------------------------------------------
3352
        public function encode($intext, $outfile = false) 
3353
        {
3354
            $code = new QRcode();
3355
3356
            if ($this->eightbit) {
3357
                $code->encodeString8bit($intext, $this->version, $this->level);
3358
            } else {
3359
                $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
3360
            }
3361
            
3362
            QRtools::markTime('after_encode');
3363
            
3364
            if ($outfile !== false) {
3365
                file_put_contents($outfile, join("\n", QRtools::binarize($code->data)));
3366
            } else {
3367
                return QRtools::binarize($code->data);
3368
            }
3369
        }
3370
        
3371
        //----------------------------------------------------------------------
3372
        public function encodePNG($intext, $outfile = false, $saveandprint = false) 
3373
        {
3374
            try {
3375
            
3376
                ob_start();
3377
                $tab = $this->encode($intext);
3378
                $err = ob_get_contents();
3379
                ob_end_clean();
3380
                
3381
                if ($err != '') {
3382
                                    QRtools::log($outfile, $err);
3383
                }
3384
                
3385
                $maxSize = (int) (QR_PNG_MAXIMUM_SIZE / (count($tab) + 2 * $this->margin));
3386
                
3387
                QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin, $saveandprint);
3388
            
3389
            } catch (Exception $e) {
3390
            
3391
                QRtools::log($outfile, $e->getMessage());
3392
            
3393
            }
3394
        }
3395
    }
3396
3397
3398