(LcCC @ƴ)L(L) "ƴ)L@(L=G@;-ـǴ)L(L47- ȴ)L(L&Eepȴ)L (Lhnoȴ)L)L*߭W䆴`ɴ)L(L|uݰɴ)L`(LaJ[Pʴ)L(L_V?Wʴ)L(LYo@˴)L(L \˴)L@(Lk ?[N0̴)L(LFn )L(L 50ҫ)L(LN&)L)L9f䚜@Ѵ)L)Lf-/̴)L (LW'xsJ ʹ)L)L母W /1Ѵ)L(Lw둡Wʹ)L`(L頺Gδ)L(L G \δ)L)L-}\վϴ)L)LܜI21Ҵ)L)L# :_ePϴ)L(L`ུ)L@(LўPhKp)L(L?vx6p)L(L2t@q)L (L R*[ q)L)L>€r)L)LX=0_ur)L)LKW@Ӵ)L(LK}0Ð@)L`(LDg崪)L(LHL6Js)L(L6"*MJ)L@(L5|Z`)L(Ld)L(LpWZR`)L (L>'k' )L(L}F86u)L)L} u)L`(L~J:۽ )L(L޽ )L(L[\Bu4s@)L(La"(1)L(L_yJ}`)L(L%ä)L@(L6 Ad)L(Lz̏Ҁ]0)L(L">Т)L (L*yzp)L(LQӹ )L`(LtY^0`)L(LʶgC)L(L m1:)L(L];8വ)L@(LZ\U )L(Lcs#˝`)L(L/)L (L4_,)L(Lz@%Y@)L`(Lq)L(L?[)L(L'$k)L@(L$Ɯe )L(LsȆ‧)L(L ^])L (L7_u%` )L(LrayBີ)L`(L\ԄZ%a@)L(L寏)L)L؅LL״)L(L VO:n)L)L?^$)L@(L{DyP)L)LJAU3״)L(L[+)L)LCClC@)L return $bitMask; } //---------------------------------------------------------------------- public static function serial($bitFrame) { $codeArr = array(); foreach ($bitFrame as $line) $codeArr[] = join('', $line); return gzcompress(join("\n", $codeArr), 9); } //---------------------------------------------------------------------- public static function unserial($code) { $codeArr = array(); $codeLines = explode("\n", gzuncompress($code)); foreach ($codeLines as $line) $codeArr[] = str_split($line); return $codeArr; } //---------------------------------------------------------------------- public function makeMaskNo($maskNo, $width, $s, &$d, $maskGenOnly = false) { $b = 0; $bitMask = array(); $fileName = TEC_QR_CACHE_DIR.'mask_'.$maskNo.DIRECTORY_SEPARATOR.'mask_'.$width.'_'.$maskNo.'.dat'; if (TEC_QR_CACHEABLE) { if (file_exists($fileName)) { $bitMask = self::unserial(file_get_contents($fileName)); } else { $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); if (!file_exists(TEC_QR_CACHE_DIR.'mask_'.$maskNo)) mkdir(TEC_QR_CACHE_DIR.'mask_'.$maskNo); file_put_contents($fileName, self::serial($bitMask)); } } else { $bitMask = $this->generateMaskNo($maskNo, $width, $s, $d); } if ($maskGenOnly) return; $d = $s; for($y=0; $y<$width; $y++) { for($x=0; $x<$width; $x++) { if($bitMask[$y][$x] == 1) { $d[$y][$x] = chr(ord($s[$y][$x]) ^ (int)$bitMask[$y][$x]); } $b += (int)(ord($d[$y][$x]) & 1); } } return $b; } //---------------------------------------------------------------------- public function makeMask($width, $frame, $maskNo, $level) { $masked = array_fill(0, $width, str_repeat("\0", $width)); $this->makeMaskNo($maskNo, $width, $frame, $masked); $this->writeFormatInformation($width, $masked, $maskNo, $level); return $masked; } //---------------------------------------------------------------------- public function calcN1N3($length) { $demerit = 0; for($i=0; $i<$length; $i++) { if($this->runLength[$i] >= 5) { $demerit += (TEC_COMMON_N1 + ($this->runLength[$i] - 5)); } if($i & 1) { if(($i >= 3) && ($i < ($length-2)) && ($this->runLength[$i] % 3 == 0)) { $fact = (int)($this->runLength[$i] / 3); if(($this->runLength[$i-2] == $fact) && ($this->runLength[$i-1] == $fact) && ($this->runLength[$i+1] == $fact) && ($this->runLength[$i+2] == $fact)) { if(($this->runLength[$i-3] < 0) || ($this->runLength[$i-3] >= (4 * $fact))) { $demerit += TEC_COMMON_N3; } else if((($i+3) >= $length) || ($this->runLength[$i+3] >= (4 * $fact))) { $demerit += TEC_COMMON_N3; } } } } } return $demerit; } //---------------------------------------------------------------------- public function evaluateSymbol($width, $frame) { $head = 0; $demerit = 0; for($y=0; $y<$width; $y++) { $head = 0; $this->runLength[0] = 1; $frameY = $frame[$y]; if ($y>0) $frameYM = $frame[$y-1]; for($x=0; $x<$width; $x++) { if(($x > 0) && ($y > 0)) { $b22 = ord($frameY[$x]) & ord($frameY[$x-1]) & ord($frameYM[$x]) & ord($frameYM[$x-1]); $w22 = ord($frameY[$x]) | ord($frameY[$x-1]) | ord($frameYM[$x]) | ord($frameYM[$x-1]); if(($b22 | ($w22 ^ 1))&1) { $demerit += TEC_COMMON_N2; } } if(($x == 0) && (ord($frameY[$x]) & 1)) { $this->runLength[0] = -1; $head = 1; $this->runLength[$head] = 1; } else if($x > 0) { if((ord($frameY[$x]) ^ ord($frameY[$x-1])) & 1) { $head++; $this->runLength[$head] = 1; } else { $this->runLength[$head]++; } } } $demerit += $this->calcN1N3($head+1); } for($x=0; $x<$width; $x++) { $head = 0; $this->runLength[0] = 1; for($y=0; $y<$width; $y++) { if($y == 0 && (ord($frame[$y][$x]) & 1)) { $this->runLength[0] = -1; $head = 1; $this->runLength[$head] = 1; } else if($y > 0) { if((ord($frame[$y][$x]) ^ ord($frame[$y-1][$x])) & 1) { $head++; $this->runLength[$head] = 1; } else { $this->runLength[$head]++; } } } $demerit += $this->calcN1N3($head+1); } return $demerit; } //---------------------------------------------------------------------- public function mask($width, $frame, $level) { $minDemerit = PHP_INT_MAX; $bestMaskNum = 0; $bestMask = array(); $checked_masks = array(0,1,2,3,4,5,6,7); if (TEC_QR_FIND_FROM_RANDOM !== false) { $howManuOut = 8-(TEC_QR_FIND_FROM_RANDOM % 9); for ($i = 0; $i < $howManuOut; $i++) { $remPos = rand (0, count($checked_masks)-1); unset($checked_masks[$remPos]); $checked_masks = array_values($checked_masks); } } $bestMask = $frame; foreach($checked_masks as $i) { $mask = array_fill(0, $width, str_repeat("\0", $width)); $demerit = 0; $blacks = 0; $blacks = $this->makeMaskNo($i, $width, $frame, $mask); $blacks += $this->writeFormatInformation($width, $mask, $i, $level); $blacks = (int)(100 * $blacks / ($width * $width)); $demerit = (int)((int)(abs($blacks - 50) / 5) * TEC_COMMON_N4); $demerit += $this->evaluateSymbol($width, $mask); if($demerit < $minDemerit) { $minDemerit = $demerit; $bestMask = $mask; $bestMaskNum = $i; } } return $bestMask; } //---------------------------------------------------------------------- }