|
|
<?php |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace Zxing\Qrcode\Decoder; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final class DataBlock |
|
|
{ |
|
|
private $numDataCodewords; |
|
|
private $codewords; |
|
|
|
|
|
private function __construct($numDataCodewords, $codewords) |
|
|
{ |
|
|
$this->numDataCodewords = $numDataCodewords; |
|
|
$this->codewords = $codewords; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static function getDataBlocks($rawCodewords, |
|
|
$version, |
|
|
$ecLevel) |
|
|
{ |
|
|
|
|
|
if (count($rawCodewords) != $version->getTotalCodewords()) { |
|
|
throw new \InvalidArgumentException(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$ecBlocks = $version->getECBlocksForLevel($ecLevel); |
|
|
|
|
|
|
|
|
$totalBlocks = 0; |
|
|
$ecBlockArray = $ecBlocks->getECBlocks(); |
|
|
foreach ($ecBlockArray as $ecBlock) { |
|
|
$totalBlocks += $ecBlock->getCount(); |
|
|
} |
|
|
|
|
|
|
|
|
$result = []; |
|
|
$numResultBlocks = 0; |
|
|
foreach ($ecBlockArray as $ecBlock) { |
|
|
$ecBlockCount = $ecBlock->getCount(); |
|
|
for ($i = 0; $i < $ecBlockCount; $i++) { |
|
|
$numDataCodewords = $ecBlock->getDataCodewords(); |
|
|
$numBlockCodewords = $ecBlocks->getECCodewordsPerBlock() + $numDataCodewords; |
|
|
$result[$numResultBlocks++] = new DataBlock($numDataCodewords, fill_array(0, $numBlockCodewords, 0)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$shorterBlocksTotalCodewords = count($result[0]->codewords); |
|
|
$longerBlocksStartAt = count($result) - 1; |
|
|
while ($longerBlocksStartAt >= 0) { |
|
|
$numCodewords = count($result[$longerBlocksStartAt]->codewords); |
|
|
if ($numCodewords == $shorterBlocksTotalCodewords) { |
|
|
break; |
|
|
} |
|
|
$longerBlocksStartAt--; |
|
|
} |
|
|
$longerBlocksStartAt++; |
|
|
|
|
|
$shorterBlocksNumDataCodewords = $shorterBlocksTotalCodewords - $ecBlocks->getECCodewordsPerBlock(); |
|
|
|
|
|
|
|
|
$rawCodewordsOffset = 0; |
|
|
for ($i = 0; $i < $shorterBlocksNumDataCodewords; $i++) { |
|
|
for ($j = 0; $j < $numResultBlocks; $j++) { |
|
|
$result[$j]->codewords[$i] = $rawCodewords[$rawCodewordsOffset++]; |
|
|
} |
|
|
} |
|
|
|
|
|
for ($j = $longerBlocksStartAt; $j < $numResultBlocks; $j++) { |
|
|
$result[$j]->codewords[$shorterBlocksNumDataCodewords] = $rawCodewords[$rawCodewordsOffset++]; |
|
|
} |
|
|
|
|
|
$max = count($result[0]->codewords); |
|
|
for ($i = $shorterBlocksNumDataCodewords; $i < $max; $i++) { |
|
|
for ($j = 0; $j < $numResultBlocks; $j++) { |
|
|
$iOffset = $j < $longerBlocksStartAt ? $i : $i + 1; |
|
|
$result[$j]->codewords[$iOffset] = $rawCodewords[$rawCodewordsOffset++]; |
|
|
} |
|
|
} |
|
|
|
|
|
return $result; |
|
|
} |
|
|
|
|
|
public function getNumDataCodewords() |
|
|
{ |
|
|
return $this->numDataCodewords; |
|
|
} |
|
|
|
|
|
public function getCodewords() |
|
|
{ |
|
|
return $this->codewords; |
|
|
} |
|
|
} |
|
|
|