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.

ZXCode128Reader.m 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534
  1. /*
  2. * Copyright 2012 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 "ZXBitArray.h"
  17. #import "ZXByteArray.h"
  18. #import "ZXCode128Reader.h"
  19. #import "ZXDecodeHints.h"
  20. #import "ZXErrors.h"
  21. #import "ZXIntArray.h"
  22. #import "ZXOneDReader.h"
  23. #import "ZXResult.h"
  24. #import "ZXResultPoint.h"
  25. const int ZX_CODE128_CODE_PATTERNS_LEN = 107;
  26. const int ZX_CODE128_CODE_PATTERNS[ZX_CODE128_CODE_PATTERNS_LEN][7] = {
  27. {2, 1, 2, 2, 2, 2}, // 0
  28. {2, 2, 2, 1, 2, 2},
  29. {2, 2, 2, 2, 2, 1},
  30. {1, 2, 1, 2, 2, 3},
  31. {1, 2, 1, 3, 2, 2},
  32. {1, 3, 1, 2, 2, 2}, // 5
  33. {1, 2, 2, 2, 1, 3},
  34. {1, 2, 2, 3, 1, 2},
  35. {1, 3, 2, 2, 1, 2},
  36. {2, 2, 1, 2, 1, 3},
  37. {2, 2, 1, 3, 1, 2}, // 10
  38. {2, 3, 1, 2, 1, 2},
  39. {1, 1, 2, 2, 3, 2},
  40. {1, 2, 2, 1, 3, 2},
  41. {1, 2, 2, 2, 3, 1},
  42. {1, 1, 3, 2, 2, 2}, // 15
  43. {1, 2, 3, 1, 2, 2},
  44. {1, 2, 3, 2, 2, 1},
  45. {2, 2, 3, 2, 1, 1},
  46. {2, 2, 1, 1, 3, 2},
  47. {2, 2, 1, 2, 3, 1}, // 20
  48. {2, 1, 3, 2, 1, 2},
  49. {2, 2, 3, 1, 1, 2},
  50. {3, 1, 2, 1, 3, 1},
  51. {3, 1, 1, 2, 2, 2},
  52. {3, 2, 1, 1, 2, 2}, // 25
  53. {3, 2, 1, 2, 2, 1},
  54. {3, 1, 2, 2, 1, 2},
  55. {3, 2, 2, 1, 1, 2},
  56. {3, 2, 2, 2, 1, 1},
  57. {2, 1, 2, 1, 2, 3}, // 30
  58. {2, 1, 2, 3, 2, 1},
  59. {2, 3, 2, 1, 2, 1},
  60. {1, 1, 1, 3, 2, 3},
  61. {1, 3, 1, 1, 2, 3},
  62. {1, 3, 1, 3, 2, 1}, // 35
  63. {1, 1, 2, 3, 1, 3},
  64. {1, 3, 2, 1, 1, 3},
  65. {1, 3, 2, 3, 1, 1},
  66. {2, 1, 1, 3, 1, 3},
  67. {2, 3, 1, 1, 1, 3}, // 40
  68. {2, 3, 1, 3, 1, 1},
  69. {1, 1, 2, 1, 3, 3},
  70. {1, 1, 2, 3, 3, 1},
  71. {1, 3, 2, 1, 3, 1},
  72. {1, 1, 3, 1, 2, 3}, // 45
  73. {1, 1, 3, 3, 2, 1},
  74. {1, 3, 3, 1, 2, 1},
  75. {3, 1, 3, 1, 2, 1},
  76. {2, 1, 1, 3, 3, 1},
  77. {2, 3, 1, 1, 3, 1}, // 50
  78. {2, 1, 3, 1, 1, 3},
  79. {2, 1, 3, 3, 1, 1},
  80. {2, 1, 3, 1, 3, 1},
  81. {3, 1, 1, 1, 2, 3},
  82. {3, 1, 1, 3, 2, 1}, // 55
  83. {3, 3, 1, 1, 2, 1},
  84. {3, 1, 2, 1, 1, 3},
  85. {3, 1, 2, 3, 1, 1},
  86. {3, 3, 2, 1, 1, 1},
  87. {3, 1, 4, 1, 1, 1}, // 60
  88. {2, 2, 1, 4, 1, 1},
  89. {4, 3, 1, 1, 1, 1},
  90. {1, 1, 1, 2, 2, 4},
  91. {1, 1, 1, 4, 2, 2},
  92. {1, 2, 1, 1, 2, 4}, // 65
  93. {1, 2, 1, 4, 2, 1},
  94. {1, 4, 1, 1, 2, 2},
  95. {1, 4, 1, 2, 2, 1},
  96. {1, 1, 2, 2, 1, 4},
  97. {1, 1, 2, 4, 1, 2}, // 70
  98. {1, 2, 2, 1, 1, 4},
  99. {1, 2, 2, 4, 1, 1},
  100. {1, 4, 2, 1, 1, 2},
  101. {1, 4, 2, 2, 1, 1},
  102. {2, 4, 1, 2, 1, 1}, // 75
  103. {2, 2, 1, 1, 1, 4},
  104. {4, 1, 3, 1, 1, 1},
  105. {2, 4, 1, 1, 1, 2},
  106. {1, 3, 4, 1, 1, 1},
  107. {1, 1, 1, 2, 4, 2}, // 80
  108. {1, 2, 1, 1, 4, 2},
  109. {1, 2, 1, 2, 4, 1},
  110. {1, 1, 4, 2, 1, 2},
  111. {1, 2, 4, 1, 1, 2},
  112. {1, 2, 4, 2, 1, 1}, // 85
  113. {4, 1, 1, 2, 1, 2},
  114. {4, 2, 1, 1, 1, 2},
  115. {4, 2, 1, 2, 1, 1},
  116. {2, 1, 2, 1, 4, 1},
  117. {2, 1, 4, 1, 2, 1}, // 90
  118. {4, 1, 2, 1, 2, 1},
  119. {1, 1, 1, 1, 4, 3},
  120. {1, 1, 1, 3, 4, 1},
  121. {1, 3, 1, 1, 4, 1},
  122. {1, 1, 4, 1, 1, 3}, // 95
  123. {1, 1, 4, 3, 1, 1},
  124. {4, 1, 1, 1, 1, 3},
  125. {4, 1, 1, 3, 1, 1},
  126. {1, 1, 3, 1, 4, 1},
  127. {1, 1, 4, 1, 3, 1}, // 100
  128. {3, 1, 1, 1, 4, 1},
  129. {4, 1, 1, 1, 3, 1},
  130. {2, 1, 1, 4, 1, 2},
  131. {2, 1, 1, 2, 1, 4},
  132. {2, 1, 1, 2, 3, 2}, // 105
  133. {2, 3, 3, 1, 1, 1, 2}
  134. };
  135. static float ZX_CODE128_MAX_AVG_VARIANCE = 0.25f;
  136. static float ZX_CODE128_MAX_INDIVIDUAL_VARIANCE = 0.7f;
  137. const int ZX_CODE128_CODE_SHIFT = 98;
  138. const int ZX_CODE128_CODE_CODE_C = 99;
  139. const int ZX_CODE128_CODE_CODE_B = 100;
  140. const int ZX_CODE128_CODE_CODE_A = 101;
  141. const int ZX_CODE128_CODE_FNC_1 = 102;
  142. const int ZX_CODE128_CODE_FNC_2 = 97;
  143. const int ZX_CODE128_CODE_FNC_3 = 96;
  144. const int ZX_CODE128_CODE_FNC_4_A = 101;
  145. const int ZX_CODE128_CODE_FNC_4_B = 100;
  146. const int ZX_CODE128_CODE_START_A = 103;
  147. const int ZX_CODE128_CODE_START_B = 104;
  148. const int ZX_CODE128_CODE_START_C = 105;
  149. const int ZX_CODE128_CODE_STOP = 106;
  150. @implementation ZXCode128Reader
  151. - (ZXIntArray *)findStartPattern:(ZXBitArray *)row {
  152. int width = row.size;
  153. int rowOffset = [row nextSet:0];
  154. int counterPosition = 0;
  155. ZXIntArray *counters = [[ZXIntArray alloc] initWithLength:6];
  156. int32_t *array = counters.array;
  157. int patternStart = rowOffset;
  158. BOOL isWhite = NO;
  159. int patternLength = (int)counters.length;
  160. for (int i = rowOffset; i < width; i++) {
  161. if ([row get:i] ^ isWhite) {
  162. array[counterPosition]++;
  163. } else {
  164. if (counterPosition == patternLength - 1) {
  165. float bestVariance = ZX_CODE128_MAX_AVG_VARIANCE;
  166. int bestMatch = -1;
  167. for (int startCode = ZX_CODE128_CODE_START_A; startCode <= ZX_CODE128_CODE_START_C; startCode++) {
  168. float variance = [ZXOneDReader patternMatchVariance:counters pattern:ZX_CODE128_CODE_PATTERNS[startCode] maxIndividualVariance:ZX_CODE128_MAX_INDIVIDUAL_VARIANCE];
  169. if (variance < bestVariance) {
  170. bestVariance = variance;
  171. bestMatch = startCode;
  172. }
  173. }
  174. // Look for whitespace before start pattern, >= 50% of width of start pattern
  175. if (bestMatch >= 0 &&
  176. [row isRange:MAX(0, patternStart - (i - patternStart) / 2) end:patternStart value:NO]) {
  177. return [[ZXIntArray alloc] initWithInts:patternStart, i, bestMatch, -1];
  178. }
  179. patternStart += array[0] + array[1];
  180. for (int y = 2; y < patternLength; y++) {
  181. array[y - 2] = array[y];
  182. }
  183. array[patternLength - 2] = 0;
  184. array[patternLength - 1] = 0;
  185. counterPosition--;
  186. } else {
  187. counterPosition++;
  188. }
  189. array[counterPosition] = 1;
  190. isWhite = !isWhite;
  191. }
  192. }
  193. return nil;
  194. }
  195. - (int)decodeCode:(ZXBitArray *)row counters:(ZXIntArray *)counters rowOffset:(int)rowOffset {
  196. if (![ZXOneDReader recordPattern:row start:rowOffset counters:counters]) {
  197. return -1;
  198. }
  199. float bestVariance = ZX_CODE128_MAX_AVG_VARIANCE;
  200. int bestMatch = -1;
  201. for (int d = 0; d < ZX_CODE128_CODE_PATTERNS_LEN; d++) {
  202. float variance = [ZXOneDReader patternMatchVariance:counters pattern:ZX_CODE128_CODE_PATTERNS[d] maxIndividualVariance:ZX_CODE128_MAX_INDIVIDUAL_VARIANCE];
  203. if (variance < bestVariance) {
  204. bestVariance = variance;
  205. bestMatch = d;
  206. }
  207. }
  208. if (bestMatch >= 0) {
  209. return bestMatch;
  210. } else {
  211. return -1;
  212. }
  213. }
  214. - (ZXResult *)decodeRow:(int)rowNumber row:(ZXBitArray *)row hints:(ZXDecodeHints *)hints error:(NSError **)error {
  215. BOOL convertFNC1 = hints && hints.assumeGS1;
  216. ZXIntArray *startPatternInfo = [self findStartPattern:row];
  217. if (!startPatternInfo) {
  218. if (error) *error = ZXNotFoundErrorInstance();
  219. return nil;
  220. }
  221. int startCode = startPatternInfo.array[2];
  222. int codeSet;
  223. NSMutableArray *rawCodes = [NSMutableArray arrayWithObject:@(startCode)];
  224. switch (startCode) {
  225. case ZX_CODE128_CODE_START_A:
  226. codeSet = ZX_CODE128_CODE_CODE_A;
  227. break;
  228. case ZX_CODE128_CODE_START_B:
  229. codeSet = ZX_CODE128_CODE_CODE_B;
  230. break;
  231. case ZX_CODE128_CODE_START_C:
  232. codeSet = ZX_CODE128_CODE_CODE_C;
  233. break;
  234. default:
  235. if (error) *error = ZXFormatErrorInstance();
  236. return nil;
  237. }
  238. BOOL done = NO;
  239. BOOL isNextShifted = NO;
  240. NSMutableString *result = [NSMutableString stringWithCapacity:20];
  241. int lastStart = startPatternInfo.array[0];
  242. int nextStart = startPatternInfo.array[1];
  243. ZXIntArray *counters = [[ZXIntArray alloc] initWithLength:6];
  244. int lastCode = 0;
  245. int code = 0;
  246. int checksumTotal = startCode;
  247. int multiplier = 0;
  248. BOOL lastCharacterWasPrintable = YES;
  249. BOOL upperMode = NO;
  250. BOOL shiftUpperMode = NO;
  251. while (!done) {
  252. BOOL unshift = isNextShifted;
  253. isNextShifted = NO;
  254. // Save off last code
  255. lastCode = code;
  256. // Decode another code from image
  257. code = [self decodeCode:row counters:counters rowOffset:nextStart];
  258. if (code == -1) {
  259. if (error) *error = ZXNotFoundErrorInstance();
  260. return nil;
  261. }
  262. [rawCodes addObject:@(code)];
  263. // Remember whether the last code was printable or not (excluding ZX_CODE128_CODE_STOP)
  264. if (code != ZX_CODE128_CODE_STOP) {
  265. lastCharacterWasPrintable = YES;
  266. }
  267. // Add to checksum computation (if not ZX_CODE128_CODE_STOP of course)
  268. if (code != ZX_CODE128_CODE_STOP) {
  269. multiplier++;
  270. checksumTotal += multiplier * code;
  271. }
  272. // Advance to where the next code will to start
  273. lastStart = nextStart;
  274. nextStart += [counters sum];
  275. // Take care of illegal start codes
  276. switch (code) {
  277. case ZX_CODE128_CODE_START_A:
  278. case ZX_CODE128_CODE_START_B:
  279. case ZX_CODE128_CODE_START_C:
  280. if (error) *error = ZXFormatErrorInstance();
  281. return nil;
  282. }
  283. switch (codeSet) {
  284. case ZX_CODE128_CODE_CODE_A:
  285. if (code < 64) {
  286. if (shiftUpperMode == upperMode) {
  287. [result appendFormat:@"%C", (unichar)(' ' + code)];
  288. } else {
  289. [result appendFormat:@"%C", (unichar)(' ' + code + 128)];
  290. }
  291. shiftUpperMode = NO;
  292. } else if (code < 96) {
  293. if (shiftUpperMode == upperMode) {
  294. [result appendFormat:@"%C", (unichar)(code - 64)];
  295. } else {
  296. [result appendFormat:@"%C", (unichar)(code + 64)];
  297. }
  298. shiftUpperMode = NO;
  299. } else {
  300. // Don't let CODE_STOP, which always appears, affect whether whether we think the last
  301. // code was printable or not.
  302. if (code != ZX_CODE128_CODE_STOP) {
  303. lastCharacterWasPrintable = NO;
  304. }
  305. switch (code) {
  306. case ZX_CODE128_CODE_FNC_1:
  307. if (convertFNC1) {
  308. if (result.length == 0) {
  309. // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
  310. // is FNC1 then this is GS1-128. We add the symbology identifier.
  311. [result appendString:@"]C1"];
  312. } else {
  313. // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
  314. [result appendFormat:@"%C", (unichar) 29];
  315. }
  316. }
  317. break;
  318. case ZX_CODE128_CODE_FNC_2:
  319. case ZX_CODE128_CODE_FNC_3:
  320. // do nothing?
  321. break;
  322. case ZX_CODE128_CODE_FNC_4_A:
  323. if (!upperMode && shiftUpperMode) {
  324. upperMode = YES;
  325. shiftUpperMode = NO;
  326. } else if (upperMode && shiftUpperMode) {
  327. upperMode = NO;
  328. shiftUpperMode = NO;
  329. } else {
  330. shiftUpperMode = YES;
  331. }
  332. break;
  333. case ZX_CODE128_CODE_SHIFT:
  334. isNextShifted = YES;
  335. codeSet = ZX_CODE128_CODE_CODE_B;
  336. break;
  337. case ZX_CODE128_CODE_CODE_B:
  338. codeSet = ZX_CODE128_CODE_CODE_B;
  339. break;
  340. case ZX_CODE128_CODE_CODE_C:
  341. codeSet = ZX_CODE128_CODE_CODE_C;
  342. break;
  343. case ZX_CODE128_CODE_STOP:
  344. done = YES;
  345. break;
  346. }
  347. }
  348. break;
  349. case ZX_CODE128_CODE_CODE_B:
  350. if (code < 96) {
  351. if (shiftUpperMode == upperMode) {
  352. [result appendFormat:@"%C", (unichar)(' ' + code)];
  353. } else {
  354. [result appendFormat:@"%C", (unichar)(' ' + code + 128)];
  355. }
  356. shiftUpperMode = NO;
  357. } else {
  358. if (code != ZX_CODE128_CODE_STOP) {
  359. lastCharacterWasPrintable = NO;
  360. }
  361. switch (code) {
  362. case ZX_CODE128_CODE_FNC_1:
  363. if (convertFNC1) {
  364. if (result.length == 0) {
  365. // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
  366. // is FNC1 then this is GS1-128. We add the symbology identifier.
  367. [result appendString:@"]C1"];
  368. } else {
  369. // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
  370. [result appendFormat:@"%C", (unichar) 29];
  371. }
  372. }
  373. break;
  374. case ZX_CODE128_CODE_FNC_2:
  375. case ZX_CODE128_CODE_FNC_3:
  376. // do nothing?
  377. break;
  378. case ZX_CODE128_CODE_FNC_4_B:
  379. if (!upperMode && shiftUpperMode) {
  380. upperMode = YES;
  381. shiftUpperMode = NO;
  382. } else if (upperMode && shiftUpperMode) {
  383. upperMode = NO;
  384. shiftUpperMode = NO;
  385. } else {
  386. shiftUpperMode = YES;
  387. }
  388. break;
  389. case ZX_CODE128_CODE_SHIFT:
  390. isNextShifted = YES;
  391. codeSet = ZX_CODE128_CODE_CODE_A;
  392. break;
  393. case ZX_CODE128_CODE_CODE_A:
  394. codeSet = ZX_CODE128_CODE_CODE_A;
  395. break;
  396. case ZX_CODE128_CODE_CODE_C:
  397. codeSet = ZX_CODE128_CODE_CODE_C;
  398. break;
  399. case ZX_CODE128_CODE_STOP:
  400. done = YES;
  401. break;
  402. }
  403. }
  404. break;
  405. case ZX_CODE128_CODE_CODE_C:
  406. if (code < 100) {
  407. if (code < 10) {
  408. [result appendString:@"0"];
  409. }
  410. [result appendFormat:@"%d", code];
  411. } else {
  412. if (code != ZX_CODE128_CODE_STOP) {
  413. lastCharacterWasPrintable = NO;
  414. }
  415. switch (code) {
  416. case ZX_CODE128_CODE_FNC_1:
  417. if (convertFNC1) {
  418. if (result.length == 0) {
  419. // GS1 specification 5.4.3.7. and 5.4.6.4. If the first char after the start code
  420. // is FNC1 then this is GS1-128. We add the symbology identifier.
  421. [result appendString:@"]C1"];
  422. } else {
  423. // GS1 specification 5.4.7.5. Every subsequent FNC1 is returned as ASCII 29 (GS)
  424. [result appendFormat:@"%C", (unichar) 29];
  425. }
  426. }
  427. break;
  428. case ZX_CODE128_CODE_CODE_A:
  429. codeSet = ZX_CODE128_CODE_CODE_A;
  430. break;
  431. case ZX_CODE128_CODE_CODE_B:
  432. codeSet = ZX_CODE128_CODE_CODE_B;
  433. break;
  434. case ZX_CODE128_CODE_STOP:
  435. done = YES;
  436. break;
  437. }
  438. }
  439. break;
  440. }
  441. // Unshift back to another code set if we were shifted
  442. if (unshift) {
  443. codeSet = codeSet == ZX_CODE128_CODE_CODE_A ? ZX_CODE128_CODE_CODE_B : ZX_CODE128_CODE_CODE_A;
  444. }
  445. }
  446. int lastPatternSize = nextStart - lastStart;
  447. // Check for ample whitespace following pattern, but, to do this we first need to remember that
  448. // we fudged decoding CODE_STOP since it actually has 7 bars, not 6. There is a black bar left
  449. // to read off. Would be slightly better to properly read. Here we just skip it:
  450. nextStart = [row nextUnset:nextStart];
  451. if (![row isRange:nextStart end:MIN(row.size, nextStart + (nextStart - lastStart) / 2) value:NO]) {
  452. if (error) *error = ZXNotFoundErrorInstance();
  453. return nil;
  454. }
  455. // Pull out from sum the value of the penultimate check code
  456. checksumTotal -= multiplier * lastCode;
  457. // lastCode is the checksum then:
  458. if (checksumTotal % 103 != lastCode) {
  459. if (error) *error = ZXChecksumErrorInstance();
  460. return nil;
  461. }
  462. // Need to pull out the check digits from string
  463. NSUInteger resultLength = [result length];
  464. if (resultLength == 0) {
  465. // false positive
  466. if (error) *error = ZXNotFoundErrorInstance();
  467. return nil;
  468. }
  469. // Only bother if the result had at least one character, and if the checksum digit happened to
  470. // be a printable character. If it was just interpreted as a control code, nothing to remove.
  471. if (resultLength > 0 && lastCharacterWasPrintable) {
  472. if (codeSet == ZX_CODE128_CODE_CODE_C) {
  473. [result deleteCharactersInRange:NSMakeRange(resultLength - 2, 2)];
  474. } else {
  475. [result deleteCharactersInRange:NSMakeRange(resultLength - 1, 1)];
  476. }
  477. }
  478. float left = (float)(startPatternInfo.array[1] + startPatternInfo.array[0]) / 2.0f;
  479. float right = lastStart + lastPatternSize / 2.0f;
  480. NSUInteger rawCodesSize = [rawCodes count];
  481. ZXByteArray *rawBytes = [[ZXByteArray alloc] initWithLength:(unsigned int)rawCodesSize];
  482. for (int i = 0; i < rawCodesSize; i++) {
  483. rawBytes.array[i] = (int8_t)[rawCodes[i] intValue];
  484. }
  485. return [ZXResult resultWithText:result
  486. rawBytes:rawBytes
  487. resultPoints:@[[[ZXResultPoint alloc] initWithX:left y:(float)rowNumber],
  488. [[ZXResultPoint alloc] initWithX:right y:(float)rowNumber]]
  489. format:kBarcodeFormatCode128];
  490. }
  491. @end