You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ZXDataMatrixDefaultPlacement.m 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright 2013 ZXing authors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "ZXDataMatrixDefaultPlacement.h"
  17. @implementation ZXDataMatrixDefaultPlacement
  18. - (id)initWithCodewords:(NSString *)codewords numcols:(int)numcols numrows:(int)numrows {
  19. if (self = [super init]) {
  20. _codewords = [codewords copy];
  21. _numcols = numcols;
  22. _numrows = numrows;
  23. _bitsLen = numcols * numrows;
  24. _bits = (int8_t *)malloc(_bitsLen * sizeof(int8_t));
  25. memset(_bits, -1, _bitsLen); //Initialize with "not set" value
  26. }
  27. return self;
  28. }
  29. - (void)dealloc {
  30. if (_bits != NULL) {
  31. free(_bits);
  32. _bits = NULL;
  33. }
  34. }
  35. - (BOOL)bitAtCol:(int)col row:(int)row {
  36. return self.bits[row * self.numcols + col] == 1;
  37. }
  38. - (void)setBitAtCol:(int)col row:(int)row bit:(BOOL)bit {
  39. self.bits[row * self.numcols + col] = bit ? (int8_t) 1 : (int8_t) 0;
  40. }
  41. - (BOOL)hasBitAtCol:(int)col row:(int)row {
  42. return self.bits[row * self.numcols + col] >= 0;
  43. }
  44. - (void)place {
  45. int pos = 0;
  46. int row = 4;
  47. int col = 0;
  48. do {
  49. /* repeatedly first check for one of the special corner cases, then... */
  50. if ((row == self.numrows) && (col == 0)) {
  51. [self corner1:pos++];
  52. }
  53. if ((row == self.numrows - 2) && (col == 0) && ((self.numcols % 4) != 0)) {
  54. [self corner2:pos++];
  55. }
  56. if ((row == self.numrows - 2) && (col == 0) && (self.numcols % 8 == 4)) {
  57. [self corner3:pos++];
  58. }
  59. if ((row == self.numrows + 4) && (col == 2) && ((self.numcols % 8) == 0)) {
  60. [self corner4:pos++];
  61. }
  62. /* sweep upward diagonally, inserting successive characters... */
  63. do {
  64. if ((row < self.numrows) && (col >= 0) && ![self hasBitAtCol:col row:row]) {
  65. [self utahAtRow:row col:col pos:pos++];
  66. }
  67. row -= 2;
  68. col += 2;
  69. } while (row >= 0 && (col < self.numcols));
  70. row++;
  71. col += 3;
  72. /* and then sweep downward diagonally, inserting successive characters, ... */
  73. do {
  74. if ((row >= 0) && (col < self.numcols) && ![self hasBitAtCol:col row:row]) {
  75. [self utahAtRow:row col:col pos:pos++];
  76. }
  77. row += 2;
  78. col -= 2;
  79. } while ((row < self.numrows) && (col >= 0));
  80. row += 3;
  81. col++;
  82. /* ...until the entire array is scanned */
  83. } while ((row < self.numrows) || (col < self.numcols));
  84. /* Lastly, if the lower righthand corner is untouched, fill in fixed pattern */
  85. if (![self hasBitAtCol:self.numcols - 1 row:self.numrows - 1]) {
  86. [self setBitAtCol:self.numcols - 1 row:self.numrows - 1 bit:YES];
  87. [self setBitAtCol:self.numcols - 2 row:self.numrows - 2 bit:YES];
  88. }
  89. }
  90. - (void)moduleAtRow:(int)row col:(int)col pos:(int)pos bit:(int)bit {
  91. if (row < 0) {
  92. row += self.numrows;
  93. col += 4 - ((self.numrows + 4) % 8);
  94. }
  95. if (col < 0) {
  96. col += self.numcols;
  97. row += 4 - ((self.numcols + 4) % 8);
  98. }
  99. // Note the conversion:
  100. int v = [self.codewords characterAtIndex:pos];
  101. v &= 1 << (8 - bit);
  102. [self setBitAtCol:col row:row bit:v != 0];
  103. }
  104. /**
  105. * Places the 8 bits of a utah-shaped symbol character in ECC200.
  106. *
  107. * @param row the row
  108. * @param col the column
  109. * @param pos character position
  110. */
  111. - (void)utahAtRow:(int)row col:(int)col pos:(int)pos {
  112. [self moduleAtRow:row - 2 col:col - 2 pos:pos bit:1];
  113. [self moduleAtRow:row - 2 col:col - 1 pos:pos bit:2];
  114. [self moduleAtRow:row - 1 col:col - 2 pos:pos bit:3];
  115. [self moduleAtRow:row - 1 col:col - 1 pos:pos bit:4];
  116. [self moduleAtRow:row - 1 col:col pos:pos bit:5];
  117. [self moduleAtRow:row col:col - 2 pos:pos bit:6];
  118. [self moduleAtRow:row col:col - 1 pos:pos bit:7];
  119. [self moduleAtRow:row col:col pos:pos bit:8];
  120. }
  121. - (void)corner1:(int)pos {
  122. [self moduleAtRow:self.numrows - 1 col:0 pos:pos bit:1];
  123. [self moduleAtRow:self.numrows - 1 col:1 pos:pos bit:2];
  124. [self moduleAtRow:self.numrows - 1 col:2 pos:pos bit:3];
  125. [self moduleAtRow:0 col:self.numcols - 2 pos:pos bit:4];
  126. [self moduleAtRow:0 col:self.numcols - 1 pos:pos bit:5];
  127. [self moduleAtRow:1 col:self.numcols - 1 pos:pos bit:6];
  128. [self moduleAtRow:2 col:self.numcols - 1 pos:pos bit:7];
  129. [self moduleAtRow:3 col:self.numcols - 1 pos:pos bit:8];
  130. }
  131. - (void)corner2:(int)pos {
  132. [self moduleAtRow:self.numrows - 3 col:0 pos:pos bit:1];
  133. [self moduleAtRow:self.numrows - 2 col:0 pos:pos bit:2];
  134. [self moduleAtRow:self.numrows - 1 col:0 pos:pos bit:3];
  135. [self moduleAtRow:0 col:self.numcols - 4 pos:pos bit:4];
  136. [self moduleAtRow:0 col:self.numcols - 3 pos:pos bit:5];
  137. [self moduleAtRow:0 col:self.numcols - 2 pos:pos bit:6];
  138. [self moduleAtRow:0 col:self.numcols - 1 pos:pos bit:7];
  139. [self moduleAtRow:1 col:self.numcols - 1 pos:pos bit:8];
  140. }
  141. - (void)corner3:(int)pos {
  142. [self moduleAtRow:self.numrows - 3 col:0 pos:pos bit:1];
  143. [self moduleAtRow:self.numrows - 2 col:0 pos:pos bit:2];
  144. [self moduleAtRow:self.numrows - 1 col:0 pos:pos bit:3];
  145. [self moduleAtRow:0 col:self.numcols - 2 pos:pos bit:4];
  146. [self moduleAtRow:0 col:self.numcols - 1 pos:pos bit:5];
  147. [self moduleAtRow:1 col:self.numcols - 1 pos:pos bit:6];
  148. [self moduleAtRow:2 col:self.numcols - 1 pos:pos bit:7];
  149. [self moduleAtRow:3 col:self.numcols - 1 pos:pos bit:8];
  150. }
  151. - (void)corner4:(int)pos {
  152. [self moduleAtRow:self.numrows - 1 col:0 pos:pos bit:1];
  153. [self moduleAtRow:self.numrows - 1 col:self.numcols - 1 pos:pos bit:2];
  154. [self moduleAtRow:0 col:self.numcols - 3 pos:pos bit:3];
  155. [self moduleAtRow:0 col:self.numcols - 2 pos:pos bit:4];
  156. [self moduleAtRow:0 col:self.numcols - 1 pos:pos bit:5];
  157. [self moduleAtRow:1 col:self.numcols - 3 pos:pos bit:6];
  158. [self moduleAtRow:1 col:self.numcols - 2 pos:pos bit:7];
  159. [self moduleAtRow:1 col:self.numcols - 1 pos:pos bit:8];
  160. }
  161. @end