6 * This file contains MERGED version of PHP QR Code library.
7 * It was auto-generated from full version for your convenience.
9 * This merged version was configured to not require any external files,
10 * with disabled cache, error logging and weaker but faster mask matching.
11 * If you need tune it up please use non-merged version.
13 * For full version, documentation, examples of use please visit:
15 * http://phpqrcode.sourceforge.net/
16 * https://sourceforge.net/projects/phpqrcode/
17 * https://github.com/t0k4rt/phpqrcode
19 * PHP QR Code is distributed under LGPL 3
20 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
22 * This library is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU Lesser General Public
24 * License as published by the Free Software Foundation; either
25 * version 3 of the License, or any later version.
27 * This library is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30 * Lesser General Public License for more details.
32 * You should have received a copy of the GNU Lesser General Public
33 * License along with this library; if not, write to the Free Software
34 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
46 //---- qrconst.php -----------------------------
57 * Based on libqrencode C library distributed under LGPL 2.1
58 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
60 * PHP QR Code is distributed under LGPL 3
61 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
63 * This library is free software; you can redistribute it and/or
64 * modify it under the terms of the GNU Lesser General Public
65 * License as published by the Free Software Foundation; either
66 * version 3 of the License, or any later version.
68 * This library is distributed in the hope that it will be useful,
69 * but WITHOUT ANY WARRANTY; without even the implied warranty of
70 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
71 * Lesser General Public License for more details.
73 * You should have received a copy of the GNU Lesser General Public
74 * License along with this library; if not, write to the Free Software
75 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
80 define('QR_MODE_NUL', -1);
81 define('QR_MODE_NUM', 0);
82 define('QR_MODE_AN', 1);
83 define('QR_MODE_8', 2);
84 define('QR_MODE_KANJI', 3);
85 define('QR_MODE_STRUCTURE', 4);
87 // Levels of error correction.
89 define('QR_ECLEVEL_L', 0);
90 define('QR_ECLEVEL_M', 1);
91 define('QR_ECLEVEL_Q', 2);
92 define('QR_ECLEVEL_H', 3);
94 // Supported output formats
96 define('QR_FORMAT_TEXT', 0);
97 define('QR_FORMAT_PNG', 1);
100 public static function set(&$srctab, $x, $y, $repl, $replLen = false) {
101 $srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl));
107 //---- merged_config.php -----------------------------
113 * PHP QR Code encoder
115 * Config file, tuned-up for merged verion
118 define('QR_CACHEABLE', false); // use cache - more disk reads but less CPU power, masks and format templates are stored there
119 define('QR_CACHE_DIR', false); // used when QR_CACHEABLE === true
120 define('QR_LOG_DIR', false); // default error logs dir
122 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
123 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
124 define('QR_DEFAULT_MASK', 2); // when QR_FIND_BEST_MASK === false
126 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
131 //---- qrtools.php -----------------------------
137 * PHP QR Code encoder
139 * Toolset, handy and debug utilites.
141 * PHP QR Code is distributed under LGPL 3
142 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
144 * This library is free software; you can redistribute it and/or
145 * modify it under the terms of the GNU Lesser General Public
146 * License as published by the Free Software Foundation; either
147 * version 3 of the License, or any later version.
149 * This library is distributed in the hope that it will be useful,
150 * but WITHOUT ANY WARRANTY; without even the implied warranty of
151 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
152 * Lesser General Public License for more details.
154 * You should have received a copy of the GNU Lesser General Public
155 * License along with this library; if not, write to the Free Software
156 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
161 //----------------------------------------------------------------------
162 public static function binarize($frame)
164 $len = count($frame);
165 foreach ($frame as &$frameLine) {
167 for($i=0; $i<$len; $i++
) {
168 $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0';
175 //----------------------------------------------------------------------
176 public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037')
178 $barcode_array = array();
180 if (!is_array($mode))
181 $mode = explode(',', $mode);
185 if (count($mode) > 1) {
186 $eccLevel = $mode[1];
189 $qrTab = QRcode
::text($code, false, $eccLevel);
190 $size = count($qrTab);
192 $barcode_array['num_rows'] = $size;
193 $barcode_array['num_cols'] = $size;
194 $barcode_array['bcode'] = array();
196 foreach ($qrTab as $line) {
198 foreach(str_split($line) as $char)
199 $arrAdd[] = ($char=='1')?1:0;
200 $barcode_array['bcode'][] = $arrAdd;
203 return $barcode_array;
206 //----------------------------------------------------------------------
207 public static function clearCache()
209 self
::$frames = array();
212 //----------------------------------------------------------------------
213 public static function buildCache()
215 QRtools
::markTime('before_build_cache');
217 $mask = new QRmask();
218 for ($a=1; $a <= QRSPEC_VERSION_MAX
; $a++
) {
219 $frame = QRspec
::newFrame($a);
221 $fileName = QR_CACHE_DIR
.'frame_'.$a.'.png';
222 QRimage
::png(self
::binarize($frame), $fileName, 1, 0);
225 $width = count($frame);
226 $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
227 for ($maskNo=0; $maskNo<8; $maskNo++
)
228 $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true);
231 QRtools
::markTime('after_build_cache');
234 //----------------------------------------------------------------------
235 public static function log($outfile, $err)
237 if (QR_LOG_DIR
!== false) {
239 if ($outfile !== false) {
240 file_put_contents(QR_LOG_DIR
.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND
);
242 file_put_contents(QR_LOG_DIR
.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND
);
248 //----------------------------------------------------------------------
249 public static function dumpMask($frame)
251 $width = count($frame);
252 for($y=0;$y<$width;$y++
) {
253 for($x=0;$x<$width;$x++
) {
254 echo ord($frame[$y][$x]).',';
259 //----------------------------------------------------------------------
260 public static function markTime($markerId)
262 list($usec, $sec) = explode(" ", microtime());
263 $time = ((float)$usec +
(float)$sec);
265 if (!isset($GLOBALS['qr_time_bench']))
266 $GLOBALS['qr_time_bench'] = array();
268 $GLOBALS['qr_time_bench'][$markerId] = $time;
271 //----------------------------------------------------------------------
272 public static function timeBenchmark()
274 self
::markTime('finish');
280 echo '<table cellpadding="3" cellspacing="1">
281 <thead><tr style="border-bottom:1px solid silver"><td colspan="2" style="text-align:center">BENCHMARK</td></tr></thead>
284 foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) {
286 echo '<tr><th style="text-align:right">till '.$markerId.': </th><td>'.number_format($thisTime-$lastTime, 6).'s</td></tr>';
288 $startTime = $thisTime;
292 $lastTime = $thisTime;
295 echo '</tbody><tfoot>
296 <tr style="border-top:2px solid black"><th style="text-align:right">TOTAL: </th><td>'.number_format($lastTime-$startTime, 6).'s</td></tr>
301 public static function save($content, $filename_path)
304 $handle = fopen($filename_path, "w");
305 fwrite($handle, $content);
308 } catch (Exception
$e) {
309 echo 'Exception reƧue : ', $e->getMessage(), "\n";
316 //##########################################################################
318 QRtools
::markTime('start');
323 //---- qrspec.php -----------------------------
329 * PHP QR Code encoder
331 * QR Code specifications
333 * Based on libqrencode C library distributed under LGPL 2.1
334 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
336 * PHP QR Code is distributed under LGPL 3
337 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
339 * The following data / specifications are taken from
340 * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
342 * "Automatic identification and data capture techniques --
343 * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
345 * This library is free software; you can redistribute it and/or
346 * modify it under the terms of the GNU Lesser General Public
347 * License as published by the Free Software Foundation; either
348 * version 3 of the License, or any later version.
350 * This library is distributed in the hope that it will be useful,
351 * but WITHOUT ANY WARRANTY; without even the implied warranty of
352 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
353 * Lesser General Public License for more details.
355 * You should have received a copy of the GNU Lesser General Public
356 * License along with this library; if not, write to the Free Software
357 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
360 define('QRSPEC_VERSION_MAX', 40);
361 define('QRSPEC_WIDTH_MAX', 177);
363 define('QRCAP_WIDTH', 0);
364 define('QRCAP_WORDS', 1);
365 define('QRCAP_REMINDER', 2);
366 define('QRCAP_EC', 3);
370 public static $capacity = array(
371 array( 0, 0, 0, array( 0, 0, 0, 0)),
372 array( 21, 26, 0, array( 7, 10, 13, 17)), // 1
373 array( 25, 44, 7, array( 10, 16, 22, 28)),
374 array( 29, 70, 7, array( 15, 26, 36, 44)),
375 array( 33, 100, 7, array( 20, 36, 52, 64)),
376 array( 37, 134, 7, array( 26, 48, 72, 88)), // 5
377 array( 41, 172, 7, array( 36, 64, 96, 112)),
378 array( 45, 196, 0, array( 40, 72, 108, 130)),
379 array( 49, 242, 0, array( 48, 88, 132, 156)),
380 array( 53, 292, 0, array( 60, 110, 160, 192)),
381 array( 57, 346, 0, array( 72, 130, 192, 224)), //10
382 array( 61, 404, 0, array( 80, 150, 224, 264)),
383 array( 65, 466, 0, array( 96, 176, 260, 308)),
384 array( 69, 532, 0, array( 104, 198, 288, 352)),
385 array( 73, 581, 3, array( 120, 216, 320, 384)),
386 array( 77, 655, 3, array( 132, 240, 360, 432)), //15
387 array( 81, 733, 3, array( 144, 280, 408, 480)),
388 array( 85, 815, 3, array( 168, 308, 448, 532)),
389 array( 89, 901, 3, array( 180, 338, 504, 588)),
390 array( 93, 991, 3, array( 196, 364, 546, 650)),
391 array( 97, 1085, 3, array( 224, 416, 600, 700)), //20
392 array(101, 1156, 4, array( 224, 442, 644, 750)),
393 array(105, 1258, 4, array( 252, 476, 690, 816)),
394 array(109, 1364, 4, array( 270, 504, 750, 900)),
395 array(113, 1474, 4, array( 300, 560, 810, 960)),
396 array(117, 1588, 4, array( 312, 588, 870, 1050)), //25
397 array(121, 1706, 4, array( 336, 644, 952, 1110)),
398 array(125, 1828, 4, array( 360, 700, 1020, 1200)),
399 array(129, 1921, 3, array( 390, 728, 1050, 1260)),
400 array(133, 2051, 3, array( 420, 784, 1140, 1350)),
401 array(137, 2185, 3, array( 450, 812, 1200, 1440)), //30
402 array(141, 2323, 3, array( 480, 868, 1290, 1530)),
403 array(145, 2465, 3, array( 510, 924, 1350, 1620)),
404 array(149, 2611, 3, array( 540, 980, 1440, 1710)),
405 array(153, 2761, 3, array( 570, 1036, 1530, 1800)),
406 array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35
407 array(161, 3034, 0, array( 600, 1120, 1680, 1980)),
408 array(165, 3196, 0, array( 630, 1204, 1770, 2100)),
409 array(169, 3362, 0, array( 660, 1260, 1860, 2220)),
410 array(173, 3532, 0, array( 720, 1316, 1950, 2310)),
411 array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40
414 //----------------------------------------------------------------------
415 public static function getDataLength($version, $level)
417 return self
::$capacity[$version][QRCAP_WORDS
] - self
::$capacity[$version][QRCAP_EC
][$level];
420 //----------------------------------------------------------------------
421 public static function getECCLength($version, $level)
423 return self
::$capacity[$version][QRCAP_EC
][$level];
426 //----------------------------------------------------------------------
427 public static function getWidth($version)
429 return self
::$capacity[$version][QRCAP_WIDTH
];
432 //----------------------------------------------------------------------
433 public static function getRemainder($version)
435 return self
::$capacity[$version][QRCAP_REMINDER
];
438 //----------------------------------------------------------------------
439 public static function getMinimumVersion($size, $level)
442 for($i=1; $i<= QRSPEC_VERSION_MAX
; $i++
) {
443 $words = self
::$capacity[$i][QRCAP_WORDS
] - self
::$capacity[$i][QRCAP_EC
][$level];
451 //######################################################################
453 public static $lengthTableBits = array(
460 //----------------------------------------------------------------------
461 public static function lengthIndicator($mode, $version)
463 if ($mode == QR_MODE_STRUCTURE
)
468 } else if ($version <= 26) {
474 return self
::$lengthTableBits[$mode][$l];
477 //----------------------------------------------------------------------
478 public static function maximumWords($mode, $version)
480 if($mode == QR_MODE_STRUCTURE
)
485 } else if($version <= 26) {
491 $bits = self
::$lengthTableBits[$mode][$l];
492 $words = (1 << $bits) - 1;
494 if($mode == QR_MODE_KANJI
) {
495 $words *= 2; // the number of bytes is required
501 // Error correction code -----------------------------------------------
502 // Table of the error correction code (Reed-Solomon block)
503 // See Table 12-16 (pp.30-36), JIS X0510:2004.
505 public static $eccTable = array(
506 array(array( 0, 0), array( 0, 0), array( 0, 0), array( 0, 0)),
507 array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)), // 1
508 array(array( 1, 0), array( 1, 0), array( 1, 0), array( 1, 0)),
509 array(array( 1, 0), array( 1, 0), array( 2, 0), array( 2, 0)),
510 array(array( 1, 0), array( 2, 0), array( 2, 0), array( 4, 0)),
511 array(array( 1, 0), array( 2, 0), array( 2, 2), array( 2, 2)), // 5
512 array(array( 2, 0), array( 4, 0), array( 4, 0), array( 4, 0)),
513 array(array( 2, 0), array( 4, 0), array( 2, 4), array( 4, 1)),
514 array(array( 2, 0), array( 2, 2), array( 4, 2), array( 4, 2)),
515 array(array( 2, 0), array( 3, 2), array( 4, 4), array( 4, 4)),
516 array(array( 2, 2), array( 4, 1), array( 6, 2), array( 6, 2)), //10
517 array(array( 4, 0), array( 1, 4), array( 4, 4), array( 3, 8)),
518 array(array( 2, 2), array( 6, 2), array( 4, 6), array( 7, 4)),
519 array(array( 4, 0), array( 8, 1), array( 8, 4), array(12, 4)),
520 array(array( 3, 1), array( 4, 5), array(11, 5), array(11, 5)),
521 array(array( 5, 1), array( 5, 5), array( 5, 7), array(11, 7)), //15
522 array(array( 5, 1), array( 7, 3), array(15, 2), array( 3, 13)),
523 array(array( 1, 5), array(10, 1), array( 1, 15), array( 2, 17)),
524 array(array( 5, 1), array( 9, 4), array(17, 1), array( 2, 19)),
525 array(array( 3, 4), array( 3, 11), array(17, 4), array( 9, 16)),
526 array(array( 3, 5), array( 3, 13), array(15, 5), array(15, 10)), //20
527 array(array( 4, 4), array(17, 0), array(17, 6), array(19, 6)),
528 array(array( 2, 7), array(17, 0), array( 7, 16), array(34, 0)),
529 array(array( 4, 5), array( 4, 14), array(11, 14), array(16, 14)),
530 array(array( 6, 4), array( 6, 14), array(11, 16), array(30, 2)),
531 array(array( 8, 4), array( 8, 13), array( 7, 22), array(22, 13)), //25
532 array(array(10, 2), array(19, 4), array(28, 6), array(33, 4)),
533 array(array( 8, 4), array(22, 3), array( 8, 26), array(12, 28)),
534 array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)),
535 array(array( 7, 7), array(21, 7), array( 1, 37), array(19, 26)),
536 array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30
537 array(array(13, 3), array( 2, 29), array(42, 1), array(23, 28)),
538 array(array(17, 0), array(10, 23), array(10, 35), array(19, 35)),
539 array(array(17, 1), array(14, 21), array(29, 19), array(11, 46)),
540 array(array(13, 6), array(14, 23), array(44, 7), array(59, 1)),
541 array(array(12, 7), array(12, 26), array(39, 14), array(22, 41)), //35
542 array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),
543 array(array(17, 4), array(29, 14), array(49, 10), array(24, 46)),
544 array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)),
545 array(array(20, 4), array(40, 7), array(43, 22), array(10, 67)),
546 array(array(19, 6), array(18, 31), array(34, 34), array(20, 61)),//40
549 //----------------------------------------------------------------------
552 public static function getEccSpec($version, $level, array &$spec)
554 if (count($spec) < 5) {
555 $spec = array(0,0,0,0,0);
558 $b1 = self
::$eccTable[$version][$level][0];
559 $b2 = self
::$eccTable[$version][$level][1];
560 $data = self
::getDataLength($version, $level);
561 $ecc = self
::getECCLength($version, $level);
565 $spec[1] = (int)($data / $b1);
566 $spec[2] = (int)($ecc / $b1);
571 $spec[1] = (int)($data / ($b1 +
$b2));
572 $spec[2] = (int)($ecc / ($b1 +
$b2));
574 $spec[4] = $spec[1] +
1;
578 // Alignment pattern ---------------------------------------------------
580 // Positions of alignment patterns.
581 // This array includes only the second and the third position of the
582 // alignment patterns. Rest of them can be calculated from the distance
585 // See Table 1 in Appendix E (pp.71) of JIS X0510:2004.
587 public static $alignmentPattern = array(
589 array( 0, 0), array(18, 0), array(22, 0), array(26, 0), array(30, 0), // 1- 5
590 array(34, 0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10
591 array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15
592 array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20
593 array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25
594 array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30
595 array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35
596 array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40
600 /** --------------------------------------------------------------------
601 * Put an alignment marker.
604 * @param ox,oy center coordinate of the pattern
606 public static function putAlignmentMarker(array &$frame, $ox, $oy)
609 "\xa1\xa1\xa1\xa1\xa1",
610 "\xa1\xa0\xa0\xa0\xa1",
611 "\xa1\xa0\xa1\xa0\xa1",
612 "\xa1\xa0\xa0\xa0\xa1",
613 "\xa1\xa1\xa1\xa1\xa1"
619 for($y=0; $y<5; $y++
) {
620 QRstr
::set($frame, $xStart, $yStart+
$y, $finder[$y]);
624 //----------------------------------------------------------------------
625 public static function putAlignmentPattern($version, &$frame, $width)
630 $d = self
::$alignmentPattern[$version][1] - self
::$alignmentPattern[$version][0];
634 $w = (int)(($width - self
::$alignmentPattern[$version][0]) / $d +
2);
637 if($w * $w - 3 == 1) {
638 $x = self
::$alignmentPattern[$version][0];
639 $y = self
::$alignmentPattern[$version][0];
640 self
::putAlignmentMarker($frame, $x, $y);
644 $cx = self
::$alignmentPattern[$version][0];
645 for($x=1; $x<$w - 1; $x++
) {
646 self
::putAlignmentMarker($frame, 6, $cx);
647 self
::putAlignmentMarker($frame, $cx, 6);
651 $cy = self
::$alignmentPattern[$version][0];
652 for($y=0; $y<$w-1; $y++
) {
653 $cx = self
::$alignmentPattern[$version][0];
654 for($x=0; $x<$w-1; $x++
) {
655 self
::putAlignmentMarker($frame, $cx, $cy);
662 // Version information pattern -----------------------------------------
664 // Version information pattern (BCH coded).
665 // See Table 1 in Appendix D (pp.68) of JIS X0510:2004.
667 // size: [QRSPEC_VERSION_MAX - 6]
669 public static $versionPattern = array(
670 0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,
671 0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,
672 0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,
673 0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,
677 //----------------------------------------------------------------------
678 public static function getVersionPattern($version)
680 if($version < 7 || $version > QRSPEC_VERSION_MAX
)
683 return self
::$versionPattern[$version -7];
686 // Format information --------------------------------------------------
687 // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib)
689 public static $formatInfo = array(
690 array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),
691 array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),
692 array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),
693 array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)
696 public static function getFormatInfo($mask, $level)
698 if($mask < 0 || $mask > 7)
701 if($level < 0 || $level > 3)
704 return self
::$formatInfo[$level][$mask];
707 // Frame ---------------------------------------------------------------
708 // Cache of initial frames.
710 public static $frames = array();
712 /** --------------------------------------------------------------------
713 * Put a finder pattern.
716 * @param ox,oy upper-left coordinate of the pattern
718 public static function putFinderPattern(&$frame, $ox, $oy)
721 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",
722 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
723 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
724 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
725 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",
726 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",
727 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"
730 for($y=0; $y<7; $y++
) {
731 QRstr
::set($frame, $ox, $oy+
$y, $finder[$y]);
735 //----------------------------------------------------------------------
736 public static function createFrame($version)
738 $width = self
::$capacity[$version][QRCAP_WIDTH
];
739 $frameLine = str_repeat ("\0", $width);
740 $frame = array_fill(0, $width, $frameLine);
743 self
::putFinderPattern($frame, 0, 0);
744 self
::putFinderPattern($frame, $width - 7, 0);
745 self
::putFinderPattern($frame, 0, $width - 7);
748 $yOffset = $width - 7;
750 for($y=0; $y<7; $y++
) {
751 $frame[$y][7] = "\xc0";
752 $frame[$y][$width - 8] = "\xc0";
753 $frame[$yOffset][7] = "\xc0";
757 $setPattern = str_repeat("\xc0", 8);
759 QRstr
::set($frame, 0, 7, $setPattern);
760 QRstr
::set($frame, $width-8, 7, $setPattern);
761 QRstr
::set($frame, 0, $width - 8, $setPattern);
764 $setPattern = str_repeat("\x84", 9);
765 QRstr
::set($frame, 0, 8, $setPattern);
766 QRstr
::set($frame, $width - 8, 8, $setPattern, 8);
768 $yOffset = $width - 8;
770 for($y=0; $y<8; $y++
,$yOffset++
) {
771 $frame[$y][8] = "\x84";
772 $frame[$yOffset][8] = "\x84";
777 for($i=1; $i<$width-15; $i++
) {
778 $frame[6][7+
$i] = chr(0x90 | ($i & 1));
779 $frame[7+
$i][6] = chr(0x90 | ($i & 1));
783 self
::putAlignmentPattern($version, $frame, $width);
785 // Version information
787 $vinf = self
::getVersionPattern($version);
791 for($x=0; $x<6; $x++
) {
792 for($y=0; $y<3; $y++
) {
793 $frame[($width - 11)+
$y][$x] = chr(0x88 | ($v & 1));
799 for($y=0; $y<6; $y++
) {
800 for($x=0; $x<3; $x++
) {
801 $frame[$y][$x+
($width - 11)] = chr(0x88 | ($v & 1));
807 // and a little bit...
808 $frame[$width - 8][8] = "\x81";
813 //----------------------------------------------------------------------
814 public static function debug($frame, $binary_mode = false)
818 foreach ($frame as &$frameLine) {
819 $frameLine = join('<span class="m"> </span>', explode('0', $frameLine));
820 $frameLine = join('██', explode('1', $frameLine));
825 .m { background
-color
: white
; }
828 echo '<pre><tt><br/ ><br/ ><br/ > ';
829 echo join("<br/ > ", $frame);
830 echo '</tt></pre><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >';
834 foreach ($frame as &$frameLine) {
835 $frameLine = join('<span class="m"> </span>', explode("\xc0", $frameLine));
836 $frameLine = join('<span class="m">▒</span>', explode("\xc1", $frameLine));
837 $frameLine = join('<span class="p"> </span>', explode("\xa0", $frameLine));
838 $frameLine = join('<span class="p">▒</span>', explode("\xa1", $frameLine));
839 $frameLine = join('<span class="s">◇</span>', explode("\x84", $frameLine)); //format 0
840 $frameLine = join('<span class="s">◆</span>', explode("\x85", $frameLine)); //format 1
841 $frameLine = join('<span class="x">☢</span>', explode("\x81", $frameLine)); //special bit
842 $frameLine = join('<span class="c"> </span>', explode("\x90", $frameLine)); //clock 0
843 $frameLine = join('<span class="c">◷</span>', explode("\x91", $frameLine)); //clock 1
844 $frameLine = join('<span class="f"> </span>', explode("\x88", $frameLine)); //version
845 $frameLine = join('<span class="f">▒</span>', explode("\x89", $frameLine)); //version
846 $frameLine = join('♦', explode("\x01", $frameLine));
847 $frameLine = join('⋅', explode("\0", $frameLine));
852 .p { background
-color
: yellow
; }
853 .m { background
-color
: #00FF00; }
854 .s { background
-color
: #FF0000; }
855 .c { background
-color
: aqua
; }
856 .x { background
-color
: pink
; }
857 .f { background
-color
: gold
; }
861 echo join("<br/ >", $frame);
867 //----------------------------------------------------------------------
868 public static function serial($frame)
870 return gzcompress(join("\n", $frame), 9);
873 //----------------------------------------------------------------------
874 public static function unserial($code)
876 return explode("\n", gzuncompress($code));
879 //----------------------------------------------------------------------
880 public static function newFrame($version)
882 if($version < 1 || $version > QRSPEC_VERSION_MAX
)
885 if(!isset(self
::$frames[$version])) {
887 $fileName = QR_CACHE_DIR
.'frame_'.$version.'.dat';
890 if (file_exists($fileName)) {
891 self
::$frames[$version] = self
::unserial(file_get_contents($fileName));
893 self
::$frames[$version] = self
::createFrame($version);
894 file_put_contents($fileName, self
::serial(self
::$frames[$version]));
897 self
::$frames[$version] = self
::createFrame($version);
901 if(is_null(self
::$frames[$version]))
904 return self
::$frames[$version];
907 //----------------------------------------------------------------------
908 public static function rsBlockNum($spec) { return $spec
[0] + $spec
[3]; }
909 public static function rsBlockNum1($spec) { return $spec
[0]; }
910 public static function rsDataCodes1($spec) { return $spec
[1]; }
911 public static function rsEccCodes1($spec) { return $spec
[2]; }
912 public static function rsBlockNum2($spec) { return $spec
[3]; }
913 public static function rsDataCodes2($spec) { return $spec
[4]; }
914 public static function rsEccCodes2($spec) { return $spec
[2]; }
915 public static function rsDataLength($spec) { return ($spec
[0] * $spec
[1]) +
($spec
[3] * $spec
[4]); }
916 public static function rsEccLength($spec) { return ($spec
[0] + $spec
[3]) * $spec
[2]; }
922 //---- qrimage.php -----------------------------
928 * PHP QR Code encoder
930 * Image output of code using GD2
932 * PHP QR Code is distributed under LGPL 3
933 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
935 * This library is free software; you can redistribute it and/or
936 * modify it under the terms of the GNU Lesser General Public
937 * License as published by the Free Software Foundation; either
938 * version 3 of the License, or any later version.
940 * This library is distributed in the hope that it will be useful,
941 * but WITHOUT ANY WARRANTY; without even the implied warranty of
942 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
943 * Lesser General Public License for more details.
945 * You should have received a copy of the GNU Lesser General Public
946 * License along with this library; if not, write to the Free Software
947 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
950 define('QR_IMAGE', true);
954 //----------------------------------------------------------------------
955 public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE, $back_color, $fore_color)
957 $image = self
::image($frame, $pixelPerPoint, $outerFrame, $back_color, $fore_color);
959 if ($filename === false) {
960 Header("Content-type: image/png");
963 if($saveandprint===TRUE){
964 ImagePng($image, $filename);
965 header("Content-type: image/png");
968 ImagePng($image, $filename);
972 ImageDestroy($image);
975 //----------------------------------------------------------------------
976 public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85)
978 $image = self
::image($frame, $pixelPerPoint, $outerFrame);
980 if ($filename === false) {
981 Header("Content-type: image/jpeg");
982 ImageJpeg($image, null, $q);
984 ImageJpeg($image, $filename, $q);
987 ImageDestroy($image);
990 //----------------------------------------------------------------------
991 private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4, $back_color = 0xFFFFFF, $fore_color = 0x000000)
994 $w = strlen($frame[0]);
996 $imgW = $w +
2*$outerFrame;
997 $imgH = $h +
2*$outerFrame;
999 $base_image =ImageCreate($imgW, $imgH);
1001 // convert a hexadecimal color code into decimal format (red = 255 0 0, green = 0 255 0, blue = 0 0 255)
1002 $r1 = round((($fore_color & 0xFF0000) >> 16), 5);
1003 $g1 = round((($fore_color & 0x00FF00) >> 8), 5);
1004 $b1 = round(($fore_color & 0x0000FF), 5);
1006 // convert a hexadecimal color code into decimal format (red = 255 0 0, green = 0 255 0, blue = 0 0 255)
1007 $r2 = round((($back_color & 0xFF0000) >> 16), 5);
1008 $g2 = round((($back_color & 0x00FF00) >> 8), 5);
1009 $b2 = round(($back_color & 0x0000FF), 5);
1013 $col[0] = ImageColorAllocate($base_image, $r2, $g2, $b2);
1014 $col[1] = ImageColorAllocate($base_image, $r1, $g1, $b1);
1016 imagefill($base_image, 0, 0, $col[0]);
1018 for($y=0; $y<$h; $y++
) {
1019 for($x=0; $x<$w; $x++
) {
1020 if ($frame[$y][$x] == '1') {
1021 ImageSetPixel($base_image,$x+
$outerFrame,$y+
$outerFrame,$col[1]);
1026 $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);
1027 ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);
1028 ImageDestroy($base_image);
1030 return $target_image;
1037 //---- qrinput.php -----------------------------
1043 * PHP QR Code encoder
1045 * Input encoding class
1047 * Based on libqrencode C library distributed under LGPL 2.1
1048 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
1050 * PHP QR Code is distributed under LGPL 3
1051 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
1053 * This library is free software; you can redistribute it and/or
1054 * modify it under the terms of the GNU Lesser General Public
1055 * License as published by the Free Software Foundation; either
1056 * version 3 of the License, or any later version.
1058 * This library is distributed in the hope that it will be useful,
1059 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1060 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1061 * Lesser General Public License for more details.
1063 * You should have received a copy of the GNU Lesser General Public
1064 * License along with this library; if not, write to the Free Software
1065 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1068 define('STRUCTURE_HEADER_BITS', 20);
1069 define('MAX_STRUCTURED_SYMBOLS', 16);
1078 public function __construct($mode, $size, $data, $bstream = null)
1080 $setData = array_slice($data, 0, $size);
1082 if (count($setData) < $size) {
1083 $setData = array_merge($setData, array_fill(0,$size-count($setData),0));
1086 if(!QRinput
::check($mode, $size, $setData)) {
1087 throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData));
1090 $this->mode
= $mode;
1091 $this->size
= $size;
1092 $this->data
= $setData;
1093 $this->bstream
= $bstream;
1096 //----------------------------------------------------------------------
1097 public function encodeModeNum($version)
1101 $words = (int)($this->size
/ 3);
1102 $bs = new QRbitstream();
1105 $bs->appendNum(4, $val);
1106 $bs->appendNum(QRspec
::lengthIndicator(QR_MODE_NUM
, $version), $this->size
);
1108 for($i=0; $i<$words; $i++
) {
1109 $val = (ord($this->data
[$i*3 ]) - ord('0')) * 100;
1110 $val +
= (ord($this->data
[$i*3+
1]) - ord('0')) * 10;
1111 $val +
= (ord($this->data
[$i*3+
2]) - ord('0'));
1112 $bs->appendNum(10, $val);
1115 if($this->size
- $words * 3 == 1) {
1116 $val = ord($this->data
[$words*3]) - ord('0');
1117 $bs->appendNum(4, $val);
1118 } else if($this->size
- $words * 3 == 2) {
1119 $val = (ord($this->data
[$words*3 ]) - ord('0')) * 10;
1120 $val +
= (ord($this->data
[$words*3+
1]) - ord('0'));
1121 $bs->appendNum(7, $val);
1124 $this->bstream
= $bs;
1127 } catch (Exception
$e) {
1132 //----------------------------------------------------------------------
1133 public function encodeModeAn($version)
1136 $words = (int)($this->size
/ 2);
1137 $bs = new QRbitstream();
1139 $bs->appendNum(4, 0x02);
1140 $bs->appendNum(QRspec
::lengthIndicator(QR_MODE_AN
, $version), $this->size
);
1142 for($i=0; $i<$words; $i++
) {
1143 $val = (int)QRinput
::lookAnTable(ord($this->data
[$i*2 ])) * 45;
1144 $val +
= (int)QRinput
::lookAnTable(ord($this->data
[$i*2+
1]));
1146 $bs->appendNum(11, $val);
1149 if($this->size
& 1) {
1150 $val = QRinput
::lookAnTable(ord($this->data
[$words * 2]));
1151 $bs->appendNum(6, $val);
1154 $this->bstream
= $bs;
1157 } catch (Exception
$e) {
1162 //----------------------------------------------------------------------
1163 public function encodeMode8($version)
1166 $bs = new QRbitstream();
1168 $bs->appendNum(4, 0x4);
1169 $bs->appendNum(QRspec
::lengthIndicator(QR_MODE_8
, $version), $this->size
);
1171 for($i=0; $i<$this->size
; $i++
) {
1172 $bs->appendNum(8, ord($this->data
[$i]));
1175 $this->bstream
= $bs;
1178 } catch (Exception
$e) {
1183 //----------------------------------------------------------------------
1184 public function encodeModeKanji($version)
1188 $bs = new QRbitrtream();
1190 $bs->appendNum(4, 0x8);
1191 $bs->appendNum(QRspec
::lengthIndicator(QR_MODE_KANJI
, $version), (int)($this->size
/ 2));
1193 for($i=0; $i<$this->size
; $i+
=2) {
1194 $val = (ord($this->data
[$i]) << 8) | ord($this->data
[$i+
1]);
1195 if($val <= 0x9ffc) {
1201 $h = ($val >> 8) * 0xc0;
1202 $val = ($val & 0xff) +
$h;
1204 $bs->appendNum(13, $val);
1207 $this->bstream
= $bs;
1210 } catch (Exception
$e) {
1215 //----------------------------------------------------------------------
1216 public function encodeModeStructure()
1219 $bs = new QRbitstream();
1221 $bs->appendNum(4, 0x03);
1222 $bs->appendNum(4, ord($this->data
[1]) - 1);
1223 $bs->appendNum(4, ord($this->data
[0]) - 1);
1224 $bs->appendNum(8, ord($this->data
[2]));
1226 $this->bstream
= $bs;
1229 } catch (Exception
$e) {
1234 //----------------------------------------------------------------------
1235 public function estimateBitStreamSizeOfEntry($version)
1242 switch($this->mode
) {
1243 case QR_MODE_NUM
: $bits = QRinput
::estimateBitsModeNum($this->size
); break;
1244 case QR_MODE_AN
: $bits = QRinput
::estimateBitsModeAn($this->size
); break;
1245 case QR_MODE_8
: $bits = QRinput
::estimateBitsMode8($this->size
); break;
1246 case QR_MODE_KANJI
: $bits = QRinput
::estimateBitsModeKanji($this->size
);break;
1247 case QR_MODE_STRUCTURE
: return STRUCTURE_HEADER_BITS
;
1252 $l = QRspec
::lengthIndicator($this->mode
, $version);
1254 $num = (int)(($this->size +
$m - 1) / $m);
1256 $bits +
= $num * (4 +
$l);
1261 //----------------------------------------------------------------------
1262 public function encodeBitStream($version)
1266 unset($this->bstream
);
1267 $words = QRspec
::maximumWords($this->mode
, $version);
1269 if($this->size
> $words) {
1271 $st1 = new QRinputItem($this->mode
, $words, $this->data
);
1272 $st2 = new QRinputItem($this->mode
, $this->size
- $words, array_slice($this->data
, $words));
1274 $st1->encodeBitStream($version);
1275 $st2->encodeBitStream($version);
1277 $this->bstream
= new QRbitstream();
1278 $this->bstream
->append($st1->bstream
);
1279 $this->bstream
->append($st2->bstream
);
1288 switch($this->mode
) {
1289 case QR_MODE_NUM
: $ret = $this->encodeModeNum($version); break;
1290 case QR_MODE_AN
: $ret = $this->encodeModeAn($version); break;
1291 case QR_MODE_8
: $ret = $this->encodeMode8($version); break;
1292 case QR_MODE_KANJI
: $ret = $this->encodeModeKanji($version);break;
1293 case QR_MODE_STRUCTURE
: $ret = $this->encodeModeStructure(); break;
1303 return $this->bstream
->size();
1305 } catch (Exception
$e) {
1311 //##########################################################################
1320 //----------------------------------------------------------------------
1321 public function __construct($version = 0, $level = QR_ECLEVEL_L
)
1323 if ($version < 0 || $version > QRSPEC_VERSION_MAX
|| $level > QR_ECLEVEL_H
) {
1324 throw new Exception('Invalid version no');
1327 $this->version
= $version;
1328 $this->level
= $level;
1331 //----------------------------------------------------------------------
1332 public function getVersion()
1334 return $this->version
;
1337 //----------------------------------------------------------------------
1338 public function setVersion($version)
1340 if($version < 0 || $version > QRSPEC_VERSION_MAX
) {
1341 throw new Exception('Invalid version no');
1345 $this->version
= $version;
1350 //----------------------------------------------------------------------
1351 public function getErrorCorrectionLevel()
1353 return $this->level
;
1356 //----------------------------------------------------------------------
1357 public function setErrorCorrectionLevel($level)
1359 if($level > QR_ECLEVEL_H
) {
1360 throw new Exception('Invalid ECLEVEL');
1364 $this->level
= $level;
1369 //----------------------------------------------------------------------
1370 public function appendEntry(QRinputItem
$entry)
1372 $this->items
[] = $entry;
1375 //----------------------------------------------------------------------
1376 public function append($mode, $size, $data)
1379 $entry = new QRinputItem($mode, $size, $data);
1380 $this->items
[] = $entry;
1382 } catch (Exception
$e) {
1387 //----------------------------------------------------------------------
1389 public function insertStructuredAppendHeader($size, $index, $parity)
1391 if( $size > MAX_STRUCTURED_SYMBOLS
) {
1392 throw new Exception('insertStructuredAppendHeader wrong size');
1395 if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS
) {
1396 throw new Exception('insertStructuredAppendHeader wrong index');
1399 $buf = array($size, $index, $parity);
1402 $entry = new QRinputItem(QR_MODE_STRUCTURE
, 3, buf
);
1403 array_unshift($this->items
, $entry);
1405 } catch (Exception
$e) {
1410 //----------------------------------------------------------------------
1411 public function calcParity()
1415 foreach($this->items
as $item) {
1416 if($item->mode
!= QR_MODE_STRUCTURE
) {
1417 for($i=$item->size
-1; $i>=0; $i--) {
1418 $parity ^
= $item->data
[$i];
1426 //----------------------------------------------------------------------
1427 public static function checkModeNum($size, $data)
1429 for($i=0; $i<$size; $i++
) {
1430 if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){
1438 //----------------------------------------------------------------------
1439 public static function estimateBitsModeNum($size)
1441 $w = (int)$size / 3;
1444 switch($size - $w * 3) {
1458 //----------------------------------------------------------------------
1459 public static $anTable = array(
1460 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1461 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1462 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
1463 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
1464 -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1465 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,
1466 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1467 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
1470 //----------------------------------------------------------------------
1471 public static function lookAnTable($c)
1473 return (($c > 127)?-1:self
::$anTable[$c]);
1476 //----------------------------------------------------------------------
1477 public static function checkModeAn($size, $data)
1479 for($i=0; $i<$size; $i++
) {
1480 if (self
::lookAnTable(ord($data[$i])) == -1) {
1488 //----------------------------------------------------------------------
1489 public static function estimateBitsModeAn($size)
1491 $w = (int)($size / 2);
1501 //----------------------------------------------------------------------
1502 public static function estimateBitsMode8($size)
1507 //----------------------------------------------------------------------
1508 public function estimateBitsModeKanji($size)
1510 return (int)(($size / 2) * 13);
1513 //----------------------------------------------------------------------
1514 public static function checkModeKanji($size, $data)
1519 for($i=0; $i<$size; $i+
=2) {
1520 $val = (ord($data[$i]) << 8) | ord($data[$i+
1]);
1522 || ($val > 0x9ffc && $val < 0xe040)
1531 /***********************************************************************
1533 **********************************************************************/
1535 public static function check($mode, $size, $data)
1541 case QR_MODE_NUM
: return self
::checkModeNum($size, $data); break;
1542 case QR_MODE_AN
: return self
::checkModeAn($size, $data); break;
1543 case QR_MODE_KANJI
: return self
::checkModeKanji($size, $data); break;
1544 case QR_MODE_8
: return true; break;
1545 case QR_MODE_STRUCTURE
: return true; break;
1555 //----------------------------------------------------------------------
1556 public function estimateBitStreamSize($version)
1560 foreach($this->items
as $item) {
1561 $bits +
= $item->estimateBitStreamSizeOfEntry($version);
1567 //----------------------------------------------------------------------
1568 public function estimateVersion()
1574 $bits = $this->estimateBitStreamSize($prev);
1575 $version = QRspec
::getMinimumVersion((int)(($bits +
7) / 8), $this->level
);
1579 } while ($version > $prev);
1584 //----------------------------------------------------------------------
1585 public static function lengthOfCode($mode, $version, $bits)
1587 $payload = $bits - 4 - QRspec
::lengthIndicator($mode, $version);
1590 $chunks = (int)($payload / 10);
1591 $remain = $payload - $chunks * 10;
1592 $size = $chunks * 3;
1595 } else if($remain >= 4) {
1600 $chunks = (int)($payload / 11);
1601 $remain = $payload - $chunks * 11;
1602 $size = $chunks * 2;
1607 $size = (int)($payload / 8);
1610 $size = (int)(($payload / 13) * 2);
1612 case QR_MODE_STRUCTURE
:
1613 $size = (int)($payload / 8);
1620 $maxsize = QRspec
::maximumWords($mode, $version);
1621 if($size < 0) $size = 0;
1622 if($size > $maxsize) $size = $maxsize;
1627 //----------------------------------------------------------------------
1628 public function createBitStream()
1632 foreach($this->items
as $item) {
1633 $bits = $item->encodeBitStream($this->version
);
1644 //----------------------------------------------------------------------
1645 public function convertData()
1647 $ver = $this->estimateVersion();
1648 if($ver > $this->getVersion()) {
1649 $this->setVersion($ver);
1653 $bits = $this->createBitStream();
1658 $ver = QRspec
::getMinimumVersion((int)(($bits +
7) / 8), $this->level
);
1660 throw new Exception('WRONG VERSION');
1661 } else if($ver > $this->getVersion()) {
1662 $this->setVersion($ver);
1671 //----------------------------------------------------------------------
1672 public function appendPaddingBit(&$bstream)
1674 $bits = $bstream->size();
1675 $maxwords = QRspec
::getDataLength($this->version
, $this->level
);
1676 $maxbits = $maxwords * 8;
1678 if ($maxbits == $bits) {
1682 if ($maxbits - $bits < 5) {
1683 return $bstream->appendNum($maxbits - $bits, 0);
1687 $words = (int)(($bits +
7) / 8);
1689 $padding = new QRbitstream();
1690 $ret = $padding->appendNum($words * 8 - $bits +
4, 0);
1695 $padlen = $maxwords - $words;
1700 for($i=0; $i<$padlen; $i++
) {
1701 $padbuf[$i] = ($i&1)?0x11:0xec;
1704 $ret = $padding->appendBytes($padlen, $padbuf);
1711 $ret = $bstream->append($padding);
1716 //----------------------------------------------------------------------
1717 public function mergeBitStream()
1719 if($this->convertData() < 0) {
1723 $bstream = new QRbitstream();
1725 foreach($this->items
as $item) {
1726 $ret = $bstream->append($item->bstream
);
1735 //----------------------------------------------------------------------
1736 public function getBitStream()
1739 $bstream = $this->mergeBitStream();
1741 if($bstream == null) {
1745 $ret = $this->appendPaddingBit($bstream);
1753 //----------------------------------------------------------------------
1754 public function getByteStream()
1756 $bstream = $this->getBitStream();
1757 if($bstream == null) {
1761 return $bstream->toByte();
1770 //---- qrbitstream.php -----------------------------
1776 * PHP QR Code encoder
1780 * Based on libqrencode C library distributed under LGPL 2.1
1781 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
1783 * PHP QR Code is distributed under LGPL 3
1784 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
1786 * This library is free software; you can redistribute it and/or
1787 * modify it under the terms of the GNU Lesser General Public
1788 * License as published by the Free Software Foundation; either
1789 * version 3 of the License, or any later version.
1791 * This library is distributed in the hope that it will be useful,
1792 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1793 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1794 * Lesser General Public License for more details.
1796 * You should have received a copy of the GNU Lesser General Public
1797 * License along with this library; if not, write to the Free Software
1798 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1803 public $data = array();
1805 //----------------------------------------------------------------------
1806 public function size()
1808 return count($this->data
);
1811 //----------------------------------------------------------------------
1812 public function allocate($setLength)
1814 $this->data
= array_fill(0, $setLength, 0);
1818 //----------------------------------------------------------------------
1819 public static function newFromNum($bits, $num)
1821 $bstream = new QRbitstream();
1822 $bstream->allocate($bits);
1824 $mask = 1 << ($bits - 1);
1825 for($i=0; $i<$bits; $i++
) {
1827 $bstream->data
[$i] = 1;
1829 $bstream->data
[$i] = 0;
1837 //----------------------------------------------------------------------
1838 public static function newFromBytes($size, $data)
1840 $bstream = new QRbitstream();
1841 $bstream->allocate($size * 8);
1844 for($i=0; $i<$size; $i++
) {
1846 for($j=0; $j<8; $j++
) {
1847 if($data[$i] & $mask) {
1848 $bstream->data
[$p] = 1;
1850 $bstream->data
[$p] = 0;
1860 //----------------------------------------------------------------------
1861 public function append(QRbitstream
$arg)
1863 if (is_null($arg)) {
1867 if($arg->size() == 0) {
1871 if($this->size() == 0) {
1872 $this->data
= $arg->data
;
1876 $this->data
= array_values(array_merge($this->data
, $arg->data
));
1881 //----------------------------------------------------------------------
1882 public function appendNum($bits, $num)
1887 $b = QRbitstream
::newFromNum($bits, $num);
1892 $ret = $this->append($b);
1898 //----------------------------------------------------------------------
1899 public function appendBytes($size, $data)
1904 $b = QRbitstream
::newFromBytes($size, $data);
1909 $ret = $this->append($b);
1915 //----------------------------------------------------------------------
1916 public function toByte()
1919 $size = $this->size();
1925 $data = array_fill(0, (int)(($size +
7) / 8), 0);
1926 $bytes = (int)($size / 8);
1930 for($i=0; $i<$bytes; $i++
) {
1932 for($j=0; $j<8; $j++
) {
1934 $v |= $this->data
[$p];
1942 for($j=0; $j<($size & 7); $j++
) {
1944 $v |= $this->data
[$p];
1958 //---- qrsplit.php -----------------------------
1964 * PHP QR Code encoder
1966 * Input splitting classes
1968 * Based on libqrencode C library distributed under LGPL 2.1
1969 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
1971 * PHP QR Code is distributed under LGPL 3
1972 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
1974 * The following data / specifications are taken from
1975 * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
1977 * "Automatic identification and data capture techniques --
1978 * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
1980 * This library is free software; you can redistribute it and/or
1981 * modify it under the terms of the GNU Lesser General Public
1982 * License as published by the Free Software Foundation; either
1983 * version 3 of the License, or any later version.
1985 * This library is distributed in the hope that it will be useful,
1986 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1987 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1988 * Lesser General Public License for more details.
1990 * You should have received a copy of the GNU Lesser General Public
1991 * License along with this library; if not, write to the Free Software
1992 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1996 public $dataStr = '';
2000 //----------------------------------------------------------------------
2001 public function __construct($dataStr, $input, $modeHint)
2003 $this->dataStr
= $dataStr;
2004 $this->input
= $input;
2005 $this->modeHint
= $modeHint;
2008 //----------------------------------------------------------------------
2009 public static function isdigitat($str, $pos)
2011 if ($pos >= strlen($str))
2014 return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9')));
2017 //----------------------------------------------------------------------
2018 public static function isalnumat($str, $pos)
2020 if ($pos >= strlen($str))
2023 return (QRinput
::lookAnTable(ord($str[$pos])) >= 0);
2026 //----------------------------------------------------------------------
2027 public function identifyMode($pos)
2029 if ($pos >= strlen($this->dataStr
))
2032 $c = $this->dataStr
[$pos];
2034 if(self
::isdigitat($this->dataStr
, $pos)) {
2036 } else if(self
::isalnumat($this->dataStr
, $pos)) {
2038 } else if($this->modeHint
== QR_MODE_KANJI
) {
2040 if ($pos+
1 < strlen($this->dataStr
))
2042 $d = $this->dataStr
[$pos+
1];
2043 $word = (ord($c) << 8) | ord($d);
2044 if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) {
2045 return QR_MODE_KANJI
;
2053 //----------------------------------------------------------------------
2054 public function eatNum()
2056 $ln = QRspec
::lengthIndicator(QR_MODE_NUM
, $this->input
->getVersion());
2059 while(self
::isdigitat($this->dataStr
, $p)) {
2064 $mode = $this->identifyMode($p);
2066 if($mode == QR_MODE_8
) {
2067 $dif = QRinput
::estimateBitsModeNum($run) +
4 +
$ln
2068 + QRinput
::estimateBitsMode8(1) // + 4 + l8
2069 - QRinput
::estimateBitsMode8($run +
1); // - 4 - l8
2071 return $this->eat8();
2074 if($mode == QR_MODE_AN
) {
2075 $dif = QRinput
::estimateBitsModeNum($run) +
4 +
$ln
2076 + QRinput
::estimateBitsModeAn(1) // + 4 + la
2077 - QRinput
::estimateBitsModeAn($run +
1);// - 4 - la
2079 return $this->eatAn();
2083 $ret = $this->input
->append(QR_MODE_NUM
, $run, str_split($this->dataStr
));
2090 //----------------------------------------------------------------------
2091 public function eatAn()
2093 $la = QRspec
::lengthIndicator(QR_MODE_AN
, $this->input
->getVersion());
2094 $ln = QRspec
::lengthIndicator(QR_MODE_NUM
, $this->input
->getVersion());
2098 while(self
::isalnumat($this->dataStr
, $p)) {
2099 if(self
::isdigitat($this->dataStr
, $p)) {
2101 while(self
::isdigitat($this->dataStr
, $q)) {
2105 $dif = QRinput
::estimateBitsModeAn($p) // + 4 + la
2106 + QRinput
::estimateBitsModeNum($q - $p) +
4 +
$ln
2107 - QRinput
::estimateBitsModeAn($q); // - 4 - la
2121 if(!self
::isalnumat($this->dataStr
, $p)) {
2122 $dif = QRinput
::estimateBitsModeAn($run) +
4 +
$la
2123 + QRinput
::estimateBitsMode8(1) // + 4 + l8
2124 - QRinput
::estimateBitsMode8($run +
1); // - 4 - l8
2126 return $this->eat8();
2130 $ret = $this->input
->append(QR_MODE_AN
, $run, str_split($this->dataStr
));
2137 //----------------------------------------------------------------------
2138 public function eatKanji()
2142 while($this->identifyMode($p) == QR_MODE_KANJI
) {
2146 $ret = $this->input
->append(QR_MODE_KANJI
, $p, str_split($this->dataStr
));
2153 //----------------------------------------------------------------------
2154 public function eat8()
2156 $la = QRspec
::lengthIndicator(QR_MODE_AN
, $this->input
->getVersion());
2157 $ln = QRspec
::lengthIndicator(QR_MODE_NUM
, $this->input
->getVersion());
2160 $dataStrLen = strlen($this->dataStr
);
2162 while($p < $dataStrLen) {
2164 $mode = $this->identifyMode($p);
2165 if($mode == QR_MODE_KANJI
) {
2168 if($mode == QR_MODE_NUM
) {
2170 while(self
::isdigitat($this->dataStr
, $q)) {
2173 $dif = QRinput
::estimateBitsMode8($p) // + 4 + l8
2174 + QRinput
::estimateBitsModeNum($q - $p) +
4 +
$ln
2175 - QRinput
::estimateBitsMode8($q); // - 4 - l8
2181 } else if($mode == QR_MODE_AN
) {
2183 while(self
::isalnumat($this->dataStr
, $q)) {
2186 $dif = QRinput
::estimateBitsMode8($p) // + 4 + l8
2187 + QRinput
::estimateBitsModeAn($q - $p) +
4 +
$la
2188 - QRinput
::estimateBitsMode8($q); // - 4 - l8
2200 $ret = $this->input
->append(QR_MODE_8
, $run, str_split($this->dataStr
));
2208 //----------------------------------------------------------------------
2209 public function splitString()
2211 while (strlen($this->dataStr
) > 0)
2213 if($this->dataStr
== '')
2216 $mode = $this->identifyMode(0);
2219 case QR_MODE_NUM
: $length = $this->eatNum(); break;
2220 case QR_MODE_AN
: $length = $this->eatAn(); break;
2222 if ($mode == QR_MODE_KANJI
)
2223 $length = $this->eatKanji();
2224 else $length = $this->eat8();
2226 default: $length = $this->eat8(); break;
2230 if($length == 0) return 0;
2231 if($length < 0) return -1;
2233 $this->dataStr
= substr($this->dataStr
, $length);
2237 //----------------------------------------------------------------------
2238 public function toUpper()
2240 $stringLen = strlen($this->dataStr
);
2243 while ($p<$stringLen) {
2244 $mode = self
::identifyMode(substr($this->dataStr
, $p));
2245 if($mode == QR_MODE_KANJI
) {
2248 if (ord($this->dataStr
[$p]) >= ord('a') && ord($this->dataStr
[$p]) <= ord('z')) {
2249 $this->dataStr
[$p] = chr(ord($this->dataStr
[$p]) - 32);
2255 return $this->dataStr
;
2258 //----------------------------------------------------------------------
2259 public static function splitStringToQRinput($string, QRinput
$input, $modeHint, $casesensitive = true)
2261 if(is_null($string) || $string == '\0' || $string == '') {
2262 throw new Exception('empty string!!!');
2265 $split = new QRsplit($string, $input, $modeHint);
2270 return $split->splitString();
2276 //---- qrrscode.php -----------------------------
2282 * PHP QR Code encoder
2284 * Reed-Solomon error correction support
2286 * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
2287 * (libfec is released under the GNU Lesser General Public License.)
2289 * Based on libqrencode C library distributed under LGPL 2.1
2290 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
2292 * PHP QR Code is distributed under LGPL 3
2293 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
2295 * This library is free software; you can redistribute it and/or
2296 * modify it under the terms of the GNU Lesser General Public
2297 * License as published by the Free Software Foundation; either
2298 * version 3 of the License, or any later version.
2300 * This library is distributed in the hope that it will be useful,
2301 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2302 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2303 * Lesser General Public License for more details.
2305 * You should have received a copy of the GNU Lesser General Public
2306 * License along with this library; if not, write to the Free Software
2307 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2312 public $mm; // Bits per symbol
2313 public $nn; // Symbols per block (= (1<<mm)-1)
2314 public $alpha_to = array(); // log lookup table
2315 public $index_of = array(); // Antilog lookup table
2316 public $genpoly = array(); // Generator polynomial
2317 public $nroots; // Number of generator roots = number of parity symbols
2318 public $fcr; // First consecutive root, index form
2319 public $prim; // Primitive element, index form
2320 public $iprim; // prim-th root of 1, index form
2321 public $pad; // Padding bytes in shortened block
2324 //----------------------------------------------------------------------
2325 public function modnn($x)
2327 while ($x >= $this->nn
) {
2329 $x = ($x >> $this->mm
) +
($x & $this->nn
);
2335 //----------------------------------------------------------------------
2336 public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
2338 // Common code for intializing a Reed-Solomon control block (char or int symbols)
2339 // Copyright 2004 Phil Karn, KA9Q
2340 // May be used under the terms of the GNU Lesser General Public License (LGPL)
2344 // Check parameter ranges
2345 if($symsize < 0 || $symsize > 8) return $rs;
2346 if($fcr < 0 || $fcr >= (1<<$symsize)) return $rs;
2347 if($prim <= 0 || $prim >= (1<<$symsize)) return $rs;
2348 if($nroots < 0 || $nroots >= (1<<$symsize)) return $rs; // Can't have more roots than symbol values!
2349 if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding
2351 $rs = new QRrsItem();
2353 $rs->nn
= (1<<$symsize)-1;
2356 $rs->alpha_to
= array_fill(0, $rs->nn+
1, 0);
2357 $rs->index_of
= array_fill(0, $rs->nn+
1, 0);
2359 // PHP style macro replacement ;)
2363 // Generate Galois field lookup tables
2364 $rs->index_of
[0] = $A0; // log(zero) = -inf
2365 $rs->alpha_to
[$A0] = 0; // alpha**-inf = 0
2368 for($i=0; $i<$rs->nn
; $i++
) {
2369 $rs->index_of
[$sr] = $i;
2370 $rs->alpha_to
[$i] = $sr;
2372 if($sr & (1<<$symsize)) {
2379 // field generator polynomial is not primitive!
2384 /* Form RS code generator polynomial from its roots */
2385 $rs->genpoly
= array_fill(0, $nroots+
1, 0);
2389 $rs->nroots
= $nroots;
2390 $rs->gfpoly
= $gfpoly;
2392 /* Find prim-th root of 1, used in decoding */
2393 for($iprim=1;($iprim %
$prim) != 0;$iprim +
= $rs->nn
)
2394 ; // intentional empty-body loop!
2396 $rs->iprim
= (int)($iprim / $prim);
2397 $rs->genpoly
[0] = 1;
2399 for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++
, $root +
= $prim) {
2400 $rs->genpoly
[$i+
1] = 1;
2402 // Multiply rs->genpoly[] by @**(root + x)
2403 for ($j = $i; $j > 0; $j--) {
2404 if ($rs->genpoly
[$j] != 0) {
2405 $rs->genpoly
[$j] = $rs->genpoly
[$j-1] ^
$rs->alpha_to
[$rs->modnn($rs->index_of
[$rs->genpoly
[$j]] +
$root)];
2407 $rs->genpoly
[$j] = $rs->genpoly
[$j-1];
2410 // rs->genpoly[0] can never be zero
2411 $rs->genpoly
[0] = $rs->alpha_to
[$rs->modnn($rs->index_of
[$rs->genpoly
[0]] +
$root)];
2414 // convert rs->genpoly[] to index form for quicker encoding
2415 for ($i = 0; $i <= $nroots; $i++
)
2416 $rs->genpoly
[$i] = $rs->index_of
[$rs->genpoly
[$i]];
2421 //----------------------------------------------------------------------
2422 public function encode_rs_char($data, &$parity)
2426 $ALPHA_TO =& $this->alpha_to
;
2427 $INDEX_OF =& $this->index_of
;
2428 $GENPOLY =& $this->genpoly
;
2429 $NROOTS =& $this->nroots
;
2431 $PRIM =& $this->prim
;
2432 $IPRIM =& $this->iprim
;
2436 $parity = array_fill(0, $NROOTS, 0);
2438 for($i=0; $i< ($NN-$NROOTS-$PAD); $i++
) {
2440 $feedback = $INDEX_OF[$data[$i] ^
$parity[0]];
2441 if($feedback != $A0) {
2442 // feedback term is non-zero
2444 // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must
2445 // always be for the polynomials constructed by init_rs()
2446 $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] +
$feedback);
2448 for($j=1;$j<$NROOTS;$j++
) {
2449 $parity[$j] ^
= $ALPHA_TO[$this->modnn($feedback +
$GENPOLY[$NROOTS-$j])];
2454 array_shift($parity);
2455 if($feedback != $A0) {
2456 array_push($parity, $ALPHA_TO[$this->modnn($feedback +
$GENPOLY[0])]);
2458 array_push($parity, 0);
2464 //##########################################################################
2468 public static $items = array();
2470 //----------------------------------------------------------------------
2471 public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)
2473 foreach(self
::$items as $rs) {
2474 if($rs->pad
!= $pad) continue;
2475 if($rs->nroots
!= $nroots) continue;
2476 if($rs->mm
!= $symsize) continue;
2477 if($rs->gfpoly
!= $gfpoly) continue;
2478 if($rs->fcr
!= $fcr) continue;
2479 if($rs->prim
!= $prim) continue;
2484 $rs = QRrsItem
::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);
2485 array_unshift(self
::$items, $rs);
2493 //---- qrmask.php -----------------------------
2499 * PHP QR Code encoder
2503 * Based on libqrencode C library distributed under LGPL 2.1
2504 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
2506 * PHP QR Code is distributed under LGPL 3
2507 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
2509 * This library is free software; you can redistribute it and/or
2510 * modify it under the terms of the GNU Lesser General Public
2511 * License as published by the Free Software Foundation; either
2512 * version 3 of the License, or any later version.
2514 * This library is distributed in the hope that it will be useful,
2515 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2516 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2517 * Lesser General Public License for more details.
2519 * You should have received a copy of the GNU Lesser General Public
2520 * License along with this library; if not, write to the Free Software
2521 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2531 public $runLength = array();
2533 //----------------------------------------------------------------------
2534 public function __construct()
2536 $this->runLength
= array_fill(0, QRSPEC_WIDTH_MAX +
1, 0);
2539 //----------------------------------------------------------------------
2540 public function writeFormatInformation($width, &$frame, $mask, $level)
2543 $format = QRspec
::getFormatInfo($mask, $level);
2545 for($i=0; $i<8; $i++
) {
2553 $frame[8][$width - 1 - $i] = chr($v);
2555 $frame[$i][8] = chr($v);
2557 $frame[$i +
1][8] = chr($v);
2559 $format = $format >> 1;
2562 for($i=0; $i<7; $i++
) {
2570 $frame[$width - 7 +
$i][8] = chr($v);
2572 $frame[8][7] = chr($v);
2574 $frame[8][6 - $i] = chr($v);
2577 $format = $format >> 1;
2583 //----------------------------------------------------------------------
2584 public function mask0($x, $y) { return ($x+$y
)&1; }
2585 public function mask1($x, $y) { return ($y
&1); }
2586 public function mask2($x, $y) { return ($x%
3); }
2587 public function mask3($x, $y) { return ($x+$y
)%
3; }
2588 public function mask4($x, $y) { return (((int)($y
/2))+
((int)($x
/3)))&1; }
2589 public function mask5($x, $y) { return (($x
*$y
)&1)+
($x
*$y
)%
3; }
2590 public function mask6($x, $y) { return ((($x
*$y
)&1)+
($x
*$y
)%
3)&1; }
2591 public function mask7($x, $y) { return ((($x
*$y
)%
3)+
(($x+$y
)&1))&1; }
2593 //----------------------------------------------------------------------
2594 private function generateMaskNo($maskNo, $width, $frame)
2596 $bitMask = array_fill(0, $width, array_fill(0, $width, 0));
2598 for($y=0; $y<$width; $y++
) {
2599 for($x=0; $x<$width; $x++
) {
2600 if(ord($frame[$y][$x]) & 0x80) {
2601 $bitMask[$y][$x] = 0;
2603 $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y);
2604 $bitMask[$y][$x] = ($maskFunc == 0)?1:0;
2613 //----------------------------------------------------------------------
2614 public static function serial($bitFrame)
2618 foreach ($bitFrame as $line)
2619 $codeArr[] = join('', $line);
2621 return gzcompress(join("\n", $codeArr), 9);
2624 //----------------------------------------------------------------------
2625 public static function unserial($code)
2629 $codeLines = explode("\n", gzuncompress($code));
2630 foreach ($codeLines as $line)
2631 $codeArr[] = str_split($line);
2636 //----------------------------------------------------------------------
2637 public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false)
2642 $fileName = QR_CACHE_DIR
.'mask_'.$maskNo.DIRECTORY_SEPARATOR
.'mask_'.$width.'_'.$maskNo.'.dat';
2645 if (file_exists($fileName)) {
2646 $bitMask = self
::unserial(file_get_contents($fileName));
2648 $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
2649 if (!file_exists(QR_CACHE_DIR
.'mask_'.$maskNo))
2650 mkdir(QR_CACHE_DIR
.'mask_'.$maskNo);
2651 file_put_contents($fileName, self
::serial($bitMask));
2654 $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
2662 for($y=0; $y<$width; $y++
) {
2663 for($x=0; $x<$width; $x++
) {
2664 if($bitMask[$y][$x] == 1) {
2665 $d[$y][$x] = chr(ord($s[$y][$x]) ^
(int)$bitMask[$y][$x]);
2667 $b +
= (int)(ord($d[$y][$x]) & 1);
2674 //----------------------------------------------------------------------
2675 public function makeMask($width, $frame, $maskNo, $level)
2677 $masked = array_fill(0, $width, str_repeat("\0", $width));
2678 $this->makeMaskNo($maskNo, $width, $frame, $masked);
2679 $this->writeFormatInformation($width, $masked, $maskNo, $level);
2684 //----------------------------------------------------------------------
2685 public function calcN1N3($length)
2689 for($i=0; $i<$length; $i++
) {
2691 if($this->runLength
[$i] >= 5) {
2692 $demerit +
= (N1 +
($this->runLength
[$i] - 5));
2695 if(($i >= 3) && ($i < ($length-2)) && ($this->runLength
[$i] %
3 == 0)) {
2696 $fact = (int)($this->runLength
[$i] / 3);
2697 if(($this->runLength
[$i-2] == $fact) &&
2698 ($this->runLength
[$i-1] == $fact) &&
2699 ($this->runLength
[$i+
1] == $fact) &&
2700 ($this->runLength
[$i+
2] == $fact)) {
2701 if(($this->runLength
[$i-3] < 0) || ($this->runLength
[$i-3] >= (4 * $fact))) {
2703 } else if((($i+
3) >= $length) || ($this->runLength
[$i+
3] >= (4 * $fact))) {
2713 //----------------------------------------------------------------------
2714 public function evaluateSymbol($width, $frame)
2719 for($y=0; $y<$width; $y++
) {
2721 $this->runLength
[0] = 1;
2723 $frameY = $frame[$y];
2726 $frameYM = $frame[$y-1];
2728 for($x=0; $x<$width; $x++
) {
2729 if(($x > 0) && ($y > 0)) {
2730 $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]);
2731 $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]);
2733 if(($b22 | ($w22 ^
1))&1) {
2737 if(($x == 0) && (ord($frameY[$x]) & 1)) {
2738 $this->runLength
[0] = -1;
2740 $this->runLength
[$head] = 1;
2742 if((ord($frameY[$x]) ^
ord($frameY[$x-1])) & 1) {
2744 $this->runLength
[$head] = 1;
2746 $this->runLength
[$head]++
;
2751 $demerit +
= $this->calcN1N3($head+
1);
2754 for($x=0; $x<$width; $x++
) {
2756 $this->runLength
[0] = 1;
2758 for($y=0; $y<$width; $y++
) {
2759 if($y == 0 && (ord($frame[$y][$x]) & 1)) {
2760 $this->runLength
[0] = -1;
2762 $this->runLength
[$head] = 1;
2764 if((ord($frame[$y][$x]) ^
ord($frame[$y-1][$x])) & 1) {
2766 $this->runLength
[$head] = 1;
2768 $this->runLength
[$head]++
;
2773 $demerit +
= $this->calcN1N3($head+
1);
2780 //----------------------------------------------------------------------
2781 public function mask($width, $frame, $level)
2783 $minDemerit = PHP_INT_MAX
;
2785 $bestMask = array();
2787 $checked_masks = array(0,1,2,3,4,5,6,7);
2789 if (QR_FIND_FROM_RANDOM
!== false) {
2791 $howManuOut = 8-(QR_FIND_FROM_RANDOM %
9);
2792 for ($i = 0; $i < $howManuOut; $i++
) {
2793 $remPos = rand (0, count($checked_masks)-1);
2794 unset($checked_masks[$remPos]);
2795 $checked_masks = array_values($checked_masks);
2802 foreach($checked_masks as $i) {
2803 $mask = array_fill(0, $width, str_repeat("\0", $width));
2807 $blacks = $this->makeMaskNo($i, $width, $frame, $mask);
2808 $blacks +
= $this->writeFormatInformation($width, $mask, $i, $level);
2809 $blacks = (int)(100 * $blacks / ($width * $width));
2810 $demerit = (int)((int)(abs($blacks - 50) / 5) * N4
);
2811 $demerit +
= $this->evaluateSymbol($width, $mask);
2813 if($demerit < $minDemerit) {
2814 $minDemerit = $demerit;
2823 //----------------------------------------------------------------------
2829 //---- qrencode.php -----------------------------
2835 * PHP QR Code encoder
2837 * Main encoder classes.
2839 * Based on libqrencode C library distributed under LGPL 2.1
2840 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
2842 * PHP QR Code is distributed under LGPL 3
2843 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
2845 * This library is free software; you can redistribute it and/or
2846 * modify it under the terms of the GNU Lesser General Public
2847 * License as published by the Free Software Foundation; either
2848 * version 3 of the License, or any later version.
2850 * This library is distributed in the hope that it will be useful,
2851 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2852 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2853 * Lesser General Public License for more details.
2855 * You should have received a copy of the GNU Lesser General Public
2856 * License along with this library; if not, write to the Free Software
2857 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2862 public $data = array();
2864 public $ecc = array();
2866 public function __construct($dl, $data, $el, &$ecc, QRrsItem
$rs)
2868 $rs->encode_rs_char($data, $ecc);
2870 $this->dataLength
= $dl;
2871 $this->data
= $data;
2872 $this->eccLength
= $el;
2877 //##########################################################################
2881 public $datacode = array();
2882 public $ecccode = array();
2884 public $rsblocks = array(); //of RSblock
2890 //----------------------------------------------------------------------
2891 public function __construct(QRinput
$input)
2893 $spec = array(0,0,0,0,0);
2895 $this->datacode
= $input->getByteStream();
2896 if(is_null($this->datacode
)) {
2897 throw new Exception('null imput string');
2900 QRspec
::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);
2902 $this->version
= $input->getVersion();
2903 $this->b1
= QRspec
::rsBlockNum1($spec);
2904 $this->dataLength
= QRspec
::rsDataLength($spec);
2905 $this->eccLength
= QRspec
::rsEccLength($spec);
2906 $this->ecccode
= array_fill(0, $this->eccLength
, 0);
2907 $this->blocks
= QRspec
::rsBlockNum($spec);
2909 $ret = $this->init($spec);
2911 throw new Exception('block alloc error');
2918 //----------------------------------------------------------------------
2919 public function init(array $spec)
2921 $dl = QRspec
::rsDataCodes1($spec);
2922 $el = QRspec
::rsEccCodes1($spec);
2923 $rs = QRrs
::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
2929 for($i=0; $i<QRspec
::rsBlockNum1($spec); $i++
) {
2930 $ecc = array_slice($this->ecccode
,$eccPos);
2931 $this->rsblocks
[$blockNo] = new QRrsblock($dl, array_slice($this->datacode
, $dataPos), $el, $ecc, $rs);
2932 $this->ecccode
= array_merge(array_slice($this->ecccode
,0, $eccPos), $ecc);
2939 if(QRspec
::rsBlockNum2($spec) == 0)
2942 $dl = QRspec
::rsDataCodes2($spec);
2943 $el = QRspec
::rsEccCodes2($spec);
2944 $rs = QRrs
::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
2946 if($rs == NULL) return -1;
2948 for($i=0; $i<QRspec
::rsBlockNum2($spec); $i++
) {
2949 $ecc = array_slice($this->ecccode
,$eccPos);
2950 $this->rsblocks
[$blockNo] = new QRrsblock($dl, array_slice($this->datacode
, $dataPos), $el, $ecc, $rs);
2951 $this->ecccode
= array_merge(array_slice($this->ecccode
,0, $eccPos), $ecc);
2961 //----------------------------------------------------------------------
2962 public function getCode()
2966 if($this->count
< $this->dataLength
) {
2967 $row = $this->count %
$this->blocks
;
2968 $col = $this->count
/ $this->blocks
;
2969 if($col >= $this->rsblocks
[0]->dataLength
) {
2972 $ret = $this->rsblocks
[$row]->data
[$col];
2973 } else if($this->count
< $this->dataLength +
$this->eccLength
) {
2974 $row = ($this->count
- $this->dataLength
) %
$this->blocks
;
2975 $col = ($this->count
- $this->dataLength
) / $this->blocks
;
2976 $ret = $this->rsblocks
[$row]->ecc
[$col];
2986 //##########################################################################
2994 //----------------------------------------------------------------------
2995 public function encodeMask(QRinput
$input, $mask)
2997 if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX
) {
2998 throw new Exception('wrong version');
3000 if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H
) {
3001 throw new Exception('wrong level');
3004 $raw = new QRrawcode($input);
3006 QRtools
::markTime('after_raw');
3008 $version = $raw->version
;
3009 $width = QRspec
::getWidth($version);
3010 $frame = QRspec
::newFrame($version);
3012 $filler = new FrameFiller($width, $frame);
3013 if(is_null($filler)) {
3017 // inteleaved data and ecc codes
3018 for($i=0; $i<$raw->dataLength +
$raw->eccLength
; $i++
) {
3019 $code = $raw->getCode();
3021 for($j=0; $j<8; $j++
) {
3022 $addr = $filler->next();
3023 $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));
3028 QRtools
::markTime('after_filler');
3033 $j = QRspec
::getRemainder($version);
3034 for($i=0; $i<$j; $i++
) {
3035 $addr = $filler->next();
3036 $filler->setFrameAt($addr, 0x02);
3039 $frame = $filler->frame
;
3044 $maskObj = new QRmask();
3047 if (QR_FIND_BEST_MASK
) {
3048 $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());
3050 $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK
) %
8), $input->getErrorCorrectionLevel());
3053 $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());
3056 if($masked == NULL) {
3060 QRtools
::markTime('after_mask');
3062 $this->version
= $version;
3063 $this->width
= $width;
3064 $this->data
= $masked;
3069 //----------------------------------------------------------------------
3070 public function encodeInput(QRinput
$input)
3072 return $this->encodeMask($input, -1);
3075 //----------------------------------------------------------------------
3076 public function encodeString8bit($string, $version, $level)
3078 if($string == NULL) {
3079 throw new Exception('empty string!');
3083 $input = new QRinput($version, $level);
3084 if($input == NULL) return NULL;
3086 $ret = $input->append($input, QR_MODE_8
, strlen($string), str_split($string));
3091 return $this->encodeInput($input);
3094 //----------------------------------------------------------------------
3095 public function encodeString($string, $version, $level, $hint, $casesensitive)
3098 if($hint != QR_MODE_8
&& $hint != QR_MODE_KANJI
) {
3099 throw new Exception('bad hint');
3103 $input = new QRinput($version, $level);
3104 if($input == NULL) return NULL;
3106 $ret = QRsplit
::splitStringToQRinput($string, $input, $hint, $casesensitive);
3111 return $this->encodeInput($input);
3114 //----------------------------------------------------------------------
3115 public static function png($text, $outfile = false, $level = QR_ECLEVEL_L
, $size = 3, $margin = 4, $saveandprint=false, $back_color = 0xFFFFFF, $fore_color = 0x000000)
3117 $enc = QRencode
::factory($level, $size, $margin, $back_color, $fore_color);
3118 return $enc->encodePNG($text, $outfile, $saveandprint=false);
3121 //----------------------------------------------------------------------
3122 public static function text($text, $outfile = false, $level = QR_ECLEVEL_L
, $size = 3, $margin = 4)
3124 $enc = QRencode
::factory($level, $size, $margin);
3125 return $enc->encode($text, $outfile);
3128 //----------------------------------------------------------------------
3129 public static function eps($text, $outfile = false, $level = QR_ECLEVEL_L
, $size = 3, $margin = 4, $saveandprint=false, $back_color = 0xFFFFFF, $fore_color = 0x000000, $cmyk = false)
3131 $enc = QRencode
::factory($level, $size, $margin, $back_color, $fore_color, $cmyk);
3132 return $enc->encodeEPS($text, $outfile, $saveandprint=false);
3135 //----------------------------------------------------------------------
3136 public static function svg($text, $outfile = false, $level = QR_ECLEVEL_L
, $size = 3, $margin = 4, $saveandprint=false, $back_color = 0xFFFFFF, $fore_color = 0x000000)
3138 $enc = QRencode
::factory($level, $size, $margin, $back_color, $fore_color);
3139 return $enc->encodeSVG($text, $outfile, $saveandprint=false);
3142 //----------------------------------------------------------------------
3143 public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L
, $size = 3, $margin = 4)
3145 $enc = QRencode
::factory($level, $size, $margin);
3146 return $enc->encodeRAW($text, $outfile);
3150 //##########################################################################
3161 //----------------------------------------------------------------------
3162 public function __construct($width, &$frame)
3164 $this->width
= $width;
3165 $this->frame
= $frame;
3166 $this->x
= $width - 1;
3167 $this->y
= $width - 1;
3172 //----------------------------------------------------------------------
3173 public function setFrameAt($at, $val)
3175 $this->frame
[$at['y']][$at['x']] = chr($val);
3178 //----------------------------------------------------------------------
3179 public function getFrameAt($at)
3181 return ord($this->frame
[$at['y']][$at['x']]);
3184 //----------------------------------------------------------------------
3185 public function next()
3189 if($this->bit
== -1) {
3191 return array('x'=>$this->x
, 'y'=>$this->y
);
3198 if($this->bit
== 0) {
3207 if($this->dir
< 0) {
3228 if($x < 0 || $y < 0) return null;
3233 } while(ord($this->frame
[$y][$x]) & 0x80);
3235 return array('x'=>$x, 'y'=>$y);
3240 //##########################################################################
3244 public $casesensitive = true;
3245 public $eightbit = false;
3247 public $version = 0;
3250 public $back_color = 0xFFFFFF;
3251 public $fore_color = 0x000000;
3253 public $structured = 0; // not supported yet
3255 public $level = QR_ECLEVEL_L
;
3256 public $hint = QR_MODE_8
;
3258 //----------------------------------------------------------------------
3259 public static function factory($level = QR_ECLEVEL_L
, $size = 3, $margin = 4, $back_color = 0xFFFFFF, $fore_color = 0x000000, $cmyk = false)
3261 $enc = new QRencode();
3263 $enc->margin
= $margin;
3264 $enc->fore_color
= $fore_color;
3265 $enc->back_color
= $back_color;
3268 switch ($level.'') {
3273 $enc->level
= $level;
3277 $enc->level
= QR_ECLEVEL_L
;
3281 $enc->level
= QR_ECLEVEL_M
;
3285 $enc->level
= QR_ECLEVEL_Q
;
3289 $enc->level
= QR_ECLEVEL_H
;
3296 //----------------------------------------------------------------------
3297 public function encodeRAW($intext, $outfile = false)
3299 $code = new QRcode();
3301 if($this->eightbit
) {
3302 $code->encodeString8bit($intext, $this->version
, $this->level
);
3304 $code->encodeString($intext, $this->version
, $this->level
, $this->hint
, $this->casesensitive
);
3310 //----------------------------------------------------------------------
3311 public function encode($intext, $outfile = false)
3313 $code = new QRcode();
3315 if($this->eightbit
) {
3316 $code->encodeString8bit($intext, $this->version
, $this->level
);
3318 $code->encodeString($intext, $this->version
, $this->level
, $this->hint
, $this->casesensitive
);
3321 QRtools
::markTime('after_encode');
3323 if ($outfile!== false) {
3324 file_put_contents($outfile, join("\n", QRtools
::binarize($code->data
)));
3326 return QRtools
::binarize($code->data
);
3330 //----------------------------------------------------------------------
3331 public function encodePNG($intext, $outfile = false,$saveandprint=false)
3336 $tab = $this->encode($intext);
3337 $err = ob_get_contents();
3341 QRtools
::log($outfile, $err);
3343 $maxSize = (int)(QR_PNG_MAXIMUM_SIZE
/ (count($tab)+
2*$this->margin
));
3345 QRimage
::png($tab, $outfile, min(max(1, $this->size
), $maxSize), $this->margin
,$saveandprint, $this->back_color
, $this->fore_color
);
3347 } catch (Exception
$e) {
3349 QRtools
::log($outfile, $e->getMessage());
3354 //----------------------------------------------------------------------
3355 public function encodeEPS($intext, $outfile = false,$saveandprint=false)
3360 $tab = $this->encode($intext);
3361 $err = ob_get_contents();
3365 QRtools
::log($outfile, $err);
3367 $maxSize = (int)(QR_PNG_MAXIMUM_SIZE
/ (count($tab)+
2*$this->margin
));
3369 QRvect
::eps($tab, $outfile, min(max(1, $this->size
), $maxSize), $this->margin
,$saveandprint, $this->back_color
, $this->fore_color
, $this->cmyk
);
3371 } catch (Exception
$e) {
3373 QRtools
::log($outfile, $e->getMessage());
3378 //----------------------------------------------------------------------
3379 public function encodeSVG($intext, $outfile = false,$saveandprint=false)
3384 $tab = $this->encode($intext);
3385 $err = ob_get_contents();
3389 QRtools
::log($outfile, $err);
3391 $maxSize = (int)(QR_PNG_MAXIMUM_SIZE
/ (count($tab)+
2*$this->margin
));
3393 QRvect
::svg($tab, $outfile, min(max(1, $this->size
), $maxSize), $this->margin
,$saveandprint, $this->back_color
, $this->fore_color
);
3395 } catch (Exception
$e) {
3397 QRtools
::log($outfile, $e->getMessage());
3406 //---- qrvect.php -----------------------------
3412 * PHP QR Code encoder
3414 * Image output of code using GD2
3416 * PHP QR Code is distributed under LGPL 3
3417 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
3419 * This library is free software; you can redistribute it and/or
3420 * modify it under the terms of the GNU Lesser General Public
3421 * License as published by the Free Software Foundation; either
3422 * version 3 of the License, or any later version.
3424 * This library is distributed in the hope that it will be useful,
3425 * but WITHOUT ANY WARRANTY; without even the implied warranty of
3426 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3427 * Lesser General Public License for more details.
3429 * You should have received a copy of the GNU Lesser General Public
3430 * License along with this library; if not, write to the Free Software
3431 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
3434 define('QR_VECT', true);
3438 //----------------------------------------------------------------------
3439 public static function eps($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE, $back_color = 0xFFFFFF, $fore_color = 0x000000, $cmyk = false)
3441 $vect = self
::vectEPS($frame, $pixelPerPoint, $outerFrame, $back_color, $fore_color, $cmyk);
3443 if ($filename === false) {
3444 header("Content-Type: application/postscript");
3445 header('Content-Disposition: filename="qrcode.eps"');
3448 if($saveandprint===TRUE){
3449 QRtools
::save($vect, $filename);
3450 header("Content-Type: application/postscript");
3451 header('Content-Disposition: filename="qrcode.eps"');
3454 QRtools
::save($vect, $filename);
3460 //----------------------------------------------------------------------
3461 private static function vectEPS($frame, $pixelPerPoint = 4, $outerFrame = 4, $back_color = 0xFFFFFF, $fore_color = 0x000000, $cmyk = false)
3464 $w = strlen($frame[0]);
3466 $imgW = $w +
2*$outerFrame;
3467 $imgH = $h +
2*$outerFrame;
3471 // convert color value into decimal eps format
3472 $c = round((($fore_color & 0xFF000000) >> 16) / 255, 5);
3473 $m = round((($fore_color & 0x00FF0000) >> 16) / 255, 5);
3474 $y = round((($fore_color & 0x0000FF00) >> 8) / 255, 5);
3475 $k = round(($fore_color & 0x000000FF) / 255, 5);
3476 $fore_color_string = $c.' '.$m.' '.$y.' '.$k.' setcmykcolor'."\n";
3478 // convert color value into decimal eps format
3479 $c = round((($back_color & 0xFF000000) >> 16) / 255, 5);
3480 $m = round((($back_color & 0x00FF0000) >> 16) / 255, 5);
3481 $y = round((($back_color & 0x0000FF00) >> 8) / 255, 5);
3482 $k = round(($back_color & 0x000000FF) / 255, 5);
3483 $back_color_string = $c.' '.$m.' '.$y.' '.$k.' setcmykcolor'."\n";
3487 // convert a hexadecimal color code into decimal eps format (green = 0 1 0, blue = 0 0 1, ...)
3488 $r = round((($fore_color & 0xFF0000) >> 16) / 255, 5);
3489 $b = round((($fore_color & 0x00FF00) >> 8) / 255, 5);
3490 $g = round(($fore_color & 0x0000FF) / 255, 5);
3491 $fore_color_string = $r.' '.$b.' '.$g.' setrgbcolor'."\n";
3493 // convert a hexadecimal color code into decimal eps format (green = 0 1 0, blue = 0 0 1, ...)
3494 $r = round((($back_color & 0xFF0000) >> 16) / 255, 5);
3495 $b = round((($back_color & 0x00FF00) >> 8) / 255, 5);
3496 $g = round(($back_color & 0x0000FF) / 255, 5);
3497 $back_color_string = $r.' '.$b.' '.$g.' setrgbcolor'."\n";
3501 '%!PS-Adobe EPSF-3.0'."\n".
3502 '%%Creator: PHPQrcodeLib'."\n".
3503 '%%Title: QRcode'."\n".
3504 '%%CreationDate: '.date('Y-m-d')."\n".
3505 '%%DocumentData: Clean7Bit'."\n".
3506 '%%LanguageLevel: 2'."\n".
3508 '%%BoundingBox: 0 0 '.$imgW * $pixelPerPoint.' '.$imgH * $pixelPerPoint."\n";
3511 $output .= $pixelPerPoint.' '.$pixelPerPoint.' scale'."\n";
3512 // position the center of the coordinate system
3514 $output .= $outerFrame.' '.$outerFrame.' translate'."\n";
3519 // redefine the 'rectfill' operator to shorten the syntax
3520 $output .= '/F { rectfill } def'."\n";
3522 // set the symbol color
3523 $output .= $back_color_string;
3524 $output .= '-'.$outerFrame.' -'.$outerFrame.' '.($w +
2*$outerFrame).' '.($h +
2*$outerFrame).' F'."\n";
3527 // set the symbol color
3528 $output .= $fore_color_string;
3530 // Convert the matrix into pixels
3532 for($i=0; $i<$h; $i++
) {
3533 for($j=0; $j<$w; $j++
) {
3534 if( $frame[$i][$j] == '1') {
3537 $output .= $x.' '.$y.' 1 1 F'."\n";
3548 //----------------------------------------------------------------------
3549 public static function svg($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE, $back_color, $fore_color)
3551 $vect = self
::vectSVG($frame, $pixelPerPoint, $outerFrame, $back_color, $fore_color);
3553 if ($filename === false) {
3554 header("Content-Type: image/svg+xml");
3555 //header('Content-Disposition: attachment, filename="qrcode.svg"');
3558 if($saveandprint===TRUE){
3559 QRtools
::save($vect, $filename);
3560 header("Content-Type: image/svg+xml");
3561 //header('Content-Disposition: filename="'.$filename.'"');
3564 QRtools
::save($vect, $filename);
3570 //----------------------------------------------------------------------
3571 private static function vectSVG($frame, $pixelPerPoint = 4, $outerFrame = 4, $back_color = 0xFFFFFF, $fore_color = 0x000000)
3574 $w = strlen($frame[0]);
3576 $imgW = $w +
2*$outerFrame;
3577 $imgH = $h +
2*$outerFrame;
3581 '<?xml version="1.0" encoding="utf-8"?>'."\n".
3582 '<svg version="1.1" baseProfile="full" width="'.$imgW * $pixelPerPoint.'" height="'.$imgH * $pixelPerPoint.'" viewBox="0 0 '.$imgW * $pixelPerPoint.' '.$imgH * $pixelPerPoint.'"
3583 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events">'."\n".
3584 '<desc></desc>'."\n";
3587 '<?xml version="1.0" encoding="utf-8"?>'."\n".
3588 '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">'."\n".
3589 '<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" xmlns:xlink="http://www.w3.org/1999/xlink" width="'.$imgW * $pixelPerPoint.'" height="'.$imgH * $pixelPerPoint.'" viewBox="0 0 '.$imgW * $pixelPerPoint.' '.$imgH * $pixelPerPoint.'">'."\n".
3590 '<desc></desc>'."\n";
3592 if(!empty($back_color)) {
3593 $backgroundcolor = str_pad(dechex($back_color), 6, "0", STR_PAD_LEFT
);
3594 $output .= '<rect width="'.$imgW * $pixelPerPoint.'" height="'.$imgH * $pixelPerPoint.'" fill="#'.$backgroundcolor.'" cx="0" cy="0" />'."\n";
3599 '<rect id="p" width="'.$pixelPerPoint.'" height="'.$pixelPerPoint.'" />'."\n".
3601 '<g fill="#'.str_pad(dechex($fore_color), 6, "0", STR_PAD_LEFT
).'">'."\n";
3604 // Convert the matrix into pixels
3606 for($i=0; $i<$h; $i++
) {
3607 for($j=0; $j<$w; $j++
) {
3608 if( $frame[$i][$j] == '1') {
3609 $y = ($i +
$outerFrame) * $pixelPerPoint;
3610 $x = ($j +
$outerFrame) * $pixelPerPoint;
3611 $output .= '<use x="'.$x.'" y="'.$y.'" xlink:href="#p" />'."\n";