smiley 10 سال پیش
والد
کامیت
514f95c742

+ 24 - 0
examples/custom.php

@@ -0,0 +1,24 @@
+<?php
+
+require_once '../vendor/autoload.php';
+
+use codemasher\QRCode\QRCode;
+use codemasher\QRCode\QRConst;
+
+$starttime = microtime(true);
+
+// google authenticator
+// https://chart.googleapis.com/chart?chs=200x200&chld=M%7C0&cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%3Fsecret%3DB3JX4VCVJDVNXNZ5%26issuer%3Dchillerlan.net
+
+$qrcode = (new QRCode(5, QRConst::ERROR_CORRECT_LEVEL_M))
+	->addData('otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net')
+	->make();
+
+for($row = 0; $row < $qrcode->moduleCount; $row++){
+	for($col = 0; $col < $qrcode->moduleCount; $col++){
+		echo $qrcode->isDark($row, $col) ? 'X' : ' ';
+	}
+	echo PHP_EOL;
+}
+
+echo 'QRCode '.round((microtime(true)-$starttime), 5).PHP_EOL;

+ 35 - 0
examples/html.php

@@ -0,0 +1,35 @@
+<?php
+
+require_once '../vendor/autoload.php';
+
+use codemasher\QRCode\QRCode;
+use codemasher\QRCode\QRConst;
+//---------------------------------------------------------
+
+echo '<style>
+.qrcode{
+	border-style:none;
+	border-collapse:collapse;
+	margin:0;
+	padding:0;
+}
+
+.dark, .light{
+	margin:0;
+	padding:0;
+	width: 1.25mm;
+	height: 1.25mm;
+}
+
+.dark{
+	background-color: #000;
+}
+
+.light{
+	background-color: #fff;
+}
+</style>';
+
+// google authenticator
+$qr = (new QRCode)->getMinimumQRCode('otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net', QRConst::ERROR_CORRECT_LEVEL_M);
+echo $qr->printHTML();

+ 15 - 0
examples/image.php

@@ -0,0 +1,15 @@
+<?php
+
+require_once '../vendor/autoload.php';
+
+use codemasher\QRCode\QRCode;
+use codemasher\QRCode\QRConst;
+
+// google authenticator
+$qr = (new QRCode)->getMinimumQRCode('otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net', QRConst::ERROR_CORRECT_LEVEL_L);
+
+header('Content-type: image/png');
+
+$im = $qr->createImage(5, 5);
+imagepng($im);
+imagedestroy($im);

+ 0 - 22
examples/sample_custom.php

@@ -1,22 +0,0 @@
-<?php
-
-require_once '../vendor/autoload.php';
-
-use codemasher\QRCode\QRCode;
-use codemasher\QRCode\QRConst;
-
-$qrcode = new QRCode;
-$qr = $qrcode->getMinimumQRCode('イメージ作成(引数:サイズ,マージン', QRConst::ERROR_CORRECT_LEVEL_L);
-
-
-header('Content-type: text/plain');
-
-$m = $qr->getModuleCount();
-
-for($row = 0; $row < $m; $row++){
-	for($col = 0; $col < $m; $col++){
-		echo $qr->isDark($row, $col) ? '#' : ' ';
-	}
-	echo PHP_EOL;
-}
-

+ 0 - 42
examples/sample_html.php

@@ -1,42 +0,0 @@
-<?php
-
-require_once '../vendor/autoload.php';
-
-use codemasher\QRCode\QRCode;
-use codemasher\QRCode\QRConst;
-//---------------------------------------------------------
-
-$qrcode = new QRCode;
-
-
-print('<h4>明示的に型番を指定</h4>');
-
-// エラー訂正レベルを設定
-// QR_ERROR_CORRECT_LEVEL_L : 7%
-// QR_ERROR_CORRECT_LEVEL_M : 15%
-// QR_ERROR_CORRECT_LEVEL_Q : 25%
-// QR_ERROR_CORRECT_LEVEL_H : 30%
-$qrcode->setErrorCorrectLevel(QRConst::ERROR_CORRECT_LEVEL_L);
-
-// 型番(大きさ)を設定
-// 1~10
-$qrcode->setTypeNumber(3);
-
-// データ(文字列※)を設定
-// ※日本語はSJIS
-$qrcode->addData('QRコード');
-
-// QRコードを作成
-$qrcode->make();
-
-// HTML出力
-echo $qrcode->printHTML();
-
-//---------------------------------------------------------
-print('<h4>型番自動</h4>');
-
-// 型番が最小となるQRコードを作成
-$qr = $qrcode->getMinimumQRCode('QRコード', QRConst::ERROR_CORRECT_LEVEL_L);
-
-// HTML出力
-echo $qr->printHTML();

+ 0 - 18
examples/sample_image.php

@@ -1,18 +0,0 @@
-<?php
-
-require_once '../vendor/autoload.php';
-
-use codemasher\QRCode\QRCode;
-use codemasher\QRCode\QRConst;
-
-$qrcode = new QRCode;
-$qr = $qrcode->getMinimumQRCode('QRコード', QRConst::ERROR_CORRECT_LEVEL_L);
-
-// イメージ作成(引数:サイズ,マージン)
-$im = $qr->createImage(2, 4);
-
-header('Content-type: image/png');
-imagepng($im);
-
-imagedestroy($im);
-

+ 4 - 28
src/BitBuffer.php

