|
|
<?php |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace Zxing; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final class PlanarYUVLuminanceSource extends LuminanceSource |
|
|
{ |
|
|
private static $THUMBNAIL_SCALE_FACTOR = 2; |
|
|
|
|
|
private $yuvData; |
|
|
private $dataWidth; |
|
|
private $dataHeight; |
|
|
private $left; |
|
|
private $top; |
|
|
|
|
|
public function __construct($yuvData, |
|
|
$dataWidth, |
|
|
$dataHeight, |
|
|
$left, |
|
|
$top, |
|
|
$width, |
|
|
$height, |
|
|
$reverseHorizontal) |
|
|
{ |
|
|
parent::__construct($width, $height); |
|
|
|
|
|
if ($left + $width > $dataWidth || $top + $height > $dataHeight) { |
|
|
throw new \InvalidArgumentException("Crop rectangle does not fit within image data."); |
|
|
} |
|
|
|
|
|
$this->yuvData = $yuvData; |
|
|
$this->dataWidth = $dataWidth; |
|
|
$this->dataHeight = $dataHeight; |
|
|
$this->left = $left; |
|
|
$this->top = $top; |
|
|
if ($reverseHorizontal) { |
|
|
$this->reverseHorizontal($width, $height); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public function getRow($y, $row = null) |
|
|
{ |
|
|
if ($y < 0 || $y >= getHeight()) { |
|
|
throw new \InvalidArgumentException("Requested row is outside the image: " + y); |
|
|
} |
|
|
$width = $this->getWidth(); |
|
|
if ($row == null || count($row) < $width) { |
|
|
$row = []; |
|
|
} |
|
|
$offset = ($y + $this->top) * $this->dataWidth + $this->left; |
|
|
$row = arraycopy($this->yuvData, $offset, $row, 0, $width); |
|
|
|
|
|
return $row; |
|
|
} |
|
|
|
|
|
|
|
|
public function getMatrix() |
|
|
{ |
|
|
$width = $this->getWidth(); |
|
|
$height = $this->getHeight(); |
|
|
|
|
|
|
|
|
|
|
|
if ($width == $this->dataWidth && $height == $this->dataHeight) { |
|
|
return $this->yuvData; |
|
|
} |
|
|
|
|
|
$area = $width * $height; |
|
|
$matrix = []; |
|
|
$inputOffset = $this->top * $this->dataWidth + $this->left; |
|
|
|
|
|
|
|
|
if ($width == $this->dataWidth) { |
|
|
$matrix = arraycopy($this->yuvData, $inputOffset, $matrix, 0, $area); |
|
|
|
|
|
return $matrix; |
|
|
} |
|
|
|
|
|
|
|
|
$yuv = $this->yuvData; |
|
|
for ($y = 0; $y < $height; $y++) { |
|
|
$outputOffset = $y * $width; |
|
|
$matrix = arraycopy($this->yuvData, $inputOffset, $matrix, $outputOffset, $width); |
|
|
$inputOffset += $this->dataWidth; |
|
|
} |
|
|
|
|
|
return $matrix; |
|
|
} |
|
|
|
|
|
|
|
|
public function isCropSupported() |
|
|
{ |
|
|
return true; |
|
|
} |
|
|
|
|
|
|
|
|
public function crop($left, $top, $width, $height) |
|
|
{ |
|
|
return new PlanarYUVLuminanceSource($this->yuvData, |
|
|
$this->dataWidth, |
|
|
$this->dataHeight, |
|
|
$this->left + $left, |
|
|
$this->top + $top, |
|
|
$width, |
|
|
$height, |
|
|
false); |
|
|
} |
|
|
|
|
|
public function renderThumbnail() |
|
|
{ |
|
|
$width = (int)($this->getWidth() / self::$THUMBNAIL_SCALE_FACTOR); |
|
|
$height = (int)($this->getHeight() / self::$THUMBNAIL_SCALE_FACTOR); |
|
|
$pixels = []; |
|
|
$yuv = $this->yuvData; |
|
|
$inputOffset = $this->top * $this->dataWidth + $this->left; |
|
|
|
|
|
for ($y = 0; $y < $height; $y++) { |
|
|
$outputOffset = $y * $width; |
|
|
for ($x = 0; $x < $width; $x++) { |
|
|
$grey = ($yuv[$inputOffset + $x * self::$THUMBNAIL_SCALE_FACTOR] & 0xff); |
|
|
$pixels[$outputOffset + $x] = (0xFF000000 | ($grey * 0x00010101)); |
|
|
} |
|
|
$inputOffset += $this->dataWidth * self::$THUMBNAIL_SCALE_FACTOR; |
|
|
} |
|
|
|
|
|
return $pixels; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|