Вход Регистрация
Файл: PROFIWM.COM/modules/servis/qr/qrencode.php
Строк: 359
<?php
/*
 * PHP QR Code encoder
 *
 * Main encoder classes.
 *
 * Based on libqrencode C library distributed under LGPL 2.1
 * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
 *
 * PHP QR Code is distributed under LGPL 3
 * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 */
 
    
class QRrsblock {
        public 
$dataLength;
        public 
$data = array();
        public 
$eccLength;
        public 
$ecc = array();
        
        public function 
__construct($dl, $data, $el, &$ecc, QRrsItem $rs)
        {
            
$rs->encode_rs_char($data, $ecc);
        
            
$this->dataLength = $dl;
            
$this->data = $data;
            
$this->eccLength = $el;
            
$this->ecc = $ecc;
        }
    };
    
    
//##########################################################################

    
class QRrawcode {
        public 
$version;
        public 
$datacode = array();
        public 
$ecccode = array();
        public 
$blocks;
        public 
$rsblocks = array(); //of RSblock
        
public $count;
        public 
$dataLength;
        public 
$eccLength;
        public 
$b1;
        
        
//----------------------------------------------------------------------
        
public function __construct(QRinput $input)
        {
            
$spec = array(0,0,0,0,0);
            
            
$this->datacode = $input->getByteStream();
            if(
is_null($this->datacode)) {
                throw new 
Exception('null imput string');
            }

            
QRspec::getEccSpec($input->getVersion(), $input->getErrorCorrectionLevel(), $spec);

            
$this->version = $input->getVersion();
            
$this->b1 = QRspec::rsBlockNum1($spec);
            
$this->dataLength = QRspec::rsDataLength($spec);
            
$this->eccLength = QRspec::rsEccLength($spec);
            
$this->ecccode = array_fill(0, $this->eccLength, 0);
            
$this->blocks = QRspec::rsBlockNum($spec);
            
            
$ret = $this->init($spec);
            if(
$ret < 0) {
                throw new 
Exception('block alloc error');
                return 
null;
            }

            
$this->count = 0;
        }
        
        
//----------------------------------------------------------------------
        
public function init(array $spec)
        {
            
$dl = QRspec::rsDataCodes1($spec);
            
$el = QRspec::rsEccCodes1($spec);
            
$rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
            

            
$blockNo = 0;
            
$dataPos = 0;
            
$eccPos = 0;
            for(
$i=0; $i<QRspec::rsBlockNum1($spec); $i++) {
                
$ecc = array_slice($this->ecccode,$eccPos);
                
$this->rsblocks[$blockNo] = new 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(
QRspec::rsBlockNum2($spec) == 0)
                return 
0;

            
$dl = QRspec::rsDataCodes2($spec);
            
$el = QRspec::rsEccCodes2($spec);
            
$rs = QRrs::init_rs(8, 0x11d, 0, 1, $el, 255 - $dl - $el);
            
            if(
$rs == NULL) return -1;
            
            for(
$i=0; $i<QRspec::rsBlockNum2($spec); $i++) {
                
$ecc = array_slice($this->ecccode,$eccPos);
                
$this->rsblocks[$blockNo] = new 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;
        }
        
        
//----------------------------------------------------------------------
        
public function getCode()
        {
            
$ret;

            if(
$this->count < $this->dataLength) {
                
$row = $this->count % $this->blocks;
                
$col = $this->count / $this->blocks;
                if(
$col >= $this->rsblocks[0]->dataLength) {
                    
$row += $this->b1;
                }
                
$ret = $this->rsblocks[$row]->data[$col];
            } else if(
$this->count < $this->dataLength + $this->eccLength) {
                
$row = ($this->count - $this->dataLength) % $this->blocks;
                
$col = ($this->count - $this->dataLength) / $this->blocks;
                
$ret = $this->rsblocks[$row]->ecc[$col];
            } else {
                return 
0;
            }
            
$this->count++;
            
            return 
$ret;
        }
    }

    
//##########################################################################
    
    
class QRcode {
    
        public 
$version;
        public 
$width;
        public 
$data; 
        
        
//----------------------------------------------------------------------
        
public function encodeMask(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 QRrawcode($input);
            
            
QRtools::markTime('after_raw');
            
            
$version = $raw->version;
            
$width = QRspec::getWidth($version);
            
$frame = QRspec::newFrame($version);
            
            
$filler = new 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, 0x02 | (($bit & $code) != 0));
                    
$bit = $bit >> 1;
                }
            }
            
            
QRtools::markTime('after_filler');
            