@@ -19,12 +19,12 @@ class BitBuffer{
 	/**
 	/**
 	 * @var array
 	 * @var array
 	 */
 	 */
-	protected $buffer = [];
+	public $buffer = [];
 
 
 	/**
 	/**
 	 * @var int
 	 * @var int
 	 */
 	 */
-	protected $length = 0;
+	public $length = 0;
 
 
 	/**
 	/**
 	 *
 	 *
@@ -34,43 +34,19 @@ class BitBuffer{
 		$this->length = 0;
 		$this->length = 0;
 	}
 	}
 
 
-	/**
-	 * @return array
-	 */
-	public function getBuffer(){
-		return $this->buffer;
-	}
-
-	/**
-	 * @return int
-	 */
-	public function getLengthInBits(){
-		return $this->length;
-	}
-
 	/**
 	/**
 	 * @return string
 	 * @return string
 	 */
 	 */
 	public function __toString(){
 	public function __toString(){
 		$buffer = '';
 		$buffer = '';
 
 
-		$count = $this->getLengthInBits();
-		for($i = 0; $i < $count; $i++){
-			$buffer .= $this->get($i) ? '1' : '0';
+		for($i = 0; $i < $this->length; $i++){
+			$buffer .= (string)(int)(($this->buffer[(int)floor($i / 8)] >> (7 - $i % 8))&1) === 1;
 		}
 		}
 
 
 		return $buffer;
 		return $buffer;
 	}
 	}
 
 
-	/**
-	 * @param $index
-	 *
-	 * @return bool
-	 */
-	public function get($index){
-		return (($this->buffer[(int)floor($index / 8)] >> (7 - $index % 8))&1) === 1;
-	}
-
 	/**
 	/**
 	 * @param $num
 	 * @param $num
 	 * @param $length
 	 * @param $length

+ 17 - 25
src/Data/AlphaNum.php

@@ -26,33 +26,25 @@ class AlphaNum extends QRDataBase implements QRDataInterface{
 	/**
 	/**
 	 * @var
 	 * @var
 	 */
 	 */
-	protected $mode = QRConst::MODE_ALPHA_NUM;
+	public $mode = QRConst::MODE_ALPHANUM;
 
 
 	/**
 	/**
 	 * @param $buffer
 	 * @param $buffer
 	 */
 	 */
 	public function write(BitBuffer &$buffer){
 	public function write(BitBuffer &$buffer){
-		$data = $this->getData();
 
 
 		$i = 0;
 		$i = 0;
-		$len = strlen($data);
+		$len = strlen($this->data);
 		while($i + 1 < $len){
 		while($i + 1 < $len){
-			$buffer->put($this->getCode(ord($data[$i])) * 45 + $this->getCode(ord($data[$i + 1])), 11);
+			$buffer->put($this->getCode(ord($this->data[$i])) * 45 + $this->getCode(ord($this->data[$i + 1])), 11);
 			$i += 2;
 			$i += 2;
 		}
 		}
 
 
 		if($i < $len){
 		if($i < $len){
-			$buffer->put($this->getCode(ord($data[$i])), 6);
+			$buffer->put($this->getCode(ord($this->data[$i])), 6);
 		}
 		}
 	}
 	}
 
 
-	/**
-	 * @return int
-	 */
-	public function getLength(){
-		return strlen($this->getData());
-	}
-
 	/**
 	/**
 	 * @param $c
 	 * @param $c
 	 *
 	 *
@@ -61,23 +53,23 @@ class AlphaNum extends QRDataBase implements QRDataInterface{
 	 */
 	 */
 	protected function getCode($c){
 	protected function getCode($c){
 
 
-		if($this->util->toCharCode('0') <= $c && $c <= $this->util->toCharCode('9')){
-			return $c - $this->util->toCharCode('0');
+		if(ord('0') <= $c && $c <= ord('9')){
+			return $c - ord('0');
 		}
 		}
-		else if($this->util->toCharCode('A') <= $c && $c <= $this->util->toCharCode('Z')){
-			return $c - $this->util->toCharCode('A') + 10;
+		else if(ord('A') <= $c && $c <= ord('Z')){
+			return $c - ord('A') + 10;
 		}
 		}
 		else{
 		else{
 			switch($c){
 			switch($c){
-				case $this->util->toCharCode(' '): return 36;
-				case $this->util->toCharCode('$'): return 37;
-				case $this->util->toCharCode('%'): return 38;
-				case $this->util->toCharCode('*'): return 39;
-				case $this->util->toCharCode('+'): return 40;
-				case $this->util->toCharCode('-'): return 41;
-				case $this->util->toCharCode('.'): return 42;
-				case $this->util->toCharCode('/'): return 43;
-				case $this->util->toCharCode(':'): return 44;
+				case ord(' '): return 36;
+				case ord('$'): return 37;
+				case ord('%'): return 38;
+				case ord('*'): return 39;
+				case ord('+'): return 40;
+				case ord('-'): return 41;
+				case ord('.'): return 42;
+				case ord('/'): return 43;
+				case ord(':'): return 44;
 				default :
 				default :
 					throw new QRCodeException('illegal char: '.$c);
 					throw new QRCodeException('illegal char: '.$c);
 			}
 			}

+ 6 - 15
src/Data/EightBitByte.php → src/Data/Byte.php

@@ -1,7 +1,7 @@
 <?php
 <?php
 /**
 /**
  *
  *
- * @filesource   EightBitByte.php
+ * @filesource   Byte.php
  * @created      25.11.2015
  * @created      25.11.2015
  * @package      codemasher\QRCode
  * @package      codemasher\QRCode
  * @author       Smiley <smiley@chillerlan.net>
  * @author       Smiley <smiley@chillerlan.net>
@@ -18,32 +18,23 @@ use codemasher\QRCode\Data\QRDataInterface;
 
 
 
 
 /**
 /**
- * Class EightBitByte
+ * Class Byte
  */
  */
-class EightBitByte extends QRDataBase implements QRDataInterface{
+class Byte extends QRDataBase implements QRDataInterface{
 
 
 	/**
 	/**
 	 * @var
 	 * @var
 	 */
 	 */
-	protected $mode = QRConst::MODE_8BIT_BYTE;
+	public $mode = QRConst::MODE_BYTE;
 
 
 	/**
 	/**
 	 * @param $buffer
 	 * @param $buffer
 	 */
 	 */
 	public function write(BitBuffer &$buffer){
 	public function write(BitBuffer &$buffer){
-		$data = $this->getData();
-
-		$len = strlen($data);
+		$len = strlen($this->data);
 		for($i = 0; $i < $len; $i++){
 		for($i = 0; $i < $len; $i++){
-			$buffer->put(ord($data[$i]), 8);
+			$buffer->put(ord($this->data[$i]), 8);
 		}
 		}
 	}
 	}
 
 
-	/**
-	 * @return int
-	 */
-	public function getLength(){
-		return strlen($this->getData());
-	}
-
 }
 }

+ 6 - 6
src/Data/Kanji.php

@@ -25,7 +25,7 @@ class Kanji extends QRDataBase implements QRDataInterface{
 	/**
 	/**
 	 * @var
 	 * @var
 	 */
 	 */
-	protected $mode = QRConst::MODE_KANJI;
+	public $mode = QRConst::MODE_KANJI;
 
 
 	/**
 	/**
 	 * @param $buffer
 	 * @param $buffer
@@ -33,12 +33,11 @@ class Kanji extends QRDataBase implements QRDataInterface{
 	 * @throws \codemasher\QRCode\QRCodeException
 	 * @throws \codemasher\QRCode\QRCodeException
 	 */
 	 */
 	public function write(BitBuffer &$buffer){
 	public function write(BitBuffer &$buffer){
-		$data = $this->getData();
 
 
 		$i = 0;
 		$i = 0;
-		$len = strlen($data);
+		$len = strlen($this->data);
 		while($i + 1 < $len){
 		while($i + 1 < $len){
-			$c = ((0xff&ord($data[$i])) << 8)|(0xff&ord($data[$i + 1]));
+			$c = ((0xff&ord($this->data[$i])) << 8)|(0xff&ord($this->data[$i + 1]));
 
 
 			if(0x8140 <= $c && $c <= 0x9FFC){
 			if(0x8140 <= $c && $c <= 0x9FFC){
 				$c -= 0x8140;
 				$c -= 0x8140;
@@ -55,7 +54,7 @@ class Kanji extends QRDataBase implements QRDataInterface{
 			$i += 2;
 			$i += 2;
 		}
 		}
 
 
-		if($i < strlen($data)){
+		if($i < $len){
 			throw new QRCodeException('illegal char at '.($i + 1));
 			throw new QRCodeException('illegal char at '.($i + 1));
 		}
 		}
 	}
 	}
@@ -64,6 +63,7 @@ class Kanji extends QRDataBase implements QRDataInterface{
 	 * @return float
 	 * @return float
 	 */
 	 */
 	public function getLength(){
 	public function getLength(){
-		return floor(strlen($this->getData()) / 2);
+		return floor(strlen($this->data) / 2);
 	}
 	}
+
 }
 }

+ 25 - 35
src/Data/Number.php

@@ -23,25 +23,21 @@ use codemasher\QRCode\QRConst;
 class Number extends QRDataBase implements QRDataInterface{
 class Number extends QRDataBase implements QRDataInterface{
 
 
 	/**
 	/**
-	 * @var
+	 * @var int
 	 */
 	 */
-	protected $mode = QRConst::MODE_NUMBER;
-
-	/**
-	 * @var \codemasher\QRCode\Util
-	 */
-	protected $util;
+	public $mode = QRConst::MODE_NUMBER;
 
 
 	/**
 	/**
 	 * @param $buffer
 	 * @param $buffer
+	 *
+	 * @return $this
 	 */
 	 */
 	public function write(BitBuffer &$buffer){
 	public function write(BitBuffer &$buffer){
-		$data = $this->getData();
 
 
 		$i = 0;
 		$i = 0;
-		$len = strlen($data);
+		$len = strlen($this->data);
 		while($i + 2 < $len){
 		while($i + 2 < $len){
-			$num = $this->parseInt(substr($data, $i, 3));
+			$num = $this->parseInt(substr($this->data, $i, 3));
 			$buffer->put($num, 10);
 			$buffer->put($num, 10);
 			$i += 3;
 			$i += 3;
 		}
 		}
@@ -49,50 +45,44 @@ class Number extends QRDataBase implements QRDataInterface{
 		if($i < $len){
 		if($i < $len){
 
 
 			if($len - $i === 1){
 			if($len - $i === 1){
-				$num = $this->parseInt(substr($data, $i, $i + 1));
+				$num = $this->parseInt(substr($this->data, $i, $i + 1));
 				$buffer->put($num, 4);
 				$buffer->put($num, 4);
 			}
 			}
 			else if($len - $i === 2){
 			else if($len - $i === 2){
-				$num = $this->parseInt(substr($data, $i, $i + 2));
+				$num = $this->parseInt(substr($this->data, $i, $i + 2));
 				$buffer->put($num, 7);
 				$buffer->put($num, 7);
 			}
 			}
+
 		}
 		}
-	}
 
 
-	/**
-	 * @return int
-	 */
-	public function getLength(){
-		return strlen($this->getData());
+		return $this;
 	}
 	}
 
 
 	/**
 	/**
-	 * @param $s
+	 * @param string $string
 	 *
 	 *
 	 * @return int
 	 * @return int
+	 * @throws \codemasher\QRCode\QRCodeException
 	 */
 	 */
-	protected function parseInt($s){
+	protected function parseInt($string){
 		$num = 0;
 		$num = 0;
 
 
-		for($i = 0; $i < strlen($s); $i++){
-			$num = $num * 10 + $this->parseIntAt(ord($s[$i]));
-		}
+		$len = strlen($string);
+		for($i = 0; $i < $len; $i++){
+			$c = ord($string[$i]);
 
 
-		return $num;
-	}
+			$ord0 = ord('0');
+			if(ord('0') <= $c && $c <= ord('9')){
+				$c = $c - $ord0;
+			}
+			else{
+				throw new QRCodeException('illegal char: '.$c);
+			}
 
 
-	/**
-	 * @param $c
-	 *
-	 * @return mixed
-	 * @throws \codemasher\QRCode\QRCodeException
-	 */
-	protected function parseIntAt($c){
-		if($this->util->toCharCode('0') <= $c && $c <= $this->util->toCharCode('9')){
-			return $c - $this->util->toCharCode('0');
+			$num = $num * 10 + $c;
 		}
 		}
 
 
-		throw new QRCodeException('illegal char: '.$c);
+		return $num;
 	}
 	}
 
 
 }
 }

+ 16 - 40
src/Data/QRDataBase.php

@@ -15,22 +15,21 @@ use codemasher\QRCode\BitBuffer;
 use codemasher\QRCode\QRConst;
 use codemasher\QRCode\QRConst;
 use codemasher\QRCode\QRCodeException;
 use codemasher\QRCode\QRCodeException;
 use codemasher\QRCode\Util;
 use codemasher\QRCode\Util;
-use codemasher\QRCode\Data\QRDataInterface;
 
 
 /**
 /**
  * Class QRDataBase
  * Class QRDataBase
  */
  */
-class QRDataBase implements QRDataInterface{
+class QRDataBase{
 
 
 	/**
 	/**
 	 * @var
 	 * @var
 	 */
 	 */
-	protected $mode;
+	public $mode;
 
 
 	/**
 	/**
 	 * @var
 	 * @var
 	 */
 	 */
-	protected $data;
+	public $data;
 
 
 	/**
 	/**
 	 * @var \codemasher\QRCode\Util
 	 * @var \codemasher\QRCode\Util
@@ -47,34 +46,11 @@ class QRDataBase implements QRDataInterface{
 		$this->util = new Util;
 		$this->util = new Util;
 	}
 	}
 
 
-	/**
-	 * @return mixed
-	 */
-	public function getMode(){
-		return $this->mode;
-	}
-
-	/**
-	 * @return mixed
-	 */
-	public function getData(){
-		return $this->data;
-	}
-
 	/**
 	/**
 	 * @throws \codemasher\QRCode\QRCodeException
 	 * @throws \codemasher\QRCode\QRCodeException
 	 */
 	 */
 	public function getLength(){
 	public function getLength(){
-		throw new QRCodeException('not implemented.');
-	}
-
-	/**
-	 * @param $buffer
-	 *
-	 * @throws \codemasher\QRCode\QRCodeException
-	 */
-	public function write(BitBuffer &$buffer){
-		throw new QRCodeException('not implemented.');
+		return strlen($this->data);
 	}
 	}
 
 
 	/**
 	/**
@@ -88,10 +64,10 @@ class QRDataBase implements QRDataInterface{
 
 
 			// 1 - 9
 			// 1 - 9
 			switch($this->mode){
 			switch($this->mode){
-				case QRConst::MODE_NUMBER   : return 10;
-				case QRConst::MODE_ALPHA_NUM: return 9;
-				case QRConst::MODE_8BIT_BYTE: return 8;
-				case QRConst::MODE_KANJI    : return 8;
+				case QRConst::MODE_NUMBER  : return 10;
+				case QRConst::MODE_ALPHANUM: return 9;
+				case QRConst::MODE_BYTE    : return 8;
+				case QRConst::MODE_KANJI   : return 8;
 				default :
 				default :
 					throw new QRCodeException('mode: '.$this->mode);
 					throw new QRCodeException('mode: '.$this->mode);
 			}
 			}
@@ -101,10 +77,10 @@ class QRDataBase implements QRDataInterface{
 
 
 			// 10 - 26
 			// 10 - 26
 			switch($this->mode){
 			switch($this->mode){
-				case QRConst::MODE_NUMBER   : return 12;
-				case QRConst::MODE_ALPHA_NUM: return 11;
-				case QRConst::MODE_8BIT_BYTE: return 16;
-				case QRConst::MODE_KANJI    : return 10;
+				case QRConst::MODE_NUMBER  : return 12;
+				case QRConst::MODE_ALPHANUM: return 11;
+				case QRConst::MODE_BYTE    : return 16;
+				case QRConst::MODE_KANJI   : return 10;
 				default :
 				default :
 					throw new QRCodeException('mode: '.$this->mode);
 					throw new QRCodeException('mode: '.$this->mode);
 			}
 			}
@@ -114,10 +90,10 @@ class QRDataBase implements QRDataInterface{
 
 
 			// 27 - 40
 			// 27 - 40
 			switch($this->mode){
 			switch($this->mode){
-				case QRConst::MODE_NUMBER   : return 14;
-				case QRConst::MODE_ALPHA_NUM: return 13;
-				case QRConst::MODE_8BIT_BYTE: return 16;
-				case QRConst::MODE_KANJI    : return 12;
+				case QRConst::MODE_NUMBER  : return 14;
+				case QRConst::MODE_ALPHANUM: return 13;
+				case QRConst::MODE_BYTE    : return 16;
+				case QRConst::MODE_KANJI   : return 12;
 				default :
 				default :
 					throw new QRCodeException('mode: '.$this->mode);
 					throw new QRCodeException('mode: '.$this->mode);
 			}
 			}

+ 1 - 10
src/Data/QRDataInterface.php

@@ -27,16 +27,6 @@ interface QRDataInterface{
 	 */
 	 */
 	public function getLength();
 	public function getLength();
 
 
-	/**
-	 * @return mixed
-	 */
-	public function getData();
-
-	/**
-	 * @return mixed
-	 */
-	public function getMode();
-
 	/**
 	/**
 	 * @param $type
 	 * @param $type
 	 *
 	 *
@@ -44,4 +34,5 @@ interface QRDataInterface{
 	 * @throws \codemasher\QRCode\QRCodeException
 	 * @throws \codemasher\QRCode\QRCodeException
 	 */
 	 */
 	public function getLengthInBits($type);
 	public function getLengthInBits($type);
+
 }
 }

+ 0 - 104
src/Math.php

@@ -1,104 +0,0 @@
-<?php
-/**
- *
- * @filesource   Math.php
- * @created      25.11.2015
- * @package      codemasher\QRCode
- * @author       Smiley <smiley@chillerlan.net>
- * @copyright    2015 Smiley
- * @license      MIT
- */
-
-namespace codemasher\QRCode;
-
-use codemasher\QRCode\QRCodeException;
-
-/**
- * Class Math
- */
-class Math{
-
-	/**
-	 * @var array
-	 */
-	protected $QR_MATH_EXP_TABLE;
-
-	/**
-	 * @var array
-	 */
-	protected $QR_MATH_LOG_TABLE;
-
-	/**
-	 * Math constructor.
-	 */
-	public function __construct(){
-		$this->QR_MATH_EXP_TABLE = $this->createNumArray(256);
-
-		for($i = 0; $i < 8; $i++){
-			$this->QR_MATH_EXP_TABLE[$i] = 1 << $i;
-		}
-
-		for($i = 8; $i < 256; $i++){
-			$this->QR_MATH_EXP_TABLE[$i] =
-				$this->QR_MATH_EXP_TABLE[$i - 4]
-				^$this->QR_MATH_EXP_TABLE[$i - 5]
-				^$this->QR_MATH_EXP_TABLE[$i - 6]
-				^$this->QR_MATH_EXP_TABLE[$i - 8];
-		}
-
-		$this->QR_MATH_LOG_TABLE = $this->createNumArray(256);
-
-		for($i = 0; $i < 255; $i++){
-			$this->QR_MATH_LOG_TABLE[$this->QR_MATH_EXP_TABLE[$i]] = $i;
-		}
-	}
-
-	/**
-	 * @param int $length
-	 *
-	 * @return array
-	 */
-	public function createNumArray($length){
-		$num_array = [];
-
-		for($i = 0; $i < $length; $i++){
-			$num_array[] = 0;
-		}
-
-		return $num_array;
-	}
-
-	/**
-	 * @param int $n
-	 *
-	 * @return mixed
-	 * @throws \codemasher\QRCode\QRCodeException
-	 */
-	public function glog($n){
-
-		if($n < 1){
-			throw new QRCodeException('log('.$n.')');
-		}
-
-		return $this->QR_MATH_LOG_TABLE[$n];
-	}
-
-	/**
-	 * @param int $n
-	 *
-	 * @return mixed
-	 */
-	public function gexp($n){
-
-		while($n < 0){
-			$n += 255;
-		}
-
-		while($n >= 256){
-			$n -= 255;
-		}
-
-		return $this->QR_MATH_EXP_TABLE[$n];
-	}
-
-}

+ 20 - 0
src/Output/QROutputInterface.php

@@ -0,0 +1,20 @@
+<?php
+/**
+ * Interface QROutputInterface,
+ *
+ * @filesource   QROutputInterface.php
+ * @created      02.12.2015
+ * @package      codemasher\QRCode\Output
+ * @author       Smiley <smiley@chillerlan.net>
+ * @copyright    2015 Smiley
+ * @license      MIT
+ */
+
+namespace codemasher\QRCode\Output;
+
+/**
+ *
+ */
+interface QROutputInterface{
+
+}

+ 119 - 53
src/Polynomial.php

@@ -11,22 +11,25 @@
 
 
 namespace codemasher\QRCode;
 namespace codemasher\QRCode;
 
 
-use codemasher\QRCode\Math;
-
 /**
 /**
  * Class Polynomial
  * Class Polynomial
  */
  */
 class Polynomial{
 class Polynomial{
 
 
 	/**
 	/**
-	 * @var
+	 * @var array
+	 */
+	public $num = [];
+
+	/**
+	 * @var array
 	 */
 	 */
-	protected $num;
+	protected $EXP_TABLE = [];
 
 
 	/**
 	/**
-	 * @var \codemasher\QRCode\Math
+	 * @var array
 	 */
 	 */
-	protected $math;
+	protected $LOG_TABLE = [];
 
 
 	/**
 	/**
 	 * Polynomial constructor.
 	 * Polynomial constructor.
@@ -34,56 +37,74 @@ class Polynomial{
 	 * @param array $num
 	 * @param array $num
 	 * @param int   $shift
 	 * @param int   $shift
 	 */
 	 */
-	public function __construct(array $num, $shift = 0){
-		$this->math = new Math;
+	public function __construct(array $num = [1], $shift = 0){
+		$this->setNum($num, $shift)
+		     ->setTables();
+	}
 
 
+	/**
+	 * @param array $num
+	 * @param int   $shift
+	 *
+	 * @return $this
+	 */
+	public function setNum(array $num, $shift = 0){
 		$offset = 0;
 		$offset = 0;
-		while($offset < count($num) && $num[$offset] === 0){
+		$numCount = count($num);
+
+		while($offset < $numCount && $num[$offset] === 0){
 			$offset++;
 			$offset++;
 		}
 		}
 
 
-		$this->num = $this->math->createNumArray(count($num) - $offset + $shift);
-		for($i = 0; $i < count($num) - $offset; $i++){
+		$this->num = [];
+		for($i = 0; $i < $numCount - $offset + $shift; $i++){
+			$this->num[] = 0;
+		}
+
+		for($i = 0; $i < $numCount - $offset; $i++){
 			$this->num[$i] = $num[$i + $offset];
 			$this->num[$i] = $num[$i + $offset];
 		}
 		}
-	}
 
 
-	/**
-	 * @param $index
-	 * @todo rename!
-	 *
-	 * @return mixed
-	 */
-	public function getNum($index){
-		return $this->num[$index];
+		return $this;
 	}
 	}
 
 
 	/**
 	/**
-	 * @return int
+	 * @return $this
 	 */
 	 */
-	public function getLength(){
-		return count($this->num);
-	}
+	protected function setTables(){
+		$numArr = [];
+		for($i = 0; $i < 256; $i++){
+			$numArr[] = 0;
+		}
 
 
-	/**
-	 * PHP5
-	 * @return string
-	 */
-	public function __toString(){
-		return $this->toString();
+		$this->EXP_TABLE = $this->LOG_TABLE = $numArr;
+
+		for($i = 0; $i < 8; $i++){
+			$this->EXP_TABLE[$i] = 1 << $i;
+		}
+
+		for($i = 8; $i < 256; $i++){
+			$this->EXP_TABLE[$i] = $this->EXP_TABLE[$i - 4] ^ $this->EXP_TABLE[$i - 5] ^ $this->EXP_TABLE[$i - 6] ^ $this->EXP_TABLE[$i - 8];
+		}
+
+		for($i = 0; $i < 255; $i++){
+			$this->LOG_TABLE[$this->EXP_TABLE[$i]] = $i;
+		}
+
+		return $this;
 	}
 	}
 
 
 	/**
 	/**
 	 * @return string
 	 * @return string
 	 */
 	 */
-	public function toString(){
+	public function __toString(){
 		$buffer = '';
 		$buffer = '';
 
 
-		for($i = 0; $i < $this->getLength(); $i++){
+		foreach($this->num as $i => $value){
 			if($i > 0){
 			if($i > 0){
 				$buffer .= ',';
 				$buffer .= ',';
 			}
 			}
-			$buffer .= $this->getNum($i);
+			$buffer .= $value;
 		}
 		}
 
 
 		return $buffer;
 		return $buffer;
@@ -95,56 +116,101 @@ class Polynomial{
 	public function toLogString(){
 	public function toLogString(){
 		$buffer = '';
 		$buffer = '';
 
 
-		for($i = 0; $i < $this->getLength(); $i++){
+		foreach($this->num as $i => $value){
 			if($i > 0){
 			if($i > 0){
 				$buffer .= ',';
 				$buffer .= ',';
 			}
 			}
-			$buffer .= $this->math->glog($this->getNum($i));
+			$buffer .= $this->glog($value);
 		}
 		}
 
 
 		return $buffer;
 		return $buffer;
 	}
 	}
 
 
 	/**
 	/**
-	 * @param \codemasher\QRCode\Polynomial $e
+	 * @param array $e
 	 *
 	 *
-	 * @return \codemasher\QRCode\Polynomial
+	 * @return $this
 	 */
 	 */
-	public function multiply($e){
-		$num = $this->math->createNumArray($this->getLength() + $e->getLength() - 1);
+	public function multiply(array $e){
 
 
-		for($i = 0; $i < $this->getLength(); $i++){
-			for($j = 0; $j < $e->getLength(); $j++){
-				$num[$i + $j] ^= $this->math->gexp($this->math->glog($this->getNum($i)) + $this->math->glog($e->getNum($j)));
+		$num = [];
+		$len = count($this->num) + count($e) - 1;
+		for($i = 0; $i < $len; $i++){
+			$num[] = 0;
+		}
+
+		foreach($this->num as $i => $vi){
+			foreach($e as $j => $vj){
+				$num[$i + $j] ^= $this->gexp($this->glog($vi) + $this->glog($vj));
 			}
 			}
 		}
 		}
 
 
-		return new Polynomial($num);
+		$this->setNum($num);
+
+		return $this;
 	}
 	}
 
 
 	/**
 	/**
-	 * @param \codemasher\QRCode\Polynomial $e
+	 * @param array $e
 	 *
 	 *
-	 * @return $this|\codemasher\QRCode\Polynomial
+	 * @return $this
 	 */
 	 */
 	public function mod($e){
 	public function mod($e){
+#		$starttime = microtime(true);
 
 
-		if($this->getLength() - $e->getLength() < 0){
+		if(count($this->num) - count($e) < 0){
 			return $this;
 			return $this;
 		}
 		}
 
 
-		$ratio = $this->math->glog($this->getNum(0)) - $this->math->glog($e->getNum(0));
+		$ratio = $this->glog($this->num[0]) - $this->glog($e[0]);
+
+		$num = [];
+		foreach($this->num as $i => $value){
+			$num[$i] = $value;
+		}
+
+		foreach($e as $i => $value){
+			$num[$i] ^= $this->gexp($this->glog($e[$i]) + $ratio);
+		}
+
+		$this->setNum($num)->mod($e);
+
+#		echo 'Polynomial::mod '.round((microtime(true)-$starttime), 5).PHP_EOL;
+
+		return $num;
+	}
+
+	/**
+	 * @param int $n
+	 *
+	 * @return mixed
+	 * @throws \codemasher\QRCode\QRCodeException
+	 */
+	public function glog($n){
+
+		if($n < 1){
+			throw new QRCodeException('log('.$n.')');
+		}
+
+		return $this->LOG_TABLE[$n];
+	}
+
+	/**
+	 * @param int $n
+	 *
+	 * @return mixed
+	 */
+	public function gexp($n){
 
 
-		$num = $this->math->createNumArray($this->getLength());
-		for($i = 0; $i < $this->getLength(); $i++){
-			$num[$i] = $this->getNum($i);
+		while($n < 0){
+			$n += 255;
 		}
 		}
 
 
-		for($i = 0; $i < $e->getLength(); $i++){
-			$num[$i] ^= $this->math->gexp($this->math->glog($e->getNum($i)) + $ratio);
+		while($n >= 256){
+			$n -= 255;
 		}
 		}
 
 
-		return (new Polynomial($num))->mod($e);
+		return $this->EXP_TABLE[$n];
 	}
 	}
 
 
 }
 }

+ 324 - 331
src/QRCode.php

@@ -1,5 +1,6 @@
 <?php
 <?php
 /**
 /**
+ * Class QRCode
  *
  *
  * @filesource   QRCode.php
  * @filesource   QRCode.php
  * @created      26.11.2015
  * @created      26.11.2015
@@ -11,15 +12,16 @@
 
 
 namespace codemasher\QRCode;
 namespace codemasher\QRCode;
 
 
+use codemasher\QRCode\Polynomial;
+use codemasher\QRCode\QRConst;
 use codemasher\QRCode\Data\AlphaNum;
 use codemasher\QRCode\Data\AlphaNum;
-use codemasher\QRCode\Data\EightBitByte;
+use codemasher\QRCode\Data\Byte;
 use codemasher\QRCode\Data\Kanji;
 use codemasher\QRCode\Data\Kanji;
 use codemasher\QRCode\Data\Number;
 use codemasher\QRCode\Data\Number;
 use codemasher\QRCode\Data\QRDataInterface;
 use codemasher\QRCode\Data\QRDataInterface;
-use codemasher\QRCode\QRConst;
 
 
 /**
 /**
- * Class QRCode
+ * @link https://github.com/kazuhikoarase/qrcode-generator/tree/master/php
  */
  */
 class QRCode{
 class QRCode{
 
 
@@ -29,22 +31,22 @@ class QRCode{
 	/**
 	/**
 	 * @var int
 	 * @var int
 	 */
 	 */
-	protected $typeNumber;
+	public $typeNumber;
 
 
 	/**
 	/**
-	 * @var
+	 * @var array
 	 */
 	 */
 	protected $modules;
 	protected $modules;
 
 
 	/**
 	/**
-	 * @var
+	 * @var int
 	 */
 	 */
-	protected $moduleCount;
+	public $moduleCount;
 
 
 	/**
 	/**
 	 * @var int
 	 * @var int
 	 */
 	 */
-	protected $errorCorrectLevel;
+	public $errorCorrectLevel;
 
 
 	/**
 	/**
 	 * @var array
 	 * @var array
@@ -56,6 +58,11 @@ class QRCode{
 	 */
 	 */
 	protected $rsBlockList = [];
 	protected $rsBlockList = [];
 
 
+	/**
+	 * @var
+	 */
+	protected $data;
+
 	/**
 	/**
 	 * @var \codemasher\QRCode\Util
 	 * @var \codemasher\QRCode\Util
 	 */
 	 */
@@ -86,134 +93,45 @@ class QRCode{
 		$this->errorCorrectLevel = $errorCorrectLevel;
 		$this->errorCorrectLevel = $errorCorrectLevel;
 	}
 	}
 
 
-	/**
-	 * @return int
-	 */
-	public function getTypeNumber(){
-		return $this->typeNumber;
-	}
-
-	/**
-	 * @param int $typeNumber
-	 */
-	public function setTypeNumber($typeNumber){
-		$this->typeNumber = $typeNumber;
-	}
-
-	/**
-	 * @return int
-	 */
-	public function getErrorCorrectLevel(){
-		return $this->errorCorrectLevel;
-	}
-
-	/**
-	 * @param int $errorCorrectLevel
-	 */
-	public function setErrorCorrectLevel($errorCorrectLevel){
-		$this->errorCorrectLevel = $errorCorrectLevel;
-	}
-
 	/**
 	/**
 	 * @param string $data
 	 * @param string $data
 	 * @param int    $mode
 	 * @param int    $mode
 	 *
 	 *
+	 * @return $this
 	 * @throws \codemasher\QRCode\QRCodeException
 	 * @throws \codemasher\QRCode\QRCodeException
 	 */
 	 */
-	public function addData($data, $mode = 0){
-		if($mode === 0){
+	public function addData($data, $mode = null){
+		if($mode === null){
 			$mode = $this->util->getMode($data);
 			$mode = $this->util->getMode($data);
 		}
 		}
 
 
 		switch($mode){
 		switch($mode){
-			case QRConst::MODE_NUMBER   :
-				$this->addDataImpl(new Number($data));
-				break;
-			case QRConst::MODE_ALPHA_NUM:
-				$this->addDataImpl(new AlphaNum($data));
-				break;
-			case QRConst::MODE_8BIT_BYTE:
-				$this->addDataImpl(new EightBitByte($data));
-				break;
-			case QRConst::MODE_KANJI    :
-				$this->addDataImpl(new Kanji($data));
-				break;
-			default :
+			case QRConst::MODE_NUMBER   : $this->qrDataList[] = new Number($data); break;
+			case QRConst::MODE_ALPHANUM:$this->qrDataList[] = new AlphaNum($data); break;
+			case QRConst::MODE_BYTE:$this->qrDataList[] = new Byte($data); break;
+			case QRConst::MODE_KANJI    : $this->qrDataList[] = new Kanji($data); break;
+			default:
 				throw new QRCodeException('mode: '.$mode);
 				throw new QRCodeException('mode: '.$mode);
 		}
 		}
-	}
-
-	/**
-	 *
-	 */
-	public function clearData(){
-		$this->qrDataList = [];
-	}
-
-	/**
-	 * @param \codemasher\QRCode\Data\QRDataInterface $qrData
-	 *
-	 * @return $this
-	 */
-	public function addDataImpl(QRDataInterface &$qrData){
-		$this->qrDataList[] = $qrData;
 
 
 		return $this;
 		return $this;
 	}
 	}
 
 
-	/**
-	 * @return int
-	 */
-	public function getDataCount(){
-		return count($this->qrDataList);
-	}
-
-	/**
-	 * @param int $index
-	 *
-	 * @return \codemasher\QRCode\Data\QRDataInterface
-	 */
-	public function getData($index){
-		return $this->qrDataList[$index];
-	}
-
 	/**
 	/**
 	 * @param int $row
 	 * @param int $row
 	 * @param int $col
 	 * @param int $col
 	 *
 	 *
-	 * @return mixed
+	 * @return bool
 	 */
 	 */
 	public function isDark($row, $col){
 	public function isDark($row, $col){
 		if($this->modules[$row][$col] !== null){
 		if($this->modules[$row][$col] !== null){
-			return $this->modules[$row][$col];
+			return (bool)$this->modules[$row][$col];
 		}
 		}
 		else{
 		else{
 			return false;
 			return false;
 		}
 		}
 	}
 	}
 
 
-	/**
-	 * @return mixed
-	 */
-	public function getModuleCount(){
-		return $this->moduleCount;
-	}
-
-	/**
-	 * used for converting fg/bg colors (e.g. #0000ff = 0x0000FF) - added 2015.07.27 ~ DoktorJ
-	 *
-	 * @param int $hex
-	 *
-	 * @return array
-	 */
-	public function hex2rgb($hex = 0x0){
-		return [
-			'r' => floor($hex / 65536),
-			'g' => floor($hex / 256) % 256,
-			'b' => $hex % 256,
-		];
-	}
-
 	/**
 	/**
 	 *
 	 *
 	 */
 	 */
@@ -226,15 +144,123 @@ class QRCode{
 	/**
 	/**
 	 * @return int
 	 * @return int
 	 */
 	 */
-	public function getBestMaskPattern(){
+	protected function getBestMaskPattern(){
 		$minLostPoint = 0;
 		$minLostPoint = 0;
 		$pattern = 0;
 		$pattern = 0;
 
 
 		for($i = 0; $i < 8; $i++){
 		for($i = 0; $i < 8; $i++){
 			$this->makeImpl(true, $i);
 			$this->makeImpl(true, $i);
-			$lostPoint = $this->util->getLostPoint($this);
+			$lostPoint = 0;
+
+			// LEVEL1
+
+			for($row = 0; $row < $this->moduleCount; $row++){
+				for($col = 0; $col < $this->moduleCount; $col++){
+					$sameCount = 0;
+					$dark = $this->isDark($row, $col);
+
+					for($r = -1; $r <= 1; $r++){
+						if($row + $r < 0 || $this->moduleCount <= $row + $r){
+							continue;
+						}
+
+						for($c = -1; $c <= 1; $c++){
+
+							if($col + $c < 0 || $this->moduleCount <= $col + $c){
+								continue;
+							}
+
+							if($r == 0 && $c == 0){
+								continue;
+							}
+
+							if($dark === $this->isDark($row + $r, $col + $c)){
+								$sameCount++;
+							}
+						}
+					}
+
+					if($sameCount > 5){
+						$lostPoint += (3 + $sameCount - 5);
+					}
+				}
+			}
+
+			// LEVEL2
+
+			for($row = 0; $row < $this->moduleCount - 1; $row++){
+				for($col = 0; $col < $this->moduleCount - 1; $col++){
+					$count = 0;
+
+					if($this->isDark($row, $col)){
+						$count++;
+					}
+
+					if($this->isDark($row + 1, $col)){
+						$count++;
+					}
+
+					if($this->isDark($row, $col + 1)){
+						$count++;
+					}
+
+					if($this->isDark($row + 1, $col + 1)){
+						$count++;
+					}
+
+					if($count === 0 || $count === 4){
+						$lostPoint += 3;
+					}
+				}
+			}
+
+			// LEVEL3
+
+			for($row = 0; $row < $this->moduleCount; $row++){
+				for($col = 0; $col < $this->moduleCount - 6; $col++){
+					if($this->isDark($row, $col)
+							&& !$this->isDark($row, $col + 1)
+							&& $this->isDark($row, $col + 2)
+							&& $this->isDark($row, $col + 3)
+							&& $this->isDark($row, $col + 4)
+							&& !$this->isDark($row, $col + 5)
+							&& $this->isDark($row, $col + 6)
+					){
+						$lostPoint += 40;
+					}
+				}
+			}
 
 
-			if($i == 0 || $minLostPoint > $lostPoint){
+			for($col = 0; $col < $this->moduleCount; $col++){
+				for($row = 0; $row < $this->moduleCount - 6; $row++){
+					if($this->isDark($row, $col)
+							&& !$this->isDark($row + 1, $col)
+							&& $this->isDark($row + 2, $col)
+							&& $this->isDark($row + 3, $col)
+							&& $this->isDark($row + 4, $col)
+							&& !$this->isDark($row + 5, $col)
+							&& $this->isDark($row + 6, $col)
+					){
+						$lostPoint += 40;
+					}
+				}
+			}
+
+			// LEVEL4
+
+			$darkCount = 0;
+			for($col = 0; $col < $this->moduleCount; $col++){
+				for($row = 0; $row < $this->moduleCount; $row++){
+					if($this->isDark($row, $col)){
+						$darkCount++;
+					}
+				}
+			}
+
+			$ratio = abs(100 * $darkCount / $this->moduleCount / $this->moduleCount - 50) / 5;
+			$lostPoint += $ratio * 10;
+
+			if($i === 0 || $minLostPoint > $lostPoint){
 				$minLostPoint = $lostPoint;
 				$minLostPoint = $lostPoint;
 				$pattern = $i;
 				$pattern = $i;
 			}
 			}
@@ -244,63 +270,117 @@ class QRCode{
 	}
 	}
 
 
 	/**
 	/**
-	 * @param int $length
-	 *
-	 * @return array
-	 */
-	public function createNullArray($length){
-		$nullArray = [];
-		for($i = 0; $i < $length; $i++){
-			$nullArray[] = null;
-		}
-
-		return $nullArray;
-	}
-
-	/**
-	 * @param $test
-	 * @param $maskPattern
+	 * @param bool $test
+	 * @param int  $maskPattern
 	 *
 	 *
 	 * @return $this
 	 * @return $this
 	 */
 	 */
-	public function makeImpl($test, $maskPattern){
+	protected function makeImpl($test, $maskPattern){
 		$this->moduleCount = $this->typeNumber * 4 + 17;
 		$this->moduleCount = $this->typeNumber * 4 + 17;
 		$this->modules = [];
 		$this->modules = [];
 
 
+		$nullArray = [];
+		for($i = 0; $i < $this->moduleCount; $i++){
+			$nullArray[] = null;
+		}
+
 		for($i = 0; $i < $this->moduleCount; $i++){
 		for($i = 0; $i < $this->moduleCount; $i++){
-			$this->modules[] = $this->createNullArray($this->moduleCount);
+			$this->modules[] = $nullArray;
 		}
 		}
 
 
 		$this->setupPositionProbePattern(0, 0)
 		$this->setupPositionProbePattern(0, 0)
 		     ->setupPositionProbePattern($this->moduleCount - 7, 0)
 		     ->setupPositionProbePattern($this->moduleCount - 7, 0)
-		     ->setupPositionProbePattern(0, $this->moduleCount - 7)
-		     ->setupPositionAdjustPattern()
-		     ->setupTimingPattern()
-		     ->setupTypeInfo($test, $maskPattern);
+		     ->setupPositionProbePattern(0, $this->moduleCount - 7);
+
+
+		$pos = $this->util->PATTERN_POSITION[$this->typeNumber - 1];
+		$posCount = count($pos);
+
+		for($i = 0; $i < $posCount; $i++){
+			for($j = 0; $j < $posCount; $j++){
+				if($this->modules[$pos[$i]][$pos[$j]] !== null){
+					continue;
+				}
+
+				for($r = -2; $r <= 2; $r++){
+					for($c = -2; $c <= 2; $c++){
+						$this->modules[$pos[$i] + $r][$pos[$j] + $c] =
+								$r === -2 || $r === 2 || $c === -2 || $c === 2 || ($r === 0 && $c === 0);
+					}
+				}
+
+			}
+		}
+
+		for($r = 8; $r < $this->moduleCount - 8; $r++){
+			if($this->modules[$r][6] !== null){
+				continue;
+			}
+
+			$this->modules[$r][6] = $this->modules[6][$r] = $r % 2 === 0;
+		}
+
+		$data = ($this->errorCorrectLevel << 3) | $maskPattern;
+		$bits = $this->util->getBCHTypeInfo($data);
+
+		for($i = 0; $i < 15; $i++){
+			$mod = !$test && (($bits >> $i) & 1) === 1;
+
+			if($i < 6){
+				$this->modules[$i][8] = $mod;
+			}
+			else if($i < 8){
+				$this->modules[$i + 1][8] = $mod;
+			}
+			else{
+				$this->modules[$this->moduleCount - 15 + $i][8] = $mod;
+			}
+
+			if($i < 8){
+				$this->modules[8][$this->moduleCount - $i - 1] = $mod;
+			}
+			else if($i < 9){
+				$this->modules[8][15 - $i - 1 + 1] = $mod;
+			}
+			else{
+				$this->modules[8][15 - $i - 1] = $mod;
+			}
+
+		}
+
+		$this->modules[$this->moduleCount - 8][8] = !$test;
 
 
 		if($this->typeNumber >= 7){
 		if($this->typeNumber >= 7){
-			$this->setupTypeNumber($test);
+			$bits = $this->util->getBCHTypeNumber($this->typeNumber);
+
+			for($i = 0; $i < 18; $i++){
+				$a = (int)floor($i / 3);
+				$b = $i % 3 + $this->moduleCount - 8 - 3;
+				$mod = !$test && (($bits >> $i) & 1) === 1;
+
+				$this->modules[$a][$b] = $this->modules[$b][$a] = $mod;
+			}
 		}
 		}
 
 
-		$data = $this->createData($this->typeNumber, $this->errorCorrectLevel);
+		$this->data = $this->createData($this->typeNumber, $this->errorCorrectLevel);
 
 
-		$this->mapData($data, $maskPattern);
+		$this->mapData($maskPattern);
 
 
 		return $this;
 		return $this;
 	}
 	}
 
 
 	/**
 	/**
-	 * @param $data
 	 * @param $maskPattern
 	 * @param $maskPattern
 	 *
 	 *
 	 * @return $this
 	 * @return $this
 	 * @throws \codemasher\QRCode\QRCodeException
 	 * @throws \codemasher\QRCode\QRCodeException
 	 */
 	 */
-	public function mapData(&$data, $maskPattern){
+	protected function mapData($maskPattern){
 		$inc = -1;
 		$inc = -1;
 		$row = $this->moduleCount - 1;
 		$row = $this->moduleCount - 1;
 		$bitIndex = 7;
 		$bitIndex = 7;
 		$byteIndex = 0;
 		$byteIndex = 0;
+		$dataCount = count($this->data);
 
 
 		for($col = $this->moduleCount - 1; $col > 0; $col -= 2){
 		for($col = $this->moduleCount - 1; $col > 0; $col -= 2){
 
 
@@ -309,18 +389,28 @@ class QRCode{
 			}
 			}
 
 
 			while(true){
 			while(true){
-
 				for($c = 0; $c < 2; $c++){
 				for($c = 0; $c < 2; $c++){
 
 
 					if($this->modules[$row][$col - $c] === null){
 					if($this->modules[$row][$col - $c] === null){
-
 						$dark = false;
 						$dark = false;
 
 
-						if($byteIndex < count($data)){
-							$dark = ((($data[$byteIndex] >> $bitIndex) & 1) == 1);
+						if($byteIndex < $dataCount){
+							$dark = (($this->data[$byteIndex] >> $bitIndex) & 1) === 1;
 						}
 						}
 
 
-						$mask = $this->util->getMask($maskPattern, $row, $col - $c);
+						$_col = $col - $c;
+						switch($maskPattern){
+							case QRConst::MASK_PATTERN000: $mask = ($row + $_col) % 2 === 0; break;
+							case QRConst::MASK_PATTERN001: $mask = $row % 2 === 0; break;
+							case QRConst::MASK_PATTERN010: $mask = $_col % 3 === 0; break;
+							case QRConst::MASK_PATTERN011: $mask = ($row + $_col) % 3 === 0; break;
+							case QRConst::MASK_PATTERN100: $mask = (floor($row / 2) + floor($_col / 3)) % 2 === 0; break;
+							case QRConst::MASK_PATTERN101: $mask = ($row * $_col) % 2 + ($row * $_col) % 3 === 0; break;
+							case QRConst::MASK_PATTERN110: $mask = (($row * $_col) % 2 + ($row * $_col) % 3) % 2 === 0; break;
+							case QRConst::MASK_PATTERN111: $mask = (($row * $_col) % 3 + ($row + $_col) % 2) % 2 === 0; break;
+							default :
+								throw new QRCodeException('mask: '.$maskPattern);
+						}
 
 
 						if($mask){
 						if($mask){
 							$dark = !$dark;
 							$dark = !$dark;
@@ -329,10 +419,11 @@ class QRCode{
 						$this->modules[$row][$col - $c] = $dark;
 						$this->modules[$row][$col - $c] = $dark;
 						$bitIndex--;
 						$bitIndex--;
 
 
-						if($bitIndex == -1){
+						if($bitIndex === -1){
 							$byteIndex++;
 							$byteIndex++;
 							$bitIndex = 7;
 							$bitIndex = 7;
 						}
 						}
+
 					}
 					}
 				}
 				}
 
 
@@ -349,171 +440,41 @@ class QRCode{
 		return $this;
 		return $this;
 	}
 	}
 
 
-	/**
-	 * @return $this
-	 */
-	public function setupPositionAdjustPattern(){
-		$pos = $this->util->getPatternPosition($this->typeNumber);
-
-		$posCount = count($pos);
-		for($i = 0; $i < $posCount; $i++){
-			for($j = 0; $j < $posCount; $j++){
-
-				$row = $pos[$i];
-				$col = $pos[$j];
-
-				if($this->modules[$row][$col] !== null){
-					continue;
-				}
-
-				for($r = -2; $r <= 2; $r++){
-					for($c = -2; $c <= 2; $c++){
-
-						if($r == -2 || $r == 2 || $c == -2 || $c == 2
-							|| ($r == 0 && $c == 0)
-						){
-							$this->modules[$row + $r][$col + $c] = true;
-						}
-						else{
-							$this->modules[$row + $r][$col + $c] = false;
-						}
-					}
-				}
-			}
-		}
-
-		return $this;
-	}
-
 	/**
 	/**
 	 * @param $row
 	 * @param $row
 	 * @param $col
 	 * @param $col
 	 *
 	 *
 	 * @return $this
 	 * @return $this
 	 */
 	 */
-	public function setupPositionProbePattern($row, $col){
+	protected function setupPositionProbePattern($row, $col){
 
 
 		for($r = -1; $r <= 7; $r++){
 		for($r = -1; $r <= 7; $r++){
 			for($c = -1; $c <= 7; $c++){
 			for($c = -1; $c <= 7; $c++){
 
 
-				if($row + $r <= -1 || $this->moduleCount <= $row + $r
-					|| $col + $c <= -1 || $this->moduleCount <= $col + $c
-				){
+				if($row + $r <= -1 || $this->moduleCount <= $row + $r || $col + $c <= -1 || $this->moduleCount <= $col + $c){
 					continue;
 					continue;
 				}
 				}
 
 
-				if((0 <= $r && $r <= 6 && ($c == 0 || $c == 6))
-					|| (0 <= $c && $c <= 6 && ($r == 0 || $r == 6))
-					|| (2 <= $r && $r <= 4 && 2 <= $c && $c <= 4)
-				){
-					$this->modules[$row + $r][$col + $c] = true;
-				}
-				else{
-					$this->modules[$row + $r][$col + $c] = false;
-				}
+				$this->modules[$row + $r][$col + $c] =
+					(0 <= $r && $r <= 6 && ($c === 0 || $c === 6))
+						|| (0 <= $c && $c <= 6 && ($r == 0 || $r === 6))
+						|| (2 <= $r && $r <= 4 && 2 <= $c && $c <= 4);
 			}
 			}
 		}
 		}
 
 
 		return $this;
 		return $this;
 	}
 	}
 
 
-	/**
-	 * @return $this
-	 */
-	public function setupTimingPattern(){
-
-		for($r = 8; $r < $this->moduleCount - 8; $r++){
-			if($this->modules[$r][6] !== null){
-				continue;
-			}
-			$this->modules[$r][6] = ($r % 2 == 0);
-		}
-
-		for($c = 8; $c < $this->moduleCount - 8; $c++){
-			if($this->modules[6][$c] !== null){
-				continue;
-			}
-			$this->modules[6][$c] = ($c % 2 == 0);
-		}
-
-		return $this;
-	}
-
-	/**
-	 * @param $test
-	 *
-	 * @return $this
-	 */
-	public function setupTypeNumber($test){
-		$bits = $this->util->getBCHTypeNumber($this->typeNumber);
-
-		for($i = 0; $i < 18; $i++){
-			$this->modules[(int)floor($i / 3)][$i % 3 + $this->moduleCount - 8 - 3] = !$test && (($bits >> $i) & 1) === 1;
-		}
-
-		for($i = 0; $i < 18; $i++){
-			$this->modules[$i % 3 + $this->moduleCount - 8 - 3][(int)floor($i / 3)] = !$test && (($bits >> $i) & 1) === 1;
-		}
-
-		return $this;
-	}
-
-	/**
-	 * @param $test
-	 * @param $maskPattern
-	 *
-	 * @return $this
-	 */
-	public function setupTypeInfo($test, $maskPattern){
-
-		$data = ($this->errorCorrectLevel << 3) | $maskPattern;
-		$bits = $this->util->getBCHTypeInfo($data);
-
-		for($i = 0; $i < 15; $i++){
-
-			$mod = !$test && (($bits >> $i) & 1) === 1;
-
-			if($i < 6){
-				$this->modules[$i][8] = $mod;
-			}
-			else if($i < 8){
-				$this->modules[$i + 1][8] = $mod;
-			}
-			else{
-				$this->modules[$this->moduleCount - 15 + $i][8] = $mod;
-			}
-		}
-
-		for($i = 0; $i < 15; $i++){
-
-			$mod = !$test && (($bits >> $i) & 1) === 1;
-
-			if($i < 8){
-				$this->modules[8][$this->moduleCount - $i - 1] = $mod;
-			}
-			else if($i < 9){
-				$this->modules[8][15 - $i - 1 + 1] = $mod;
-			}
-			else{
-				$this->modules[8][15 - $i - 1] = $mod;
-			}
-		}
-
-		$this->modules[$this->moduleCount - 8][8] = !$test;
-
-		return $this;
-	}
-
 	/**
 	/**
 	 * @param $typeNumber
 	 * @param $typeNumber
 	 * @param $errorCorrectLevel
 	 * @param $errorCorrectLevel
 	 *
 	 *
 	 * @return array
 	 * @return array
 	 * @throws \codemasher\QRCode\QRCodeException
 	 * @throws \codemasher\QRCode\QRCodeException
-	 * @todo: slooooow
+	 * @todo: slooooow in PHP5
 	 *
 	 *
 	 */
 	 */
-	public function createData($typeNumber, $errorCorrectLevel){
+	protected function createData($typeNumber, $errorCorrectLevel){
 		$this->bitBuffer->reset();
 		$this->bitBuffer->reset();
 
 
 		$count = count($this->qrDataList);
 		$count = count($this->qrDataList);
@@ -521,7 +482,7 @@ class QRCode{
 			/** @var \codemasher\QRCode\Data\QRDataInterface $data */
 			/** @var \codemasher\QRCode\Data\QRDataInterface $data */
 			$data = $this->qrDataList[$i];
 			$data = $this->qrDataList[$i];
 
 
-			$this->bitBuffer->put($data->getMode(), 4);
+			$this->bitBuffer->put($data->mode, 4);
 			$this->bitBuffer->put($data->getLength(), $data->getLengthInBits($typeNumber));
 			$this->bitBuffer->put($data->getLength(), $data->getLengthInBits($typeNumber));
 			$data->write($this->bitBuffer);
 			$data->write($this->bitBuffer);
 		}
 		}
@@ -531,88 +492,122 @@ class QRCode{
 
 
 		$count = count($this->rsBlockList);
 		$count = count($this->rsBlockList);
 		for($i = 0; $i < $count; $i++){
 		for($i = 0; $i < $count; $i++){
-			$this->rsBlock->setCount($this->rsBlockList[$i][0], $this->rsBlockList[$i][1]);
+			$this->rsBlock->totalCount = $this->rsBlockList[$i][0];
+			$this->rsBlock->dataCount = $this->rsBlockList[$i][1];
 
 
-			$totalDataCount += $this->rsBlock->getDataCount();
+			$totalDataCount += $this->rsBlock->dataCount;
 		}
 		}
 
 
-		if($this->bitBuffer->getLengthInBits() > $totalDataCount * 8){
-			throw new QRCodeException('code length overflow. ('.$this->bitBuffer->getLengthInBits().'>'.($totalDataCount * 8).')');
+		if($this->bitBuffer->length > $totalDataCount * 8){
+			throw new QRCodeException('code length overflow. ('.$this->bitBuffer->length.'>'.($totalDataCount * 8).')');
 		}
 		}
 
 
 		// end code.
 		// end code.
-		if($this->bitBuffer->getLengthInBits() + 4 <= $totalDataCount * 8){
+		if($this->bitBuffer->length + 4 <= $totalDataCount * 8){
 			$this->bitBuffer->put(0, 4);
 			$this->bitBuffer->put(0, 4);
 		}
 		}
 
 
 		// padding
 		// padding
-		while($this->bitBuffer->getLengthInBits() % 8 != 0){
+		while($this->bitBuffer->length % 8 != 0){
 			$this->bitBuffer->putBit(false);
 			$this->bitBuffer->putBit(false);
 		}
 		}
 
 
 		// padding
 		// padding
 		while(true){
 		while(true){
 
 
-			if($this->bitBuffer->getLengthInBits() >= $totalDataCount * 8){
+			if($this->bitBuffer->length >= $totalDataCount * 8){
 				break;
 				break;
 			}
 			}
 			$this->bitBuffer->put(self::QR_PAD0, 8);
 			$this->bitBuffer->put(self::QR_PAD0, 8);
 
 
-			if($this->bitBuffer->getLengthInBits() >= $totalDataCount * 8){
+			if($this->bitBuffer->length >= $totalDataCount * 8){
 				break;
 				break;
 			}
 			}
 
 
 			$this->bitBuffer->put(self::QR_PAD1, 8);
 			$this->bitBuffer->put(self::QR_PAD1, 8);
 		}
 		}
 
 
-		return $this->createBytes();
-	}
 
 
-	/**
-	 * @return array
-	 */
-	public function createBytes(){
 		$offset = $maxDcCount = $maxEcCount = 0;
 		$offset = $maxDcCount = $maxEcCount = 0;
-		$dcdata = $ecdata = $this->createNullArray(count($this->rsBlockList));
 		$rsBlockCount = count($this->rsBlockList);
 		$rsBlockCount = count($this->rsBlockList);
 
 
+		$nullArray = [];
+		for($i = 0; $i < $rsBlockCount; $i++){
+			$nullArray[] = null;
+		}
+
+		$dcdata = $ecdata = $nullArray;
+		$totalCodeCount = 0;
+
 		for($r = 0; $r < $rsBlockCount; $r++){
 		for($r = 0; $r < $rsBlockCount; $r++){
-			$this->rsBlock->setCount($this->rsBlockList[$r][0], $this->rsBlockList[$r][1]);
+			$this->rsBlock->totalCount = $this->rsBlockList[$r][0];
+			$this->rsBlock->dataCount = $this->rsBlockList[$r][1];
+
 
 
-			$dcCount = $this->rsBlock->getDataCount();
-			$ecCount = $this->rsBlock->getTotalCount() - $dcCount;
+			$dcCount = $this->rsBlock->dataCount;
+			$ecCount = $this->rsBlock->totalCount - $dcCount;
 
 
 			$maxDcCount = max($maxDcCount, $dcCount);
 			$maxDcCount = max($maxDcCount, $dcCount);
 			$maxEcCount = max($maxEcCount, $ecCount);
 			$maxEcCount = max($maxEcCount, $ecCount);
 
 
-			$dcdata[$r] = $this->createNullArray($dcCount);
+			$_nullArray = [];
+			for($i = 0; $i < $dcCount; $i++){
+				$_nullArray[] = null;
+			}
+
+			$dcdata[$r] = $_nullArray;
 			$dcdataCount = count($dcdata[$r]);
 			$dcdataCount = count($dcdata[$r]);
 			for($i = 0; $i < $dcdataCount; $i++){
 			for($i = 0; $i < $dcdataCount; $i++){
-				$bdata = $this->bitBuffer->getBuffer();
+				$bdata = $this->bitBuffer->buffer;
 				$dcdata[$r][$i] = 0xff & $bdata[$i + $offset];
 				$dcdata[$r][$i] = 0xff & $bdata[$i + $offset];
 			}
 			}
 			$offset += $dcCount;
 			$offset += $dcCount;
 
 
-			$rsPoly = $this->util->getErrorCorrectPolynomial($ecCount);
-			$rawPoly = new Polynomial($dcdata[$r], $rsPoly->getLength() - 1);
 
 
-			$modPoly = $rawPoly->mod($rsPoly);
-			$ecdata[$r] = $this->createNullArray($rsPoly->getLength() - 1);
+			$rsPoly = new Polynomial;
+			$modPoly = new Polynomial;
+
+$starttime = microtime(true);
+			// 0.09s
+			for($i = 0; $i < $ecCount; $i++){
+				$modPoly->setNum([1, $modPoly->gexp($i)]);
+				$rsPoly->multiply($modPoly->num);
+			}
+
+			$rsPolyCount = count($rsPoly->num);
+
+			// 0.11s
+			$modPoly->setNum($dcdata[$r], $rsPolyCount - 1)->mod($rsPoly->num);
+
+echo 'QRCode::createData '.round((microtime(true)-$starttime), 5).PHP_EOL;
+
+			$modPolyCount = count($modPoly->num);
+
+			$_nullArray = [];
+			for($i = 0; $i < $rsPolyCount - 1; $i++){
+				$_nullArray[] = null;
+			}
+
+			$ecdata[$r] = $_nullArray;
 			$ecdataCount = count($ecdata[$r]);
 			$ecdataCount = count($ecdata[$r]);
+
 			for($i = 0; $i < $ecdataCount; $i++){
 			for($i = 0; $i < $ecdataCount; $i++){
-				$modIndex = $i + $modPoly->getLength() - count($ecdata[$r]);
-				$ecdata[$r][$i] = ($modIndex >= 0) ? $modPoly->getNum($modIndex) : 0;
+				$modIndex = $i + $modPolyCount - $ecdataCount;
+				$ecdata[$r][$i] = ($modIndex >= 0) ? $modPoly->num[$modIndex] : 0;
 			}
 			}
-		}
 
 
-		$totalCodeCount = 0;
-		for($i = 0; $i < $rsBlockCount; $i++){
-			$this->rsBlock->setCount($this->rsBlockList[$i][0], $this->rsBlockList[$i][1]);
+			$this->rsBlock->totalCount = $this->rsBlockList[$r][0];
+			$this->rsBlock->dataCount = $this->rsBlockList[$r][1];
 
 
-			$totalCodeCount += $this->rsBlock->getTotalCount();
+			$totalCodeCount += $this->rsBlock->totalCount;
 		}
 		}
 
 
-		$data = $this->createNullArray($totalCodeCount);
+		$nullArray = [];
+		for($i = 0; $i < $totalCodeCount; $i++){
+			$nullArray[] = null;
+		}
+
+		$data = $nullArray;
 		$index = 0;
 		$index = 0;
 		for($i = 0; $i < $maxDcCount; $i++){
 		for($i = 0; $i < $maxDcCount; $i++){
 			for($r = 0; $r < $rsBlockCount; $r++){
 			for($r = 0; $r < $rsBlockCount; $r++){
@@ -640,27 +635,26 @@ class QRCode{
 	 * @return \codemasher\QRCode\QRCode
 	 * @return \codemasher\QRCode\QRCode
 	 * @throws \codemasher\QRCode\QRCodeException
 	 * @throws \codemasher\QRCode\QRCodeException
 	 */
 	 */
-	public function getMinimumQRCode($data, $errorCorrectLevel){
-
+	public function getMinimumQRCode($data, $errorCorrectLevel = QRConst::ERROR_CORRECT_LEVEL_H){
 		$mode = $this->util->getMode($data);
 		$mode = $this->util->getMode($data);
+		$this->addData($data, $mode);
 
 
-		$qr = new QRCode();
-		$qr->setErrorCorrectLevel($errorCorrectLevel);
-		$qr->addData($data, $mode);
+		$this->errorCorrectLevel = $errorCorrectLevel;
 
 
-		$qrData = $qr->getData(0);
+		/** @var \codemasher\QRCode\Data\QRDataBase $qrData */
+		$qrData = $this->qrDataList[0];
 		$length = $qrData->getLength();
 		$length = $qrData->getLength();
 
 
 		for($typeNumber = 1; $typeNumber <= 10; $typeNumber++){
 		for($typeNumber = 1; $typeNumber <= 10; $typeNumber++){
-			if($length <= $this->util->getMaxLength($typeNumber, $mode, $errorCorrectLevel)){
-				$qr->setTypeNumber($typeNumber);
+			if($length <= $this->util->getMaxLength($typeNumber, $mode, $this->errorCorrectLevel)){
+				$this->typeNumber = $typeNumber;
 				break;
 				break;
 			}
 			}
 		}
 		}
 
 
-		$qr->make();
+		$this->makeImpl(false, $this->getBestMaskPattern());
 
 
-		return $qr;
+		return $this;
 	}
 	}
 
 
 	/**
 	/**
@@ -692,7 +686,7 @@ class QRCode{
 			$margin = 0;
 			$margin = 0;
 		}
 		}
 
 
-		$image_size = $this->getModuleCount() * $size + $margin * 2;
+		$image_size = $this->moduleCount * $size + $margin * 2;
 
 
 		$image = imagecreatetruecolor($image_size, $image_size);
 		$image = imagecreatetruecolor($image_size, $image_size);
 
 
@@ -705,8 +699,8 @@ class QRCode{
 		}
 		}
 
 
 		// convert hexadecimal RGB to arrays for imagecolorallocate
 		// convert hexadecimal RGB to arrays for imagecolorallocate
-		$fgrgb = $this->hex2rgb($fg);
-		$bgrgb = $this->hex2rgb($bg);
+		$fgrgb = $this->util->hex2rgb($fg);
+		$bgrgb = $this->util->hex2rgb($bg);
 
 
 		// replace $black and $white with $fgc and $bgc
 		// replace $black and $white with $fgc and $bgc
 		$fgc = imagecolorallocate($image, $fgrgb['r'], $fgrgb['g'], $fgrgb['b']);
 		$fgc = imagecolorallocate($image, $fgrgb['r'], $fgrgb['g'], $fgrgb['b']);
@@ -718,9 +712,8 @@ class QRCode{
 		// update $white to $bgc
 		// update $white to $bgc
 		imagefilledrectangle($image, 0, 0, $image_size, $image_size, $bgc);
 		imagefilledrectangle($image, 0, 0, $image_size, $image_size, $bgc);
 
 
-		$count = $this->getModuleCount();
-		for($r = 0; $r < $count; $r++){
-			for($c = 0; $c < $count; $c++){
+		for($r = 0; $r < $this->moduleCount; $r++){
+			for($c = 0; $c < $this->moduleCount; $c++){
 				if($this->isDark($r, $c)){
 				if($this->isDark($r, $c)){
 
 
 					// update $black to $fgc
 					// update $black to $fgc
@@ -742,7 +735,7 @@ class QRCode{
 	 */
 	 */
 	public function printHTML(){
 	public function printHTML(){
 		$html = '<table class="qrcode">';
 		$html = '<table class="qrcode">';
-		$count = $this->getModuleCount();
+		$count = $this->moduleCount;
 
 
 		for($r = 0; $r < $count; $r++){
 		for($r = 0; $r < $count; $r++){
 			$html .= '<tr>';
 			$html .= '<tr>';

+ 2 - 2
src/QRConst.php

@@ -17,8 +17,8 @@ namespace codemasher\QRCode;
 class QRConst{
 class QRConst{
 
 
 	const MODE_NUMBER = 1 << 0;
 	const MODE_NUMBER = 1 << 0;
-	const MODE_ALPHA_NUM = 1 << 1;
-	const MODE_8BIT_BYTE = 1 << 2;
+	const MODE_ALPHANUM = 1 << 1;
+	const MODE_BYTE = 1 << 2;
 	const MODE_KANJI = 1 << 3;
 	const MODE_KANJI = 1 << 3;
 
 
 	const MASK_PATTERN000 = 0;
 	const MASK_PATTERN000 = 0;

+ 16 - 47
src/RSBlock.php

@@ -22,12 +22,12 @@ class RSBlock{
 	/**
 	/**
 	 * @var int
 	 * @var int
 	 */
 	 */
-	protected $totalCount;
+	public $totalCount;
 
 
 	/**
 	/**
 	 * @var int
 	 * @var int
 	 */
 	 */
-	protected $dataCount;
+	public $dataCount;
 
 
 	/**
 	/**
 	 * @var array
 	 * @var array
@@ -101,40 +101,28 @@ class RSBlock{
 
 
 	];
 	];
 
 
-	/**
-	 * @param int $totalCount
-	 * @param int $dataCount
-	 */
-	public function setCount($totalCount, $dataCount){
-		$this->totalCount = $totalCount;
-		$this->dataCount = $dataCount;
-	}
-
-	/**
-	 * @return int
-	 */
-	public function getDataCount(){
-		return $this->dataCount;
-	}
-
-	/**
-	 * @return int
-	 */
-	public function getTotalCount(){
-		return $this->totalCount;
-	}
-
 	/**
 	/**
 	 * @param $typeNumber
 	 * @param $typeNumber
 	 * @param $errorCorrectLevel
 	 * @param $errorCorrectLevel
 	 *
 	 *
 	 * @return array
 	 * @return array
+	 * @throws \codemasher\QRCode\QRCodeException
 	 */
 	 */
 	public function getRSBlocks($typeNumber, $errorCorrectLevel){
 	public function getRSBlocks($typeNumber, $errorCorrectLevel){
-		$rsBlock = $this->getRsBlockTable($typeNumber, $errorCorrectLevel);
-		$length = count($rsBlock) / 3;
-		$list = [];
 
 
+		switch($errorCorrectLevel){
+			case QRConst::ERROR_CORRECT_LEVEL_L: $rsBlock = 0; break;
+			case QRConst::ERROR_CORRECT_LEVEL_M: $rsBlock = 1; break;
+			case QRConst::ERROR_CORRECT_LEVEL_Q: $rsBlock = 2; break;
+			case QRConst::ERROR_CORRECT_LEVEL_H: $rsBlock = 3; break;
+			default:
+				throw new QRCodeException('tn:'.$typeNumber.'/ecl:'.$errorCorrectLevel);
+		}
+
+		$rsBlock = $this->QR_RS_BLOCK_TABLE[($typeNumber - 1) * 4 + $rsBlock];
+
+		$list = [];
+		$length = count($rsBlock) / 3;
 		for($i = 0; $i < $length; $i++){
 		for($i = 0; $i < $length; $i++){
 			$count = $rsBlock[$i * 3 + 0];
 			$count = $rsBlock[$i * 3 + 0];
 			$totalCount = $rsBlock[$i * 3 + 1];
 			$totalCount = $rsBlock[$i * 3 + 1];
@@ -148,24 +136,5 @@ class RSBlock{
 		return $list;
 		return $list;
 	}
 	}
 
 
-	/**
-	 * @param $typeNumber
-	 * @param $errorCorrectLevel
-	 *
-	 * @return mixed
-	 * @throws \codemasher\QRCode\QRCodeException
-	 */
-	public function getRsBlockTable($typeNumber, $errorCorrectLevel){
-
-		switch($errorCorrectLevel){
-			case QRConst::ERROR_CORRECT_LEVEL_L: return $this->QR_RS_BLOCK_TABLE[($typeNumber - 1) * 4 + 0];
-			case QRConst::ERROR_CORRECT_LEVEL_M: return $this->QR_RS_BLOCK_TABLE[($typeNumber - 1) * 4 + 1];
-			case QRConst::ERROR_CORRECT_LEVEL_Q: return $this->QR_RS_BLOCK_TABLE[($typeNumber - 1) * 4 + 2];
-			case QRConst::ERROR_CORRECT_LEVEL_H: return $this->QR_RS_BLOCK_TABLE[($typeNumber - 1) * 4 + 3];
-			default:
-				throw new QRCodeException('tn:'.$typeNumber.'/ecl:'.$errorCorrectLevel);
-		}
-
-	}
 
 
 }
 }

+ 48 - 243
src/Util.php

@@ -11,7 +11,6 @@
 
 
 namespace codemasher\QRCode;
 namespace codemasher\QRCode;
 
 
-use codemasher\QRCode\Math;
 use codemasher\QRCode\Polynomial;
 use codemasher\QRCode\Polynomial;
 use codemasher\QRCode\QRCode;
 use codemasher\QRCode\QRCode;
 use codemasher\QRCode\QRConst;
 use codemasher\QRCode\QRConst;
@@ -29,7 +28,7 @@ class Util{
 	/**
 	/**
 	 * @var array
 	 * @var array
 	 */
 	 */
-	protected $QR_MAX_LENGTH = [
+	public $MAX_LENGTH = [
 		[[41, 25, 17, 10], [34, 20, 14, 8], [27, 16, 11, 7], [17, 10, 7, 4]],
 		[[41, 25, 17, 10], [34, 20, 14, 8], [27, 16, 11, 7], [17, 10, 7, 4]],
 		[[77, 47, 32, 20], [63, 38, 26, 16], [48, 29, 20, 12], [34, 20, 14, 8]],
 		[[77, 47, 32, 20], [63, 38, 26, 16], [48, 29, 20, 12], [34, 20, 14, 8]],
 		[[127, 77, 53, 32], [101, 61, 42, 26], [77, 47, 32, 20], [58, 35, 24, 15]],
 		[[127, 77, 53, 32], [101, 61, 42, 26], [77, 47, 32, 20], [58, 35, 24, 15]],
@@ -45,7 +44,7 @@ class Util{
 	/**
 	/**
 	 * @var array
 	 * @var array
 	 */
 	 */
-	protected $QR_PATTERN_POSITION_TABLE = [
+	public $PATTERN_POSITION = [
 		[],
 		[],
 		[6, 18],
 		[6, 18],
 		[6, 22],
 		[6, 22],
@@ -88,27 +87,6 @@ class Util{
 		[6, 30, 58, 86, 114, 142, 170],
 		[6, 30, 58, 86, 114, 142, 170],
 	];
 	];
 
 
-	/**
-	 * @var \codemasher\QRCode\Math
-	 */
-	protected $math;
-
-	/**
-	 * Util constructor.
-	 */
-	public function __construct(){
-		$this->math = new Math;
-	}
-
-	/**
-	 * @param int $typeNumber
-	 *
-	 * @return array
-	 */
-	public function getPatternPosition($typeNumber){
-		return $this->QR_PATTERN_POSITION_TABLE[$typeNumber - 1];
-	}
-
 	/**
 	/**
 	 * @param int $typeNumber
 	 * @param int $typeNumber
 	 * @param int $mode
 	 * @param int $mode
@@ -121,209 +99,26 @@ class Util{
 		$_type = $typeNumber - 1;
 		$_type = $typeNumber - 1;
 
 
 		switch($errorCorrectLevel){
 		switch($errorCorrectLevel){
-			case QRConst::ERROR_CORRECT_LEVEL_L:
-				$_err = 0;
-				break;
-			case QRConst::ERROR_CORRECT_LEVEL_M:
-				$_err = 1;
-				break;
-			case QRConst::ERROR_CORRECT_LEVEL_Q:
-				$_err = 2;
-				break;
-			case QRConst::ERROR_CORRECT_LEVEL_H:
-				$_err = 3;
-				break;
+			case QRConst::ERROR_CORRECT_LEVEL_L: $_err = 0; break;
+			case QRConst::ERROR_CORRECT_LEVEL_M: $_err = 1; break;
+			case QRConst::ERROR_CORRECT_LEVEL_Q: $_err = 2; break;
+			case QRConst::ERROR_CORRECT_LEVEL_H: $_err = 3; break;
 			default:
 			default:
 				throw new QRCodeException('$_err: '.$errorCorrectLevel);
 				throw new QRCodeException('$_err: '.$errorCorrectLevel);
 		}
 		}
 
 
 		switch($mode){
 		switch($mode){
-			case QRConst::MODE_NUMBER:
-				$_mode = 0;
-				break;
-			case QRConst::MODE_ALPHA_NUM:
-				$_mode = 1;
-				break;
-			case QRConst::MODE_8BIT_BYTE:
-				$_mode = 2;
-				break;
-			case QRConst::MODE_KANJI:
-				$_mode = 3;
-				break;
+			case QRConst::MODE_NUMBER   : $_mode = 0; break;
+			case QRConst::MODE_ALPHANUM: $_mode = 1; break;
+			case QRConst::MODE_BYTE: $_mode = 2; break;
+			case QRConst::MODE_KANJI    : $_mode = 3; break;
 			default :
 			default :
 				throw new QRCodeException('$_mode: '.$mode);
 				throw new QRCodeException('$_mode: '.$mode);
 		}
 		}
 
 
-		return $this->QR_MAX_LENGTH[$_type][$_err][$_mode];
-	}
-
-	/**
-	 * @param $errorCorrectLength
-	 *
-	 * @return \codemasher\QRCode\Polynomial
-	 */
-	public function getErrorCorrectPolynomial($errorCorrectLength){
-		$a = new Polynomial([1]);
-
-		for($i = 0; $i < $errorCorrectLength; $i++){
-			$a = $a->multiply(new Polynomial([1, $this->math->gexp($i)]));
-		}
-
-		return $a;
+		return $this->MAX_LENGTH[$_type][$_err][$_mode];
 	}
 	}
 
 
-	/**
-	 * @param $maskPattern
-	 * @param $i
-	 * @param $j
-	 *
-	 * @return bool
-	 * @throws \codemasher\QRCode\QRCodeException
-	 */
-	public function getMask($maskPattern, $i, $j){
-
-		switch($maskPattern){
-			case QRConst::MASK_PATTERN000:
-				return ($i + $j) % 2 === 0;
-			case QRConst::MASK_PATTERN001:
-				return $i % 2 === 0;
-			case QRConst::MASK_PATTERN010:
-				return $j % 3 === 0;
-			case QRConst::MASK_PATTERN011:
-				return ($i + $j) % 3 === 0;
-			case QRConst::MASK_PATTERN100:
-				return (floor($i / 2) + floor($j / 3)) % 2 === 0;
-			case QRConst::MASK_PATTERN101:
-				return ($i * $j) % 2 + ($i * $j) % 3 === 0;
-			case QRConst::MASK_PATTERN110:
-				return (($i * $j) % 2 + ($i * $j) % 3) % 2 === 0;
-			case QRConst::MASK_PATTERN111:
-				return (($i * $j) % 3 + ($i + $j) % 2) % 2 === 0;
-			default :
-				throw new QRCodeException('mask: '.$maskPattern);
-		}
-	}
-
-	/**
-	 * @param \codemasher\QRCode\QRCode $qrCode
-	 *
-	 * @return float|int
-	 */
-	public function getLostPoint(QRCode $qrCode){
-		$moduleCount = $qrCode->getModuleCount();
-
-		$lostPoint = 0;
-
-		// LEVEL1
-
-		for($row = 0; $row < $moduleCount; $row++){
-			for($col = 0; $col < $moduleCount; $col++){
-				$sameCount = 0;
-				$dark = $qrCode->isDark($row, $col);
-
-				for($r = -1; $r <= 1; $r++){
-					if($row + $r < 0 || $moduleCount <= $row + $r){
-						continue;
-					}
-
-					for($c = -1; $c <= 1; $c++){
-
-						if($col + $c < 0 || $moduleCount <= $col + $c){
-							continue;
-						}
-
-						if($r == 0 && $c == 0){
-							continue;
-						}
-
-						if($dark == $qrCode->isDark($row + $r, $col + $c)){
-							$sameCount++;
-						}
-					}
-				}
-
-				if($sameCount > 5){
-					$lostPoint += (3 + $sameCount - 5);
-				}
-			}
-		}
-
-		// LEVEL2
-
-		for($row = 0; $row < $moduleCount - 1; $row++){
-			for($col = 0; $col < $moduleCount - 1; $col++){
-				$count = 0;
-
-				if($qrCode->isDark($row, $col)){
-					$count++;
-				}
-
-				if($qrCode->isDark($row + 1, $col)){
-					$count++;
-				}
-
-				if($qrCode->isDark($row, $col + 1)){
-					$count++;
-				}
-
-				if($qrCode->isDark($row + 1, $col + 1)){
-					$count++;
-				}
-
-				if($count === 0 || $count === 4){
-					$lostPoint += 3;
-				}
-			}
-		}
-
-		// LEVEL3
-
-		for($row = 0; $row < $moduleCount; $row++){
-			for($col = 0; $col < $moduleCount - 6; $col++){
-				if($qrCode->isDark($row, $col)
-					&& !$qrCode->isDark($row, $col + 1)
-					&& $qrCode->isDark($row, $col + 2)
-					&& $qrCode->isDark($row, $col + 3)
-					&& $qrCode->isDark($row, $col + 4)
-					&& !$qrCode->isDark($row, $col + 5)
-					&& $qrCode->isDark($row, $col + 6)
-				){
-					$lostPoint += 40;
-				}
-			}
-		}
-
-		for($col = 0; $col < $moduleCount; $col++){
-			for($row = 0; $row < $moduleCount - 6; $row++){
-				if($qrCode->isDark($row, $col)
-					&& !$qrCode->isDark($row + 1, $col)
-					&& $qrCode->isDark($row + 2, $col)
-					&& $qrCode->isDark($row + 3, $col)
-					&& $qrCode->isDark($row + 4, $col)
-					&& !$qrCode->isDark($row + 5, $col)
-					&& $qrCode->isDark($row + 6, $col)
-				){
-					$lostPoint += 40;
-				}
-			}
-		}
-
-		// LEVEL4
-
-		$darkCount = 0;
-		for($col = 0; $col < $moduleCount; $col++){
-			for($row = 0; $row < $moduleCount; $row++){
-				if($qrCode->isDark($row, $col)){
-					$darkCount++;
-				}
-			}
-		}
-
-		$ratio = abs(100 * $darkCount / $moduleCount / $moduleCount - 50) / 5;
-		$lostPoint += $ratio * 10;
-
-		return $lostPoint;
-	}
 
 
 	/**
 	/**
 	 * @param $s
 	 * @param $s
@@ -331,18 +126,20 @@ class Util{
 	 * @return int
 	 * @return int
 	 */
 	 */
 	public function getMode($s){
 	public function getMode($s){
+
 		if($this->isAlphaNum($s)){
 		if($this->isAlphaNum($s)){
 			if($this->isNumber($s)){
 			if($this->isNumber($s)){
 				return QRConst::MODE_NUMBER;
 				return QRConst::MODE_NUMBER;
 			}
 			}
-			return QRConst::MODE_ALPHA_NUM;
+			return QRConst::MODE_ALPHANUM;
 		}
 		}
 		else if($this->isKanji($s)){
 		else if($this->isKanji($s)){
 			return QRConst::MODE_KANJI;
 			return QRConst::MODE_KANJI;
 		}
 		}
 		else{
 		else{
-			return QRConst::MODE_8BIT_BYTE;
+			return QRConst::MODE_BYTE;
 		}
 		}
+
 	}
 	}
 
 
 	/**
 	/**
@@ -350,11 +147,13 @@ class Util{
 	 *
 	 *
 	 * @return bool
 	 * @return bool
 	 */
 	 */
-	public function isNumber($s){
-		for($i = 0; $i < strlen($s); $i++){
+	protected function isNumber($s){
+
+		$len = strlen($s);
+		for($i = 0; $i < $len; $i++){
 			$c = ord($s[$i]);
 			$c = ord($s[$i]);
 
 
-			if(!($this->toCharCode('0') <= $c && $c <= $this->toCharCode('9'))){
+			if(!(ord('0') <= $c && $c <= ord('9'))){
 				return false;
 				return false;
 			}
 			}
 		}
 		}
@@ -367,14 +166,13 @@ class Util{
 	 *
 	 *
 	 * @return bool
 	 * @return bool
 	 */
 	 */
-	public function isAlphaNum($s){
-		for($i = 0; $i < strlen($s); $i++){
+	protected function isAlphaNum($s){
+
+		$len = strlen($s);
+		for($i = 0; $i < $len; $i++){
 			$c = ord($s[$i]);
 			$c = ord($s[$i]);
 
 
-			if(!($this->toCharCode('0') <= $c && $c <= $this->toCharCode('9'))
-				&& !($this->toCharCode('A') <= $c && $c <= $this->toCharCode('Z'))
-				&& strpos(' $%*+-./:', $s[$i]) === false
-			){
+			if(!(ord('0') <= $c && $c <= ord('9')) && !(ord('A') <= $c && $c <= ord('Z')) && strpos(' $%*+-./:', $s[$i]) === false){
 				return false;
 				return false;
 			}
 			}
 		}
 		}
@@ -387,12 +185,12 @@ class Util{
 	 *
 	 *
 	 * @return bool
 	 * @return bool
 	 */
 	 */
-	public function isKanji($s){
-		$data = $s;
-		$i = 0;
+	protected function isKanji($s){
 
 
-		while($i + 1 < strlen($data)){
-			$c = ((0xff&ord($data[$i])) << 8)|(0xff&ord($data[$i + 1]));
+		$i = 0;
+		$len = strlen($s);
+		while($i + 1 < $len){
+			$c = ((0xff&ord($s[$i])) << 8)|(0xff&ord($s[$i + 1]));
 
 
 			if(!(0x8140 <= $c && $c <= 0x9FFC) && !(0xE040 <= $c && $c <= 0xEBBF)){
 			if(!(0x8140 <= $c && $c <= 0x9FFC) && !(0xE040 <= $c && $c <= 0xEBBF)){
 				return false;
 				return false;
@@ -401,22 +199,13 @@ class Util{
 			$i += 2;
 			$i += 2;
 		}
 		}
 
 
-		if($i < strlen($data)){
+		if($i < $len){
 			return false;
 			return false;
 		}
 		}
 
 
 		return true;
 		return true;
 	}
 	}
 
 
-	/**
-	 * @param $s
-	 *
-	 * @return int
-	 */
-	public function toCharCode($s){
-		return ord($s[0]);
-	}
-
 	/**
 	/**
 	 * @param $data
 	 * @param $data
 	 *
 	 *
@@ -455,7 +244,7 @@ class Util{
 	public function getBCHDigit($data){
 	public function getBCHDigit($data){
 		$digit = 0;
 		$digit = 0;
 
 
-		while($data != 0){
+		while($data !== 0){
 			$digit++;
 			$digit++;
 			$data >>= 1;
 			$data >>= 1;
 		}
 		}
@@ -463,4 +252,20 @@ class Util{
 		return $digit;
 		return $digit;
 	}
 	}
 
 
+
+	/**
+	 * used for converting fg/bg colors (e.g. #0000ff = 0x0000FF) - added 2015.07.27 ~ DoktorJ
+	 *
+	 * @param int $hex
+	 *
+	 * @return array
+	 */
+	public function hex2rgb($hex = 0x0){
+		return [
+				'r' => floor($hex / 65536),
+				'g' => floor($hex / 256) % 256,
+				'b' => $hex % 256,
+		];
+	}
+
 }
 }