survey_seahorse

Software Engineering Project - Fall 2018
Log | Files | Refs | README

phpqrcode.php (121780B)


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