Passed
Push — v5 ( 93618e...84eb31 )
by smiley
01:52
created

LuminanceSource::setLuminancePixel()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 3
c 1
b 0
f 0
nc 4
nop 3
dl 0
loc 6
rs 10
1
<?php
2
/**
3
 * Class LuminanceSource
4
 *
5
 * @created      24.01.2021
6
 * @author       ZXing Authors
7
 * @author       Smiley <[email protected]>
8
 * @copyright    2021 Smiley
9
 * @license      Apache-2.0
10
 */
11
12
namespace chillerlan\QRCode\Decoder;
13
14
use InvalidArgumentException;
15
use function chillerlan\QRCode\Common\arraycopy;
16
17
/**
18
 * The purpose of this class hierarchy is to abstract different bitmap implementations across
19
 * platforms into a standard interface for requesting greyscale luminance values. The interface
20
 * only provides immutable methods; therefore crop and rotation create copies. This is to ensure
21
 * that one Reader does not modify the original luminance source and leave it in an unknown state
22
 * for other Readers in the chain.
23
 *
24
 * @author [email protected] (Daniel Switkin)
25
 */
26
abstract class LuminanceSource{
27
28
	protected array $luminances;
29
	protected int   $width;
30
	protected int   $height;
31
32
	public function __construct(int $width, int $height){
33
		$this->width  = $width;
34
		$this->height = $height;
35
		// In order to measure pure decoding speed, we convert the entire image to a greyscale array
36
		// up front, which is the same as the Y channel of the YUVLuminanceSource in the real app.
37
		$this->luminances = [];
38
		// @todo: grayscale?
39
		//$this->luminances = $this->grayScaleToBitmap($this->grayscale());
40
	}
41
42
	/**
43
	 * Fetches luminance data for the underlying bitmap. Values should be fetched using:
44
	 * {@code int luminance = array[y * width + x] & 0xff}
45
	 *
46
	 * @return array A row-major 2D array of luminance values. Do not use result.length as it may be
47
	 *         larger than width * height bytes on some platforms. Do not modify the contents
48
	 *         of the result.
49
	 */
50
	public function getMatrix():array{
51
		return $this->luminances;
52
	}
53
54
	/**
55
	 * @return int The width of the bitmap.
56
	 */
57
	public function getWidth():int{
58
		return $this->width;
59
	}
60
61
	/**
62
	 * @return int The height of the bitmap.
63
	 */
64
	public function getHeight():int{
65
		return $this->height;
66
	}
67
68
	/**
69
	 * Fetches one row of luminance data from the underlying platform's bitmap. Values range from
70
	 * 0 (black) to 255 (white). Because Java does not have an unsigned byte type, callers will have
71
	 * to bitwise and with 0xff for each value. It is preferable for implementations of this method
72
	 * to only fetch this row rather than the whole image, since no 2D Readers may be installed and
73
	 * getMatrix() may never be called.
74
	 *
75
	 * @param int $y  The row to fetch, which must be in [0,getHeight())
76
	 *
77
	 * @return array An array containing the luminance data.
78
	 */
79
	public function getRow(int $y):array{
80
81
		if($y < 0 || $y >= $this->getHeight()){
82
			throw new InvalidArgumentException('Requested row is outside the image: '.$y);
83
		}
84
85
		return arraycopy($this->luminances, $y * $this->width, [], 0, $this->width);
86
	}
87
88
	/**
89
	 * @param int $r
90
	 * @param int $g
91
	 * @param int $b
92
	 *
93
	 * @return void
94
	 */
95
	protected function setLuminancePixel(int $r, int $g, int $b):void{
96
		$this->luminances[] = $r === $g && $g === $b
97
			// Image is already greyscale, so pick any channel.
98
			? $r // (($r + 128) % 256) - 128;
99
			// Calculate luminance cheaply, favoring green.
100
			: ($r + 2 * $g + $b) / 4; // (((($r + 2 * $g + $b) / 4) + 128) % 256) - 128;
101
	}
102
103
}
104