DataMask.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. <?php
  2. /*
  3. * Copyright 2007 ZXing authors
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. namespace Zxing\Qrcode\Decoder;
  18. use Zxing\Common\BitMatrix;
  19. /**
  20. * <p>Encapsulates data masks for the data bits in a QR code, per ISO 18004:2006 6.8. Implementations
  21. * of this class can un-mask a raw BitMatrix. For simplicity, they will unmask the entire BitMatrix,
  22. * including areas used for finder patterns, timing patterns, etc. These areas should be unused
  23. * after the point they are unmasked anyway.</p>
  24. *
  25. * <p>Note that the diagram in section 6.8.1 is misleading since it indicates that i is column position
  26. * and j is row position. In fact, as the text says, i is row position and j is column position.</p>
  27. *
  28. * @author Sean Owen
  29. */
  30. abstract class DataMask
  31. {
  32. /**
  33. * See ISO 18004:2006 6.8.1
  34. */
  35. private static $DATA_MASKS = array();
  36. static function Init()
  37. {
  38. self::$DATA_MASKS = array(
  39. new DataMask000(),
  40. new DataMask001(),
  41. new DataMask010(),
  42. new DataMask011(),
  43. new DataMask100(),
  44. new DataMask101(),
  45. new DataMask110(),
  46. new DataMask111(),
  47. );
  48. }
  49. function __construct()
  50. {
  51. }
  52. /**
  53. * <p>Implementations of this method reverse the data masking process applied to a QR Code and
  54. * make its bits ready to read.</p>
  55. *
  56. * @param bits representation of QR Code bits
  57. * @param dimension dimension of QR Code, represented by bits, being unmasked
  58. */
  59. final function unmaskBitMatrix($bits, $dimension)
  60. {
  61. for ($i = 0; $i < $dimension; $i++) {
  62. for ($j = 0; $j < $dimension; $j++) {
  63. if ($this->isMasked($i, $j)) {
  64. $bits->flip($j, $i);
  65. }
  66. }
  67. }
  68. }
  69. abstract function isMasked($i, $j);
  70. /**
  71. * @param reference a value between 0 and 7 indicating one of the eight possible
  72. * data mask patterns a QR Code may use
  73. * @return DataMask encapsulating the data mask pattern
  74. */
  75. static function forReference($reference)
  76. {
  77. if ($reference < 0 || $reference > 7) {
  78. throw new \InvalidArgumentException();
  79. }
  80. return self::$DATA_MASKS[$reference];
  81. }
  82. }
  83. DataMask::Init();
  84. /**
  85. * 000: mask bits for which (x + y) mod 2 == 0
  86. */
  87. final class DataMask000 extends DataMask {
  88. // @Override
  89. function isMasked($i, $j) {
  90. return (($i + $j) & 0x01) == 0;
  91. }
  92. }
  93. /**
  94. * 001: mask bits for which x mod 2 == 0
  95. */
  96. final class DataMask001 extends DataMask {
  97. //@Override
  98. function isMasked($i, $j) {
  99. return ($i & 0x01) == 0;
  100. }
  101. }
  102. /**
  103. * 010: mask bits for which y mod 3 == 0
  104. */
  105. final class DataMask010 extends DataMask {
  106. //@Override
  107. function isMasked($i, $j) {
  108. return $j % 3 == 0;
  109. }
  110. }
  111. /**
  112. * 011: mask bits for which (x + y) mod 3 == 0
  113. */
  114. final class DataMask011 extends DataMask {
  115. //@Override
  116. function isMasked($i, $j) {
  117. return ($i + $j) % 3 == 0;
  118. }
  119. }
  120. /**
  121. * 100: mask bits for which (x/2 + y/3) mod 2 == 0
  122. */
  123. final class DataMask100 extends DataMask {
  124. //@Override
  125. function isMasked($i, $j) {
  126. return intval((intval($i / 2) + intval($j /3)) & 0x01) == 0;
  127. }
  128. }
  129. /**
  130. * 101: mask bits for which xy mod 2 + xy mod 3 == 0
  131. */
  132. final class DataMask101 extends DataMask {
  133. //@Override
  134. function isMasked($i, $j) {
  135. $temp = $i * $j;
  136. return ($temp & 0x01) + ($temp % 3) == 0;
  137. }
  138. }
  139. /**
  140. * 110: mask bits for which (xy mod 2 + xy mod 3) mod 2 == 0
  141. */
  142. final class DataMask110 extends DataMask {
  143. //@Override
  144. function isMasked($i, $j) {
  145. $temp = $i * $j;
  146. return ((($temp & 0x01) + ($temp % 3)) & 0x01) == 0;
  147. }
  148. }
  149. /**
  150. * 111: mask bits for which ((x+y)mod 2 + xy mod 3) mod 2 == 0
  151. */
  152. final class DataMask111 extends DataMask {
  153. //@Override
  154. function isMasked($i, $j) {
  155. return (((($i + $j) & 0x01) + (($i * $j) % 3)) & 0x01) == 0;
  156. }
  157. }