459 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			PHP
		
	
	
		
		
			
		
	
	
			459 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			PHP
		
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace Zxing\Common;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								final class BitMatrix
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    private $width;
							 | 
						||
| 
								 | 
							
								    private $height;
							 | 
						||
| 
								 | 
							
								    private $rowSize;
							 | 
						||
| 
								 | 
							
								    private $bits;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function __construct($width, $height = false, $rowSize = false, $bits = false)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!$height) {
							 | 
						||
| 
								 | 
							
								            $height = $width;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (!$rowSize) {
							 | 
						||
| 
								 | 
							
								            $rowSize = (int)(($width + 31) / 32);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (!$bits) {
							 | 
						||
| 
								 | 
							
								            $bits = fill_array(0, $rowSize * $height, 0);
							 | 
						||
| 
								 | 
							
								//            [];//new int[rowSize * height];
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $this->width   = $width;
							 | 
						||
| 
								 | 
							
								        $this->height  = $height;
							 | 
						||
| 
								 | 
							
								        $this->rowSize = $rowSize;
							 | 
						||
| 
								 | 
							
								        $this->bits    = $bits;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public static function parse($stringRepresentation, $setString, $unsetString)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!$stringRepresentation) {
							 | 
						||
| 
								 | 
							
								            throw new \InvalidArgumentException();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $bits        = [];
							 | 
						||
| 
								 | 
							
								        $bitsPos     = 0;
							 | 
						||
| 
								 | 
							
								        $rowStartPos = 0;
							 | 
						||
| 
								 | 
							
								        $rowLength   = -1;
							 | 
						||
| 
								 | 
							
								        $nRows       = 0;
							 | 
						||
| 
								 | 
							
								        $pos         = 0;
							 | 
						||
| 
								 | 
							
								        while ($pos < strlen($stringRepresentation)) {
							 | 
						||
| 
								 | 
							
								            if ($stringRepresentation[$pos] == '\n' ||
							 | 
						||
| 
								 | 
							
								                $stringRepresentation->{$pos} == '\r') {
							 | 
						||
| 
								 | 
							
								                if ($bitsPos > $rowStartPos) {
							 | 
						||
| 
								 | 
							
								                    if ($rowLength == -1) {
							 | 
						||
| 
								 | 
							
								                        $rowLength = $bitsPos - $rowStartPos;
							 | 
						||
| 
								 | 
							
								                    } else if ($bitsPos - $rowStartPos != $rowLength) {
							 | 
						||
| 
								 | 
							
								                        throw new \InvalidArgumentException("row lengths do not match");
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    $rowStartPos = $bitsPos;
							 | 
						||
| 
								 | 
							
								                    $nRows++;
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								                $pos++;
							 | 
						||
| 
								 | 
							
								            } else if (substr($stringRepresentation, $pos, strlen($setString)) == $setString) {
							 | 
						||
| 
								 | 
							
								                $pos            += strlen($setString);
							 | 
						||
| 
								 | 
							
								                $bits[$bitsPos] = true;
							 | 
						||
| 
								 | 
							
								                $bitsPos++;
							 | 
						||
| 
								 | 
							
								            } else if (substr($stringRepresentation, $pos + strlen($unsetString)) == $unsetString) {
							 | 
						||
| 
								 | 
							
								                $pos            += strlen($unsetString);
							 | 
						||
| 
								 | 
							
								                $bits[$bitsPos] = false;
							 | 
						||
| 
								 | 
							
								                $bitsPos++;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                throw new \InvalidArgumentException(
							 | 
						||
| 
								 | 
							
								                    "illegal character encountered: " . substr($stringRepresentation, $pos));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // no EOL at end?
							 | 
						||
| 
								 | 
							
								        if ($bitsPos > $rowStartPos) {
							 | 
						||
| 
								 | 
							
								            if ($rowLength == -1) {
							 | 
						||
| 
								 | 
							
								                $rowLength = $bitsPos - $rowStartPos;
							 | 
						||
| 
								 | 
							
								            } else if ($bitsPos - $rowStartPos != $rowLength) {
							 | 
						||
| 
								 | 
							
								                throw new \InvalidArgumentException("row lengths do not match");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            $nRows++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $matrix = new BitMatrix($rowLength, $nRows);
							 | 
						||
| 
								 | 
							
								        for ($i = 0; $i < $bitsPos; $i++) {
							 | 
						||
| 
								 | 
							
								            if ($bits[$i]) {
							 | 
						||
| 
								 | 
							
								                $matrix->set($i % $rowLength, $i / $rowLength);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $matrix;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * <p>Sets the given bit to true.</p>
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param $x ;  The horizontal component (i.e. which column)
							 | 
						||
| 
								 | 
							
								     * @param $y ;   The vertical component (i.e. which row)
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function set($x, $y)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $offset = (int)($y * $this->rowSize + ($x / 32));
							 | 
						||
| 
								 | 
							
								        if (!isset($this->bits[$offset])) {
							 | 
						||
| 
								 | 
							
								            $this->bits[$offset] = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        //$this->bits[$offset] = $this->bits[$offset];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //  if($this->bits[$offset]>200748364){
							 | 
						||
| 
								 | 
							
								        //$this->bits= array(0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-16777216,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-1090519040,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,1056964608,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,-1358954496,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,117440512,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,50331648,-1,-1,-1,-1,65535,0,0,0,0,0,0,0,33554432,-1,-1,536870911,-4096,65279,0,0,0,0,0,0,0,0,-1,-1,65535,-4096,65535,0,0,0,0,0,0,0,0,-193,536870911,0,-4096,65279,0,0,0,0,0,0,0,0,-254,32767,0,-4096,61951,0,0,0,0,0,0,0,0,20913920,0,0,-4096,50175,0,0,0,0,0,0,0,0,0,0,0,-4096,60159,0,0,0,0,0,0,0,0,0,0,0,-4096,64255,0,0,0,0,0,0,0,0,0,0,0,-8192,56319,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,0,0,0,0,-4096,16777215,0,0,0,0,0,0,0,251658240,0,0,0,-4096,-1,255,0,256,0,0,0,0,117440512,0,0,0,-4096,-1,255,0,512,0,0,0,0,117440512,0,0,0,-4096,-1,255,0,1024,0,0,0,0,117440512,0,0,0,-4096,-1,223,0,256,0,0,0,0,117440512,0,0,33030144,-4096,-1,191,0,256,0,0,0,0,117440512,0,0,33554428,-4096,-1,255,0,768,0,0,0,0,117440512,0,402849792,67108862,-8192,-1,255,0,768,0,0,0,0,117440512,0,470278396,63045630,-8192,-1,255,0,256,0,0,0,0,251658240,-8388608,470278399,58720286,-8192,-1,2686975,0,3842,0,0,0,0,251658240,-131072,1007149567,58720286,-8192,-1,2031615,0,3879,0,0,0,0,251658240,536739840,1007092192,58720286,-8192,-1,851967,0,3840,0,0,0,0,251658240,917504,1007092192,58720284,-8192,-1,2031615,0,3968,0,0,0,0,251658240,917504,1007092160,59244060,-8192,-1,65535,0,7936,0,0,0,0,251658240,917504,1009779136,59244060,-8192,-1,9371647,0,1792,0,0,0,0,251658240,917504,946921920,59244060,-8192,-1,8585215,0,1792,0,0,0,0,117440512,-15859712,477159875,59244060,-8192,-1,65535,0,12032,0,0,0,0,251658240,-15859712,52490691,59244060,-8192,-1,-1,0,65408,0,0,0,0,251658240,-15859712,58778051,59244060,-8192,-1,-1,0,65473,0,0,0,0,251658240,-15859712,125886915,59244060,-8192,-1,-1,0,65472,0,0,0,0,251658240,-15859712,58778051,59244060,-8192,-1,-1,0,65408,0,0,0,0,251658240,-15859712,8380867,59244060,-8192,-1,-1,0,65473,0,0,0,0,251658240,-15859712,8380867,59244060,-8192,-1,-1,0,131011,0,0,0,0,251658240,-15859712,8380867,58720284,-8192,-1,-1,0,130947,0,0,0,0,251658240,-15859712,2089411,58720284,-8192,-1,-1,0,130947,0,0,0,0,251658240,-32636928,449,58720284,-8192,-1,-1,33554431,131015,0,0,0,0,251658240,786432,448,62914588,-8192,-1,-1,16777215,131015,0,0,0,0,251658240,786432,448,67108860,-8192,-1,-1,553648127,131015,0,0,0,0,251658240,786432,946864576,67108860,-8192,-1,-1,32505855,131015,0,0,0,0,251658240,786432,946921976,8388604,-8192,-1,-1,8191999,131015,0,0,0,0,251658240,-262144,946921983,248,-8192,-1,-1,8126463,196551,0,0,0,0,251658240,-262144,7397887,0,-8192,-1,-1,16777215,262087,0,0,0,0,251658240,-262144,8257543,0,-8192,-1,-1,-2121269249,262095,0,0,0,0,520093696,0,8257536,0,-8192,-1,-1,-201326593,262095,0,0,0,0,520290304,0,8257536,117963776,-8192,-1,-1,-201326593,262095,0,0,0,0,520093696,0,-2140143616,118488579,-8192,-1,-1,-201326593,131023,0,0,0,0,520093696,0,-2131697280,118488579,-8192,-1,-1,-503316481,131023,0,0,0,0,520093696,2145386496,-2131631232,118484995,-16384,-1,-1,-469762049,262095,0,0,0,0,520093696,2147221504,552649600,118481344,-16384,-1,-1,-469762049,131023,0,0,0,0,520290304,2147221504,2029002240,118481344,-16384,-1,-1,-469762049,262031,0,0,0,0,520290304,-266600448,2029001791,125952960,-16384,-1,-1,-469762049,262031,0,0,0,0,1057423360,-266600448,2027953215,133177312,-16384,-1,-1,-134217729,262111,0,0,0,0,1058471936,-266600448,-119531393,133177343,-16384,-1,-1,-134217729,262111,0,0,0
							 | 
						||
| 
								 | 
							
								        $bob                 = $this->bits[$offset];
							 | 
						||
| 
								 | 
							
								        $bob                 |= 1 << ($x & 0x1f);
							 | 
						||
| 
								 | 
							
								        $this->bits[$offset] |= ($bob);
							 | 
						||
| 
								 | 
							
								        //$this->bits[$offset] = intval32bits($this->bits[$offset]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        //}
							 | 
						||
| 
								 | 
							
								//16777216
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function _unset($x, $y)
							 | 
						||
| 
								 | 
							
								    {//было unset, php не позволяет использовать unset
							 | 
						||
| 
								 | 
							
								        $offset              = (int)($y * $this->rowSize + ($x / 32));
							 | 
						||
| 
								 | 
							
								        $this->bits[$offset] &= ~(1 << ($x & 0x1f));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**1 << (249 & 0x1f)
							 | 
						||
| 
								 | 
							
								     * <p>Flips the given bit.</p>
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param $x ;  The horizontal component (i.e. which column)
							 | 
						||
| 
								 | 
							
								     * @param $y ;  The vertical component (i.e. which row)
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function flip($x, $y)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $offset = $y * $this->rowSize + (int)($x / 32);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $this->bits[$offset] = ($this->bits[$offset] ^ (1 << ($x & 0x1f)));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Exclusive-or (XOR): Flip the bit in this {@code BitMatrix} if the corresponding
							 | 
						||
| 
								 | 
							
								     * mask bit is set.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param $mask ;  XOR mask
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function _xor($mask)
							 | 
						||
| 
								 | 
							
								    {//было xor, php не позволяет использовать xor
							 | 
						||
| 
								 | 
							
								        if ($this->width != $mask->getWidth() || $this->height != $mask->getHeight()
							 | 
						||
| 
								 | 
							
								            || $this->rowSize != $mask->getRowSize()) {
							 | 
						||
| 
								 | 
							
								            throw new \InvalidArgumentException("input matrix dimensions do not match");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $rowArray = new BitArray($this->width / 32 + 1);
							 | 
						||
| 
								 | 
							
								        for ($y = 0; $y < $this->height; $y++) {
							 | 
						||
| 
								 | 
							
								            $offset = $y * $this->rowSize;
							 | 
						||
| 
								 | 
							
								            $row    = $mask->getRow($y, $rowArray)->getBitArray();
							 | 
						||
| 
								 | 
							
								            for ($x = 0; $x < $this->rowSize; $x++) {
							 | 
						||
| 
								 | 
							
								                $this->bits[$offset + $x] ^= $row[$x];
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Clears all bits (sets to false).
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function clear()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $max = count($this->bits);
							 | 
						||
| 
								 | 
							
								        for ($i = 0; $i < $max; $i++) {
							 | 
						||
| 
								 | 
							
								            $this->bits[$i] = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * <p>Sets a square region of the bit matrix to true.</p>
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param $left   ;  The horizontal position to begin at (inclusive)
							 | 
						||
| 
								 | 
							
								     * @param $top    ;  The vertical position to begin at (inclusive)
							 | 
						||
| 
								 | 
							
								     * @param $width  ;  The width of the region
							 | 
						||
| 
								 | 
							
								     * @param $height ;  The height of the region
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function setRegion($left, $top, $width, $height)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($top < 0 || $left < 0) {
							 | 
						||
| 
								 | 
							
								            throw new \InvalidArgumentException("Left and top must be nonnegative");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if ($height < 1 || $width < 1) {
							 | 
						||
| 
								 | 
							
								            throw new \InvalidArgumentException("Height and width must be at least 1");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $right  = $left + $width;
							 | 
						||
| 
								 | 
							
								        $bottom = $top + $height;
							 | 
						||
| 
								 | 
							
								        if ($bottom > $this->height || $right > $this->width) { //> this.height || right > this.width
							 | 
						||
| 
								 | 
							
								            throw new \InvalidArgumentException("The region must fit inside the matrix");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        for ($y = $top; $y < $bottom; $y++) {
							 | 
						||
| 
								 | 
							
								            $offset = $y * $this->rowSize;
							 | 
						||
| 
								 | 
							
								            for ($x = $left; $x < $right; $x++) {
							 | 
						||
| 
								 | 
							
								                $this->bits[$offset + (int)($x / 32)] = ($this->bits[$offset + (int)($x / 32)] |= 1 << ($x & 0x1f));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Modifies this {@code BitMatrix} to represent the same but rotated 180 degrees
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function rotate180()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $width     = $this->getWidth();
							 | 
						||
| 
								 | 
							
								        $height    = $this->getHeight();
							 | 
						||
| 
								 | 
							
								        $topRow    = new BitArray($width);
							 | 
						||
| 
								 | 
							
								        $bottomRow = new BitArray($width);
							 | 
						||
| 
								 | 
							
								        for ($i = 0; $i < ($height + 1) / 2; $i++) {
							 | 
						||
| 
								 | 
							
								            $topRow    = $this->getRow($i, $topRow);
							 | 
						||
| 
								 | 
							
								            $bottomRow = $this->getRow($height - 1 - $i, $bottomRow);
							 | 
						||
| 
								 | 
							
								            $topRow->reverse();
							 | 
						||
| 
								 | 
							
								            $bottomRow->reverse();
							 | 
						||
| 
								 | 
							
								            $this->setRow($i, $bottomRow);
							 | 
						||
| 
								 | 
							
								            $this->setRow($height - 1 - $i, $topRow);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @return The width of the matrix
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getWidth()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->width;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * A fast method to retrieve one row of data from the matrix as a BitArray.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param $y   ;  The row to retrieve
							 | 
						||
| 
								 | 
							
								     * @param $row ;  An optional caller-allocated BitArray, will be allocated if null or too small
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return The resulting BitArray - this reference should always be used even when passing
							 | 
						||
| 
								 | 
							
								     *         your own row
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getRow($y, $row)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($row == null || $row->getSize() < $this->width) {
							 | 
						||
| 
								 | 
							
								            $row = new BitArray($this->width);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $row->clear();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $offset = $y * $this->rowSize;
							 | 
						||
| 
								 | 
							
								        for ($x = 0; $x < $this->rowSize; $x++) {
							 | 
						||
| 
								 | 
							
								            $row->setBulk($x * 32, $this->bits[$offset + $x]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $row;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @param $y   ;  row to set
							 | 
						||
| 
								 | 
							
								     * @param $row ;  {@link BitArray} to copy from
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function setRow($y, $row)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->bits = arraycopy($row->getBitArray(), 0, $this->bits, $y * $this->rowSize, $this->rowSize);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * This is useful in detecting the enclosing rectangle of a 'pure' barcode.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return {@code left,top,width,height} enclosing rectangle of all 1 bits, or null if it is all white
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getEnclosingRectangle()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $left   = $this->width;
							 | 
						||
| 
								 | 
							
								        $top    = $this->height;
							 | 
						||
| 
								 | 
							
								        $right  = -1;
							 | 
						||
| 
								 | 
							
								        $bottom = -1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for ($y = 0; $y < $this->height; $y++) {
							 | 
						||
| 
								 | 
							
								            for ($x32 = 0; $x32 < $this->rowSize; $x32++) {
							 | 
						||
| 
								 | 
							
								                $theBits = $this->bits[$y * $this->rowSize + $x32];
							 | 
						||
| 
								 | 
							
								                if ($theBits != 0) {
							 | 
						||
| 
								 | 
							
								                    if ($y < $top) {
							 | 
						||
| 
								 | 
							
								                        $top = $y;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    if ($y > $bottom) {
							 | 
						||
| 
								 | 
							
								                        $bottom = $y;
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    if ($x32 * 32 < $left) {
							 | 
						||
| 
								 | 
							
								                        $bit = 0;
							 | 
						||
| 
								 | 
							
								                        while (($theBits << (31 - $bit)) == 0) {
							 | 
						||
| 
								 | 
							
								                            $bit++;
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                        if (($x32 * 32 + $bit) < $left) {
							 | 
						||
| 
								 | 
							
								                            $left = $x32 * 32 + $bit;
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                    if ($x32 * 32 + 31 > $right) {
							 | 
						||
| 
								 | 
							
								                        $bit = 31;
							 | 
						||
| 
								 | 
							
								                        while ((sdvig3($theBits, $bit)) == 0) {//>>>
							 | 
						||
| 
								 | 
							
								                            $bit--;
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                        if (($x32 * 32 + $bit) > $right) {
							 | 
						||
| 
								 | 
							
								                            $right = $x32 * 32 + $bit;
							 | 
						||
| 
								 | 
							
								                        }
							 | 
						||
| 
								 | 
							
								                    }
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $width  = $right - $left;
							 | 
						||
| 
								 | 
							
								        $height = $bottom - $top;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($width < 0 || $height < 0) {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return [$left, $top, $width, $height];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * This is useful in detecting a corner of a 'pure' barcode.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return {@code x,y} coordinate of top-left-most 1 bit, or null if it is all white
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getTopLeftOnBit()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $bitsOffset = 0;
							 | 
						||
| 
								 | 
							
								        while ($bitsOffset < count($this->bits) && $this->bits[$bitsOffset] == 0) {
							 | 
						||
| 
								 | 
							
								            $bitsOffset++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if ($bitsOffset == count($this->bits)) {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $y = $bitsOffset / $this->rowSize;
							 | 
						||
| 
								 | 
							
								        $x = ($bitsOffset % $this->rowSize) * 32;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $theBits = $this->bits[$bitsOffset];
							 | 
						||
| 
								 | 
							
								        $bit     = 0;
							 | 
						||
| 
								 | 
							
								        while (($theBits << (31 - $bit)) == 0) {
							 | 
						||
| 
								 | 
							
								            $bit++;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $x += $bit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return [$x, $y];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function getBottomRightOnBit()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $bitsOffset = count($this->bits) - 1;
							 | 
						||
| 
								 | 
							
								        while ($bitsOffset >= 0 && $this->bits[$bitsOffset] == 0) {
							 | 
						||
| 
								 | 
							
								            $bitsOffset--;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if ($bitsOffset < 0) {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $y = $bitsOffset / $this->rowSize;
							 | 
						||
| 
								 | 
							
								        $x = ($bitsOffset % $this->rowSize) * 32;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $theBits = $this->bits[$bitsOffset];
							 | 
						||
| 
								 | 
							
								        $bit     = 31;
							 | 
						||
| 
								 | 
							
								        while ((sdvig3($theBits, $bit)) == 0) {//>>>
							 | 
						||
| 
								 | 
							
								            $bit--;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $x += $bit;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return [$x, $y];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @return The height of the matrix
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getHeight()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->height;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @return The row size of the matrix
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function getRowSize()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->rowSize;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function equals($o)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!($o instanceof BitMatrix)) {
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $other = $o;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $this->width == $other->width
							 | 
						||
| 
								 | 
							
								            && $this->height == $other->height
							 | 
						||
| 
								 | 
							
								            && $this->rowSize == $other->rowSize
							 | 
						||
| 
								 | 
							
								            && $this->bits === $other->bits;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    //@Override
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function hashCode()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $hash = $this->width;
							 | 
						||
| 
								 | 
							
								        $hash = 31 * $hash + $this->width;
							 | 
						||
| 
								 | 
							
								        $hash = 31 * $hash + $this->height;
							 | 
						||
| 
								 | 
							
								        $hash = 31 * $hash + $this->rowSize;
							 | 
						||
| 
								 | 
							
								        $hash = 31 * $hash + hashCode($this->bits);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $hash;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    //@Override
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function toString($setString = '', $unsetString = '', $lineSeparator = '')
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!$setString || !$unsetString) {
							 | 
						||
| 
								 | 
							
								            return (string)'X ' . '  ';
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if ($lineSeparator && $lineSeparator !== "\n") {
							 | 
						||
| 
								 | 
							
								            return $this->toString_($setString, $unsetString, $lineSeparator);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return (string)($setString . $unsetString . "\n");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function toString_($setString, $unsetString, $lineSeparator)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        //$result = new StringBuilder(height * (width + 1));
							 | 
						||
| 
								 | 
							
								        $result = '';
							 | 
						||
| 
								 | 
							
								        for ($y = 0; $y < $this->height; $y++) {
							 | 
						||
| 
								 | 
							
								            for ($x = 0; $x < $this->width; $x++) {
							 | 
						||
| 
								 | 
							
								                $result .= ($this->get($x, $y) ? $setString : $unsetString);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            $result .= ($lineSeparator);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return (string)$result;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @deprecated call {@link #toString(String,String)} only, which uses \n line separator always
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    // @Deprecated
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * <p>Gets the requested bit, where true means black.</p>
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param $x ;  The horizontal component (i.e. which column)
							 | 
						||
| 
								 | 
							
								     * @param $y ;  The vertical component (i.e. which row)
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return value of given bit in matrix
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function get($x, $y)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $offset = (int)($y * $this->rowSize + ($x / 32));
							 | 
						||
| 
								 | 
							
								        if (!isset($this->bits[$offset])) {
							 | 
						||
| 
								 | 
							
								            $this->bits[$offset] = 0;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // return (($this->bits[$offset] >> ($x & 0x1f)) & 1) != 0;
							 | 
						||
| 
								 | 
							
								        return (uRShift($this->bits[$offset], ($x & 0x1f)) & 1) != 0;//было >>> вместо >>, не знаю как эмулировать беззнаковый сдвиг
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//  @Override
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    public function _clone()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return new BitMatrix($this->width, $this->height, $this->rowSize, $this->bits);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |