6TF9鱈o3GwY9"rwU7bTyYHT hwigCt汾|I ?i{"3;`gC[A3t,/)>:(>][!kʿ0t$y}w_PUk, 5,eo)V<ϣjdzQ zSs1ߝt1@>R[>vN>aIKeI vopS< 7/%uURW6N$dηQWÛ5ydر0 *;y `n^AL/ZoUV`Tp;Ks," jA5(K];&Ɨ'yKZ8#0h]11.dhcbF7#on6 ';MޜGv8+j؏ e۵>밹- fЌLӧa | -W2|kM9c3QZ܏ 6@}DY`I"CU7WQM瀙OV^Y-jڃu;UYt$ȭŚgX'=V_80gh*av·%85Vkb6¤zeM\gjԸe _|vUl|xWו*/bAK8`G\%쀤O9.YFFp]}L.c3Bx"192+P/fRk?ާd9Y덎-h: Ջu͡f션!~߼sJ:TK7cOT"ܡhSWi;)~s+`;}~:-jΞְaOR c0?hB!.Z{`rޢ eU\ !2'RVϹRrrX,64T$ oV5'hć$[&gA9%s,|R"HD \L]lQRu+#Mg{@!\*]b{HZ}!?Ĥb~kwr8; j.( ;g"%3Y9aHeq8hͨNѧ~P;a pHTL!"n#E>޲Rଦ& &~՚Q0[{TM Jȴlz}>bɃyY-=\u"lxFir3|2GOBIU.)Ql~2v&q(W`;*XO8vyg<@h#F #F?fqΪ e}p(8:E4~m[^S9xzC~,Uv.mȇ'qc%W0S|.Ss3XqC?ne{o`fMyHhۯnAb #VBoѹSg#jm, #K.kCOa"bZ3'놲|:#*%F>k;P` -GITٳ8j-h,Zq8TXIUy9%RPS/71@4]Lg;C F_b2DTx _͝5Wt薢ƅLXބ *iG,=,(ɾv '2&l0):/;SZtsӡOSnB-뗻o=Rn5_O FLD&2GOBIU.]?rV%?_/45 x)'TkV PݏX sx;/bAK8`G"P.'D w45^osò%54j\9Z䶟(}|C [f6ä*3,G\wU}17U?(6nnf$I,M`],~3h $ͽ6D'B~#ݫUe6s!wbtj8V/ DE*|%gYE]xA=Y=@* 0~|#Ex;+2}o ̹oE#i FCk\pe3BLj^m5{=Z -Ržz=xBZ@|Z02+)Yd&;\ts] YI5}2ϥ$4$ ;TCH}q ^Üt4,ɬ?c`/1'-+r?:g0#VZa—3=;GoEJLg;C F_<BT+^J}[-8_H&ۖ[IZ+nm#A3t,/)>:(>Z粰w&K4 lpo Ջu͡f션!~߼bKWHӊ]@3Z1BIfGY)Ln_~ fHe8 COj,#SGw*P0+vWalU9>X&R{t{,-jΞְaOR z#Ji~T%ƺ3Q gr1U v{^^F' P=:/#E;@,Ba= zUKNw3\n/v(EyTHqQO]HQ͖@˃V[ۃüOq^5+t "K Q*\kc q# 4G;;|N~'xzQc x!ۗ! ֡ʞGsP̏ e8F bnm v>'D`+K-QL`ԇE٨3JQ6RF9@` 1#% RQf]--vYH 7 \RbD?]HjW*gr0? 7y |aɚ^<]d{p~d+@ R iij}P'U%.`̇]R.|MSؽܤT=pxwOAPޯ%x ƋT !'-UJy{>FI@-dఐ#5x=yBQ0m|Ilabn !9}fڟDWaY[N=]l@ uKCL⮎ =ļHc1V[8$hZc!;8b^ )!NY,潆墷JZ{^n]?&xӃjSx_G٩0i(j\9Z䶟(}LYB7x}+9Hb?, в@u>-|km1l*3OE&O:~o<ٓ-qxf$2A&6gox0]ԉe몔V&3ClY$d\rf[Bfuo=PW`o(\w+c䗅Sx^fuh}R#A~֢FwoY>ށ>:^Ħvswrc 2T|[;ۉ/}umU5o#Ff f4i{LuF:iz.A"OčIRl&f*^=|,dx7p 1Ok)!V+ ۸q&^?P'E|PJ(2? !jn"XZ/f|*TK7EdڐSxsetRow(int $y, BitArray $row) : void { $bits = $row->getBitArray(); for ($i = 0; $i < $this->rowSize; ++$i) { $this->bits[$y * $this->rowSize + $i] = $bits[$i]; } } /** * This is useful in detecting the enclosing rectangle of a 'pure' barcode. * * @return int[]|null */ public function getEnclosingRectangle() : ?array { $left = $this->width; $top = $this->height; $right = -1; $bottom = -1; for ($y = 0; $y < $this->height; ++$y) { for ($x32 = 0; $x32 < $this->rowSize; ++$x32) { $bits = $this->bits[$y * $this->rowSize + $x32]; if (0 !== $bits) { if ($y < $top) { $top = $y; } if ($y > $bottom) { $bottom = $y; } if ($x32 * 32 < $left) { $bit = 0; while (($bits << (31 - $bit)) === 0) { $bit++; } if (($x32 * 32 + $bit) < $left) { $left = $x32 * 32 + $bit; } } } if ($x32 * 32 + 31 > $right) { $bit = 31; while (0 === BitUtils::unsignedRightShift($bits, $bit)) { --$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]; } /** * Gets the most top left set bit. * * This is useful in detecting a corner of a 'pure' barcode. * * @return int[]|null */ public function getTopLeftOnBit() : ?array { $bitsOffset = 0; while ($bitsOffset < count($this->bits) && 0 === $this->bits[$bitsOffset]) { ++$bitsOffset; } if (count($this->bits) === $bitsOffset) { return null; } $x = intdiv($bitsOffset, $this->rowSize); $y = ($bitsOffset % $this->rowSize) << 5; $bits = $this->bits[$bitsOffset]; $bit = 0; while (0 === ($bits << (31 - $bit))) { ++$bit; } $x += $bit; return [$x, $y]; } /** * Gets the most bottom right set bit. * * This is useful in detecting a corner of a 'pure' barcode. * * @return int[]|null */ public function getBottomRightOnBit() : ?array { $bitsOffset = count($this->bits) - 1; while ($bitsOffset >= 0 && 0 === $this->bits[$bitsOffset]) { --$bitsOffset; } if ($bitsOffset < 0) { return null; } $x = intdiv($bitsOffset, $this->rowSize); $y = ($bitsOffset % $this->rowSize) << 5; $bits = $this->bits[$bitsOffset]; $bit = 0; while (0 === BitUtils::unsignedRightShift($bits, $bit)) { --$bit; } $x += $bit; return [$x, $y]; } /** * Gets the width of the matrix, */ public function getWidth() : int { return $this->width; } /** * Gets the height of the matrix. */ public function getHeight() : int { return $this->height; } }