]>
Raphaƫl G. Git Repositories - cdn/blob - vendor/phpqrcode/qrinput.php
   7  * Based on libqrencode C library distributed under LGPL 2.1 
   8  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net> 
  10  * PHP QR Code is distributed under LGPL 3 
  11  * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm> 
  13  * This library is free software; you can redistribute it and/or 
  14  * modify it under the terms of the GNU Lesser General Public 
  15  * License as published by the Free Software Foundation; either 
  16  * version 3 of the License, or any later version. 
  18  * This library is distributed in the hope that it will be useful, 
  19  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
  20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
  21  * Lesser General Public License for more details. 
  23  * You should have received a copy of the GNU Lesser General Public 
  24  * License along with this library; if not, write to the Free Software 
  25  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 
  28     define('STRUCTURE_HEADER_BITS',  20); 
  29     define('MAX_STRUCTURED_SYMBOLS', 16); 
  38         public function __construct($mode, $size, $data, $bstream = null)  
  40             $setData = array_slice($data, 0, $size); 
  42             if (count($setData) < $size) { 
  43                 $setData = array_merge($setData, array_fill(0,$size-count($setData),0)); 
  46             if(!QRinput
::check($mode, $size, $setData)) { 
  47                 throw new Exception('Error m:'.$mode.',s:'.$size.',d:'.join(',',$setData)); 
  52             $this->data 
= $setData; 
  53             $this->bstream 
= $bstream; 
  56         //---------------------------------------------------------------------- 
  57         public function encodeModeNum($version) 
  61                 $words = (int)($this->size 
/ 3); 
  62                 $bs = new QRbitstream(); 
  65                 $bs->appendNum(4, $val); 
  66                 $bs->appendNum(QRspec
::lengthIndicator(QR_MODE_NUM
, $version), $this->size
); 
  68                 for($i=0; $i<$words; $i++
) { 
  69                     $val  = (ord($this->data
[$i*3  ]) - ord('0')) * 100; 
  70                     $val +
= (ord($this->data
[$i*3+
1]) - ord('0')) * 10; 
  71                     $val +
= (ord($this->data
[$i*3+
2]) - ord('0')); 
  72                     $bs->appendNum(10, $val); 
  75                 if($this->size 
- $words * 3 == 1) { 
  76                     $val = ord($this->data
[$words*3]) - ord('0'); 
  77                     $bs->appendNum(4, $val); 
  78                 } else if($this->size 
- $words * 3 == 2) { 
  79                     $val  = (ord($this->data
[$words*3  ]) - ord('0')) * 10; 
  80                     $val +
= (ord($this->data
[$words*3+
1]) - ord('0')); 
  81                     $bs->appendNum(7, $val); 
  87             } catch (Exception 
$e) { 
  92         //---------------------------------------------------------------------- 
  93         public function encodeModeAn($version) 
  96                 $words = (int)($this->size 
/ 2); 
  97                 $bs = new QRbitstream(); 
  99                 $bs->appendNum(4, 0x02); 
 100                 $bs->appendNum(QRspec
::lengthIndicator(QR_MODE_AN
, $version), $this->size
); 
 102                 for($i=0; $i<$words; $i++
) { 
 103                     $val  = (int)QRinput
::lookAnTable(ord($this->data
[$i*2  ])) * 45; 
 104                     $val +
= (int)QRinput
::lookAnTable(ord($this->data
[$i*2+
1])); 
 106                     $bs->appendNum(11, $val); 
 109                 if($this->size 
& 1) { 
 110                     $val = QRinput
::lookAnTable(ord($this->data
[$words * 2])); 
 111                     $bs->appendNum(6, $val); 
 114                 $this->bstream 
= $bs; 
 117             } catch (Exception 
$e) { 
 122         //---------------------------------------------------------------------- 
 123         public function encodeMode8($version) 
 126                 $bs = new QRbitstream(); 
 128                 $bs->appendNum(4, 0x4); 
 129                 $bs->appendNum(QRspec
::lengthIndicator(QR_MODE_8
, $version), $this->size
); 
 131                 for($i=0; $i<$this->size
; $i++
) { 
 132                     $bs->appendNum(8, ord($this->data
[$i])); 
 135                 $this->bstream 
= $bs; 
 138             } catch (Exception 
$e) { 
 143         //---------------------------------------------------------------------- 
 144         public function encodeModeKanji($version) 
 148                 $bs = new QRbitrtream(); 
 150                 $bs->appendNum(4, 0x8); 
 151                 $bs->appendNum(QRspec
::lengthIndicator(QR_MODE_KANJI
, $version), (int)($this->size 
/ 2)); 
 153                 for($i=0; $i<$this->size
; $i+
=2) { 
 154                     $val = (ord($this->data
[$i]) << 8) | ord($this->data
[$i+
1]); 
 161                     $h = ($val >> 8) * 0xc0; 
 162                     $val = ($val & 0xff) + 
$h; 
 164                     $bs->appendNum(13, $val); 
 167                 $this->bstream 
= $bs; 
 170             } catch (Exception 
$e) { 
 175         //---------------------------------------------------------------------- 
 176         public function encodeModeStructure() 
 179                 $bs =  new QRbitstream(); 
 181                 $bs->appendNum(4, 0x03); 
 182                 $bs->appendNum(4, ord($this->data
[1]) - 1); 
 183                 $bs->appendNum(4, ord($this->data
[0]) - 1); 
 184                 $bs->appendNum(8, ord($this->data
[2])); 
 186                 $this->bstream 
= $bs; 
 189             } catch (Exception 
$e) { 
 194         //---------------------------------------------------------------------- 
 195         public function estimateBitStreamSizeOfEntry($version) 
 202             switch($this->mode
) { 
 203                 case QR_MODE_NUM
:        $bits = QRinput
::estimateBitsModeNum($this->size
);    break; 
 204                 case QR_MODE_AN
:        $bits = QRinput
::estimateBitsModeAn($this->size
);    break; 
 205                 case QR_MODE_8
:            $bits = QRinput
::estimateBitsMode8($this->size
);    break; 
 206                 case QR_MODE_KANJI
:        $bits = QRinput
::estimateBitsModeKanji($this->size
);break; 
 207                 case QR_MODE_STRUCTURE
:    return STRUCTURE_HEADER_BITS
;             
 212             $l = QRspec
::lengthIndicator($this->mode
, $version); 
 214             $num = (int)(($this->size + 
$m - 1) / $m); 
 216             $bits +
= $num * (4 + 
$l); 
 221         //---------------------------------------------------------------------- 
 222         public function encodeBitStream($version) 
 226                 unset($this->bstream
); 
 227                 $words = QRspec
::maximumWords($this->mode
, $version); 
 229                 if($this->size 
> $words) { 
 231                     $st1 = new QRinputItem($this->mode
, $words, $this->data
); 
 232                     $st2 = new QRinputItem($this->mode
, $this->size 
- $words, array_slice($this->data
, $words)); 
 234                     $st1->encodeBitStream($version); 
 235                     $st2->encodeBitStream($version); 
 237                     $this->bstream 
= new QRbitstream(); 
 238                     $this->bstream
->append($st1->bstream
); 
 239                     $this->bstream
->append($st2->bstream
); 
 248                     switch($this->mode
) { 
 249                         case QR_MODE_NUM
:        $ret = $this->encodeModeNum($version);    break; 
 250                         case QR_MODE_AN
:        $ret = $this->encodeModeAn($version);    break; 
 251                         case QR_MODE_8
:            $ret = $this->encodeMode8($version);    break; 
 252                         case QR_MODE_KANJI
:        $ret = $this->encodeModeKanji($version);break; 
 253                         case QR_MODE_STRUCTURE
:    $ret = $this->encodeModeStructure();    break; 
 263                 return $this->bstream
->size(); 
 265             } catch (Exception 
$e) { 
 271     //########################################################################## 
 280         //---------------------------------------------------------------------- 
 281         public function __construct($version = 0, $level = QR_ECLEVEL_L
) 
 283             if ($version < 0 || $version > QRSPEC_VERSION_MAX 
|| $level > QR_ECLEVEL_H
) { 
 284                 throw new Exception('Invalid version no'); 
 287             $this->version 
= $version; 
 288             $this->level 
= $level; 
 291         //---------------------------------------------------------------------- 
 292         public function getVersion() 
 294             return $this->version
; 
 297         //---------------------------------------------------------------------- 
 298         public function setVersion($version) 
 300             if($version < 0 || $version > QRSPEC_VERSION_MAX
) { 
 301                 throw new Exception('Invalid version no'); 
 305             $this->version 
= $version; 
 310         //---------------------------------------------------------------------- 
 311         public function getErrorCorrectionLevel() 
 316         //---------------------------------------------------------------------- 
 317         public function setErrorCorrectionLevel($level) 
 319             if($level > QR_ECLEVEL_H
) { 
 320                 throw new Exception('Invalid ECLEVEL'); 
 324             $this->level 
= $level; 
 329         //---------------------------------------------------------------------- 
 330         public function appendEntry(QRinputItem 
$entry) 
 332             $this->items
[] = $entry; 
 335         //---------------------------------------------------------------------- 
 336         public function append($mode, $size, $data) 
 339                 $entry = new QRinputItem($mode, $size, $data); 
 340                 $this->items
[] = $entry; 
 342             } catch (Exception 
$e) { 
 347         //---------------------------------------------------------------------- 
 349         public function insertStructuredAppendHeader($size, $index, $parity) 
 351             if( $size > MAX_STRUCTURED_SYMBOLS 
) { 
 352                 throw new Exception('insertStructuredAppendHeader wrong size'); 
 355             if( $index <= 0 || $index > MAX_STRUCTURED_SYMBOLS 
) { 
 356                 throw new Exception('insertStructuredAppendHeader wrong index'); 
 359             $buf = array($size, $index, $parity); 
 362                 $entry = new QRinputItem(QR_MODE_STRUCTURE
, 3, buf
); 
 363                 array_unshift($this->items
, $entry); 
 365             } catch (Exception 
$e) { 
 370         //---------------------------------------------------------------------- 
 371         public function calcParity() 
 375             foreach($this->items 
as $item) { 
 376                 if($item->mode 
!= QR_MODE_STRUCTURE
) { 
 377                     for($i=$item->size
-1; $i>=0; $i--) { 
 378                         $parity ^
= $item->data
[$i]; 
 386         //---------------------------------------------------------------------- 
 387         public static function checkModeNum($size, $data) 
 389             for($i=0; $i<$size; $i++
) { 
 390                 if((ord($data[$i]) < ord('0')) || (ord($data[$i]) > ord('9'))){ 
 398         //---------------------------------------------------------------------- 
 399         public static function estimateBitsModeNum($size) 
 404             switch($size - $w * 3) { 
 418         //---------------------------------------------------------------------- 
 419         public static $anTable = array( 
 420             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 421             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 422             36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43, 
 423              0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 44, -1, -1, -1, -1, -1, 
 424             -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 
 425             25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, 
 426             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 
 427             -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 
 430         //---------------------------------------------------------------------- 
 431         public static function lookAnTable($c) 
 433             return (($c > 127)?-1:self
::$anTable[$c]); 
 436         //---------------------------------------------------------------------- 
 437         public static function checkModeAn($size, $data) 
 439             for($i=0; $i<$size; $i++
) { 
 440                 if (self
::lookAnTable(ord($data[$i])) == -1) { 
 448         //---------------------------------------------------------------------- 
 449         public static function estimateBitsModeAn($size) 
 451             $w = (int)($size / 2); 
 461         //---------------------------------------------------------------------- 
 462         public static function estimateBitsMode8($size) 
 467         //---------------------------------------------------------------------- 
 468         public function estimateBitsModeKanji($size) 
 470             return (int)(($size / 2) * 13); 
 473         //---------------------------------------------------------------------- 
 474         public static function checkModeKanji($size, $data) 
 479             for($i=0; $i<$size; $i+
=2) { 
 480                 $val = (ord($data[$i]) << 8) | ord($data[$i+
1]); 
 482                 || ($val > 0x9ffc && $val < 0xe040)  
 491         /*********************************************************************** 
 493          **********************************************************************/ 
 495         public static function check($mode, $size, $data) 
 501                 case QR_MODE_NUM
:       return self
::checkModeNum($size, $data);   break; 
 502                 case QR_MODE_AN
:        return self
::checkModeAn($size, $data);    break; 
 503                 case QR_MODE_KANJI
:     return self
::checkModeKanji($size, $data); break; 
 504                 case QR_MODE_8
:         return true; break; 
 505                 case QR_MODE_STRUCTURE
: return true; break; 
 515         //---------------------------------------------------------------------- 
 516         public function estimateBitStreamSize($version) 
 520             foreach($this->items 
as $item) { 
 521                 $bits +
= $item->estimateBitStreamSizeOfEntry($version); 
 527         //---------------------------------------------------------------------- 
 528         public function estimateVersion() 
 534                 $bits = $this->estimateBitStreamSize($prev); 
 535                 $version = QRspec
::getMinimumVersion((int)(($bits + 
7) / 8), $this->level
); 
 539             } while ($version > $prev); 
 544         //---------------------------------------------------------------------- 
 545         public static function lengthOfCode($mode, $version, $bits) 
 547             $payload = $bits - 4 - QRspec
::lengthIndicator($mode, $version); 
 550                     $chunks = (int)($payload / 10); 
 551                     $remain = $payload - $chunks * 10; 
 555                     } else if($remain >= 4) { 
 560                     $chunks = (int)($payload / 11); 
 561                     $remain = $payload - $chunks * 11; 
 567                     $size = (int)($payload / 8); 
 570                     $size = (int)(($payload / 13) * 2); 
 572                 case QR_MODE_STRUCTURE
: 
 573                     $size = (int)($payload / 8); 
 580             $maxsize = QRspec
::maximumWords($mode, $version); 
 581             if($size < 0) $size = 0; 
 582             if($size > $maxsize) $size = $maxsize; 
 587         //---------------------------------------------------------------------- 
 588         public function createBitStream() 
 592             foreach($this->items 
as $item) { 
 593                 $bits = $item->encodeBitStream($this->version
); 
 604         //---------------------------------------------------------------------- 
 605         public function convertData() 
 607             $ver = $this->estimateVersion(); 
 608             if($ver > $this->getVersion()) { 
 609                 $this->setVersion($ver); 
 613                 $bits = $this->createBitStream(); 
 618                 $ver = QRspec
::getMinimumVersion((int)(($bits + 
7) / 8), $this->level
); 
 620                     throw new Exception('WRONG VERSION'); 
 621                 } else if($ver > $this->getVersion()) { 
 622                     $this->setVersion($ver); 
 631         //---------------------------------------------------------------------- 
 632         public function appendPaddingBit(&$bstream) 
 634             $bits = $bstream->size(); 
 635             $maxwords = QRspec
::getDataLength($this->version
, $this->level
); 
 636             $maxbits = $maxwords * 8; 
 638             if ($maxbits == $bits) { 
 642             if ($maxbits - $bits < 5) { 
 643                 return $bstream->appendNum($maxbits - $bits, 0); 
 647             $words = (int)(($bits + 
7) / 8); 
 649             $padding = new QRbitstream(); 
 650             $ret = $padding->appendNum($words * 8 - $bits + 
4, 0); 
 655             $padlen = $maxwords - $words; 
 660                 for($i=0; $i<$padlen; $i++
) { 
 661                     $padbuf[$i] = ($i&1)?0x11:0xec; 
 664                 $ret = $padding->appendBytes($padlen, $padbuf); 
 671             $ret = $bstream->append($padding); 
 676         //---------------------------------------------------------------------- 
 677         public function mergeBitStream() 
 679             if($this->convertData() < 0) { 
 683             $bstream = new QRbitstream(); 
 685             foreach($this->items 
as $item) { 
 686                 $ret = $bstream->append($item->bstream
); 
 695         //---------------------------------------------------------------------- 
 696         public function getBitStream() 
 699             $bstream = $this->mergeBitStream(); 
 701             if($bstream == null) { 
 705             $ret = $this->appendPaddingBit($bstream); 
 713         //---------------------------------------------------------------------- 
 714         public function getByteStream() 
 716             $bstream = $this->getBitStream(); 
 717             if($bstream == null) { 
 721             return $bstream->toByte();