]>
git.wh0rd.org - tt-rss.git/blob - lib/phpqrcode/qrencode.php
5 * Main encoder classes.
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
30 public $data = array();
32 public $ecc = array();
34 public function __construct($dl, $data, $el, &$ecc, QRrsItem
$rs)
36 $rs->encode_rs_char($data, $ecc);
38 $this->dataLength
= $dl;
40 $this->eccLength
= $el;
45 //##########################################################################
49 public $datacode = array();
50 public $ecccode = array();
52 public $rsblocks = array(); //of RSblock
58 //----------------------------------------------------------------------
59 public function __construct(QRinput
$input)
61 $spec = array(0,0,0,0,0);
63 $this->datacode
= $input->getByteStream();
64 if(is_null($this->datacode
)) {
65 throw new Exception('null imput string');
68 QRspec
::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);
70 $this->version
= $input->getVersion();
71 $this->b1
= QRspec
::rsBlockNum1($spec);
72 $this->dataLength
= QRspec
::rsDataLength($spec);
73 $this->eccLength
= QRspec
::rsEccLength($spec);
74 $this->ecccode
= array_fill(0, $this->eccLength
, 0);
75 $this->blocks
= QRspec
::rsBlockNum($spec);
77 $ret = $this->init($spec);
79 throw new Exception('block alloc error');
86 //----------------------------------------------------------------------
87 public function init(array $spec)
89 $dl = QRspec
::rsDataCodes1($spec);
90 $el = QRspec
::rsEccCodes1($spec);
91 $rs = QRrs
::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
97 for($i=0; $i<QRspec
::rsBlockNum1($spec); $i++
) {
98 $ecc = array_slice($this->ecccode
,$eccPos);
99 $this->rsblocks
[$blockNo] = new QRrsblock($dl, array_slice($this->datacode
, $dataPos), $el, $ecc, $rs);
100 $this->ecccode
= array_merge(array_slice($this->ecccode
,0, $eccPos), $ecc);
107 if(QRspec
::rsBlockNum2($spec) == 0)
110 $dl = QRspec
::rsDataCodes2($spec);
111 $el = QRspec
::rsEccCodes2($spec);
112 $rs = QRrs
::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
114 if($rs == NULL) return -1;
116 for($i=0; $i<QRspec
::rsBlockNum2($spec); $i++
) {
117 $ecc = array_slice($this->ecccode
,$eccPos);
118 $this->rsblocks
[$blockNo] = new QRrsblock($dl, array_slice($this->datacode
, $dataPos), $el, $ecc, $rs);
119 $this->ecccode
= array_merge(array_slice($this->ecccode
,0, $eccPos), $ecc);
129 //----------------------------------------------------------------------
130 public function getCode()
134 if($this->count
< $this->dataLength
) {
135 $row = $this->count %
$this->blocks
;
136 $col = $this->count
/ $this->blocks
;
137 if($col >= $this->rsblocks
[0]->dataLength
) {
140 $ret = $this->rsblocks
[$row]->data
[$col];
141 } else if($this->count
< $this->dataLength +
$this->eccLength
) {
142 $row = ($this->count
- $this->dataLength
) %
$this->blocks
;
143 $col = ($this->count
- $this->dataLength
) / $this->blocks
;
144 $ret = $this->rsblocks
[$row]->ecc
[$col];
154 //##########################################################################
162 //----------------------------------------------------------------------
163 public function encodeMask(QRinput
$input, $mask)
165 if($input->getVersion() < 0 ||
$input->getVersion() > QRSPEC_VERSION_MAX
) {
166 throw new Exception('wrong version');
168 if($input->getErrorCorrectionLevel() > QR_ECLEVEL_H
) {
169 throw new Exception('wrong level');
172 $raw = new QRrawcode($input);
174 QRtools
::markTime('after_raw');
176 $version = $raw->version
;
177 $width = QRspec
::getWidth($version);
178 $frame = QRspec
::newFrame($version);
180 $filler = new FrameFiller($width, $frame);
181 if(is_null($filler)) {
185 // inteleaved data and ecc codes
186 for($i=0; $i<$raw->dataLength +
$raw->eccLength
; $i++
) {
187 $code = $raw->getCode();
189 for($j=0; $j<8; $j++
) {
190 $addr = $filler->next();
191 $filler->setFrameAt($addr, 0x02 |
(($bit & $code) != 0));
196 QRtools
::markTime('after_filler');
201 $j = QRspec
::getRemainder($version);
202 for($i=0; $i<$j; $i++
) {
203 $addr = $filler->next();
204 $filler->setFrameAt($addr, 0x02);
207 $frame = $filler->frame
;
212 $maskObj = new QRmask();
215 if (QR_FIND_BEST_MASK
) {
216 $masked = $maskObj->mask($width, $frame, $input->getErrorCorrectionLevel());
218 $masked = $maskObj->makeMask($width, $frame, (intval(QR_DEFAULT_MASK
) %
8), $input->getErrorCorrectionLevel());
221 $masked = $maskObj->makeMask($width, $frame, $mask, $input->getErrorCorrectionLevel());
224 if($masked == NULL) {
228 QRtools
::markTime('after_mask');
230 $this->version
= $version;
231 $this->width
= $width;
232 $this->data
= $masked;
237 //----------------------------------------------------------------------
238 public function encodeInput(QRinput
$input)
240 return $this->encodeMask($input, -1);
243 //----------------------------------------------------------------------
244 public function encodeString8bit($string, $version, $level)
247 throw new Exception('empty string!');
251 $input = new QRinput($version, $level);
252 if($input == NULL) return NULL;
254 $ret = $input->append($input, QR_MODE_8
, strlen($string), str_split($string));
259 return $this->encodeInput($input);
262 //----------------------------------------------------------------------
263 public function encodeString($string, $version, $level, $hint, $casesensitive)
266 if($hint != QR_MODE_8
&& $hint != QR_MODE_KANJI
) {
267 throw new Exception('bad hint');
271 $input = new QRinput($version, $level);
272 if($input == NULL) return NULL;
274 $ret = QRsplit
::splitStringToQRinput($string, $input, $hint, $casesensitive);
279 return $this->encodeInput($input);
282 //----------------------------------------------------------------------
283 public static function png($text, $outfile = false, $level = QR_ECLEVEL_L
, $size = 3, $margin = 4, $saveandprint=false)
285 $enc = QRencode
::factory($level, $size, $margin);
286 return $enc->encodePNG($text, $outfile, $saveandprint=false);
289 //----------------------------------------------------------------------
290 public static function text($text, $outfile = false, $level = QR_ECLEVEL_L
, $size = 3, $margin = 4)
292 $enc = QRencode
::factory($level, $size, $margin);
293 return $enc->encode($text, $outfile);
296 //----------------------------------------------------------------------
297 public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L
, $size = 3, $margin = 4)
299 $enc = QRencode
::factory($level, $size, $margin);
300 return $enc->encodeRAW($text, $outfile);
304 //##########################################################################
315 //----------------------------------------------------------------------
316 public function __construct($width, &$frame)
318 $this->width
= $width;
319 $this->frame
= $frame;
320 $this->x
= $width - 1;
321 $this->y
= $width - 1;
326 //----------------------------------------------------------------------
327 public function setFrameAt($at, $val)
329 $this->frame
[$at['y']][$at['x']] = chr($val);
332 //----------------------------------------------------------------------
333 public function getFrameAt($at)
335 return ord($this->frame
[$at['y']][$at['x']]);
338 //----------------------------------------------------------------------
339 public function next()
343 if($this->bit
== -1) {
345 return array('x'=>$this->x
, 'y'=>$this->y
);
352 if($this->bit
== 0) {
382 if($x < 0 ||
$y < 0) return null;
387 } while(ord($this->frame
[$y][$x]) & 0x80);
389 return array('x'=>$x, 'y'=>$y);
394 //##########################################################################
398 public $casesensitive = true;
399 public $eightbit = false;
405 public $structured = 0; // not supported yet
407 public $level = QR_ECLEVEL_L
;
408 public $hint = QR_MODE_8
;
410 //----------------------------------------------------------------------
411 public static function factory($level = QR_ECLEVEL_L
, $size = 3, $margin = 4)
413 $enc = new QRencode();
415 $enc->margin
= $margin;
422 $enc->level
= $level;
426 $enc->level
= QR_ECLEVEL_L
;
430 $enc->level
= QR_ECLEVEL_M
;
434 $enc->level
= QR_ECLEVEL_Q
;
438 $enc->level
= QR_ECLEVEL_H
;
445 //----------------------------------------------------------------------
446 public function encodeRAW($intext, $outfile = false)
448 $code = new QRcode();
450 if($this->eightbit
) {
451 $code->encodeString8bit($intext, $this->version
, $this->level
);
453 $code->encodeString($intext, $this->version
, $this->level
, $this->hint
, $this->casesensitive
);
459 //----------------------------------------------------------------------
460 public function encode($intext, $outfile = false)
462 $code = new QRcode();
464 if($this->eightbit
) {
465 $code->encodeString8bit($intext, $this->version
, $this->level
);
467 $code->encodeString($intext, $this->version
, $this->level
, $this->hint
, $this->casesensitive
);
470 QRtools
::markTime('after_encode');
472 if ($outfile!== false) {
473 file_put_contents($outfile, join("\n", QRtools
::binarize($code->data
)));
475 return QRtools
::binarize($code->data
);
479 //----------------------------------------------------------------------
480 public function encodePNG($intext, $outfile = false,$saveandprint=false)
485 $tab = $this->encode($intext);
486 $err = ob_get_contents();
490 QRtools
::log($outfile, $err);
492 $maxSize = (int)(QR_PNG_MAXIMUM_SIZE
/ (count($tab)+
2*$this->margin
));
494 QRimage
::png($tab, $outfile, min(max(1, $this->size
), $maxSize), $this->margin
,$saveandprint);
496 } catch (Exception
$e) {
498 QRtools
::log($outfile, $e->getMessage());