Skip to content

Commit 53f6dcf

Browse files
committed
🚿
1 parent 7c183e7 commit 53f6dcf

File tree

4 files changed

+44
-58
lines changed

4 files changed

+44
-58
lines changed

src/Decoder/Binarizer.php

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ final class Binarizer{
4646
private const LUMINANCE_BUCKETS = 32;
4747

4848
private LuminanceSourceInterface $source;
49+
private array $luminances;
4950

5051
/**
5152
*
5253
*/
5354
public function __construct(LuminanceSourceInterface $source){
54-
$this->source = $source;
55+
$this->source = $source;
56+
$this->luminances = $this->source->getLuminances();
5557
}
5658

5759
/**
@@ -182,14 +184,13 @@ private function getHistogramBlackMatrix(int $width, int $height):BitMatrix{
182184
// We delay reading the entire image luminance until the black point estimation succeeds.
183185
// Although we end up reading four rows twice, it is consistent with our motto of
184186
// "fail quickly" which is necessary for continuous scanning.
185-
$localLuminances = $this->source->getMatrix();
186-
$matrix = new BitMatrix(max($width, $height));
187+
$matrix = new BitMatrix(max($width, $height));
187188

188189
for($y = 0; $y < $height; $y++){
189190
$offset = $y * $width;
190191

191192
for($x = 0; $x < $width; $x++){
192-
$matrix->set($x, $y, (($localLuminances[$offset + $x] & 0xff) < $blackPoint), QRMatrix::M_DATA);
193+
$matrix->set($x, $y, (($this->luminances[$offset + $x] & 0xff) < $blackPoint), QRMatrix::M_DATA);
193194
}
194195
}
195196

@@ -202,7 +203,7 @@ private function getHistogramBlackMatrix(int $width, int $height):BitMatrix{
202203
*
203204
* @see http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0
204205
*/
205-
private function calculateBlackPoints(array $luminances, int $subWidth, int $subHeight, int $width, int $height):array{
206+
private function calculateBlackPoints(int $subWidth, int $subHeight, int $width, int $height):array{
206207
$blackPoints = array_fill(0, $subHeight, 0);
207208

208209
foreach($blackPoints as $key => $point){
@@ -232,7 +233,7 @@ private function calculateBlackPoints(array $luminances, int $subWidth, int $sub
232233
for($yy = 0, $offset = $yoffset * $width + $xoffset; $yy < self::BLOCK_SIZE; $yy++, $offset += $width){
233234

234235
for($xx = 0; $xx < self::BLOCK_SIZE; $xx++){
235-
$pixel = (int)($luminances[(int)($offset + $xx)]) & 0xff;
236+
$pixel = (int)($this->luminances[(int)($offset + $xx)]) & 0xff;
236237
$sum += $pixel;
237238
// still looking for good contrast
238239
if($pixel < $min){
@@ -249,7 +250,7 @@ private function calculateBlackPoints(array $luminances, int $subWidth, int $sub
249250
// finish the rest of the rows quickly
250251
for($yy++, $offset += $width; $yy < self::BLOCK_SIZE; $yy++, $offset += $width){
251252
for($xx = 0; $xx < self::BLOCK_SIZE; $xx++){
252-
$sum += (int)($luminances[(int)($offset + $xx)]) & 0xff;
253+
$sum += (int)($this->luminances[(int)($offset + $xx)]) & 0xff;
253254
}
254255
}
255256
}
@@ -275,7 +276,9 @@ private function calculateBlackPoints(array $luminances, int $subWidth, int $sub
275276
// the boundaries is used for the interior.
276277

277278
// The (min < bp) is arbitrary but works better than other heuristics that were tried.
278-
$averageNeighborBlackPoint = (int)(($blackPoints[$y - 1][$x] + (2 * $blackPoints[$y][$x - 1]) + $blackPoints[$y - 1][$x - 1]) / 4);
279+
$averageNeighborBlackPoint = (int)(
280+
($blackPoints[$y - 1][$x] + (2 * $blackPoints[$y][$x - 1]) + $blackPoints[$y - 1][$x - 1]) / 4
281+
);
279282

280283
if($min < $averageNeighborBlackPoint){
281284
$average = $averageNeighborBlackPoint;
@@ -295,15 +298,9 @@ private function calculateBlackPoints(array $luminances, int $subWidth, int $sub
295298
* of the blocks around it. Also handles the corner cases (fractional blocks are computed based
296299
* on the last pixels in the row/column which are also used in the previous block).
297300
*/
298-
private function calculateThresholdForBlock(
299-
int $subWidth,
300-
int $subHeight,
301-
int $width,
302-
int $height
303-
):BitMatrix{
301+
private function calculateThresholdForBlock(int $subWidth, int $subHeight, int $width, int $height):BitMatrix{
304302
$matrix = new BitMatrix(max($width, $height));
305-
$luminances = $this->source->getMatrix();
306-
$blackPoints = $this->calculateBlackPoints($luminances, $subWidth, $subHeight, $width, $height);
303+
$blackPoints = $this->calculateBlackPoints($subWidth, $subHeight, $width, $height);
307304

308305
for($y = 0; $y < $subHeight; $y++){
309306
$yoffset = ($y << self::BLOCK_SIZE_POWER);
@@ -326,8 +323,8 @@ private function calculateThresholdForBlock(
326323
$sum = 0;
327324

328325
for($z = -2; $z <= 2; $z++){
329-
$blackRow = $blackPoints[$top + $z];
330-
$sum += $blackRow[$left - 2] + $blackRow[$left - 1] + $blackRow[$left] + $blackRow[$left + 1] + $blackRow[$left + 2];
326+
$br = $blackPoints[$top + $z];
327+
$sum += $br[$left - 2] + $br[$left - 1] + $br[$left] + $br[$left + 1] + $br[$left + 2];
331328
}
332329

333330
$average = (int)($sum / 25);
@@ -336,7 +333,9 @@ private function calculateThresholdForBlock(
336333
for($j = 0, $o = $yoffset * $width + $xoffset; $j < self::BLOCK_SIZE; $j++, $o += $width){
337334
for($i = 0; $i < self::BLOCK_SIZE; $i++){
338335
// Comparison needs to be <= so that black == 0 pixels are black even if the threshold is 0.
339-
$matrix->set($xoffset + $i, $yoffset + $j, (((int)($luminances[$o + $i]) & 0xff) <= $average), QRMatrix::M_DATA);
336+
$v = (((int)($this->luminances[$o + $i]) & 0xff) <= $average);
337+
338+
$matrix->set($xoffset + $i, $yoffset + $j, $v, QRMatrix::M_DATA);
340339
}
341340
}
342341
}
@@ -345,6 +344,9 @@ private function calculateThresholdForBlock(
345344
return $matrix;
346345
}
347346

347+
/**
348+
* @noinspection PhpSameParameterValueInspection
349+
*/
348350
private function cap(int $value, int $min, int $max):int{
349351

350352
if($value < $min){

src/Decoder/LuminanceSourceAbstract.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function __construct(int $width, int $height, SettingsContainerInterface
4444
}
4545

4646
/** @inheritDoc */
47-
public function getMatrix():array{
47+
public function getLuminances():array{
4848
return $this->luminances;
4949
}
5050

src/Decoder/LuminanceSourceInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ interface LuminanceSourceInterface{
2222
* larger than width * height bytes on some platforms. Do not modify the contents
2323
* of the result.
2424
*/
25-
public function getMatrix():array;
25+
public function getLuminances():array;
2626

2727
/**
2828
* @return int The width of the bitmap.
@@ -39,7 +39,7 @@ public function getHeight():int;
3939
* 0 (black) to 255 (white). Because Java does not have an unsigned byte type, callers will have
4040
* to bitwise and with 0xff for each value. It is preferable for implementations of this method
4141
* to only fetch this row rather than the whole image, since no 2D Readers may be installed and
42-
* getMatrix() may never be called.
42+
* getLuminances() may never be called.
4343
*
4444
* @param int $y The row to fetch, which must be in [0,getHeight())
4545
*

src/Detector/Detector.php

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -98,21 +98,10 @@ private function calculateModuleSize(FinderPattern $topLeft, FinderPattern $topR
9898
* #sizeOfBlackWhiteBlackRunBothWays(int, int, int, int) to figure the
9999
* width of each, measuring along the axis between their centers.
100100
*/
101-
private function calculateModuleSizeOneWay(FinderPattern $pattern, FinderPattern $otherPattern):float{
101+
private function calculateModuleSizeOneWay(FinderPattern $a, FinderPattern $b):float{
102102

103-
$moduleSizeEst1 = $this->sizeOfBlackWhiteBlackRunBothWays(
104-
$pattern->getX(),
105-
$pattern->getY(),
106-
$otherPattern->getX(),
107-
$otherPattern->getY()
108-
);
109-
110-
$moduleSizeEst2 = $this->sizeOfBlackWhiteBlackRunBothWays(
111-
$otherPattern->getX(),
112-
$otherPattern->getY(),
113-
$pattern->getX(),
114-
$pattern->getY()
115-
);
103+
$moduleSizeEst1 = $this->sizeOfBlackWhiteBlackRunBothWays($a->getX(), $a->getY(), $b->getX(), $b->getY());
104+
$moduleSizeEst2 = $this->sizeOfBlackWhiteBlackRunBothWays($b->getX(), $b->getY(), $a->getX(), $a->getY());
116105

117106
if(is_nan($moduleSizeEst1)){
118107
return $moduleSizeEst2 / 7.0;
@@ -247,14 +236,9 @@ private function sizeOfBlackWhiteBlackRun(int $fromX, int $fromY, int $toX, int
247236
*
248237
* @throws \chillerlan\QRCode\Detector\QRCodeDetectorException
249238
*/
250-
private function computeDimension(
251-
FinderPattern $topLeft,
252-
FinderPattern $topRight,
253-
FinderPattern $bottomLeft,
254-
float $moduleSize
255-
):int{
256-
$tltrCentersDimension = (int)round($topLeft->getDistance($topRight) / $moduleSize);
257-
$tlblCentersDimension = (int)round($topLeft->getDistance($bottomLeft) / $moduleSize);
239+
private function computeDimension(FinderPattern $nw, FinderPattern $ne, FinderPattern $sw, float $size):int{
240+
$tltrCentersDimension = (int)round($nw->getDistance($ne) / $size);
241+
$tlblCentersDimension = (int)round($nw->getDistance($sw) / $size);
258242
$dimension = (int)((($tltrCentersDimension + $tlblCentersDimension) / 2) + 7);
259243

260244
switch($dimension % 4){
@@ -322,24 +306,24 @@ private function findAlignmentInRegion(
322306
*
323307
*/
324308
private function createTransform(
325-
FinderPattern $topLeft,
326-
FinderPattern $topRight,
327-
FinderPattern $bottomLeft,
328-
int $dimension,
329-
AlignmentPattern $alignmentPattern = null
309+
FinderPattern $nw,
310+
FinderPattern $ne,
311+
FinderPattern $sw,
312+
int $size,
313+
AlignmentPattern $ap = null
330314
):PerspectiveTransform{
331-
$dimMinusThree = (float)$dimension - 3.5;
315+
$dimMinusThree = (float)$size - 3.5;
332316

333-
if($alignmentPattern instanceof AlignmentPattern){
334-
$bottomRightX = $alignmentPattern->getX();
335-
$bottomRightY = $alignmentPattern->getY();
317+
if($ap instanceof AlignmentPattern){
318+
$bottomRightX = $ap->getX();
319+
$bottomRightY = $ap->getY();
336320
$sourceBottomRightX = $dimMinusThree - 3.0;
337321
$sourceBottomRightY = $sourceBottomRightX;
338322
}
339323
else{
340324
// Don't have an alignment pattern, just make up the bottom-right point
341-
$bottomRightX = ($topRight->getX() - $topLeft->getX()) + $bottomLeft->getX();
342-
$bottomRightY = ($topRight->getY() - $topLeft->getY()) + $bottomLeft->getY();
325+
$bottomRightX = ($ne->getX() - $nw->getX()) + $sw->getX();
326+
$bottomRightY = ($ne->getY() - $nw->getY()) + $sw->getY();
343327
$sourceBottomRightX = $dimMinusThree;
344328
$sourceBottomRightY = $dimMinusThree;
345329
}
@@ -349,10 +333,10 @@ private function createTransform(
349333
$dimMinusThree, 3.5,
350334
$sourceBottomRightX, $sourceBottomRightY,
351335
3.5, $dimMinusThree,
352-
$topLeft->getX(), $topLeft->getY(),
353-
$topRight->getX(), $topRight->getY(),
336+
$nw->getX(), $nw->getY(),
337+
$ne->getX(), $ne->getY(),
354338
$bottomRightX, $bottomRightY,
355-
$bottomLeft->getX(), $bottomLeft->getY()
339+
$sw->getX(), $sw->getY()
356340
);
357341
}
358342

0 commit comments

Comments
 (0)