public function encodeMask(wechat_qrcode_QRinput $input, $mask) { if ($input->getVersion() < 0 || $input->getVersion() > QRSPEC_VERSION_MAX) { throw new Exception('wrong version'); } if ($input->getErrorCorrectionLevel() > QR_ECLEVEL_H) { throw new Exception('wrong level'); } $raw = new wechat_qrcode_QRrawcode($input); wechat_qrcode_QRtools::markTime('after_raw'); $version = $raw->version; $width = wechat_qrcode_QRspec::getWidth($version); $frame = wechat_qrcode_QRspec::newFrame($version); $filler = new wechat_qrcode_FrameFiller($width, $frame); if (is_null($filler)) { return NULL; } // inteleaved data and ecc codes for ($i = 0; $i < $raw->dataLength + $raw->eccLength; $i++) { $code = $raw->getCode(); $bit = 0x80; for ($j = 0; $j < 8; $j++) { $addr = $filler->next(); $filler->setFrameAt($addr, 0x2 | ($bit & $code) != 0); $bit = $bit >> 1; } } wechat_qrcode_QRtools::markTime('after_filler'); unset($raw); // remainder bits $j = wechat_qrcode_QRspec::getRemainder($version); for ($i = 0; $i < $j; $i++) { $addr = $filler->next(); $filler->setFrameAt($addr, 0x2); } $frame = $filler->frame; unset($filler); // masking $maskObj = new wechat_qrcode_QRmask(); if ($mask < 0) { if (QR_FIND_BEST_MASK) { $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel()); } else { $masked = $maskObj->makeMask($width, $frame, intval(QR_DEFAULT_MASK) % 8, $input->getErrorCorrectionLevel()); } } else { $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel()); } if ($masked == NULL) { return NULL; } wechat_qrcode_QRtools::markTime('after_mask'); $this->version = $version; $this->width = $width; $this->data = $masked; return $this; }
public static function buildCache() { wechat_qrcode_QRtools::markTime('before_build_cache'); $mask = new wechat_qrcode_QRmask(); for ($a = 1; $a <= QRSPEC_VERSION_MAX; $a++) { $frame = wechat_qrcode_QRspec::newFrame($a); if (QR_IMAGE) { $fileName = QR_CACHE_DIR . 'frame_' . $a . '.png'; wechat_qrcode_QRimage::png(self::binarize($frame), $fileName, 1, 0); } $width = count($frame); $bitMask = array_fill(0, $width, array_fill(0, $width, 0)); for ($maskNo = 0; $maskNo < 8; $maskNo++) { $mask->makeMaskNo($maskNo, $width, $frame, $bitMask, true); } } wechat_qrcode_QRtools::markTime('after_build_cache'); }
public function writeFormatInformation($width, &$frame, $mask, $level) { $blacks = 0; $format = wechat_qrcode_QRspec::getFormatInfo($mask, $level); for ($i = 0; $i < 8; $i++) { if ($format & 1) { $blacks += 2; $v = 0x85; } else { $v = 0x84; } $frame[8][$width - 1 - $i] = chr($v); if ($i < 6) { $frame[$i][8] = chr($v); } else { $frame[$i + 1][8] = chr($v); } $format = $format >> 1; } for ($i = 0; $i < 7; $i++) { if ($format & 1) { $blacks += 2; $v = 0x85; } else { $v = 0x84; } $frame[$width - 7 + $i][8] = chr($v); if ($i == 0) { $frame[8][7] = chr($v); } else { $frame[8][6 - $i] = chr($v); } $format = $format >> 1; } return $blacks; }
public function eat8() { $la = wechat_qrcode_QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion()); $ln = wechat_qrcode_QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion()); $p = 1; $dataStrLen = strlen($this->dataStr); while ($p < $dataStrLen) { $mode = $this->identifyMode($p); if ($mode == QR_MODE_KANJI) { break; } if ($mode == QR_MODE_NUM) { $q = $p; while (self::isdigitat($this->dataStr, $q)) { $q++; } $dif = wechat_qrcode_QRinput::estimateBitsMode8($p) + wechat_qrcode_QRinput::estimateBitsModeNum($q - $p) + 4 + $ln - wechat_qrcode_QRinput::estimateBitsMode8($q); // - 4 - l8 if ($dif < 0) { break; } else { $p = $q; } } else { if ($mode == QR_MODE_AN) { $q = $p; while (self::isalnumat($this->dataStr, $q)) { $q++; } $dif = wechat_qrcode_QRinput::estimateBitsMode8($p) + wechat_qrcode_QRinput::estimateBitsModeAn($q - $p) + 4 + $la - wechat_qrcode_QRinput::estimateBitsMode8($q); // - 4 - l8 if ($dif < 0) { break; } else { $p = $q; } } else { $p++; } } } $run = $p; $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr)); if ($ret < 0) { return -1; } return $run; }
public function appendPaddingBit(&$bstream) { $bits = $bstream->size(); $maxwords = wechat_qrcode_QRspec::getDataLength($this->version, $this->level); $maxbits = $maxwords * 8; if ($maxbits == $bits) { return 0; } if ($maxbits - $bits < 5) { return $bstream->appendNum($maxbits - $bits, 0); } $bits += 4; $words = (int) (($bits + 7) / 8); $padding = new wechat_qrcode_QRbitstream(); $ret = $padding->appendNum($words * 8 - $bits + 4, 0); if ($ret < 0) { return $ret; } $padlen = $maxwords - $words; if ($padlen > 0) { $padbuf = array(); for ($i = 0; $i < $padlen; $i++) { $padbuf[$i] = $i & 1 ? 0x11 : 0xec; } $ret = $padding->appendBytes($padlen, $padbuf); if ($ret < 0) { return $ret; } } $ret = $bstream->append($padding); return $ret; }
public function encodeBitStream($version) { try { unset($this->bstream); $words = wechat_qrcode_QRspec::maximumWords($this->mode, $version); if ($this->size > $words) { $st1 = new wechat_qrcode_QRinputItem($this->mode, $words, $this->data); $st2 = new wechat_qrcode_QRinputItem($this->mode, $this->size - $words, array_slice($this->data, $words)); $st1->encodeBitStream($version); $st2->encodeBitStream($version); $this->bstream = new wechat_qrcode_QRbitstream(); $this->bstream->append($st1->bstream); $this->bstream->append($st2->bstream); unset($st1); unset($st2); } else { $ret = 0; switch ($this->mode) { case QR_MODE_NUM: $ret = $this->encodeModeNum($version); break; case QR_MODE_AN: $ret = $this->encodeModeAn($version); break; case QR_MODE_8: $ret = $this->encodeMode8($version); break; case QR_MODE_KANJI: $ret = $this->encodeModeKanji($version); break; case QR_MODE_STRUCTURE: $ret = $this->encodeModeStructure(); break; default: break; } if ($ret < 0) { return -1; } } return $this->bstream->size(); } catch (Exception $e) { return -1; } }
public function init(array $spec) { $dl = wechat_qrcode_QRspec::rsDataCodes1($spec); $el = wechat_qrcode_QRspec::rsEccCodes1($spec); $rs = wechat_qrcode_QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); $blockNo = 0; $dataPos = 0; $eccPos = 0; for ($i = 0; $i < wechat_qrcode_QRspec::rsBlockNum1($spec); $i++) { $ecc = array_slice($this->ecccode, $eccPos); $this->rsblocks[$blockNo] = new wechat_qrcode_QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); $this->ecccode = array_merge(array_slice($this->ecccode, 0, $eccPos), $ecc); $dataPos += $dl; $eccPos += $el; $blockNo++; } if (wechat_qrcode_QRspec::rsBlockNum2($spec) == 0) { return 0; } $dl = wechat_qrcode_QRspec::rsDataCodes2($spec); $el = wechat_qrcode_QRspec::rsEccCodes2($spec); $rs = wechat_qrcode_QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el); if ($rs == NULL) { return -1; } for ($i = 0; $i < wechat_qrcode_QRspec::rsBlockNum2($spec); $i++) { $ecc = array_slice($this->ecccode, $eccPos); $this->rsblocks[$blockNo] = new wechat_qrcode_QRrsblock($dl, array_slice($this->datacode, $dataPos), $el, $ecc, $rs); $this->ecccode = array_merge(array_slice($this->ecccode, 0, $eccPos), $ecc); $dataPos += $dl; $eccPos += $el; $blockNo++; } return 0; }