[PHP] php phpqrcode 生成二维码 →→→→→进入此内容的聊天室

来自 , 2020-02-03, 写在 PHP, 查看 118 次.
URL http://www.code666.cn/view/7fcc48d2
  1. http://blog.csdn.net/u010861514/article/details/46442819#
  2.  
  3.  
  4. <?php  
  5. // ==============php phpqrcode 生成二维码========================  
  6. // 下载地址:http://sourceforge.net/projects/phpqrcode/files/latest/download  
  7. // 只需要包含 phpqrcode.php 文件就可以。  
  8.  
  9. // 一:直接输出  
  10. include "./phpqrcode.php";  
  11. $value="http://www.useryx.com";  
  12. $errorCorrectionLevel = "L"; // 纠错级别:L、M、Q、H  
  13. $matrixPointSize = "4"; // 点的大小:1到10  
  14. QRcode::png($value, false, $errorCorrectionLevel, $matrixPointSize);  
  15.  
  16.  
  17. // 二:图片文件输出  
  18. include('./phpqrcode.php');  
  19. $data = 'http://www.useryx.com';  
  20. $filename = 'useryx.png';  //  生成的文件名  
  21. $errorCorrectionLevel = 'L';  // 纠错级别:L、M、Q、H  
  22. $matrixPointSize = 4; // 点的大小:1到10  
  23. QRcode::png($data, $filename, $errorCorrectionLevel, $matrixPointSize, 2);  
  24.  
  25.  
  26. //三: 生成中间带logo的二维码  
  27. include('./phpqrcode.php');  
  28. $value='http://www.useryx.com';  
  29. $logo = 'logo.jpg'; // 中间的logo  
  30. $QR = "base.png"; // 自定义生成的。结束后可以删除  
  31. $last = "last.png"; // 最终生成的图片  
  32. $errorCorrectionLevel = 'L';  
  33. $matrixPointSize = 10;  
  34. QRcode::png($value, $QR, $errorCorrectionLevel, $matrixPointSize, 2);  
  35. if($logo !== FALSE){  
  36.     $logo = imagecreatefromstring(file_get_contents($logo));  
  37.     $QR_width = imagesx($QR);  
  38.     $QR_height = imagesy($QR);  
  39.     $logo_width = imagesx($logo);  
  40.     $logo_height = imagesy($logo);  
  41.     $logo_qr_width = $QR_width / 5;  
  42.     $scale = $logo_width / $logo_qr_width;  
  43.     $logo_qr_height = $logo_height / $scale;  
  44.     $from_width = ($QR_width - $logo_qr_width) / 2;  
  45.     imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_qr_width, $logo_qr_height, $logo_width, $logo_height);  
  46. }  
  47. imagepng($QR,$last); // 生成最终的文件  
  48. ?>  
  49. [php] view plain copy
  50. </pre><pre name="code" class="php">  
  51. [php] view plain copy
  52. </pre><pre name="code" class="php">  
  53. [php] view plain copy
  54. </pre><pre name="code" class="php">  
  55. [php] view plain copy
  56. phpqrcode.php  
  57. [php] view plain copy
  58. <?php  
  59. /*
  60.  * PHP QR Code encoder
  61.  *
  62.  * This file contains MERGED version of PHP QR Code library.
  63.  * It was auto-generated from full version for your convenience.
  64.  *
  65.  * This merged version was configured to not requre any external files,
  66.  * with disabled cache, error loging and weker but faster mask matching.
  67.  * If you need tune it up please use non-merged version.
  68.  *
  69.  * For full version, documentation, examples of use please visit:
  70.  *
  71.  *    http://phpqrcode.sourceforge.net/
  72.  *    https://sourceforge.net/projects/phpqrcode/
  73.  *
  74.  * PHP QR Code is distributed under LGPL 3
  75.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  76.  *
  77.  * This library is free software; you can redistribute it and/or
  78.  * modify it under the terms of the GNU Lesser General Public
  79.  * License as published by the Free Software Foundation; either
  80.  * version 3 of the License, or any later version.
  81.  *
  82.  * This library is distributed in the hope that it will be useful,
  83.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  84.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  85.  * Lesser General Public License for more details.
  86.  *
  87.  * You should have received a copy of the GNU Lesser General Public
  88.  * License along with this library; if not, write to the Free Software
  89.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  90.  */  
  91.    
  92.    
  93.  
  94.  
  95. /*
  96.  * Version: 1.1.4
  97.  * Build: 2010100721
  98.  */  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105. //---- qrconst.php -----------------------------  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116. /*
  117.  * PHP QR Code encoder
  118.  *
  119.  * Common constants
  120.  *
  121.  * Based on libqrencode C library distributed under LGPL 2.1
  122.  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  123.  *
  124.  * PHP QR Code is distributed under LGPL 3
  125.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  126.  *
  127.  * This library is free software; you can redistribute it and/or
  128.  * modify it under the terms of the GNU Lesser General Public
  129.  * License as published by the Free Software Foundation; either
  130.  * version 3 of the License, or any later version.
  131.  *
  132.  * This library is distributed in the hope that it will be useful,
  133.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  134.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  135.  * Lesser General Public License for more details.
  136.  *
  137.  * You should have received a copy of the GNU Lesser General Public
  138.  * License along with this library; if not, write to the Free Software
  139.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  140.  */  
  141.    
  142. <span style="white-space:pre">    </span>// Encoding modes  
  143. <span style="white-space:pre">    </span>  
  144. <span style="white-space:pre">    </span>define('QR_MODE_NUL', -1);  
  145. <span style="white-space:pre">    </span>define('QR_MODE_NUM', 0);  
  146. <span style="white-space:pre">    </span>define('QR_MODE_AN', 1);  
  147. <span style="white-space:pre">    </span>define('QR_MODE_8', 2);  
  148. <span style="white-space:pre">    </span>define('QR_MODE_KANJI', 3);  
  149. <span style="white-space:pre">    </span>define('QR_MODE_STRUCTURE', 4);  
  150.  
  151.  
  152. <span style="white-space:pre">    </span>// Levels of error correction.  
  153.  
  154.  
  155. <span style="white-space:pre">    </span>define('QR_ECLEVEL_L', 0);  
  156. <span style="white-space:pre">    </span>define('QR_ECLEVEL_M', 1);  
  157. <span style="white-space:pre">    </span>define('QR_ECLEVEL_Q', 2);  
  158. <span style="white-space:pre">    </span>define('QR_ECLEVEL_H', 3);  
  159. <span style="white-space:pre">    </span>  
  160. <span style="white-space:pre">    </span>// Supported output formats  
  161. <span style="white-space:pre">    </span>  
  162. <span style="white-space:pre">    </span>define('QR_FORMAT_TEXT', 0);  
  163. <span style="white-space:pre">    </span>define('QR_FORMAT_PNG',  1);  
  164. <span style="white-space:pre">    </span>  
  165. <span style="white-space:pre">    </span>class qrstr {  
  166. <span style="white-space:pre">        </span>public static function set(&$srctab, $x, $y, $repl, $replLen = false) {  
  167. <span style="white-space:pre">            </span>$srctab[$y] = substr_replace($srctab[$y], ($replLen !== false)?substr($repl,0,$replLen):$repl, $x, ($replLen !== false)?$replLen:strlen($repl));  
  168. <span style="white-space:pre">        </span>}  
  169. <span style="white-space:pre">    </span>}<span style="white-space:pre">  </span>  
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176. //---- merged_config.php -----------------------------  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185. /*
  186.  * PHP QR Code encoder
  187.  *
  188.  * Config file, tuned-up for merged verion
  189.  */  
  190.        
  191.     define('QR_CACHEABLE', false);       // use cache - more disk reads but less CPU power, masks and format templates are stored there  
  192.     define('QR_CACHE_DIR', false);       // used when QR_CACHEABLE === true  
  193.     define('QR_LOG_DIR', false);         // default error logs dir    
  194.      
  195.     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  
  196.     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  
  197.     define('QR_DEFAULT_MASK', 2);                                                               // when QR_FIND_BEST_MASK === false  
  198.                                                    
  199.     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  
  200.                                                    
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207. //---- qrtools.php -----------------------------  
  208.  
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216. /*
  217.  * PHP QR Code encoder
  218.  *
  219.  * Toolset, handy and debug utilites.
  220.  *
  221.  * PHP QR Code is distributed under LGPL 3
  222.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  223.  *
  224.  * This library is free software; you can redistribute it and/or
  225.  * modify it under the terms of the GNU Lesser General Public
  226.  * License as published by the Free Software Foundation; either
  227.  * version 3 of the License, or any later version.
  228.  *
  229.  * This library is distributed in the hope that it will be useful,
  230.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  231.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  232.  * Lesser General Public License for more details.
  233.  *
  234.  * You should have received a copy of the GNU Lesser General Public
  235.  * License along with this library; if not, write to the Free Software
  236.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  237.  */  
  238.  
  239.  
  240.     class QRtools {  
  241.      
  242.         //----------------------------------------------------------------------  
  243.         public static function binarize($frame)  
  244.         {  
  245.             $len = count($frame);  
  246.             foreach ($frame as &$frameLine) {  
  247.                  
  248.                 for($i=0; $i<$len; $i++) {  
  249.                     $frameLine[$i] = (ord($frameLine[$i])&1)?'1':'0';  
  250.                 }  
  251.             }  
  252.              
  253.             return $frame;  
  254.         }  
  255.          
  256.         //----------------------------------------------------------------------  
  257.         public static function tcpdfBarcodeArray($code, $mode = 'QR,L', $tcPdfVersion = '4.5.037')  
  258.         {  
  259.             $barcode_array = array();  
  260.              
  261.             if (!is_array($mode))  
  262.                 $mode = explode(',', $mode);  
  263.                  
  264.             $eccLevel = 'L';  
  265.                  
  266.             if (count($mode) > 1) {  
  267.                 $eccLevel = $mode[1];  
  268.             }  
  269.                  
  270.             $qrTab = QRcode::text($code, false, $eccLevel);  
  271.             $size = count($qrTab);  
  272.                  
  273.             $barcode_array['num_rows'] = $size;  
  274.             $barcode_array['num_cols'] = $size;  
  275.             $barcode_array['bcode'] = array();  
  276.                  
  277.             foreach ($qrTab as $line) {  
  278.                 $arrAdd = array();  
  279.                 foreach(str_split($line) as $char)  
  280.                     $arrAdd[] = ($char=='1')?1:0;  
  281.                 $barcode_array['bcode'][] = $arrAdd;  
  282.             }  
  283.                      
  284.             return $barcode_array;  
  285.         }  
  286.          
  287.         //----------------------------------------------------------------------  
  288.         public static function clearCache()  
  289.         {  
  290.             self::$frames = array();  
  291.         }  
  292.          
  293.         //----------------------------------------------------------------------  
  294.         public static function buildCache()  
  295.         {  
  296. <span style="white-space:pre">            </span>QRtools::markTime('before_build_cache');  
  297. <span style="white-space:pre">            </span>  
  298. <span style="white-space:pre">            </span>$mask = new QRmask();  
  299.             for ($a=1; $a <= QRSPEC_VERSION_MAX; $a++) {  
  300.                 $frame = QRspec::newFrame($a);  
  301.                 if (QR_IMAGE) {  
  302.                     $fileName = QR_CACHE_DIR.'frame_'.$a.'.png';  
  303.                     QRimage::png(self::binarize($frame), $fileName, 1, 0);  
  304.                 }  
  305. <span style="white-space:pre">                </span>  
  306. <span style="white-space:pre">                </span>$width = count($frame);  
  307. <span style="white-space:pre">                </span>$bitMask = array_fill(0, $width, array_fill(0, $width, 0));  
  308. <span style="white-space:pre">                </span>for ($maskNo=0; $maskNo<8; $maskNo++)  
  309. <span style="white-space:pre">                    </span>$mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true);  
  310.             }  
  311. <span style="white-space:pre">            </span>  
  312. <span style="white-space:pre">            </span>QRtools::markTime('after_build_cache');  
  313.         }  
  314.  
  315.  
  316.         //----------------------------------------------------------------------  
  317.         public static function log($outfile, $err)  
  318.         {  
  319.             if (QR_LOG_DIR !== false) {  
  320.                 if ($err != '') {  
  321.                     if ($outfile !== false) {  
  322.                         file_put_contents(QR_LOG_DIR.basename($outfile).'-errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);  
  323.                     } else {  
  324.                         file_put_contents(QR_LOG_DIR.'errors.txt', date('Y-m-d H:i:s').': '.$err, FILE_APPEND);  
  325.                     }  
  326.                 }      
  327.             }  
  328.         }  
  329.          
  330.         //----------------------------------------------------------------------  
  331.         public static function dumpMask($frame)  
  332.         {  
  333.             $width = count($frame);  
  334.             for($y=0;$y<$width;$y++) {  
  335.                 for($x=0;$x<$width;$x++) {  
  336.                     echo ord($frame[$y][$x]).',';  
  337.                 }  
  338.             }  
  339.         }  
  340.          
  341.         //----------------------------------------------------------------------  
  342.         public static function markTime($markerId)  
  343.         {  
  344.             list($usec, $sec) = explode(" ", microtime());  
  345.             $time = ((float)$usec + (float)$sec);  
  346.              
  347.             if (!isset($GLOBALS['qr_time_bench']))  
  348.                 $GLOBALS['qr_time_bench'] = array();  
  349.              
  350.             $GLOBALS['qr_time_bench'][$markerId] = $time;  
  351.         }  
  352.          
  353.         //----------------------------------------------------------------------  
  354.         public static function timeBenchmark()  
  355.         {  
  356.             self::markTime('finish');  
  357.          
  358.             $lastTime = 0;  
  359.             $startTime = 0;  
  360.             $p = 0;  
  361.  
  362.  
  363.             echo '<table cellpadding="3" cellspacing="1">  
  364.                    <thead><tr style="border-bottom:1px solid silver"><td colspan="2" style="text-align:center">BENCHMARK</td></tr></thead>  
  365.                    <tbody>';  
  366.  
  367.  
  368.             foreach($GLOBALS['qr_time_bench'] as $markerId=>$thisTime) {  
  369.                 if ($p > 0) {  
  370.                     echo '<tr><th style="text-align:right">till '.$markerId.': </th><td>'.number_format($thisTime-$lastTime, 6).'s</td></tr>';  
  371.                 } else {  
  372.                     $startTime = $thisTime;  
  373.                 }  
  374.                  
  375.                 $p++;  
  376.                 $lastTime = $thisTime;  
  377.             }  
  378.              
  379.             echo '</tbody><tfoot>  
  380.                <tr style="border-top:2px solid black"><th style="text-align:right">TOTAL: </th><td>'.number_format($lastTime-$startTime, 6).'s</td></tr>  
  381.            </tfoot>  
  382.            </table>';  
  383.         }  
  384.          
  385.     }  
  386.      
  387.     //##########################################################################  
  388.      
  389.     QRtools::markTime('start');  
  390.      
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397. //---- qrspec.php -----------------------------  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406. /*
  407.  * PHP QR Code encoder
  408.  *
  409.  * QR Code specifications
  410.  *
  411.  * Based on libqrencode C library distributed under LGPL 2.1
  412.  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  413.  *
  414.  * PHP QR Code is distributed under LGPL 3
  415.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  416.  *
  417.  * The following data / specifications are taken from
  418.  * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
  419.  *  or
  420.  * "Automatic identification and data capture techniques --  
  421.  *  QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
  422.  *
  423.  * This library is free software; you can redistribute it and/or
  424.  * modify it under the terms of the GNU Lesser General Public
  425.  * License as published by the Free Software Foundation; either
  426.  * version 3 of the License, or any later version.
  427.  *
  428.  * This library is distributed in the hope that it will be useful,
  429.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  430.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  431.  * Lesser General Public License for more details.
  432.  *
  433.  * You should have received a copy of the GNU Lesser General Public
  434.  * License along with this library; if not, write to the Free Software
  435.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  436.  */  
  437.    
  438.     define('QRSPEC_VERSION_MAX', 40);  
  439.     define('QRSPEC_WIDTH_MAX',   177);  
  440.  
  441.  
  442.     define('QRCAP_WIDTH',        0);  
  443.     define('QRCAP_WORDS',        1);  
  444.     define('QRCAP_REMINDER',     2);  
  445.     define('QRCAP_EC',           3);  
  446.  
  447.  
  448.     class QRspec {  
  449.      
  450.         public static $capacity = array(  
  451.             array(  0,    0, 0, array(   0,    0,    0,    0)),  
  452.             array( 21,   26, 0, array(   7,   10,   13,   17)), // 1  
  453.             array( 25,   44, 7, array(  10,   16,   22,   28)),  
  454.             array( 29,   70, 7, array(  15,   26,   36,   44)),  
  455.             array( 33,  100, 7, array(  20,   36,   52,   64)),  
  456.             array( 37,  134, 7, array(  26,   48,   72,   88)), // 5  
  457.             array( 41,  172, 7, array(  36,   64,   96,  112)),  
  458.             array( 45,  196, 0, array(  40,   72,  108,  130)),  
  459.             array( 49,  242, 0, array(  48,   88,  132,  156)),  
  460.             array( 53,  292, 0, array(  60,  110,  160,  192)),  
  461.             array( 57,  346, 0, array(  72,  130,  192,  224)), //10  
  462.             array( 61,  404, 0, array(  80,  150,  224,  264)),  
  463.             array( 65,  466, 0, array(  96,  176,  260,  308)),  
  464.             array( 69,  532, 0, array( 104,  198,  288,  352)),  
  465.             array( 73,  581, 3, array( 120,  216,  320,  384)),  
  466.             array( 77,  655, 3, array( 132,  240,  360,  432)), //15  
  467.             array( 81,  733, 3, array( 144,  280,  408,  480)),  
  468.             array( 85,  815, 3, array( 168,  308,  448,  532)),  
  469.             array( 89,  901, 3, array( 180,  338,  504,  588)),  
  470.             array( 93,  991, 3, array( 196,  364,  546,  650)),  
  471.             array( 97, 1085, 3, array( 224,  416,  600,  700)), //20  
  472.             array(101, 1156, 4, array( 224,  442,  644,  750)),  
  473.             array(105, 1258, 4, array( 252,  476,  690,  816)),  
  474.             array(109, 1364, 4, array( 270,  504,  750,  900)),  
  475.             array(113, 1474, 4, array( 300,  560,  810,  960)),  
  476.             array(117, 1588, 4, array( 312,  588,  870, 1050)), //25  
  477.             array(121, 1706, 4, array( 336,  644,  952, 1110)),  
  478.             array(125, 1828, 4, array( 360,  700, 1020, 1200)),  
  479.             array(129, 1921, 3, array( 390,  728, 1050, 1260)),  
  480.             array(133, 2051, 3, array( 420,  784, 1140, 1350)),  
  481.             array(137, 2185, 3, array( 450,  812, 1200, 1440)), //30  
  482.             array(141, 2323, 3, array( 480,  868, 1290, 1530)),  
  483.             array(145, 2465, 3, array( 510,  924, 1350, 1620)),  
  484.             array(149, 2611, 3, array( 540,  980, 1440, 1710)),  
  485.             array(153, 2761, 3, array( 570, 1036, 1530, 1800)),  
  486.             array(157, 2876, 0, array( 570, 1064, 1590, 1890)), //35  
  487.             array(161, 3034, 0, array( 600, 1120, 1680, 1980)),  
  488.             array(165, 3196, 0, array( 630, 1204, 1770, 2100)),  
  489.             array(169, 3362, 0, array( 660, 1260, 1860, 2220)),  
  490.             array(173, 3532, 0, array( 720, 1316, 1950, 2310)),  
  491.             array(177, 3706, 0, array( 750, 1372, 2040, 2430)) //40  
  492.         );  
  493.          
  494.         //----------------------------------------------------------------------  
  495.         public static function getDataLength($version, $level)  
  496.         {  
  497.             return self::$capacity[$version][QRCAP_WORDS] - self::$capacity[$version][QRCAP_EC][$level];  
  498.         }  
  499.          
  500.         //----------------------------------------------------------------------  
  501.         public static function getECCLength($version, $level)  
  502.         {  
  503.             return self::$capacity[$version][QRCAP_EC][$level];  
  504.         }  
  505.          
  506.         //----------------------------------------------------------------------  
  507.         public static function getWidth($version)  
  508.         {  
  509.             return self::$capacity[$version][QRCAP_WIDTH];  
  510.         }  
  511.          
  512.         //----------------------------------------------------------------------  
  513.         public static function getRemainder($version)  
  514.         {  
  515.             return self::$capacity[$version][QRCAP_REMINDER];  
  516.         }  
  517.          
  518.         //----------------------------------------------------------------------  
  519.         public static function getMinimumVersion($size, $level)  
  520.         {  
  521.  
  522.  
  523.             for($i=1; $i<= QRSPEC_VERSION_MAX; $i++) {  
  524.                 $words  = self::$capacity[$i][QRCAP_WORDS] - self::$capacity[$i][QRCAP_EC][$level];  
  525.                 if($words >= $size)  
  526.                     return $i;  
  527.             }  
  528.  
  529.  
  530.             return -1;  
  531.         }  
  532.      
  533.         //######################################################################  
  534.          
  535.         public static $lengthTableBits = array(  
  536.             array(10, 12, 14),  
  537.             array( 9, 11, 13),  
  538.             array( 8, 16, 16),  
  539.             array( 8, 10, 12)  
  540.         );  
  541.          
  542.         //----------------------------------------------------------------------  
  543.         public static function lengthIndicator($mode, $version)  
  544.         {  
  545.             if ($mode == QR_MODE_STRUCTURE)  
  546.                 return 0;  
  547.                  
  548.             if ($version <= 9) {  
  549.                 $l = 0;  
  550.             } else if ($version <= 26) {  
  551.                 $l = 1;  
  552.             } else {  
  553.                 $l = 2;  
  554.             }  
  555.  
  556.  
  557.             return self::$lengthTableBits[$mode][$l];  
  558.         }  
  559.          
  560.         //----------------------------------------------------------------------  
  561.         public static function maximumWords($mode, $version)  
  562.         {  
  563.             if($mode == QR_MODE_STRUCTURE)  
  564.                 return 3;  
  565.                  
  566.             if($version <= 9) {  
  567.                 $l = 0;  
  568.             } else if($version <= 26) {  
  569.                 $l = 1;  
  570.             } else {  
  571.                 $l = 2;  
  572.             }  
  573.  
  574.  
  575.             $bits = self::$lengthTableBits[$mode][$l];  
  576.             $words = (1 << $bits) - 1;  
  577.              
  578.             if($mode == QR_MODE_KANJI) {  
  579.                 $words *= 2; // the number of bytes is required  
  580.             }  
  581.  
  582.  
  583.             return $words;  
  584.         }  
  585.  
  586.  
  587.         // Error correction code -----------------------------------------------  
  588.         // Table of the error correction code (Reed-Solomon block)  
  589.         // See Table 12-16 (pp.30-36), JIS X0510:2004.  
  590.  
  591.  
  592.         public static $eccTable = array(  
  593.             array(array( 0,  0), array( 0,  0), array( 0,  0), array( 0,  0)),  
  594.             array(array( 1,  0), array( 1,  0), array( 1,  0), array( 1,  0)), // 1  
  595.             array(array( 1,  0), array( 1,  0), array( 1,  0), array( 1,  0)),  
  596.             array(array( 1,  0), array( 1,  0), array( 2,  0), array( 2,  0)),  
  597.             array(array( 1,  0), array( 2,  0), array( 2,  0), array( 4,  0)),  
  598.             array(array( 1,  0), array( 2,  0), array( 2,  2), array( 2,  2)), // 5  
  599.             array(array( 2,  0), array( 4,  0), array( 4,  0), array( 4,  0)),  
  600.             array(array( 2,  0), array( 4,  0), array( 2,  4), array( 4,  1)),  
  601.             array(array( 2,  0), array( 2,  2), array( 4,  2), array( 4,  2)),  
  602.             array(array( 2,  0), array( 3,  2), array( 4,  4), array( 4,  4)),  
  603.             array(array( 2,  2), array( 4,  1), array( 6,  2), array( 6,  2)), //10  
  604.             array(array( 4,  0), array( 1,  4), array( 4,  4), array( 3,  8)),  
  605.             array(array( 2,  2), array( 6,  2), array( 4,  6), array( 7,  4)),  
  606.             array(array( 4,  0), array( 8,  1), array( 8,  4), array(12,  4)),  
  607.             array(array( 3,  1), array( 4,  5), array(11,  5), array(11,  5)),  
  608.             array(array( 5,  1), array( 5,  5), array( 5,  7), array(11,  7)), //15  
  609.             array(array( 5,  1), array( 7,  3), array(15,  2), array( 3, 13)),  
  610.             array(array( 1,  5), array(10,  1), array( 1, 15), array( 2, 17)),  
  611.             array(array( 5,  1), array( 9,  4), array(17,  1), array( 2, 19)),  
  612.             array(array( 3,  4), array( 3, 11), array(17,  4), array( 9, 16)),  
  613.             array(array( 3,  5), array( 3, 13), array(15,  5), array(15, 10)), //20  
  614.             array(array( 4,  4), array(17,  0), array(17,  6), array(19,  6)),  
  615.             array(array( 2,  7), array(17,  0), array( 7, 16), array(34,  0)),  
  616.             array(array( 4,  5), array( 4, 14), array(11, 14), array(16, 14)),  
  617.             array(array( 6,  4), array( 6, 14), array(11, 16), array(30,  2)),  
  618.             array(array( 8,  4), array( 8, 13), array( 7, 22), array(22, 13)), //25  
  619.             array(array(10,  2), array(19,  4), array(28,  6), array(33,  4)),  
  620.             array(array( 8,  4), array(22,  3), array( 8, 26), array(12, 28)),  
  621.             array(array( 3, 10), array( 3, 23), array( 4, 31), array(11, 31)),  
  622.             array(array( 7,  7), array(21,  7), array( 1, 37), array(19, 26)),  
  623.             array(array( 5, 10), array(19, 10), array(15, 25), array(23, 25)), //30  
  624.             array(array(13,  3), array( 2, 29), array(42,  1), array(23, 28)),  
  625.             array(array(17,  0), array(10, 23), array(10, 35), array(19, 35)),  
  626.             array(array(17,  1), array(14, 21), array(29, 19), array(11, 46)),  
  627.             array(array(13,  6), array(14, 23), array(44,  7), array(59,  1)),  
  628.             array(array(12,  7), array(12, 26), array(39, 14), array(22, 41)), //35  
  629.             array(array( 6, 14), array( 6, 34), array(46, 10), array( 2, 64)),  
  630.             array(array(17,  4), array(29, 14), array(49, 10), array(24, 46)),  
  631.             array(array( 4, 18), array(13, 32), array(48, 14), array(42, 32)),  
  632.             array(array(20,  4), array(40,  7), array(43, 22), array(10, 67)),  
  633.             array(array(19,  6), array(18, 31), array(34, 34), array(20, 61)),//40  
  634.         );                                                                        
  635.  
  636.  
  637.         //----------------------------------------------------------------------  
  638.         // CACHEABLE!!!  
  639.          
  640.         public static function getEccSpec($version, $level, array &$spec)  
  641.         {  
  642.             if (count($spec) < 5) {  
  643.                 $spec = array(0,0,0,0,0);  
  644.             }  
  645.  
  646.  
  647.             $b1   = self::$eccTable[$version][$level][0];  
  648.             $b2   = self::$eccTable[$version][$level][1];  
  649.             $data = self::getDataLength($version, $level);  
  650.             $ecc  = self::getECCLength($version, $level);  
  651.  
  652.  
  653.             if($b2 == 0) {  
  654.                 $spec[0] = $b1;  
  655.                 $spec[1] = (int)($data / $b1);  
  656.                 $spec[2] = (int)($ecc / $b1);  
  657.                 $spec[3] = 0;  
  658.                 $spec[4] = 0;  
  659.             } else {  
  660.                 $spec[0] = $b1;  
  661.                 $spec[1] = (int)($data / ($b1 + $b2));  
  662.                 $spec[2] = (int)($ecc  / ($b1 + $b2));  
  663.                 $spec[3] = $b2;  
  664.                 $spec[4] = $spec[1] + 1;  
  665.             }  
  666.         }  
  667.  
  668.  
  669.         // Alignment pattern ---------------------------------------------------  
  670.  
  671.  
  672.         // Positions of alignment patterns.  
  673.         // This array includes only the second and the third position of the  
  674.         // alignment patterns. Rest of them can be calculated from the distance  
  675.         // between them.  
  676.            
  677.         // See Table 1 in Appendix E (pp.71) of JIS X0510:2004.  
  678.            
  679.         public static $alignmentPattern = array(        
  680.             array( 0,  0),  
  681.             array( 0,  0), array(18,  0), array(22,  0), array(26,  0), array(30,  0), // 1- 5  
  682.             array(34,  0), array(22, 38), array(24, 42), array(26, 46), array(28, 50), // 6-10  
  683.             array(30, 54), array(32, 58), array(34, 62), array(26, 46), array(26, 48), //11-15  
  684.             array(26, 50), array(30, 54), array(30, 56), array(30, 58), array(34, 62), //16-20  
  685.             array(28, 50), array(26, 50), array(30, 54), array(28, 54), array(32, 58), //21-25  
  686.             array(30, 58), array(34, 62), array(26, 50), array(30, 54), array(26, 52), //26-30  
  687.             array(30, 56), array(34, 60), array(30, 58), array(34, 62), array(30, 54), //31-35  
  688.             array(24, 50), array(28, 54), array(32, 58), array(26, 54), array(30, 58), //35-40  
  689.         );                                                                                    
  690.  
  691.  
  692.          
  693.         /** --------------------------------------------------------------------
  694.          * Put an alignment marker.
  695.          * @param frame
  696.          * @param width
  697.          * @param ox,oy center coordinate of the pattern
  698.          */  
  699.         public static function putAlignmentMarker(array &$frame, $ox, $oy)  
  700.         {  
  701.             $finder = array(  
  702.                 "\xa1\xa1\xa1\xa1\xa1",  
  703.                 "\xa1\xa0\xa0\xa0\xa1",  
  704.                 "\xa1\xa0\xa1\xa0\xa1",  
  705.                 "\xa1\xa0\xa0\xa0\xa1",  
  706.                 "\xa1\xa1\xa1\xa1\xa1"  
  707.             );                          
  708.              
  709.             $yStart = $oy-2;          
  710.             $xStart = $ox-2;  
  711.              
  712.             for($y=0; $y<5; $y++) {  
  713.                 QRstr::set($frame, $xStart, $yStart+$y, $finder[$y]);  
  714.             }  
  715.         }  
  716.  
  717.  
  718.         //----------------------------------------------------------------------  
  719.         public static function putAlignmentPattern($version, &$frame, $width)  
  720.         {  
  721.             if($version < 2)  
  722.                 return;  
  723.  
  724.  
  725.             $d = self::$alignmentPattern[$version][1] - self::$alignmentPattern[$version][0];  
  726.             if($d < 0) {  
  727.                 $w = 2;  
  728.             } else {  
  729.                 $w = (int)(($width - self::$alignmentPattern[$version][0]) / $d + 2);  
  730.             }  
  731.  
  732.  
  733.             if($w * $w - 3 == 1) {  
  734.                 $x = self::$alignmentPattern[$version][0];  
  735.                 $y = self::$alignmentPattern[$version][0];  
  736.                 self::putAlignmentMarker($frame, $x, $y);  
  737.                 return;  
  738.             }  
  739.  
  740.  
  741.             $cx = self::$alignmentPattern[$version][0];  
  742.             for($x=1; $x<$w - 1; $x++) {  
  743.                 self::putAlignmentMarker($frame, 6, $cx);  
  744.                 self::putAlignmentMarker($frame, $cx,  6);  
  745.                 $cx += $d;  
  746.             }  
  747.  
  748.  
  749.             $cy = self::$alignmentPattern[$version][0];  
  750.             for($y=0; $y<$w-1; $y++) {  
  751.                 $cx = self::$alignmentPattern[$version][0];  
  752.                 for($x=0; $x<$w-1; $x++) {  
  753.                     self::putAlignmentMarker($frame, $cx, $cy);  
  754.                     $cx += $d;  
  755.                 }  
  756.                 $cy += $d;  
  757.             }  
  758.         }  
  759.  
  760.  
  761.         // Version information pattern -----------------------------------------  
  762.  
  763.  
  764. <span style="white-space:pre">        </span>// Version information pattern (BCH coded).  
  765.         // See Table 1 in Appendix D (pp.68) of JIS X0510:2004.  
  766.          
  767. <span style="white-space:pre">        </span>// size: [QRSPEC_VERSION_MAX - 6]  
  768. <span style="white-space:pre">        </span>  
  769.         public static $versionPattern = array(  
  770.             0x07c94, 0x085bc, 0x09a99, 0x0a4d3, 0x0bbf6, 0x0c762, 0x0d847, 0x0e60d,  
  771.             0x0f928, 0x10b78, 0x1145d, 0x12a17, 0x13532, 0x149a6, 0x15683, 0x168c9,  
  772.             0x177ec, 0x18ec4, 0x191e1, 0x1afab, 0x1b08e, 0x1cc1a, 0x1d33f, 0x1ed75,  
  773.             0x1f250, 0x209d5, 0x216f0, 0x228ba, 0x2379f, 0x24b0b, 0x2542e, 0x26a64,  
  774.             0x27541, 0x28c69  
  775.         );  
  776.  
  777.  
  778.         //----------------------------------------------------------------------  
  779.         public static function getVersionPattern($version)  
  780.         {  
  781.             if($version < 7 || $version > QRSPEC_VERSION_MAX)  
  782.                 return 0;  
  783.  
  784.  
  785.             return self::$versionPattern[$version -7];  
  786.         }  
  787.  
  788.  
  789.         // Format information --------------------------------------------------  
  790.         // See calcFormatInfo in tests/test_qrspec.c (orginal qrencode c lib)  
  791.          
  792.         public static $formatInfo = array(  
  793.             array(0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976),  
  794.             array(0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0),  
  795.             array(0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed),  
  796.             array(0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b)  
  797.         );  
  798.  
  799.  
  800.         public static function getFormatInfo($mask, $level)  
  801.         {  
  802.             if($mask < 0 || $mask > 7)  
  803.                 return 0;  
  804.                  
  805.             if($level < 0 || $level > 3)  
  806.                 return 0;                  
  807.  
  808.  
  809.             return self::$formatInfo[$level][$mask];  
  810.         }  
  811.  
  812.  
  813.         // Frame ---------------------------------------------------------------  
  814.         // Cache of initial frames.  
  815.            
  816.         public static $frames = array();  
  817.  
  818.  
  819.         /** --------------------------------------------------------------------
  820.          * Put a finder pattern.
  821.          * @param frame
  822.          * @param width
  823.          * @param ox,oy upper-left coordinate of the pattern
  824.          */  
  825.         public static function putFinderPattern(&$frame, $ox, $oy)  
  826.         {  
  827.             $finder = array(  
  828.                 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1",  
  829.                 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",  
  830.                 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",  
  831.                 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",  
  832.                 "\xc1\xc0\xc1\xc1\xc1\xc0\xc1",  
  833.                 "\xc1\xc0\xc0\xc0\xc0\xc0\xc1",  
  834.                 "\xc1\xc1\xc1\xc1\xc1\xc1\xc1"  
  835.             );                              
  836.              
  837.             for($y=0; $y<7; $y++) {  
  838.                 QRstr::set($frame, $ox, $oy+$y, $finder[$y]);  
  839.             }  
  840.         }  
  841.  
  842.  
  843.         //----------------------------------------------------------------------  
  844.         public static function createFrame($version)  
  845.         {  
  846.             $width = self::$capacity[$version][QRCAP_WIDTH];  
  847.             $frameLine = str_repeat ("\0", $width);  
  848.             $frame = array_fill(0, $width, $frameLine);  
  849.  
  850.  
  851.             // Finder pattern  
  852.             self::putFinderPattern($frame, 0, 0);  
  853.             self::putFinderPattern($frame, $width - 7, 0);  
  854.             self::putFinderPattern($frame, 0, $width - 7);  
  855.              
  856.             // Separator  
  857.             $yOffset = $width - 7;  
  858.              
  859.             for($y=0; $y<7; $y++) {  
  860.                 $frame[$y][7] = "\xc0";  
  861.                 $frame[$y][$width - 8] = "\xc0";  
  862.                 $frame[$yOffset][7] = "\xc0";  
  863.                 $yOffset++;  
  864.             }  
  865.              
  866.             $setPattern = str_repeat("\xc0", 8);  
  867.              
  868.             QRstr::set($frame, 0, 7, $setPattern);  
  869.             QRstr::set($frame, $width-8, 7, $setPattern);  
  870.             QRstr::set($frame, 0, $width - 8, $setPattern);  
  871.          
  872.             // Format info  
  873.             $setPattern = str_repeat("\x84", 9);  
  874.             QRstr::set($frame, 0, 8, $setPattern);  
  875.             QRstr::set($frame, $width - 8, 8, $setPattern, 8);  
  876.              
  877.             $yOffset = $width - 8;  
  878.  
  879.  
  880.             for($y=0; $y<8; $y++,$yOffset++) {  
  881.                 $frame[$y][8] = "\x84";  
  882.                 $frame[$yOffset][8] = "\x84";  
  883.             }  
  884.  
  885.  
  886.             // Timing pattern    
  887.              
  888.             for($i=1; $i<$width-15; $i++) {  
  889.                 $frame[6][7+$i] = chr(0x90 | ($i & 1));  
  890.                 $frame[7+$i][6] = chr(0x90 | ($i & 1));  
  891.             }  
  892.              
  893.             // Alignment pattern    
  894.             self::putAlignmentPattern($version, $frame, $width);  
  895.              
  896.             // Version information  
  897.             if($version >= 7) {  
  898.                 $vinf = self::getVersionPattern($version);  
  899.  
  900.  
  901.                 $v = $vinf;  
  902.                  
  903.                 for($x=0; $x<6; $x++) {  
  904.                     for($y=0; $y<3; $y++) {  
  905.                         $frame[($width - 11)+$y][$x] = chr(0x88 | ($v & 1));  
  906.                         $v = $v >> 1;  
  907.                     }  
  908.                 }  
  909.  
  910.  
  911.                 $v = $vinf;  
  912.                 for($y=0; $y<6; $y++) {  
  913.                     for($x=0; $x<3; $x++) {  
  914.                         $frame[$y][$x+($width - 11)] = chr(0x88 | ($v & 1));  
  915.                         $v = $v >> 1;  
  916.                     }  
  917.                 }  
  918.             }  
  919.      
  920.             // and a little bit...    
  921.             $frame[$width - 8][8] = "\x81";  
  922.              
  923.             return $frame;  
  924.         }  
  925.  
  926.  
  927.         //----------------------------------------------------------------------  
  928.         public static function debug($frame, $binary_mode = false)  
  929.         {  
  930.             if ($binary_mode) {  
  931.              
  932.                     foreach ($frame as &$frameLine) {  
  933.                         $frameLine = join('<span class="m">&nbsp;&nbsp;</span>', explode('0', $frameLine));  
  934.                         $frameLine = join('&#9608;&#9608;', explode('1', $frameLine));  
  935.                     }  
  936.                      
  937.                     ?>  
  938.                 <style>  
  939.                     .m { background-color: white; }  
  940.                 </style>  
  941.                 <?php  
  942.                     echo '<pre><tt><br/ ><br/ ><br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';  
  943.                     echo join("<br/ >&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", $frame);  
  944.                     echo '</tt></pre><br/ ><br/ ><br/ ><br/ ><br/ ><br/ >';  
  945.              
  946.             } else {  
  947.              
  948.                 foreach ($frame as &$frameLine) {  
  949.                     $frameLine = join('<span class="m">&nbsp;</span>',  explode("\xc0", $frameLine));  
  950.                     $frameLine = join('<span class="m">&#9618;</span>', explode("\xc1", $frameLine));  
  951.                     $frameLine = join('<span class="p">&nbsp;</span>',  explode("\xa0", $frameLine));  
  952.                     $frameLine = join('<span class="p">&#9618;</span>', explode("\xa1", $frameLine));  
  953.                     $frameLine = join('<span class="s">&#9671;</span>', explode("\x84", $frameLine)); //format 0  
  954.                     $frameLine = join('<span class="s">&#9670;</span>', explode("\x85", $frameLine)); //format 1  
  955.                     $frameLine = join('<span class="x">&#9762;</span>', explode("\x81", $frameLine)); //special bit  
  956.                     $frameLine = join('<span class="c">&nbsp;</span>',  explode("\x90", $frameLine)); //clock 0  
  957.                     $frameLine = join('<span class="c">&#9719;</span>', explode("\x91", $frameLine)); //clock 1  
  958.                     $frameLine = join('<span class="f">&nbsp;</span>',  explode("\x88", $frameLine)); //version  
  959.                     $frameLine = join('<span class="f">&#9618;</span>', explode("\x89", $frameLine)); //version  
  960.                     $frameLine = join('&#9830;', explode("\x01", $frameLine));  
  961.                     $frameLine = join('&#8901;', explode("\0", $frameLine));  
  962.                 }  
  963.                  
  964.                 ?>  
  965.                 <style>  
  966.                     .p { background-color: yellow; }  
  967.                     .m { background-color: #00FF00; }  
  968.                     .s { background-color: #FF0000; }  
  969.                     .c { background-color: aqua; }  
  970.                     .x { background-color: pink; }  
  971.                     .f { background-color: gold; }  
  972.                 </style>  
  973.                 <?php  
  974.                 echo "<pre><tt>";  
  975.                 echo join("<br/ >", $frame);  
  976.                 echo "</tt></pre>";  
  977.              
  978.             }  
  979.         }  
  980.  
  981.  
  982.         //----------------------------------------------------------------------  
  983.         public static function serial($frame)  
  984.         {  
  985.             return gzcompress(join("\n", $frame), 9);  
  986.         }  
  987.          
  988.         //----------------------------------------------------------------------  
  989.         public static function unserial($code)  
  990.         {  
  991.             return explode("\n", gzuncompress($code));  
  992.         }  
  993.          
  994.         //----------------------------------------------------------------------  
  995.         public static function newFrame($version)  
  996.         {  
  997.             if($version < 1 || $version > QRSPEC_VERSION_MAX)  
  998.                 return null;  
  999.  
  1000.  
  1001.             if(!isset(self::$frames[$version])) {  
  1002.                  
  1003.                 $fileName = QR_CACHE_DIR.'frame_'.$version.'.dat';  
  1004.                  
  1005.                 if (QR_CACHEABLE) {  
  1006.                     if (file_exists($fileName)) {  
  1007.                         self::$frames[$version] = self::unserial(file_get_contents($fileName));  
  1008.                     } else {  
  1009.                         self::$frames[$version] = self::createFrame($version);  
  1010.                         file_put_contents($fileName, self::serial(self::$frames[$version]));  
  1011.                     }  
  1012.                 } else {  
  1013.                     self::$frames[$version] = self::createFrame($version);  
  1014.                 }  
  1015.             }  
  1016.              
  1017.             if(is_null(self::$frames[$version]))  
  1018.                 return null;  
  1019.  
  1020.  
  1021.             return self::$frames[$version];  
  1022.         }  
  1023.  
  1024.  
  1025.         //----------------------------------------------------------------------  
  1026.         public static function rsBlockNum($spec)     { return $spec[0] + $spec[3]; }  
  1027.         public static function rsBlockNum1($spec)    { return $spec[0]; }  
  1028.         public static function rsDataCodes1($spec)   { return $spec[1]; }  
  1029.         public static function rsEccCodes1($spec)    { return $spec[2]; }  
  1030.         public static function rsBlockNum2($spec)    { return $spec[3]; }  
  1031.         public static function rsDataCodes2($spec)   { return $spec[4]; }  
  1032.         public static function rsEccCodes2($spec)    { return $spec[2]; }  
  1033.         public static function rsDataLength($spec)   { return ($spec[0] * $spec[1]) + ($spec[3] * $spec[4]);    }  
  1034.         public static function rsEccLength($spec)    { return ($spec[0] + $spec[3]) * $spec[2]; }  
  1035.          
  1036.     }  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043. //---- qrimage.php -----------------------------  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052. /*
  1053.  * PHP QR Code encoder
  1054.  *
  1055.  * Image output of code using GD2
  1056.  *
  1057.  * PHP QR Code is distributed under LGPL 3
  1058.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  1059.  *
  1060.  * This library is free software; you can redistribute it and/or
  1061.  * modify it under the terms of the GNU Lesser General Public
  1062.  * License as published by the Free Software Foundation; either
  1063.  * version 3 of the License, or any later version.
  1064.  *
  1065.  * This library is distributed in the hope that it will be useful,
  1066.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1067.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  1068.  * Lesser General Public License for more details.
  1069.  *
  1070.  * You should have received a copy of the GNU Lesser General Public
  1071.  * License along with this library; if not, write to the Free Software
  1072.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  1073.  */  
  1074.    
  1075.     define('QR_IMAGE', true);  
  1076.  
  1077.  
  1078.     class QRimage {  
  1079.      
  1080.         //----------------------------------------------------------------------  
  1081.         public static function png($frame, $filename = false, $pixelPerPoint = 4, $outerFrame = 4,$saveandprint=FALSE)  
  1082.         {  
  1083.             $image = self::image($frame, $pixelPerPoint, $outerFrame);  
  1084.              
  1085.             if ($filename === false) {  
  1086.                 Header("Content-type: image/png");  
  1087.                 ImagePng($image);  
  1088.             } else {  
  1089.                 if($saveandprint===TRUE){  
  1090.                     ImagePng($image, $filename);  
  1091.                     header("Content-type: image/png");  
  1092.                     ImagePng($image);  
  1093.                 }else{  
  1094.                     ImagePng($image, $filename);  
  1095.                 }  
  1096.             }  
  1097.              
  1098.             ImageDestroy($image);  
  1099.         }  
  1100.      
  1101.         //----------------------------------------------------------------------  
  1102.         public static function jpg($frame, $filename = false, $pixelPerPoint = 8, $outerFrame = 4, $q = 85)  
  1103.         {  
  1104.             $image = self::image($frame, $pixelPerPoint, $outerFrame);  
  1105.              
  1106.             if ($filename === false) {  
  1107.                 Header("Content-type: image/jpeg");  
  1108.                 ImageJpeg($image, null, $q);  
  1109.             } else {  
  1110.                 ImageJpeg($image, $filename, $q);              
  1111.             }  
  1112.              
  1113.             ImageDestroy($image);  
  1114.         }  
  1115.      
  1116.         //----------------------------------------------------------------------  
  1117.         private static function image($frame, $pixelPerPoint = 4, $outerFrame = 4)  
  1118.         {  
  1119.             $h = count($frame);  
  1120.             $w = strlen($frame[0]);  
  1121.              
  1122.             $imgW = $w + 2*$outerFrame;  
  1123.             $imgH = $h + 2*$outerFrame;  
  1124.              
  1125.             $base_image =ImageCreate($imgW, $imgH);  
  1126.              
  1127.             $col[0] = ImageColorAllocate($base_image,255,255,255);  
  1128.             $col[1] = ImageColorAllocate($base_image,0,0,0);  
  1129.  
  1130.  
  1131.             imagefill($base_image, 0, 0, $col[0]);  
  1132.  
  1133.  
  1134.             for($y=0; $y<$h; $y++) {  
  1135.                 for($x=0; $x<$w; $x++) {  
  1136.                     if ($frame[$y][$x] == '1') {  
  1137.                         ImageSetPixel($base_image,$x+$outerFrame,$y+$outerFrame,$col[1]);  
  1138.                     }  
  1139.                 }  
  1140.             }  
  1141.              
  1142.             $target_image =ImageCreate($imgW * $pixelPerPoint, $imgH * $pixelPerPoint);  
  1143.             ImageCopyResized($target_image, $base_image, 0, 0, 0, 0, $imgW * $pixelPerPoint, $imgH * $pixelPerPoint, $imgW, $imgH);  
  1144.             ImageDestroy($base_image);  
  1145.              
  1146.             return $target_image;  
  1147.         }  
  1148.     }  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155. //---- qrinput.php -----------------------------  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164. /*
  1165.  * PHP QR Code encoder
  1166.  *
  1167.  * Input encoding class
  1168.  *
  1169.  * Based on libqrencode C library distributed under LGPL 2.1
  1170.  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  1171.  *
  1172.  * PHP QR Code is distributed under LGPL 3
  1173.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  1174.  *
  1175.  * This library is free software; you can redistribute it and/or
  1176.  * modify it under the terms of the GNU Lesser General Public
  1177.  * License as published by the Free Software Foundation; either
  1178.  * version 3 of the License, or any later version.
  1179.  *
  1180.  * This library is distributed in the hope that it will be useful,
  1181.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1182.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  1183.  * Lesser General Public License for more details.
  1184.  *
  1185.  * You should have received a copy of the GNU Lesser General Public
  1186.  * License along with this library; if not, write to the Free Software
  1187.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  1188.  */  
  1189.    
  1190.     define('STRUCTURE_HEADER_BITS',  20);  
  1191.     define('MAX_STRUCTURED_SYMBOLS', 16);  
  1192.  
  1193.  
  1194.     class QRinputItem {  
  1195.      
  1196.         public $mode;  
  1197.         public $size;  
  1198.         public $data;  
  1199.         public $bstream;  
  1200.  
  1201.  
  1202.         public function __construct($mode, $size, $data, $bstream = null)  
  1203.         {  
  1204.             $setData = array_slice($data, 0, $size);  
  1205.              
  1206.             if (count($setData) < $size) {  
  1207.                 $setData = array_merge($setData, array_fill(0,$size-count($setData),0));  
  1208.             }  
  1209.          
  1210.             if(!QRinput::check($mode, $size, $setData)) {  
  1211.                 throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData));  
  1212.                 return null;  
  1213.             }  
  1214.              
  1215.             $this->mode = $mode;  
  1216.             $this->size = $size;  
  1217.             $this->data = $setData;  
  1218.             $this->bstream = $bstream;  
  1219.         }  
  1220.          
  1221.         //----------------------------------------------------------------------  
  1222.         public function encodeModeNum($version)  
  1223.         {  
  1224.             try {  
  1225.              
  1226.                 $words = (int)($this->size / 3);  
  1227.                 $bs = new QRbitstream();  
  1228.                  
  1229.                 $val = 0x1;  
  1230.                 $bs->appendNum(4, $val);  
  1231.                 $bs->appendNum(QRspec::lengthIndicator(QR_MODE_NUM, $version), $this->size);  
  1232.  
  1233.  
  1234.                 for($i=0; $i<$words; $i++) {  
  1235.                     $val  = (ord($this->data[$i*3  ]) - ord('0')) * 100;  
  1236.                     $val += (ord($this->data[$i*3+1]) - ord('0')) * 10;  
  1237.                     $val += (ord($this->data[$i*3+2]) - ord('0'));  
  1238.                     $bs->appendNum(10, $val);  
  1239.                 }  
  1240.  
  1241.  
  1242.                 if($this->size - $words * 3 == 1) {  
  1243.                     $val = ord($this->data[$words*3]) - ord('0');  
  1244.                     $bs->appendNum(4, $val);  
  1245.                 } else if($this->size - $words * 3 == 2) {  
  1246.                     $val  = (ord($this->data[$words*3  ]) - ord('0')) * 10;  
  1247.                     $val += (ord($this->data[$words*3+1]) - ord('0'));  
  1248.                     $bs->appendNum(7, $val);  
  1249.                 }  
  1250.  
  1251.  
  1252.                 $this->bstream = $bs;  
  1253.                 return 0;  
  1254.                  
  1255.             } catch (Exception $e) {  
  1256.                 return -1;  
  1257.             }  
  1258.         }  
  1259.          
  1260.         //----------------------------------------------------------------------  
  1261.         public function encodeModeAn($version)  
  1262.         {  
  1263.             try {  
  1264.                 $words = (int)($this->size / 2);  
  1265.                 $bs = new QRbitstream();  
  1266.                  
  1267.                 $bs->appendNum(4, 0x02);  
  1268.                 $bs->appendNum(QRspec::lengthIndicator(QR_MODE_AN, $version), $this->size);  
  1269.  
  1270.  
  1271.                 for($i=0; $i<$words; $i++) {  
  1272.                     $val  = (int)QRinput::lookAnTable(ord($this->data[$i*2  ])) * 45;  
  1273.                     $val += (int)QRinput::lookAnTable(ord($this->data[$i*2+1]));  
  1274.  
  1275.  
  1276.                     $bs->appendNum(11, $val);  
  1277.                 }  
  1278.  
  1279.  
  1280.                 if($this->size & 1) {  
  1281.                     $val = QRinput::lookAnTable(ord($this->data[$words * 2]));  
  1282.                     $bs->appendNum(6, $val);  
  1283.                 }  
  1284.          
  1285.                 $this->bstream = $bs;  
  1286.                 return 0;  
  1287.              
  1288.             } catch (Exception $e) {  
  1289.                 return -1;  
  1290.             }  
  1291.         }  
  1292.          
  1293.         //----------------------------------------------------------------------  
  1294.         public function encodeMode8($version)  
  1295.         {  
  1296.             try {  
  1297.                 $bs = new QRbitstream();  
  1298.  
  1299.  
  1300.                 $bs->appendNum(4, 0x4);  
  1301.                 $bs->appendNum(QRspec::lengthIndicator(QR_MODE_8, $version), $this->size);  
  1302.  
  1303.  
  1304.                 for($i=0; $i<$this->size; $i++) {  
  1305.                     $bs->appendNum(8, ord($this->data[$i]));  
  1306.                 }  
  1307.  
  1308.  
  1309.                 $this->bstream = $bs;  
  1310.                 return 0;  
  1311.              
  1312.             } catch (Exception $e) {  
  1313.                 return -1;  
  1314.             }  
  1315.         }  
  1316.          
  1317.         //----------------------------------------------------------------------  
  1318.         public function encodeModeKanji($version)  
  1319.         {  
  1320.             try {  
  1321.  
  1322.  
  1323.                 $bs = new QRbitrtream();  
  1324.                  
  1325.                 $bs->appendNum(4, 0x8);  
  1326.                 $bs->appendNum(QRspec::lengthIndicator(QR_MODE_KANJI, $version), (int)($this->size / 2));  
  1327.  
  1328.  
  1329.                 for($i=0; $i<$this->size; $i+=2) {  
  1330.                     $val = (ord($this->data[$i]) << 8) | ord($this->data[$i+1]);  
  1331.                     if($val <= 0x9ffc) {  
  1332.                         $val -= 0x8140;  
  1333.                     } else {  
  1334.                         $val -= 0xc140;  
  1335.                     }  
  1336.                      
  1337.                     $h = ($val >> 8) * 0xc0;  
  1338.                     $val = ($val & 0xff) + $h;  
  1339.  
  1340.  
  1341.                     $bs->appendNum(13, $val);  
  1342.                 }  
  1343.  
  1344.  
  1345.                 $this->bstream = $bs;  
  1346.                 return 0;  
  1347.              
  1348.             } catch (Exception $e) {  
  1349.                 return -1;  
  1350.             }  
  1351.         }  
  1352.  
  1353.  
  1354.         //----------------------------------------------------------------------  
  1355.         public function encodeModeStructure()  
  1356.         {  
  1357.             try {  
  1358.                 $bs =  new QRbitstream();  
  1359.                  
  1360.                 $bs->appendNum(4, 0x03);  
  1361.                 $bs->appendNum(4, ord($this->data[1]) - 1);  
  1362.                 $bs->appendNum(4, ord($this->data[0]) - 1);  
  1363.                 $bs->appendNum(8, ord($this->data[2]));  
  1364.  
  1365.  
  1366.                 $this->bstream = $bs;  
  1367.                 return 0;  
  1368.              
  1369.             } catch (Exception $e) {  
  1370.                 return -1;  
  1371.             }  
  1372.         }  
  1373.          
  1374.         //----------------------------------------------------------------------  
  1375.         public function estimateBitStreamSizeOfEntry($version)  
  1376.         {  
  1377.             $bits = 0;  
  1378.  
  1379.  
  1380.             if($version == 0)  
  1381.                 $version = 1;  
  1382.  
  1383.  
  1384.             switch($this->mode) {  
  1385.                 case QR_MODE_NUM:        $bits = QRinput::estimateBitsModeNum($this->size);    break;  
  1386.                 case QR_MODE_AN:        $bits = QRinput::estimateBitsModeAn($this->size);    break;  
  1387.                 case QR_MODE_8:            $bits = QRinput::estimateBitsMode8($this->size);    break;  
  1388.                 case QR_MODE_KANJI:        $bits = QRinput::estimateBitsModeKanji($this->size);break;  
  1389.                 case QR_MODE_STRUCTURE:    return STRUCTURE_HEADER_BITS;              
  1390.                 default:  
  1391.                     return 0;  
  1392.             }  
  1393.  
  1394.  
  1395.             $l = QRspec::lengthIndicator($this->mode, $version);  
  1396.             $m = 1 << $l;  
  1397.             $num = (int)(($this->size + $m - 1) / $m);  
  1398.  
  1399.  
  1400.             $bits += $num * (4 + $l);  
  1401.  
  1402.  
  1403.             return $bits;  
  1404.         }  
  1405.          
  1406.         //----------------------------------------------------------------------  
  1407.         public function encodeBitStream($version)  
  1408.         {  
  1409.             try {  
  1410.              
  1411.                 unset($this->bstream);  
  1412.                 $words = QRspec::maximumWords($this->mode, $version);  
  1413.                  
  1414.                 if($this->size > $words) {  
  1415.                  
  1416.                     $st1 = new QRinputItem($this->mode, $words, $this->data);  
  1417.                     $st2 = new QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words));  
  1418.  
  1419.  
  1420.                     $st1->encodeBitStream($version);  
  1421.                     $st2->encodeBitStream($version);  
  1422.                      
  1423.                     $this->bstream = new QRbitstream();  
  1424.                     $this->bstream->append($st1->bstream);  
  1425.                     $this->bstream->append($st2->bstream);  
  1426.                      
  1427.                     unset($st1);  
  1428.                     unset($st2);  
  1429.                      
  1430.                 } else {  
  1431.                      
  1432.                     $ret = 0;  
  1433.                      
  1434.                     switch($this->mode) {  
  1435.                         case QR_MODE_NUM:        $ret = $this->encodeModeNum($version);    break;  
  1436.                         case QR_MODE_AN:        $ret = $this->encodeModeAn($version);    break;  
  1437.                         case QR_MODE_8:            $ret = $this->encodeMode8($version);    break;  
  1438.                         case QR_MODE_KANJI:        $ret = $this->encodeModeKanji($version);break;  
  1439.                         case QR_MODE_STRUCTURE:    $ret = $this->encodeModeStructure();    break;  
  1440.                          
  1441.                         default:  
  1442.                             break;  
  1443.                     }  
  1444.                      
  1445.                     if($ret < 0)  
  1446.                         return -1;  
  1447.                 }  
  1448.  
  1449.  
  1450.                 return $this->bstream->size();  
  1451.              
  1452.             } catch (Exception $e) {  
  1453.                 return -1;  
  1454.             }  
  1455.         }  
  1456.     };  
  1457.      
  1458.     //##########################################################################  
  1459.  
  1460.  
  1461.     class QRinput {  
  1462.  
  1463.  
  1464.         public $items;  
  1465.          
  1466.         private $version;  
  1467.         private $level;  
  1468.          
  1469.         //----------------------------------------------------------------------  
  1470.         public function __construct($version = 0, $level = QR_ECLEVEL_L)  
  1471.         {  
  1472.             if ($version < 0 || $version > QRSPEC_VERSION_MAX || $level > QR_ECLEVEL_H) {  
  1473.                 throw new Exception('Invalid version no');  
  1474.                 return NULL;  
  1475.             }  
  1476.              
  1477.             $this->version = $version;  
  1478.             $this->level = $level;  
  1479.         }  
  1480.          
  1481.         //----------------------------------------------------------------------  
  1482.         public function getVersion()  
  1483.         {  
  1484.             return $this->version;  
  1485.         }  
  1486.          
  1487.         //----------------------------------------------------------------------  
  1488.         public function setVersion($version)  
  1489.         {  
  1490.             if($version < 0 || $version > QRSPEC_VERSION_MAX) {  
  1491.                 throw new Exception('Invalid version no');  
  1492.                 return -1;  
  1493.             }  
  1494.  
  1495.  
  1496.             $this->version = $version;  
  1497.  
  1498.  
  1499.             return 0;  
  1500.         }  
  1501.          
  1502.         //----------------------------------------------------------------------  
  1503.         public function getErrorCorrectionLevel()  
  1504.         {  
  1505.             return $this->level;  
  1506.         }  
  1507.  
  1508.  
  1509.         //----------------------------------------------------------------------  
  1510.         public function setErrorCorrectionLevel($level)  
  1511.         {  
  1512.             if($level > QR_ECLEVEL_H) {  
  1513.                 throw new Exception('Invalid ECLEVEL');  
  1514.                 return -1;  
  1515.             }  
  1516.  
  1517.  
  1518.             $this->level = $level;  
  1519.  
  1520.  
  1521.             return 0;  
  1522.         }  
  1523.          
  1524.         //----------------------------------------------------------------------  
  1525.         public function appendEntry(QRinputItem $entry)  
  1526.         {  
  1527.             $this->items[] = $entry;  
  1528.         }  
  1529.          
  1530.         //----------------------------------------------------------------------  
  1531.         public function append($mode, $size, $data)  
  1532.         {  
  1533.             try {  
  1534.                 $entry = new QRinputItem($mode, $size, $data);  
  1535.                 $this->items[] = $entry;  
  1536.                 return 0;  
  1537.             } catch (Exception $e) {  
  1538.                 return -1;  
  1539.             }  
  1540.         }  
  1541.          
  1542.         //----------------------------------------------------------------------  
  1543.          
  1544.         public function insertStructuredAppendHeader($size, $index, $parity)  
  1545.         {  
  1546.             if( $size > MAX_STRUCTURED_SYMBOLS ) {  
  1547.                 throw new Exception('insertStructuredAppendHeader wrong size');  
  1548.             }  
  1549.              
  1550.             if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS ) {  
  1551.                 throw new Exception('insertStructuredAppendHeader wrong index');  
  1552.             }  
  1553.  
  1554.  
  1555.             $buf = array($size, $index, $parity);  
  1556.              
  1557.             try {  
  1558.                 $entry = new QRinputItem(QR_MODE_STRUCTURE, 3, buf);  
  1559.                 array_unshift($this->items, $entry);  
  1560.                 return 0;  
  1561.             } catch (Exception $e) {  
  1562.                 return -1;  
  1563.             }  
  1564.         }  
  1565.  
  1566.  
  1567.         //----------------------------------------------------------------------  
  1568.         public function calcParity()  
  1569.         {  
  1570.             $parity = 0;  
  1571.              
  1572.             foreach($this->items as $item) {  
  1573.                 if($item->mode != QR_MODE_STRUCTURE) {  
  1574.                     for($i=$item->size-1; $i>=0; $i--) {  
  1575.                         $parity ^= $item->data[$i];  
  1576.                     }  
  1577.                 }  
  1578.             }  
  1579.  
  1580.  
  1581.             return $parity;  
  1582.         }  
  1583.          
  1584.         //----------------------------------------------------------------------  
  1585.         public static function checkModeNum($size, $data)  
  1586.         {  
  1587.             for($i=0; $i<$size; $i++) {  
  1588.                 if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){  
  1589.                     return false;  
  1590.                 }  
  1591.             }  
  1592.  
  1593.  
  1594.             return true;  
  1595.         }  
  1596.  
  1597.  
  1598.         //----------------------------------------------------------------------  
  1599.         public static function estimateBitsModeNum($size)  
  1600.         {  
  1601.             $w = (int)$size / 3;  
  1602.             $bits = $w * 10;  
  1603.              
  1604.             switch($size - $w * 3) {  
  1605.                 case 1:  
  1606.                     $bits += 4;  
  1607.                     break;  
  1608.                 case 2:  
  1609.                     $bits += 7;  
  1610.                     break;  
  1611.                 default:  
  1612.                     break;  
  1613.             }  
  1614.  
  1615.  
  1616.             return $bits;  
  1617.         }  
  1618.          
  1619.         //----------------------------------------------------------------------  
  1620.         public static $anTable = array(  
  1621.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  1622.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  1623.             36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,  
  1624.              0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 44, -1, -1, -1, -1, -1,  
  1625.             -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,  
  1626.             25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1,  
  1627.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  
  1628.             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  
  1629.         );  
  1630.          
  1631.         //----------------------------------------------------------------------  
  1632.         public static function lookAnTable($c)  
  1633.         {  
  1634.             return (($c > 127)?-1:self::$anTable[$c]);  
  1635.         }  
  1636.          
  1637.         //----------------------------------------------------------------------  
  1638.         public static function checkModeAn($size, $data)  
  1639.         {  
  1640.             for($i=0; $i<$size; $i++) {  
  1641.                 if (self::lookAnTable(ord($data[$i])) == -1) {  
  1642.                     return false;  
  1643.                 }  
  1644.             }  
  1645.  
  1646.  
  1647.             return true;  
  1648.         }  
  1649.          
  1650.         //----------------------------------------------------------------------  
  1651.         public static function estimateBitsModeAn($size)  
  1652.         {  
  1653.             $w = (int)($size / 2);  
  1654.             $bits = $w * 11;  
  1655.              
  1656.             if($size & 1) {  
  1657.                 $bits += 6;  
  1658.             }  
  1659.  
  1660.  
  1661.             return $bits;  
  1662.         }  
  1663.      
  1664.         //----------------------------------------------------------------------  
  1665.         public static function estimateBitsMode8($size)  
  1666.         {  
  1667.             return $size * 8;  
  1668.         }  
  1669.          
  1670.         //----------------------------------------------------------------------  
  1671.         public function estimateBitsModeKanji($size)  
  1672.         {  
  1673.             return (int)(($size / 2) * 13);  
  1674.         }  
  1675.          
  1676.         //----------------------------------------------------------------------  
  1677.         public static function checkModeKanji($size, $data)  
  1678.         {  
  1679.             if($size & 1)  
  1680.                 return false;  
  1681.  
  1682.  
  1683.             for($i=0; $i<$size; $i+=2) {  
  1684.                 $val = (ord($data[$i]) << 8) | ord($data[$i+1]);  
  1685.                 if( $val < 0x8140  
  1686.                 || ($val > 0x9ffc && $val < 0xe040)  
  1687.                 || $val > 0xebbf) {  
  1688.                     return false;  
  1689.                 }  
  1690.             }  
  1691.  
  1692.  
  1693.             return true;  
  1694.         }  
  1695.  
  1696.  
  1697.         /***********************************************************************
  1698.          * Validation
  1699.          **********************************************************************/  
  1700.  
  1701.  
  1702.         public static function check($mode, $size, $data)  
  1703.         {  
  1704.             if($size <= 0)  
  1705.                 return false;  
  1706.  
  1707.  
  1708.             switch($mode) {  
  1709.                 case QR_MODE_NUM:       return self::checkModeNum($size, $data);   break;  
  1710.                 case QR_MODE_AN:        return self::checkModeAn($size, $data);    break;  
  1711.                 case QR_MODE_KANJI:     return self::checkModeKanji($size, $data); break;  
  1712.                 case QR_MODE_8:         return true; break;  
  1713.                 case QR_MODE_STRUCTURE: return true; break;  
  1714.                  
  1715.                 default:  
  1716.                     break;  
  1717.             }  
  1718.  
  1719.  
  1720.             return false;  
  1721.         }  
  1722.          
  1723.          
  1724.         //----------------------------------------------------------------------  
  1725.         public function estimateBitStreamSize($version)  
  1726.         {  
  1727.             $bits = 0;  
  1728.  
  1729.  
  1730.             foreach($this->items as $item) {  
  1731.                 $bits += $item->estimateBitStreamSizeOfEntry($version);  
  1732.             }  
  1733.  
  1734.  
  1735.             return $bits;  
  1736.         }  
  1737.          
  1738.         //----------------------------------------------------------------------  
  1739.         public function estimateVersion()  
  1740.         {  
  1741.             $version = 0;  
  1742.             $prev = 0;  
  1743.             do {  
  1744.                 $prev = $version;  
  1745.                 $bits = $this->estimateBitStreamSize($prev);  
  1746.                 $version = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);  
  1747.                 if ($version < 0) {  
  1748.                     return -1;  
  1749.                 }  
  1750.             } while ($version > $prev);  
  1751.  
  1752.  
  1753.             return $version;  
  1754.         }  
  1755.          
  1756.         //----------------------------------------------------------------------  
  1757.         public static function lengthOfCode($mode, $version, $bits)  
  1758.         {  
  1759.             $payload = $bits - 4 - QRspec::lengthIndicator($mode, $version);  
  1760.             switch($mode) {  
  1761.                 case QR_MODE_NUM:  
  1762.                     $chunks = (int)($payload / 10);  
  1763.                     $remain = $payload - $chunks * 10;  
  1764.                     $size = $chunks * 3;  
  1765.                     if($remain >= 7) {  
  1766.                         $size += 2;  
  1767.                     } else if($remain >= 4) {  
  1768.                         $size += 1;  
  1769.                     }  
  1770.                     break;  
  1771.                 case QR_MODE_AN:  
  1772.                     $chunks = (int)($payload / 11);  
  1773.                     $remain = $payload - $chunks * 11;  
  1774.                     $size = $chunks * 2;  
  1775.                     if($remain >= 6)  
  1776.                         $size++;  
  1777.                     break;  
  1778.                 case QR_MODE_8:  
  1779.                     $size = (int)($payload / 8);  
  1780.                     break;  
  1781.                 case QR_MODE_KANJI:  
  1782.                     $size = (int)(($payload / 13) * 2);  
  1783.                     break;  
  1784.                 case QR_MODE_STRUCTURE:  
  1785.                     $size = (int)($payload / 8);  
  1786.                     break;  
  1787.                 default:  
  1788.                     $size = 0;  
  1789.                     break;  
  1790.             }  
  1791.              
  1792.             $maxsize = QRspec::maximumWords($mode, $version);  
  1793.             if($size < 0) $size = 0;  
  1794.             if($size > $maxsize) $size = $maxsize;  
  1795.  
  1796.  
  1797.             return $size;  
  1798.         }  
  1799.          
  1800.         //----------------------------------------------------------------------  
  1801.         public function createBitStream()  
  1802.         {  
  1803.             $total = 0;  
  1804.  
  1805.  
  1806.             foreach($this->items as $item) {  
  1807.                 $bits = $item->encodeBitStream($this->version);  
  1808.                  
  1809.                 if($bits < 0)  
  1810.                     return -1;  
  1811.                      
  1812.                 $total += $bits;  
  1813.             }  
  1814.  
  1815.  
  1816.             return $total;  
  1817.         }  
  1818.          
  1819.         //----------------------------------------------------------------------  
  1820.         public function convertData()  
  1821.         {  
  1822.             $ver = $this->estimateVersion();  
  1823.             if($ver > $this->getVersion()) {  
  1824.                 $this->setVersion($ver);  
  1825.             }  
  1826.  
  1827.  
  1828.             for(;;) {  
  1829.                 $bits = $this->createBitStream();  
  1830.                  
  1831.                 if($bits < 0)  
  1832.                     return -1;  
  1833.                      
  1834.                 $ver = QRspec::getMinimumVersion((int)(($bits + 7) / 8), $this->level);  
  1835.                 if($ver < 0) {  
  1836.                     throw new Exception('WRONG VERSION');  
  1837.                     return -1;  
  1838.                 } else if($ver > $this->getVersion()) {  
  1839.                     $this->setVersion($ver);  
  1840.                 } else {  
  1841.                     break;  
  1842.                 }  
  1843.             }  
  1844.  
  1845.  
  1846.             return 0;  
  1847.         }  
  1848.          
  1849.         //----------------------------------------------------------------------  
  1850.         public function appendPaddingBit(&$bstream)  
  1851.         {  
  1852.             $bits = $bstream->size();  
  1853.             $maxwords = QRspec::getDataLength($this->version, $this->level);  
  1854.             $maxbits = $maxwords * 8;  
  1855.  
  1856.  
  1857.             if ($maxbits == $bits) {  
  1858.                 return 0;  
  1859.             }  
  1860.  
  1861.  
  1862.             if ($maxbits - $bits < 5) {  
  1863.                 return $bstream->appendNum($maxbits - $bits, 0);  
  1864.             }  
  1865.  
  1866.  
  1867.             $bits += 4;  
  1868.             $words = (int)(($bits + 7) / 8);  
  1869.  
  1870.  
  1871.             $padding = new QRbitstream();  
  1872.             $ret = $padding->appendNum($words * 8 - $bits + 4, 0);  
  1873.              
  1874.             if($ret < 0)  
  1875.                 return $ret;  
  1876.  
  1877.  
  1878.             $padlen = $maxwords - $words;  
  1879.              
  1880.             if($padlen > 0) {  
  1881.                  
  1882.                 $padbuf = array();  
  1883.                 for($i=0; $i<$padlen; $i++) {  
  1884.                     $padbuf[$i] = ($i&1)?0x11:0xec;  
  1885.                 }  
  1886.                  
  1887.                 $ret = $padding->appendBytes($padlen, $padbuf);  
  1888.                  
  1889.                 if($ret < 0)  
  1890.                     return $ret;  
  1891.                  
  1892.             }  
  1893.  
  1894.  
  1895.             $ret = $bstream->append($padding);  
  1896.              
  1897.             return $ret;  
  1898.         }  
  1899.  
  1900.  
  1901.         //----------------------------------------------------------------------  
  1902.         public function mergeBitStream()  
  1903.         {  
  1904.             if($this->convertData() < 0) {  
  1905.                 return null;  
  1906.             }  
  1907.  
  1908.  
  1909.             $bstream = new QRbitstream();  
  1910.              
  1911.             foreach($this->items as $item) {  
  1912.                 $ret = $bstream->append($item->bstream);  
  1913.                 if($ret < 0) {  
  1914.                     return null;  
  1915.                 }  
  1916.             }  
  1917.  
  1918.  
  1919.             return $bstream;  
  1920.         }  
  1921.  
  1922.  
  1923.         //----------------------------------------------------------------------  
  1924.         public function getBitStream()  
  1925.         {  
  1926.  
  1927.  
  1928.             $bstream = $this->mergeBitStream();  
  1929.              
  1930.             if($bstream == null) {  
  1931.                 return null;  
  1932.             }  
  1933.              
  1934.             $ret = $this->appendPaddingBit($bstream);  
  1935.             if($ret < 0) {  
  1936.                 return null;  
  1937.             }  
  1938.  
  1939.  
  1940.             return $bstream;  
  1941.         }  
  1942.          
  1943.         //----------------------------------------------------------------------  
  1944.         public function getByteStream()  
  1945.         {  
  1946.             $bstream = $this->getBitStream();  
  1947.             if($bstream == null) {  
  1948.                 return null;  
  1949.             }  
  1950.              
  1951.             return $bstream->toByte();  
  1952.         }  
  1953.     }  
  1954.          
  1955.          
  1956.      
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963. //---- qrbitstream.php -----------------------------  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972. /*
  1973.  * PHP QR Code encoder
  1974.  *
  1975.  * Bitstream class
  1976.  *
  1977.  * Based on libqrencode C library distributed under LGPL 2.1
  1978.  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  1979.  *
  1980.  * PHP QR Code is distributed under LGPL 3
  1981.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  1982.  *
  1983.  * This library is free software; you can redistribute it and/or
  1984.  * modify it under the terms of the GNU Lesser General Public
  1985.  * License as published by the Free Software Foundation; either
  1986.  * version 3 of the License, or any later version.
  1987.  *
  1988.  * This library is distributed in the hope that it will be useful,
  1989.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1990.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  1991.  * Lesser General Public License for more details.
  1992.  *
  1993.  * You should have received a copy of the GNU Lesser General Public
  1994.  * License along with this library; if not, write to the Free Software
  1995.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  1996.  */  
  1997.        
  1998.     class QRbitstream {  
  1999.      
  2000.         public $data = array();  
  2001.          
  2002.         //----------------------------------------------------------------------  
  2003.         public function size()  
  2004.         {  
  2005.             return count($this->data);  
  2006.         }  
  2007.          
  2008.         //----------------------------------------------------------------------  
  2009.         public function allocate($setLength)  
  2010.         {  
  2011.             $this->data = array_fill(0, $setLength, 0);  
  2012.             return 0;  
  2013.         }  
  2014.      
  2015.         //----------------------------------------------------------------------  
  2016.         public static function newFromNum($bits, $num)  
  2017.         {  
  2018.             $bstream = new QRbitstream();  
  2019.             $bstream->allocate($bits);  
  2020.              
  2021.             $mask = 1 << ($bits - 1);  
  2022.             for($i=0; $i<$bits; $i++) {  
  2023.                 if($num & $mask) {  
  2024.                     $bstream->data[$i] = 1;  
  2025.                 } else {  
  2026.                     $bstream->data[$i] = 0;  
  2027.                 }  
  2028.                 $mask = $mask >> 1;  
  2029.             }  
  2030.  
  2031.  
  2032.             return $bstream;  
  2033.         }  
  2034.          
  2035.         //----------------------------------------------------------------------  
  2036.         public static function newFromBytes($size, $data)  
  2037.         {  
  2038.             $bstream = new QRbitstream();  
  2039.             $bstream->allocate($size * 8);  
  2040.             $p=0;  
  2041.  
  2042.  
  2043.             for($i=0; $i<$size; $i++) {  
  2044.                 $mask = 0x80;  
  2045.                 for($j=0; $j<8; $j++) {  
  2046.                     if($data[$i] & $mask) {  
  2047.                         $bstream->data[$p] = 1;  
  2048.                     } else {  
  2049.                         $bstream->data[$p] = 0;  
  2050.                     }  
  2051.                     $p++;  
  2052.                     $mask = $mask >> 1;  
  2053.                 }  
  2054.             }  
  2055.  
  2056.  
  2057.             return $bstream;  
  2058.         }  
  2059.          
  2060.         //----------------------------------------------------------------------  
  2061.         public function append(QRbitstream $arg)  
  2062.         {  
  2063.             if (is_null($arg)) {  
  2064.                 return -1;  
  2065.             }  
  2066.              
  2067.             if($arg->size() == 0) {  
  2068.                 return 0;  
  2069.             }  
  2070.              
  2071.             if($this->size() == 0) {  
  2072.                 $this->data = $arg->data;  
  2073.                 return 0;  
  2074.             }  
  2075.              
  2076.             $this->data = array_values(array_merge($this->data, $arg->data));  
  2077.  
  2078.  
  2079.             return 0;  
  2080.         }  
  2081.          
  2082.         //----------------------------------------------------------------------  
  2083.         public function appendNum($bits, $num)  
  2084.         {  
  2085.             if ($bits == 0)  
  2086.                 return 0;  
  2087.  
  2088.  
  2089.             $b = QRbitstream::newFromNum($bits, $num);  
  2090.              
  2091.             if(is_null($b))  
  2092.                 return -1;  
  2093.  
  2094.  
  2095.             $ret = $this->append($b);  
  2096.             unset($b);  
  2097.  
  2098.  
  2099.             return $ret;  
  2100.         }  
  2101.  
  2102.  
  2103.         //----------------------------------------------------------------------  
  2104.         public function appendBytes($size, $data)  
  2105.         {  
  2106.             if ($size == 0)  
  2107.                 return 0;  
  2108.  
  2109.  
  2110.             $b = QRbitstream::newFromBytes($size, $data);  
  2111.              
  2112.             if(is_null($b))  
  2113.                 return -1;  
  2114.  
  2115.  
  2116.             $ret = $this->append($b);  
  2117.             unset($b);  
  2118.  
  2119.  
  2120.             return $ret;  
  2121.         }  
  2122.          
  2123.         //----------------------------------------------------------------------  
  2124.         public function toByte()  
  2125.         {  
  2126.          
  2127.             $size = $this->size();  
  2128.  
  2129.  
  2130.             if($size == 0) {  
  2131.                 return array();  
  2132.             }  
  2133.              
  2134.             $data = array_fill(0, (int)(($size + 7) / 8), 0);  
  2135.             $bytes = (int)($size / 8);  
  2136.  
  2137.  
  2138.             $p = 0;  
  2139.              
  2140.             for($i=0; $i<$bytes; $i++) {  
  2141.                 $v = 0;  
  2142.                 for($j=0; $j<8; $j++) {  
  2143.                     $v = $v << 1;  
  2144.                     $v |= $this->data[$p];  
  2145.                     $p++;  
  2146.                 }  
  2147.                 $data[$i] = $v;  
  2148.             }  
  2149.              
  2150.             if($size & 7) {  
  2151.                 $v = 0;  
  2152.                 for($j=0; $j<($size & 7); $j++) {  
  2153.                     $v = $v << 1;  
  2154.                     $v |= $this->data[$p];  
  2155.                     $p++;  
  2156.                 }  
  2157.                 $data[$bytes] = $v;  
  2158.             }  
  2159.  
  2160.  
  2161.             return $data;  
  2162.         }  
  2163.  
  2164.  
  2165.     }  
  2166.  
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.  
  2174. //---- qrsplit.php -----------------------------  
  2175.  
  2176.  
  2177.  
  2178.  
  2179.  
  2180.  
  2181.  
  2182.  
  2183. /*
  2184.  * PHP QR Code encoder
  2185.  *
  2186.  * Input splitting classes
  2187.  *
  2188.  * Based on libqrencode C library distributed under LGPL 2.1
  2189.  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  2190.  *
  2191.  * PHP QR Code is distributed under LGPL 3
  2192.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  2193.  *
  2194.  * The following data / specifications are taken from
  2195.  * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)
  2196.  *  or
  2197.  * "Automatic identification and data capture techniques --  
  2198.  *  QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)
  2199.  *
  2200.  * This library is free software; you can redistribute it and/or
  2201.  * modify it under the terms of the GNU Lesser General Public
  2202.  * License as published by the Free Software Foundation; either
  2203.  * version 3 of the License, or any later version.
  2204.  *
  2205.  * This library is distributed in the hope that it will be useful,
  2206.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2207.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  2208.  * Lesser General Public License for more details.
  2209.  *
  2210.  * You should have received a copy of the GNU Lesser General Public
  2211.  * License along with this library; if not, write to the Free Software
  2212.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2213.  */  
  2214.     class QRsplit {  
  2215.  
  2216.  
  2217.         public $dataStr = '';  
  2218.         public $input;  
  2219.         public $modeHint;  
  2220.  
  2221.  
  2222.         //----------------------------------------------------------------------  
  2223.         public function __construct($dataStr, $input, $modeHint)  
  2224.         {  
  2225.             $this->dataStr  = $dataStr;  
  2226.             $this->input    = $input;  
  2227.             $this->modeHint = $modeHint;  
  2228.         }  
  2229.          
  2230.         //----------------------------------------------------------------------  
  2231.         public static function isdigitat($str, $pos)  
  2232.         {      
  2233.             if ($pos >= strlen($str))  
  2234.                 return false;  
  2235.              
  2236.             return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9')));  
  2237.         }  
  2238.          
  2239.         //----------------------------------------------------------------------  
  2240.         public static function isalnumat($str, $pos)  
  2241.         {  
  2242.             if ($pos >= strlen($str))  
  2243.                 return false;  
  2244.                  
  2245.             return (QRinput::lookAnTable(ord($str[$pos])) >= 0);  
  2246.         }  
  2247.  
  2248.  
  2249.         //----------------------------------------------------------------------  
  2250.         public function identifyMode($pos)  
  2251.         {  
  2252.             if ($pos >= strlen($this->dataStr))  
  2253.                 return QR_MODE_NUL;  
  2254.                  
  2255.             $c = $this->dataStr[$pos];  
  2256.              
  2257.             if(self::isdigitat($this->dataStr, $pos)) {  
  2258.                 return QR_MODE_NUM;  
  2259.             } else if(self::isalnumat($this->dataStr, $pos)) {  
  2260.                 return QR_MODE_AN;  
  2261.             } else if($this->modeHint == QR_MODE_KANJI) {  
  2262.              
  2263.                 if ($pos+1 < strlen($this->dataStr))  
  2264.                 {  
  2265.                     $d = $this->dataStr[$pos+1];  
  2266.                     $word = (ord($c) << 8) | ord($d);  
  2267.                     if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) {  
  2268.                         return QR_MODE_KANJI;  
  2269.                     }  
  2270.                 }  
  2271.             }  
  2272.  
  2273.  
  2274.             return QR_MODE_8;  
  2275.         }  
  2276.          
  2277.         //----------------------------------------------------------------------  
  2278.         public function eatNum()  
  2279.         {  
  2280.             $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());  
  2281.  
  2282.  
  2283.             $p = 0;  
  2284.             while(self::isdigitat($this->dataStr, $p)) {  
  2285.                 $p++;  
  2286.             }  
  2287.              
  2288.             $run = $p;  
  2289.             $mode = $this->identifyMode($p);  
  2290.              
  2291.             if($mode == QR_MODE_8) {  
  2292.                 $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln  
  2293.                      + QRinput::estimateBitsMode8(1)         // + 4 + l8  
  2294.                      - QRinput::estimateBitsMode8($run + 1); // - 4 - l8  
  2295.                 if($dif > 0) {  
  2296.                     return $this->eat8();  
  2297.                 }  
  2298.             }  
  2299.             if($mode == QR_MODE_AN) {  
  2300.                 $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln  
  2301.                      + QRinput::estimateBitsModeAn(1)        // + 4 + la  
  2302.                      - QRinput::estimateBitsModeAn($run + 1);// - 4 - la  
  2303.                 if($dif > 0) {  
  2304.                     return $this->eatAn();  
  2305.                 }  
  2306.             }  
  2307.              
  2308.             $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));  
  2309.             if($ret < 0)  
  2310.                 return -1;  
  2311.  
  2312.  
  2313.             return $run;  
  2314.         }  
  2315.          
  2316.         //----------------------------------------------------------------------  
  2317.         public function eatAn()  
  2318.         {  
  2319.             $la = QRspec::lengthIndicator(QR_MODE_AN,  $this->input->getVersion());  
  2320.             $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());  
  2321.  
  2322.  
  2323.             $p = 0;  
  2324.              
  2325.             while(self::isalnumat($this->dataStr, $p)) {  
  2326.                 if(self::isdigitat($this->dataStr, $p)) {  
  2327.                     $q = $p;  
  2328.                     while(self::isdigitat($this->dataStr, $q)) {  
  2329.                         $q++;  
  2330.                     }  
  2331.                      
  2332.                     $dif = QRinput::estimateBitsModeAn($p) // + 4 + la  
  2333.                          + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln  
  2334.                          - QRinput::estimateBitsModeAn($q); // - 4 - la  
  2335.                            
  2336.                     if($dif < 0) {  
  2337.                         break;  
  2338.                     } else {  
  2339.                         $p = $q;  
  2340.                     }  
  2341.                 } else {  
  2342.                     $p++;  
  2343.                 }  
  2344.             }  
  2345.  
  2346.  
  2347.             $run = $p;  
  2348.  
  2349.  
  2350.             if(!self::isalnumat($this->dataStr, $p)) {  
  2351.                 $dif = QRinput::estimateBitsModeAn($run) + 4 + $la  
  2352.                      + QRinput::estimateBitsMode8(1) // + 4 + l8  
  2353.                       - QRinput::estimateBitsMode8($run + 1); // - 4 - l8  
  2354.                 if($dif > 0) {  
  2355.                     return $this->eat8();  
  2356.                 }  
  2357.             }  
  2358.  
  2359.  
  2360.             $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));  
  2361.             if($ret < 0)  
  2362.                 return -1;  
  2363.  
  2364.  
  2365.             return $run;  
  2366.         }  
  2367.          
  2368.         //----------------------------------------------------------------------  
  2369.         public function eatKanji()  
  2370.         {  
  2371.             $p = 0;  
  2372.              
  2373.             while($this->identifyMode($p) == QR_MODE_KANJI) {  
  2374.                 $p += 2;  
  2375.             }  
  2376.              
  2377.             $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));  
  2378.             if($ret < 0)  
  2379.                 return -1;  
  2380.  
  2381.  
  2382.             return $run;  
  2383.         }  
  2384.  
  2385.  
  2386.         //----------------------------------------------------------------------  
  2387.         public function eat8()  
  2388.         {  
  2389.             $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());  
  2390.             $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());  
  2391.  
  2392.  
  2393.             $p = 1;  
  2394.             $dataStrLen = strlen($this->dataStr);  
  2395.              
  2396.             while($p < $dataStrLen) {  
  2397.                  
  2398.                 $mode = $this->identifyMode($p);  
  2399.                 if($mode == QR_MODE_KANJI) {  
  2400.                     break;  
  2401.                 }  
  2402.                 if($mode == QR_MODE_NUM) {  
  2403.                     $q = $p;  
  2404.                     while(self::isdigitat($this->dataStr, $q)) {  
  2405.                         $q++;  
  2406.                     }  
  2407.                     $dif = QRinput::estimateBitsMode8($p) // + 4 + l8  
  2408.                          + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln  
  2409.                          - QRinput::estimateBitsMode8($q); // - 4 - l8  
  2410.                     if($dif < 0) {  
  2411.                         break;  
  2412.                     } else {  
  2413.                         $p = $q;  
  2414.                     }  
  2415.                 } else if($mode == QR_MODE_AN) {  
  2416.                     $q = $p;  
  2417.                     while(self::isalnumat($this->dataStr, $q)) {  
  2418.                         $q++;  
  2419.                     }  
  2420.                     $dif = QRinput::estimateBitsMode8($p)  // + 4 + l8  
  2421.                          + QRinput::estimateBitsModeAn($q - $p) + 4 + $la  
  2422.                          - QRinput::estimateBitsMode8($q); // - 4 - l8  
  2423.                     if($dif < 0) {  
  2424.                         break;  
  2425.                     } else {  
  2426.                         $p = $q;  
  2427.                     }  
  2428.                 } else {  
  2429.                     $p++;  
  2430.                 }  
  2431.             }  
  2432.  
  2433.  
  2434.             $run = $p;  
  2435.             $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));  
  2436.              
  2437.             if($ret < 0)  
  2438.                 return -1;  
  2439.  
  2440.  
  2441.             return $run;  
  2442.         }  
  2443.  
  2444.  
  2445.         //----------------------------------------------------------------------  
  2446.         public function splitString()  
  2447.         {  
  2448.             while (strlen($this->dataStr) > 0)  
  2449.             {  
  2450.                 if($this->dataStr == '')  
  2451.                     return 0;  
  2452.  
  2453.  
  2454.                 $mode = $this->identifyMode(0);  
  2455.                  
  2456.                 switch ($mode) {  
  2457.                     case QR_MODE_NUM: $length = $this->eatNum(); break;  
  2458.                     case QR_MODE_AN:  $length = $this->eatAn(); break;  
  2459.                     case QR_MODE_KANJI:  
  2460.                         if ($hint == QR_MODE_KANJI)  
  2461.                                 $length = $this->eatKanji();  
  2462.                         else    $length = $this->eat8();  
  2463.                         break;  
  2464.                     default: $length = $this->eat8(); break;  
  2465.                  
  2466.                 }  
  2467.  
  2468.  
  2469.                 if($length == 0) return 0;  
  2470.                 if($length < 0)  return -1;  
  2471.                  
  2472.                 $this->dataStr = substr($this->dataStr, $length);  
  2473.             }  
  2474.         }  
  2475.  
  2476.  
  2477.         //----------------------------------------------------------------------  
  2478.         public function toUpper()  
  2479.         {  
  2480.             $stringLen = strlen($this->dataStr);  
  2481.             $p = 0;  
  2482.              
  2483.             while ($p<$stringLen) {  
  2484.                 $mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint);  
  2485.                 if($mode == QR_MODE_KANJI) {  
  2486.                     $p += 2;  
  2487.                 } else {  
  2488.                     if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) {  
  2489.                         $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);  
  2490.                     }  
  2491.                     $p++;  
  2492.                 }  
  2493.             }  
  2494.  
  2495.  
  2496.             return $this->dataStr;  
  2497.         }  
  2498.  
  2499.  
  2500.         //----------------------------------------------------------------------  
  2501.         public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true)  
  2502.         {  
  2503.             if(is_null($string) || $string == '\0' || $string == '') {  
  2504.                 throw new Exception('empty string!!!');  
  2505.             }  
  2506.  
  2507.  
  2508.             $split = new QRsplit($string, $input, $modeHint);  
  2509.              
  2510.             if(!$casesensitive)  
  2511.                 $split->toUpper();  
  2512.                  
  2513.             return $split->splitString();  
  2514.         }  
  2515.     }  
  2516.  
  2517.  
  2518.  
  2519.  
  2520.  
  2521.  
  2522. //---- qrrscode.php -----------------------------  
  2523.  
  2524.  
  2525.  
  2526.  
  2527.  
  2528.  
  2529.  
  2530.  
  2531. /*
  2532.  * PHP QR Code encoder
  2533.  *
  2534.  * Reed-Solomon error correction support
  2535.  *  
  2536.  * Copyright (C) 2002, 2003, 2004, 2006 Phil Karn, KA9Q
  2537.  * (libfec is released under the GNU Lesser General Public License.)
  2538.  *
  2539.  * Based on libqrencode C library distributed under LGPL 2.1
  2540.  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  2541.  *
  2542.  * PHP QR Code is distributed under LGPL 3
  2543.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  2544.  *
  2545.  * This library is free software; you can redistribute it and/or
  2546.  * modify it under the terms of the GNU Lesser General Public
  2547.  * License as published by the Free Software Foundation; either
  2548.  * version 3 of the License, or any later version.
  2549.  *
  2550.  * This library is distributed in the hope that it will be useful,
  2551.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2552.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  2553.  * Lesser General Public License for more details.
  2554.  *
  2555.  * You should have received a copy of the GNU Lesser General Public
  2556.  * License along with this library; if not, write to the Free Software
  2557.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2558.  */  
  2559.    
  2560.     class QRrsItem {  
  2561.      
  2562.         public $mm;                  // Bits per symbol  
  2563.         public $nn;                  // Symbols per block (= (1<<mm)-1)  
  2564.         public $alpha_to = array();  // log lookup table  
  2565.         public $index_of = array();  // Antilog lookup table  
  2566.         public $genpoly = array();   // Generator polynomial  
  2567.         public $nroots;              // Number of generator roots = number of parity symbols  
  2568.         public $fcr;                 // First consecutive root, index form  
  2569.         public $prim;                // Primitive element, index form  
  2570.         public $iprim;               // prim-th root of 1, index form  
  2571.         public $pad;                 // Padding bytes in shortened block  
  2572.         public $gfpoly;  
  2573.      
  2574.         //----------------------------------------------------------------------  
  2575.         public function modnn($x)  
  2576.         {  
  2577.             while ($x >= $this->nn) {  
  2578.                 $x -= $this->nn;  
  2579.                 $x = ($x >> $this->mm) + ($x & $this->nn);  
  2580.             }  
  2581.              
  2582.             return $x;  
  2583.         }  
  2584.          
  2585.         //----------------------------------------------------------------------  
  2586.         public static function init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)  
  2587.         {  
  2588.             // Common code for intializing a Reed-Solomon control block (char or int symbols)  
  2589.             // Copyright 2004 Phil Karn, KA9Q  
  2590.             // May be used under the terms of the GNU Lesser General Public License (LGPL)  
  2591.  
  2592.  
  2593.             $rs = null;  
  2594.              
  2595.             // Check parameter ranges  
  2596.             if($symsize < 0 || $symsize > 8)                     return $rs;  
  2597.             if($fcr < 0 || $fcr >= (1<<$symsize))                return $rs;  
  2598.             if($prim <= 0 || $prim >= (1<<$symsize))             return $rs;  
  2599.             if($nroots < 0 || $nroots >= (1<<$symsize))          return $rs; // Can't have more roots than symbol values!  
  2600.             if($pad < 0 || $pad >= ((1<<$symsize) -1 - $nroots)) return $rs; // Too much padding  
  2601.  
  2602.  
  2603.             $rs = new QRrsItem();  
  2604.             $rs->mm = $symsize;  
  2605.             $rs->nn = (1<<$symsize)-1;  
  2606.             $rs->pad = $pad;  
  2607.  
  2608.  
  2609.             $rs->alpha_to = array_fill(0, $rs->nn+1, 0);  
  2610.             $rs->index_of = array_fill(0, $rs->nn+1, 0);  
  2611.            
  2612.             // PHP style macro replacement ;)  
  2613.             $NN =& $rs->nn;  
  2614.             $A0 =& $NN;  
  2615.              
  2616.             // Generate Galois field lookup tables  
  2617.             $rs->index_of[0] = $A0; // log(zero) = -inf  
  2618.             $rs->alpha_to[$A0] = 0; // alpha**-inf = 0  
  2619.             $sr = 1;  
  2620.            
  2621.             for($i=0; $i<$rs->nn; $i++) {  
  2622.                 $rs->index_of[$sr] = $i;  
  2623.                 $rs->alpha_to[$i] = $sr;  
  2624.                 $sr <<= 1;  
  2625.                 if($sr & (1<<$symsize)) {  
  2626.                     $sr ^= $gfpoly;  
  2627.                 }  
  2628.                 $sr &= $rs->nn;  
  2629.             }  
  2630.              
  2631.             if($sr != 1){  
  2632.                 // field generator polynomial is not primitive!  
  2633.                 $rs = NULL;  
  2634.                 return $rs;  
  2635.             }  
  2636.  
  2637.  
  2638.             /* Form RS code generator polynomial from its roots */  
  2639.             $rs->genpoly = array_fill(0, $nroots+1, 0);  
  2640.          
  2641.             $rs->fcr = $fcr;  
  2642.             $rs->prim = $prim;  
  2643.             $rs->nroots = $nroots;  
  2644.             $rs->gfpoly = $gfpoly;  
  2645.  
  2646.  
  2647.             /* Find prim-th root of 1, used in decoding */  
  2648.             for($iprim=1;($iprim % $prim) != 0;$iprim += $rs->nn)  
  2649.             ; // intentional empty-body loop!  
  2650.              
  2651.             $rs->iprim = (int)($iprim / $prim);  
  2652.             $rs->genpoly[0] = 1;  
  2653.              
  2654.             for ($i = 0,$root=$fcr*$prim; $i < $nroots; $i++, $root += $prim) {  
  2655.                 $rs->genpoly[$i+1] = 1;  
  2656.  
  2657.  
  2658.                 // Multiply rs->genpoly[] by  @**(root + x)  
  2659.                 for ($j = $i; $j > 0; $j--) {  
  2660.                     if ($rs->genpoly[$j] != 0) {  
  2661.                         $rs->genpoly[$j] = $rs->genpoly[$j-1] ^ $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[$j]] + $root)];  
  2662.                     } else {  
  2663.                         $rs->genpoly[$j] = $rs->genpoly[$j-1];  
  2664.                     }  
  2665.                 }  
  2666.                 // rs->genpoly[0] can never be zero  
  2667.                 $rs->genpoly[0] = $rs->alpha_to[$rs->modnn($rs->index_of[$rs->genpoly[0]] + $root)];  
  2668.             }  
  2669.              
  2670.             // convert rs->genpoly[] to index form for quicker encoding  
  2671.             for ($i = 0; $i <= $nroots; $i++)  
  2672.                 $rs->genpoly[$i] = $rs->index_of[$rs->genpoly[$i]];  
  2673.  
  2674.  
  2675.             return $rs;  
  2676.         }  
  2677.          
  2678.         //----------------------------------------------------------------------  
  2679.         public function encode_rs_char($data, &$parity)  
  2680.         {  
  2681.             $MM       =& $this->mm;  
  2682.             $NN       =& $this->nn;  
  2683.             $ALPHA_TO =& $this->alpha_to;  
  2684.             $INDEX_OF =& $this->index_of;  
  2685.             $GENPOLY  =& $this->genpoly;  
  2686.             $NROOTS   =& $this->nroots;  
  2687.             $FCR      =& $this->fcr;  
  2688.             $PRIM     =& $this->prim;  
  2689.             $IPRIM    =& $this->iprim;  
  2690.             $PAD      =& $this->pad;  
  2691.             $A0       =& $NN;  
  2692.  
  2693.  
  2694.             $parity = array_fill(0, $NROOTS, 0);  
  2695.  
  2696.  
  2697.             for($i=0; $i< ($NN-$NROOTS-$PAD); $i++) {  
  2698.                  
  2699.                 $feedback = $INDEX_OF[$data[$i] ^ $parity[0]];  
  2700.                 if($feedback != $A0) {        
  2701.                     // feedback term is non-zero  
  2702.              
  2703.                     // This line is unnecessary when GENPOLY[NROOTS] is unity, as it must  
  2704.                     // always be for the polynomials constructed by init_rs()  
  2705.                     $feedback = $this->modnn($NN - $GENPOLY[$NROOTS] + $feedback);  
  2706.              
  2707.                     for($j=1;$j<$NROOTS;$j++) {  
  2708.                         $parity[$j] ^= $ALPHA_TO[$this->modnn($feedback + $GENPOLY[$NROOTS-$j])];  
  2709.                     }  
  2710.                 }  
  2711.                  
  2712.                 // Shift  
  2713.                 array_shift($parity);  
  2714.                 if($feedback != $A0) {  
  2715.                     array_push($parity, $ALPHA_TO[$this->modnn($feedback + $GENPOLY[0])]);  
  2716.                 } else {  
  2717.                     array_push($parity, 0);  
  2718.                 }  
  2719.             }  
  2720.         }  
  2721.     }  
  2722.      
  2723.     //##########################################################################  
  2724.      
  2725.     class QRrs {  
  2726.      
  2727.         public static $items = array();  
  2728.          
  2729.         //----------------------------------------------------------------------  
  2730.         public static function init_rs($symsize, $gfpoly, $fcr, $prim, $nroots, $pad)  
  2731.         {  
  2732.             foreach(self::$items as $rs) {  
  2733.                 if($rs->pad != $pad)       continue;  
  2734.                 if($rs->nroots != $nroots) continue;  
  2735.                 if($rs->mm != $symsize)    continue;  
  2736.                 if($rs->gfpoly != $gfpoly) continue;  
  2737.                 if($rs->fcr != $fcr)       continue;  
  2738.                 if($rs->prim != $prim)     continue;  
  2739.  
  2740.  
  2741.                 return $rs;  
  2742.             }  
  2743.  
  2744.  
  2745.             $rs = QRrsItem::init_rs_char($symsize, $gfpoly, $fcr, $prim, $nroots, $pad);  
  2746.             array_unshift(self::$items, $rs);  
  2747.  
  2748.  
  2749.             return $rs;  
  2750.         }  
  2751.     }  
  2752.  
  2753.  
  2754.  
  2755.  
  2756.  
  2757.  
  2758. //---- qrmask.php -----------------------------  
  2759.  
  2760.  
  2761.  
  2762.  
  2763.  
  2764.  
  2765.  
  2766.  
  2767. /*
  2768.  * PHP QR Code encoder
  2769.  *
  2770.  * Masking
  2771.  *
  2772.  * Based on libqrencode C library distributed under LGPL 2.1
  2773.  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  2774.  *
  2775.  * PHP QR Code is distributed under LGPL 3
  2776.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  2777.  *
  2778.  * This library is free software; you can redistribute it and/or
  2779.  * modify it under the terms of the GNU Lesser General Public
  2780.  * License as published by the Free Software Foundation; either
  2781.  * version 3 of the License, or any later version.
  2782.  *
  2783.  * This library is distributed in the hope that it will be useful,
  2784.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  2785.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  2786.  * Lesser General Public License for more details.
  2787.  *
  2788.  * You should have received a copy of the GNU Lesser General Public
  2789.  * License along with this library; if not, write to the Free Software
  2790.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  2791.  */  
  2792.    
  2793. <span style="white-space:pre">    </span>define('N1', 3);  
  2794. <span style="white-space:pre">    </span>define('N2', 3);  
  2795. <span style="white-space:pre">    </span>define('N3', 40);  
  2796. <span style="white-space:pre">    </span>define('N4', 10);  
  2797.  
  2798.  
  2799. <span style="white-space:pre">    </span>class QRmask {  
  2800. <span style="white-space:pre">    </span>  
  2801. <span style="white-space:pre">        </span>public $runLength = array();  
  2802. <span style="white-space:pre">        </span>  
  2803. <span style="white-space:pre">        </span>//----------------------------------------------------------------------  
  2804. <span style="white-space:pre">        </span>public function __construct()  
  2805.         {  
  2806.             $this->runLength = array_fill(0, QRSPEC_WIDTH_MAX + 1, 0);  
  2807.         }  
  2808.          
  2809.         //----------------------------------------------------------------------  
  2810.         public function writeFormatInformation($width, &$frame, $mask, $level)  
  2811.         {  
  2812.             $blacks = 0;  
  2813.             $format =  QRspec::getFormatInfo($mask, $level);  
  2814.  
  2815.  
  2816.             for($i=0; $i<8; $i++) {  
  2817.                 if($format & 1) {  
  2818.                     $blacks += 2;  
  2819.                     $v = 0x85;  
  2820.                 } else {  
  2821.                     $v = 0x84;  
  2822.                 }  
  2823.                  
  2824.                 $frame[8][$width - 1 - $i] = chr($v);  
  2825.                 if($i < 6) {  
  2826.                     $frame[$i][8] = chr($v);  
  2827.                 } else {  
  2828.                     $frame[$i + 1][8] = chr($v);  
  2829.                 }  
  2830.                 $format = $format >> 1;  
  2831.             }  
  2832.              
  2833.             for($i=0; $i<7; $i++) {  
  2834.                 if($format & 1) {  
  2835.                     $blacks += 2;  
  2836.                     $v = 0x85;  
  2837.                 } else {  
  2838.                     $v = 0x84;  
  2839.                 }  
  2840.                  
  2841.                 $frame[$width - 7 + $i][8] = chr($v);  
  2842.                 if($i == 0) {  
  2843.                     $frame[8][7] = chr($v);  
  2844.                 } else {  
  2845.                     $frame[8][6 - $i] = chr($v);  
  2846.                 }  
  2847.                  
  2848.                 $format = $format >> 1;  
  2849.             }  
  2850.  
  2851.  
  2852.             return $blacks;  
  2853.         }  
  2854.          
  2855.         //----------------------------------------------------------------------  
  2856.         public function mask0($x, $y) { return ($x+$y)&1;                       }  
  2857.         public function mask1($x, $y) { return ($y&1);                          }  
  2858.         public function mask2($x, $y) { return ($x%3);                          }  
  2859.         public function mask3($x, $y) { return ($x+$y)%3;                       }  
  2860.         public function mask4($x, $y) { return (((int)($y/2))+((int)($x/3)))&1; }  
  2861.         public function mask5($x, $y) { return (($x*$y)&1)+($x*$y)%3;           }  
  2862.         public function mask6($x, $y) { return ((($x*$y)&1)+($x*$y)%3)&1;       }  
  2863.         public function mask7($x, $y) { return ((($x*$y)%3)+(($x+$y)&1))&1;     }  
  2864.          
  2865.         //----------------------------------------------------------------------  
  2866.         private function generateMaskNo($maskNo, $width, $frame)  
  2867.         {  
  2868.             $bitMask = array_fill(0, $width, array_fill(0, $width, 0));  
  2869.              
  2870.             for($y=0; $y<$width; $y++) {  
  2871.                 for($x=0; $x<$width; $x++) {  
  2872.                     if(ord($frame[$y][$x]) & 0x80) {  
  2873.                         $bitMask[$y][$x] = 0;  
  2874.                     } else {  
  2875.                         $maskFunc = call_user_func(array($this, 'mask'.$maskNo), $x, $y);  
  2876.                         $bitMask[$y][$x] = ($maskFunc == 0)?1:0;  
  2877.                     }  
  2878.                      
  2879.                 }  
  2880.             }  
  2881.              
  2882.             return $bitMask;  
  2883.         }  
  2884.          
  2885.         //----------------------------------------------------------------------  
  2886.         public static function serial($bitFrame)  
  2887.         {  
  2888.             $codeArr = array();  
  2889.              
  2890.             foreach ($bitFrame as $line)  
  2891.                 $codeArr[] = join('', $line);  
  2892.                  
  2893.             return gzcompress(join("\n", $codeArr), 9);  
  2894.         }  
  2895.          
  2896.         //----------------------------------------------------------------------  
  2897.         public static function unserial($code)  
  2898.         {  
  2899.             $codeArr = array();  
  2900.              
  2901.             $codeLines = explode("\n", gzuncompress($code));  
  2902.             foreach ($codeLines as $line)  
  2903.                 $codeArr[] = str_split($line);  
  2904.              
  2905.             return $codeArr;  
  2906.         }  
  2907.          
  2908.         //----------------------------------------------------------------------  
  2909.         public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false)  
  2910.         {  
  2911.             $b = 0;  
  2912.             $bitMask = array();  
  2913.              
  2914.             $fileName = QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat';  
  2915.  
  2916.  
  2917.             if (QR_CACHEABLE) {  
  2918.                 if (file_exists($fileName)) {  
  2919.                     $bitMask = self::unserial(file_get_contents($fileName));  
  2920.                 } else {  
  2921.                     $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);  
  2922.                     if (!file_exists(QR_CACHE_DIR.'mask_'.$maskNo))  
  2923.                         mkdir(QR_CACHE_DIR.'mask_'.$maskNo);  
  2924.                     file_put_contents($fileName, self::serial($bitMask));  
  2925.                 }  
  2926.             } else {  
  2927.                 $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);  
  2928.             }  
  2929.  
  2930.  
  2931.             if ($maskGenOnly)  
  2932.                 return;  
  2933.                  
  2934.             $d = $s;  
  2935.  
  2936.  
  2937.             for($y=0; $y<$width; $y++) {  
  2938.                 for($x=0; $x<$width; $x++) {  
  2939.                     if($bitMask[$y][$x] == 1) {  
  2940.                         $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]);  
  2941.                     }  
  2942.                     $b += (int)(ord($d[$y][$x]) & 1);  
  2943.                 }  
  2944.             }  
  2945.  
  2946.  
  2947.             return $b;  
  2948.         }  
  2949.          
  2950.         //----------------------------------------------------------------------  
  2951.         public function makeMask($width, $frame, $maskNo, $level)  
  2952.         {  
  2953.             $masked = array_fill(0, $width, str_repeat("\0", $width));  
  2954.             $this->makeMaskNo($maskNo, $width, $frame, $masked);  
  2955.             $this->writeFormatInformation($width, $masked, $maskNo, $level);  
  2956.          
  2957.             return $masked;  
  2958.         }  
  2959.          
  2960.         //----------------------------------------------------------------------  
  2961.         public function calcN1N3($length)  
  2962.         {  
  2963.             $demerit = 0;  
  2964.  
  2965.  
  2966.             for($i=0; $i<$length; $i++) {  
  2967.                  
  2968.                 if($this->runLength[$i] >= 5) {  
  2969.                     $demerit += (N1 + ($this->runLength[$i] - 5));  
  2970.                 }  
  2971.                 if($i & 1) {  
  2972.                     if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) {  
  2973.                         $fact = (int)($this->runLength[$i] / 3);  
  2974.                         if(($this->runLength[$i-2] == $fact) &&  
  2975.                            ($this->runLength[$i-1] == $fact) &&  
  2976.                            ($this->runLength[$i+1] == $fact) &&  
  2977.                            ($this->runLength[$i+2] == $fact)) {  
  2978.                             if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) {  
  2979.                                 $demerit += N3;  
  2980.                             } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) {  
  2981.                                 $demerit += N3;  
  2982.                             }  
  2983.                         }  
  2984.                     }  
  2985.                 }  
  2986.             }  
  2987.             return $demerit;  
  2988.         }  
  2989.          
  2990.         //----------------------------------------------------------------------  
  2991.         public function evaluateSymbol($width, $frame)  
  2992.         {  
  2993.             $head = 0;  
  2994.             $demerit = 0;  
  2995.  
  2996.  
  2997.             for($y=0; $y<$width; $y++) {  
  2998.                 $head = 0;  
  2999.                 $this->runLength[0] = 1;  
  3000.                  
  3001.                 $frameY = $frame[$y];  
  3002.                  
  3003.                 if ($y>0)  
  3004.                     $frameYM = $frame[$y-1];  
  3005.                  
  3006.                 for($x=0; $x<$width; $x++) {  
  3007.                     if(($x > 0) && ($y > 0)) {  
  3008.                         $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]);  
  3009.                         $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]);  
  3010.                          
  3011.                         if(($b22 | ($w22 ^ 1))&1) {                                                                      
  3012.                             $demerit += N2;  
  3013.                         }  
  3014.                     }  
  3015.                     if(($x == 0) && (ord($frameY[$x]) & 1)) {  
  3016.                         $this->runLength[0] = -1;  
  3017.                         $head = 1;  
  3018.                         $this->runLength[$head] = 1;  
  3019.                     } else if($x > 0) {  
  3020.                         if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) {  
  3021.                             $head++;  
  3022.                             $this->runLength[$head] = 1;  
  3023.                         } else {  
  3024.                             $this->runLength[$head]++;  
  3025.                         }  
  3026.                     }  
  3027.                 }  
  3028.      
  3029.                 $demerit += $this->calcN1N3($head+1);  
  3030.             }  
  3031.  
  3032.  
  3033.             for($x=0; $x<$width; $x++) {  
  3034.                 $head = 0;  
  3035.                 $this->runLength[0] = 1;  
  3036.                  
  3037.                 for($y=0; $y<$width; $y++) {  
  3038.                     if($y == 0 && (ord($frame[$y][$x]) & 1)) {  
  3039.                         $this->runLength[0] = -1;  
  3040.                         $head = 1;  
  3041.                         $this->runLength[$head] = 1;  
  3042.                     } else if($y > 0) {  
  3043.                         if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) {  
  3044.                             $head++;  
  3045.                             $this->runLength[$head] = 1;  
  3046.                         } else {  
  3047.                             $this->runLength[$head]++;  
  3048.                         }  
  3049.                     }  
  3050.                 }  
  3051.              
  3052.                 $demerit += $this->calcN1N3($head+1);  
  3053.             }  
  3054.  
  3055.  
  3056.             return $demerit;  
  3057.         }  
  3058.          
  3059.          
  3060.         //----------------------------------------------------------------------  
  3061.         public function mask($width, $frame, $level)  
  3062.         {  
  3063.             $minDemerit = PHP_INT_MAX;  
  3064.             $bestMaskNum = 0;  
  3065.             $bestMask = array();  
  3066.              
  3067.             $checked_masks = array(0,1,2,3,4,5,6,7);  
  3068.              
  3069.             if (QR_FIND_FROM_RANDOM !== false) {  
  3070.              
  3071.                 $howManuOut = 8-(QR_FIND_FROM_RANDOM % 9);  
  3072.                 for ($i = 0; $i <  $howManuOut; $i++) {  
  3073.                     $remPos = rand (0, count($checked_masks)-1);  
  3074.                     unset($checked_masks[$remPos]);  
  3075.                     $checked_masks = array_values($checked_masks);  
  3076.                 }  
  3077.              
  3078.             }  
  3079.              
  3080.             $bestMask = $frame;  
  3081.                
  3082.             foreach($checked_masks as $i) {  
  3083.                 $mask = array_fill(0, $width, str_repeat("\0", $width));  
  3084.  
  3085.  
  3086.                 $demerit = 0;  
  3087.                 $blacks = 0;  
  3088.                 $blacks  = $this->makeMaskNo($i, $width, $frame, $mask);  
  3089.                 $blacks += $this->writeFormatInformation($width, $mask, $i, $level);  
  3090.                 $blacks  = (int)(100 * $blacks / ($width * $width));  
  3091.                 $demerit = (int)((int)(abs($blacks - 50) / 5) * N4);  
  3092.                 $demerit += $this->evaluateSymbol($width, $mask);  
  3093.                  
  3094.                 if($demerit < $minDemerit) {  
  3095.                     $minDemerit = $demerit;  
  3096.                     $bestMask = $mask;  
  3097.                     $bestMaskNum = $i;  
  3098.                 }  
  3099.             }  
  3100.              
  3101.             return $bestMask;  
  3102.         }  
  3103.          
  3104.         //----------------------------------------------------------------------  
  3105.     }  
  3106.  
  3107.  
  3108.  
  3109.  
  3110.  
  3111.  
  3112.  
  3113.  
  3114. //---- qrencode.php -----------------------------  
  3115.  
  3116.  
  3117.  
  3118.  
  3119.  
  3120.  
  3121.  
  3122.  
  3123. /*
  3124.  * PHP QR Code encoder
  3125.  *
  3126.  * Main encoder classes.
  3127.  *
  3128.  * Based on libqrencode C library distributed under LGPL 2.1
  3129.  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
  3130.  *
  3131.  * PHP QR Code is distributed under LGPL 3
  3132.  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
  3133.  *
  3134.  * This library is free software; you can redistribute it and/or
  3135.  * modify it under the terms of the GNU Lesser General Public
  3136.  * License as published by the Free Software Foundation; either
  3137.  * version 3 of the License, or any later version.
  3138.  *
  3139.  * This library is distributed in the hope that it will be useful,
  3140.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  3141.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  3142.  * Lesser General Public License for more details.
  3143.  *
  3144.  * You should have received a copy of the GNU Lesser General Public
  3145.  * License along with this library; if not, write to the Free Software
  3146.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  3147.  */  
  3148.    
  3149.     class QRrsblock {  
  3150.         public $dataLength;  
  3151.         public $data = array();  
  3152.         public $eccLength;  
  3153.         public $ecc = array();  
  3154.          
  3155.         public function __construct($dl, $data, $el, &$ecc, QRrsItem $rs)  
  3156.         {  
  3157.             $rs->encode_rs_char($data, $ecc);  
  3158.          
  3159.             $this->dataLength = $dl;  
  3160.             $this->data = $data;  
  3161.             $this->eccLength = $el;  
  3162.             $this->ecc = $ecc;  
  3163.         }  
  3164.     };  
  3165.      
  3166.     //##########################################################################  
  3167.  
  3168.  
  3169.     class QRrawcode {  
  3170.         public $version;  
  3171.         public $datacode = array();  
  3172.         public $ecccode = array();  
  3173.         public $blocks;  
  3174.         public $rsblocks = array(); //of RSblock  
  3175.         public $count;  
  3176.         public $dataLength;  
  3177.         public $eccLength;  
  3178.         public $b1;  
  3179.          
  3180.         //----------------------------------------------------------------------  
  3181.         public function __construct(QRinput $input)  
  3182.         {  
  3183.             $spec = array(0,0,0,0,0);  
  3184.              
  3185.             $this->datacode = $input->getByteStream();  
  3186.             if(is_null($this->datacode)) {  
  3187.                 throw new Exception('null imput string');  
  3188.             }  
  3189.  
  3190.  
  3191.             QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);  
  3192.  
  3193.  
  3194.             $this->version = $input->getVersion();  
  3195.             $this->b1 = QRspec::rsBlockNum1($spec);  
  3196.             $this->dataLength = QRspec::rsDataLength($spec);  
  3197.             $this->eccLength = QRspec::rsEccLength($spec);  
  3198.             $this->ecccode = array_fill(0, $this->eccLength, 0);  
  3199.             $this->blocks = QRspec::rsBlockNum($spec);  
  3200.              
  3201.             $ret = $this->init($spec);  
  3202.             if($ret < 0) {  
  3203.                 throw new Exception('block alloc error');  
  3204.                 return null;  
  3205.             }  
  3206.  
  3207.  
  3208.             $this->count = 0;  
  3209.         }  
  3210.          
  3211.         //----------------------------------------------------------------------  
  3212.         public function init(array $spec)  
  3213.         {  
  3214.             $dl = QRspec::rsDataCodes1($spec);  
  3215.             $el = QRspec::rsEccCodes1($spec);  
  3216.             $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);  
  3217.              
  3218.  
  3219.  
  3220.             $blockNo = 0;  
  3221.             $dataPos = 0;  
  3222.             $eccPos = 0;  
  3223.             for($i=0; $i<QRspec::rsBlockNum1($spec); $i++) {  
  3224.                 $ecc = array_slice($this->ecccode,$eccPos);  
  3225.                 $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el,  $ecc, $rs);  
  3226.                 $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);  
  3227.                  
  3228.                 $dataPos += $dl;  
  3229.                 $eccPos += $el;  
  3230.                 $blockNo++;  
  3231.             }  
  3232.  
  3233.  
  3234.             if(QRspec::rsBlockNum2($spec) == 0)  
  3235.                 return 0;  
  3236.  
  3237.  
  3238.             $dl = QRspec::rsDataCodes2($spec);  
  3239.             $el = QRspec::rsEccCodes2($spec);  
  3240.             $rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);  
  3241.              
  3242.             if($rs == NULL) return -1;  
  3243.              
  3244.             for($i=0; $i<QRspec::rsBlockNum2($spec); $i++) {  
  3245.                 $ecc = array_slice($this->ecccode,$eccPos);  
  3246.                 $this->rsblocks[$blockNo] = new QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs);  
  3247.                 $this->ecccode = array_merge(array_slice($this->ecccode,0, $eccPos), $ecc);  
  3248.                  
  3249.                 $dataPos += $dl;  
  3250.                 $eccPos += $el;  
  3251.                 $blockNo++;  
  3252.             }  
  3253.  
  3254.  
  3255.             return 0;  
  3256.         }  
  3257.          
  3258.         //----------------------------------------------------------------------  
  3259.         public function getCode()  
  3260.         {  
  3261.             $ret;  
  3262.  
  3263.  
  3264.             if($this->count < $this->dataLength) {  
  3265.                 $row = $this->count % $this->blocks;  
  3266.                 $col = $this->count / $this->blocks;  
  3267.                 if($col >= $this->rsblocks[0]->dataLength) {  
  3268.                     $row += $this->b1;  
  3269.                 }  
  3270.                 $ret = $this->rsblocks[$row]->data[$col];  
  3271.             } else if($this->count < $this->dataLength + $this->eccLength) {  
  3272.                 $row = ($this->count - $this->dataLength) % $this->blocks;  
  3273.                 $col = ($this->count - $this->dataLength) / $this->blocks;  
  3274.                 $ret = $this->rsblocks[$row]->ecc[$col];  
  3275.             } else {  
  3276.                 return 0;  
  3277.             }  
  3278.             $this->count++;  
  3279.              
  3280.             return $ret;  
  3281.         }  
  3282.     }  
  3283.  
  3284.  
  3285.     //##########################################################################  
  3286.      
  3287.     class QRcode {  
  3288.      
  3289.         public $version;  
  3290.         public $width;  
  3291.         public $data;  
  3292.          
  3293.         //----------------------------------------------------------------------  
  3294.         public function encodeMask(QRinput $input, $mask)  
  3295.         {  
  3296.             if($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) {  
  3297.                 throw new Exception('wrong version');  
  3298.             }  
  3299.             if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) {  
  3300.                 throw new Exception('wrong level');  
  3301.             }  
  3302.  
  3303.  
  3304.             $raw = new QRrawcode($input);  
  3305.              
  3306.             QRtools::markTime('after_raw');  
  3307.              
  3308.             $version = $raw->version;  
  3309.             $width = QRspec::getWidth($version);  
  3310.             $frame = QRspec::newFrame($version);  
  3311.              
  3312.             $filler = new FrameFiller($width, $frame);  
  3313.             if(is_null($filler)) {  
  3314.                 return NULL;  
  3315.             }  
  3316.  
  3317.  
  3318.             // inteleaved data and ecc codes  
  3319.             for($i=0; $i<$raw->dataLength + $raw->eccLength; $i++) {  
  3320.                 $code = $raw->getCode();  
  3321.                 $bit = 0x80;  
  3322.                 for($j=0; $j<8; $j++) {  
  3323.                     $addr = $filler->next();  
  3324.                     $filler->setFrameAt($addr, 0x02 | (($bit & $code) != 0));  
  3325.                     $bit = $bit >> 1;  
  3326.                 }  
  3327.             }  
  3328.              
  3329.             QRtools::markTime('after_filler');  
  3330.              
  3331.             unset($raw);  
  3332.              
  3333.             // remainder bits  
  3334.             $j = QRspec::getRemainder($version);  
  3335.             for($i=0; $i<$j; $i++) {  
  3336.                 $addr = $filler->next();  
  3337.                 $filler->setFrameAt($addr, 0x02);  
  3338.             }  
  3339.              
  3340.             $frame = $filler->frame;  
  3341.             unset($filler);  
  3342.              
  3343.              
  3344.             // masking  
  3345.             $maskObj = new QRmask();  
  3346.             if($mask < 0) {  
  3347.              
  3348.                 if (QR_FIND_BEST_MASK) {  
  3349.                     $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());  
  3350.                 } else {  
  3351.                     $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK) % 8), $input->getErrorCorrectionLevel());  
  3352.                 }  
  3353.             } else {  
  3354.                 $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());  
  3355.             }  
  3356.              
  3357.             if($masked == NULL) {  
  3358.                 return NULL;  
  3359.             }  
  3360.              
  3361.             QRtools::markTime('after_mask');  
  3362.              
  3363.             $this->version = $version;  
  3364.             $this->width = $width;  
  3365.             $this->data = $masked;  
  3366.              
  3367.             return $this;  
  3368.         }  
  3369.      
  3370.         //----------------------------------------------------------------------  
  3371.         public function encodeInput(QRinput $input)  
  3372.         {  
  3373.             return $this->encodeMask($input, -1);  
  3374.         }  
  3375.          
  3376.         //----------------------------------------------------------------------  
  3377.         public function encodeString8bit($string, $version, $level)  
  3378.         {  
  3379.             if(string == NULL) {  
  3380.                 throw new Exception('empty string!');  
  3381.                 return NULL;  
  3382.             }  
  3383.  
  3384.  
  3385.             $input = new QRinput($version, $level);  
  3386.             if($input == NULL) return NULL;  
  3387.  
  3388.  
  3389.             $ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string));  
  3390.             if($ret < 0) {  
  3391.                 unset($input);  
  3392.                 return NULL;  
  3393.             }  
  3394.             return $this->encodeInput($input);  
  3395.         }  
  3396.  
  3397.  
  3398.         //----------------------------------------------------------------------  
  3399.         public function encodeString($string, $version, $level, $hint, $casesensitive)  
  3400.         {  
  3401.  
  3402.  
  3403.             if($hint != QR_MODE_8 && $hint != QR_MODE_KANJI) {  
  3404.                 throw new Exception('bad hint');  
  3405.                 return NULL;  
  3406.             }  
  3407.  
  3408.  
  3409.             $input = new QRinput($version, $level);  
  3410.             if($input == NULL) return NULL;  
  3411.  
  3412.  
  3413.             $ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive);  
  3414.             if($ret < 0) {  
  3415.                 return NULL;  
  3416.             }  
  3417.  
  3418.  
  3419.             return $this->encodeInput($input);  
  3420.         }  
  3421.          
  3422.         //----------------------------------------------------------------------  
  3423.         public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false)  
  3424.         {  
  3425.             $enc = QRencode::factory($level, $size, $margin);  
  3426.             return $enc->encodePNG($text, $outfile, $saveandprint=false);  
  3427.         }  
  3428.  
  3429.  
  3430.         //----------------------------------------------------------------------  
  3431.         public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4)  
  3432.         {  
  3433.             $enc = QRencode::factory($level, $size, $margin);  
  3434.             return $enc->encode($text, $outfile);  
  3435.         }  
  3436.  
  3437.  
  3438.         //----------------------------------------------------------------------  
  3439.         public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4)  
  3440.         {  
  3441.             $enc = QRencode::factory($level, $size, $margin);  
  3442.             return $enc->encodeRAW($text, $outfile);  
  3443.         }  
  3444.     }  
  3445.      
  3446.     //##########################################################################  
  3447.      
  3448.     class FrameFiller {  
  3449.      
  3450.         public $width;  
  3451.         public $frame;  
  3452.         public $x;  
  3453.         public $y;  
  3454.         public $dir;  
  3455.         public $bit;  
  3456.          
  3457.         //----------------------------------------------------------------------  
  3458.         public function __construct($width, &$frame)  
  3459.         {  
  3460.             $this->width = $width;  
  3461.             $this->frame = $frame;  
  3462.             $this->x = $width - 1;  
  3463.             $this->y = $width - 1;  
  3464.             $this->dir = -1;  
  3465.             $this->bit = -1;  
  3466.         }  
  3467.          
  3468.         //----------------------------------------------------------------------  
  3469.         public function setFrameAt($at, $val)  
  3470.         {  
  3471.             $this->frame[$at['y']][$at['x']] = chr($val);  
  3472.         }  
  3473.          
  3474.         //----------------------------------------------------------------------  
  3475.         public function getFrameAt($at)  
  3476.         {  
  3477.             return ord($this->frame[$at['y']][$at['x']]);  
  3478.         }  
  3479.          
  3480.         //----------------------------------------------------------------------  
  3481.         public function next()  
  3482.         {  
  3483.             do {  
  3484.              
  3485.                 if($this->bit == -1) {  
  3486.                     $this->bit = 0;  
  3487.                     return array('x'=>$this->x, 'y'=>$this->y);  
  3488.                 }  
  3489.  
  3490.  
  3491.                 $x = $this->x;  
  3492.                 $y = $this->y;  
  3493.                 $w = $this->width;  
  3494.  
  3495.  
  3496.                 if($this->bit == 0) {  
  3497.                     $x--;  
  3498.                     $this->bit++;  
  3499.                 } else {  
  3500.                     $x++;  
  3501.                     $y += $this->dir;  
  3502.                     $this->bit--;  
  3503.                 }  
  3504.  
  3505.  
  3506.                 if($this->dir < 0) {  
  3507.                     if($y < 0) {  
  3508.                         $y = 0;  
  3509.                         $x -= 2;  
  3510.                         $this->dir = 1;  
  3511.                         if($x == 6) {  
  3512.                             $x--;  
  3513.                             $y = 9;  
  3514.                         }  
  3515.                     }  
  3516.                 } else {  
  3517.                     if($y == $w) {  
  3518.                         $y = $w - 1;  
  3519.                         $x -= 2;  
  3520.                         $this->dir = -1;  
  3521.                         if($x == 6) {  
  3522.                             $x--;  
  3523.                             $y -= 8;  
  3524.                         }  
  3525.                     }  
  3526.                 }  
  3527.                 if($x < 0 || $y < 0) return null;  
  3528.  
  3529.  
  3530.                 $this->x = $x;  
  3531.                 $this->y = $y;  
  3532.  
  3533.  
  3534.             } while(ord($this->frame[$y][$x]) & 0x80);  
  3535.                          
  3536.             return array('x'=>$x, 'y'=>$y);  
  3537.         }  
  3538.          
  3539.     } ;  
  3540.      
  3541.     //##########################################################################      
  3542.      
  3543.     class QRencode {  
  3544.      
  3545.         public $casesensitive = true;  
  3546.         public $eightbit = false;  
  3547.          
  3548.         public $version = 0;  
  3549.         public $size = 3;  
  3550.         public $margin = 4;  
  3551.          
  3552.         public $structured = 0; // not supported yet  
  3553.          
  3554.         public $level = QR_ECLEVEL_L;  
  3555.         public $hint = QR_MODE_8;  
  3556.          
  3557.         //----------------------------------------------------------------------  
  3558.         public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4)  
  3559.         {  
  3560.             $enc = new QRencode();  
  3561.             $enc->size = $size;  
  3562.             $enc->margin = $margin;  
  3563.              
  3564.             switch ($level.'') {  
  3565.                 case '0':  
  3566.                 case '1':  
  3567.                 case '2':  
  3568.                 case '3':  
  3569.                         $enc->level = $level;  
  3570.                     break;  
  3571.                 case 'l':  
  3572.                 case 'L':  
  3573.                         $enc->level = QR_ECLEVEL_L;  
  3574.                     break;  
  3575.                 case 'm':  
  3576.                 case 'M':  
  3577.                         $enc->level = QR_ECLEVEL_M;  
  3578.                     break;  
  3579.                 case 'q':  
  3580.                 case 'Q':  
  3581.                         $enc->level = QR_ECLEVEL_Q;  
  3582.                     break;  
  3583.                 case 'h':  
  3584.                 case 'H':  
  3585.                         $enc->level = QR_ECLEVEL_H;  
  3586.                     break;  
  3587.             }  
  3588.              
  3589.             return $enc;  
  3590.         }  
  3591.          
  3592.         //----------------------------------------------------------------------  
  3593.         public function encodeRAW($intext, $outfile = false)  
  3594.         {  
  3595.             $code = new QRcode();  
  3596.  
  3597.  
  3598.             if($this->eightbit) {  
  3599.                 $code->encodeString8bit($intext, $this->version, $this->level);  
  3600.             } else {  
  3601.                 $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);  
  3602.             }  
  3603.              
  3604.             return $code->data;  
  3605.         }  
  3606.  
  3607.  
  3608.         //----------------------------------------------------------------------  
  3609.         public function encode($intext, $outfile = false)  
  3610.         {  
  3611.             $code = new QRcode();  
  3612.  
  3613.  
  3614.             if($this->eightbit) {  
  3615.                 $code->encodeString8bit($intext, $this->version, $this->level);  
  3616.             } else {  
  3617.                 $code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);  
  3618.             }  
  3619.              
  3620.             QRtools::markTime('after_encode');  
  3621.              
  3622.             if ($outfile!== false) {  
  3623.                 file_put_contents($outfile, join("\n", QRtools::binarize($code->data)));  
  3624.             } else {  
  3625.                 return QRtools::binarize($code->data);  
  3626.             }  
  3627.         }  
  3628.          
  3629.         //----------------------------------------------------------------------  
  3630.         public function encodePNG($intext, $outfile = false,$saveandprint=false)  
  3631.         {  
  3632.             try {  
  3633.              
  3634.                 ob_start();  
  3635.                 $tab = $this->encode($intext);  
  3636.                 $err = ob_get_contents();  
  3637.                 ob_end_clean();  
  3638.                  
  3639.                 if ($err != '')  
  3640.                     QRtools::log($outfile, $err);  
  3641.                  
  3642.                 $maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin));  
  3643.                  
  3644.                 QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint);  
  3645.              
  3646.             } catch (Exception $e) {  
  3647.              
  3648.                 QRtools::log($outfile, $e->getMessage());  
  3649.              
  3650.             }  
  3651.         }  
  3652.     }  
  3653.  

回复 "php phpqrcode 生成二维码"

这儿你可以回复上面这条便签

captcha