            unset(
$raw);
            
            
// remainder bits
            
$j = QRspec::getRemainder($version);
            for(
$i=0; $i<$j; $i++) {
                
$addr = $filler->next();
                
$filler->setFrameAt($addr, 0x02);
            }
            
            
$frame = $filler->frame;
            unset(
$filler);
            
            
            
// masking
            
$maskObj = new 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;
            }
            
            
QRtools::markTime('after_mask');
            
            
$this->version = $version;
            
$this->width = $width;
            
$this->data = $masked;
            
            return 
$this;
        }
    
        
//----------------------------------------------------------------------
        
public function encodeInput(QRinput $input)
        {
            return 
$this->encodeMask($input, -1);
        }
        
        
//----------------------------------------------------------------------
        
public function encodeString8bit($string, $version, $level)
        {
            if(
string == NULL) {
                throw new 
Exception('empty string!');
                return 
NULL;
            }

            
$input = new QRinput($version, $level);
            if(
$input == NULL) return NULL;

            
$ret = $input->append($input, QR_MODE_8, strlen($string), str_split($string));
            if(
$ret < 0) {
                unset(
$input);
                return 
NULL;
            }
            return 
$this->encodeInput($input);
        }

        
//----------------------------------------------------------------------
        
public function encodeString($string, $version, $level, $hint, $casesensitive)
        {

            if(
$hint != QR_MODE_8 && $hint != QR_MODE_KANJI) {
                throw new 
Exception('bad hint');
                return 
NULL;
            }

            
$input = new QRinput($version, $level);
            if(
$input == NULL) return NULL;

            
$ret = QRsplit::splitStringToQRinput($string, $input, $hint, $casesensitive);
            if(
$ret < 0) {
                return 
NULL;
            }

            return 
$this->encodeInput($input);
        }
        
        
//----------------------------------------------------------------------
        
public static function png($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4, $saveandprint=false) 
        {
            
$enc = QRencode::factory($level, $size, $margin);
            return 
$enc->encodePNG($text, $outfile, $saveandprint=false);
        }

        
//----------------------------------------------------------------------
        
public static function text($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) 
        {
            
$enc = QRencode::factory($level, $size, $margin);
            return 
$enc->encode($text, $outfile);
        }

        
//----------------------------------------------------------------------
        
public static function raw($text, $outfile = false, $level = QR_ECLEVEL_L, $size = 3, $margin = 4) 
        {
            
$enc = QRencode::factory($level, $size, $margin);
            return 
$enc->encodeRAW($text, $outfile);
        }
    }
    
    
//##########################################################################
    
    
class FrameFiller {
    
        public 
$width;
        public 
$frame;
        public 
$x;
        public 
$y;
        public 
$dir;
        public 
$bit;
        
        
//----------------------------------------------------------------------
        
public function __construct($width, &$frame)
        {
            
$this->width = $width;
            
$this->frame = $frame;
            
$this->x = $width - 1;
            
$this->y = $width - 1;
            
$this->dir = -1;
            
$this->bit = -1;
        }
        
        
//----------------------------------------------------------------------
        
public function setFrameAt($at, $val)
        {
            
$this->frame[$at['y']][$at['x']] = chr($val);
        }
        
        
//----------------------------------------------------------------------
        
public function getFrameAt($at)
        {
            return 
ord($this->frame[$at['y']][$at['x']]);
        }
        
        
//----------------------------------------------------------------------
        
public function next()
        {
            do {
            
                if(
$this->bit == -1) {
                    
$this->bit = 0;
                    return array(
'x'=>$this->x, 'y'=>$this->y);
                }

                
$x = $this->x;
                
$y = $this->y;
                
$w = $this->width;

                if(
$this->bit == 0) {
                    
$x--;
                    
$this->bit++;
                } else {
                    
$x++;
                    
$y += $this->dir;
                    
$this->bit--;
                }

                if(
$this->dir < 0) {
                    if(
$y < 0) {
                        
$y = 0;
                        
$x -= 2;
                        
$this->dir = 1;
                        if(
$x == 6) {
                            
$x--;
                            
$y = 9;
                        }
                    }
                } else {
                    if(
$y == $w) {
                        
$y = $w - 1;
                        
$x -= 2;
                        
$this->dir = -1;
                        if(
$x == 6) {
                            
$x--;
                            
$y -= 8;
                        }
                    }
                }
                if(
$x < 0 || $y < 0) return null;

                
$this->x = $x;
                
$this->y = $y;

            } while(
ord($this->frame[$y][$x]) & 0x80);
                        
            return array(
'x'=>$x, 'y'=>$y);
        }
        
    } ;
    
    
//##########################################################################    
    
    
class QRencode {
    
        public 
$casesensitive = true;
        public 
$eightbit = false;
        
        public 
$version = 0;
        public 
$size = 3;
        public 
$margin = 4;
        
        public 
$structured = 0; // not supported yet
        
        
public $level = QR_ECLEVEL_L;
        public 
$hint = QR_MODE_8;
        
        
//----------------------------------------------------------------------
        
public static function factory($level = QR_ECLEVEL_L, $size = 3, $margin = 4)
        {
            
$enc = new QRencode();
            
$enc->size = $size;
            
$enc->margin = $margin;
            
            switch (
$level.'') {
                case 
'0':
                case 
'1':
                case 
'2':
                case 
'3':
                        
$enc->level = $level;
                    break;
                case 
'l':
                case 
'L':
                        
$enc->level = QR_ECLEVEL_L;
                    break;
                case 
'm':
                case 
'M':
                        
$enc->level = QR_ECLEVEL_M;
                    break;
                case 
'q':
                case 
'Q':
                        
$enc->level = QR_ECLEVEL_Q;
                    break;
                case 
'h':
                case 
'H':
                        
$enc->level = QR_ECLEVEL_H;
                    break;
            }
            
            return 
$enc;
        }
        
        
//----------------------------------------------------------------------
        
public function encodeRAW($intext, $outfile = false) 
        {
            
$code = new QRcode();

            if(
$this->eightbit) {
                
$code->encodeString8bit($intext, $this->version, $this->level);
            } else {
                
$code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
            }
            
            return 
$code->data;
        }

        
//----------------------------------------------------------------------
        
public function encode($intext, $outfile = false) 
        {
            
$code = new QRcode();

            if(
$this->eightbit) {
                
$code->encodeString8bit($intext, $this->version, $this->level);
            } else {
                
$code->encodeString($intext, $this->version, $this->level, $this->hint, $this->casesensitive);
            }
            
            
QRtools::markTime('after_encode');
            
            if (
$outfile!== false) {
                
file_put_contents($outfile, join("n", QRtools::binarize($code->data)));
            } else {
                return 
QRtools::binarize($code->data);
            }
        }
        
        
//----------------------------------------------------------------------
        
public function encodePNG($intext, $outfile = false,$saveandprint=false) 
        {
            try {
            
                
ob_start();
                
$tab = $this->encode($intext);
                
$err = ob_get_contents();
                
ob_end_clean();
                
                if (
$err != '')
                    
QRtools::log($outfile, $err);
                
                
$maxSize = (int)(QR_PNG_MAXIMUM_SIZE / (count($tab)+2*$this->margin));
                
                
QRimage::png($tab, $outfile, min(max(1, $this->size), $maxSize), $this->margin,$saveandprint);
            
            } catch (
Exception $e) {
            
                
QRtools::log($outfile, $e->getMessage());
            
            }
        }
    }
Онлайн: 4
Реклама