code128.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. /*------------------------------------------------------------------------
  2. * Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
  3. *
  4. * This file is part of the ZBar Bar Code Reader.
  5. *
  6. * The ZBar Bar Code Reader is free software; you can redistribute it
  7. * and/or modify it under the terms of the GNU Lesser Public License as
  8. * published by the Free Software Foundation; either version 2.1 of
  9. * the License, or (at your option) any later version.
  10. *
  11. * The ZBar Bar Code Reader is distributed in the hope that it will be
  12. * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  13. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser Public License
  17. * along with the ZBar Bar Code Reader; if not, write to the Free
  18. * Software Foundation, Inc., 51 Franklin St, Fifth Floor,
  19. * Boston, MA 02110-1301 USA
  20. *
  21. * http://sourceforge.net/projects/zbar
  22. *------------------------------------------------------------------------*/
  23. #include <config.h>
  24. #include <string.h> /* memmove */
  25. #include <zbar.h>
  26. #include "decoder.h"
  27. #ifdef DEBUG_CODE128
  28. //# define DEBUG_LEVEL (DEBUG_CODE128)
  29. #endif
  30. #include "debug.h"
  31. //#include "assert.h"
  32. #define NUM_CHARS 108 /* total number of character codes */
  33. typedef enum code128_char_e {
  34. FNC3 = 0x60,
  35. FNC2 = 0x61,
  36. SHIFT = 0x62,
  37. CODE_C = 0x63,
  38. CODE_B = 0x64,
  39. CODE_A = 0x65,
  40. FNC1 = 0x66,
  41. START_A = 0x67,
  42. START_B = 0x68,
  43. START_C = 0x69,
  44. STOP_FWD = 0x6a,
  45. STOP_REV = 0x6b,
  46. FNC4 = 0x6c,
  47. } code128_char_t;
  48. static const unsigned char characters[NUM_CHARS] = {
  49. 0x5c, 0xbf, 0xa1, /* [00] 00 */
  50. 0x2a, 0xc5, 0x0c, 0xa4, /* [03] 01 */
  51. 0x2d, 0xe3, 0x0f, /* [07] 02 */
  52. 0x5f, 0xe4, /* [0a] 03 */
  53. 0x6b, 0xe8, 0x69, 0xa7, 0xe7, /* [0c] 10 */
  54. 0xc1, 0x51, 0x1e, 0x83, 0xd9, 0x00, 0x84, 0x1f, /* [11] 11 */
  55. 0xc7, 0x0d, 0x33, 0x86, 0xb5, 0x0e, 0x15, 0x87, /* [19] 12 */
  56. 0x10, 0xda, 0x11, /* [21] 13 */
  57. 0x36, 0xe5, 0x18, 0x37, /* [24] 20 */
  58. 0xcc, 0x13, 0x39, 0x89, 0x97, 0x14, 0x1b, 0x8a, 0x3a, 0xbd, /* [28] 21 */
  59. 0xa2, 0x5e, 0x01, 0x85, 0xb0, 0x02, 0xa3, /* [32] 22 */
  60. 0xa5, 0x2c, 0x16, 0x88, 0xbc, 0x12, 0xa6, /* [39] 23 */
  61. 0x61, 0xe6, 0x56, 0x62, /* [40] 30 */
  62. 0x19, 0xdb, 0x1a, /* [44] 31 */
  63. 0xa8, 0x32, 0x1c, 0x8b, 0xcd, 0x1d, 0xa9, /* [47] 32 */
  64. 0xc3, 0x20, 0xc4, /* [4e] 33 */
  65. 0x50, 0x5d, 0xc0, /* [51] 0014 0025 0034 */
  66. 0x2b, 0xc6, /* [54] 0134 0143 */
  67. 0x2e, /* [56] 0243 */
  68. 0x53, 0x60, /* [57] 0341 0352 */
  69. 0x31, /* [59] 1024 */
  70. 0x52, 0xc2, /* [5a] 1114 1134 */
  71. 0x34, 0xc8, /* [5c] 1242 1243 */
  72. 0x55, /* [5e] 1441 */
  73. 0x57, 0x3e, 0xce, /* [5f] 4100 5200 4300 */
  74. 0x3b, 0xc9, /* [62] 4310 3410 */
  75. 0x6a, /* [64] 3420 */
  76. 0x54, 0x4f, /* [65] 1430 2530 */
  77. 0x38, /* [67] 4201 */
  78. 0x58, 0xcb, /* [68] 4111 4311 */
  79. 0x2f, 0xca, /* [6a] 2421 3421 */
  80. };
  81. static const unsigned char lo_base[8] = {
  82. 0x00, 0x07, 0x0c, 0x19, 0x24, 0x32, 0x40, 0x47
  83. };
  84. static const unsigned char lo_offset[0x80] = {
  85. 0xff, 0xf0, 0xff, 0x1f, 0xff, 0xf2, 0xff, 0xff, /* 00 [00] */
  86. 0xff, 0xff, 0xff, 0x3f, 0xf4, 0xf5, 0xff, 0x6f, /* 01 */
  87. 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf1, 0xff, 0x2f, /* 02 [07] */
  88. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x4f, /* 03 */
  89. 0xff, 0x0f, 0xf1, 0xf2, 0xff, 0x3f, 0xff, 0xf4, /* 10 [0c] */
  90. 0xf5, 0xf6, 0xf7, 0x89, 0xff, 0xab, 0xff, 0xfc, /* 11 */
  91. 0xff, 0xff, 0x0f, 0x1f, 0x23, 0x45, 0xf6, 0x7f, /* 12 [19] */
  92. 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xf9, 0xaf, /* 13 */
  93. 0xf0, 0xf1, 0xff, 0x2f, 0xff, 0xf3, 0xff, 0xff, /* 20 [24] */
  94. 0x4f, 0x5f, 0x67, 0x89, 0xfa, 0xbf, 0xff, 0xcd, /* 21 */
  95. 0xf0, 0xf1, 0xf2, 0x3f, 0xf4, 0x56, 0xff, 0xff, /* 22 [32] */
  96. 0xff, 0xff, 0x7f, 0x8f, 0x9a, 0xff, 0xbc, 0xdf, /* 23 */
  97. 0x0f, 0x1f, 0xf2, 0xff, 0xff, 0x3f, 0xff, 0xff, /* 30 [40] */
  98. 0xf4, 0xff, 0xf5, 0x6f, 0xff, 0xff, 0xff, 0xff, /* 31 */
  99. 0x0f, 0x1f, 0x23, 0xff, 0x45, 0x6f, 0xff, 0xff, /* 32 [47] */
  100. 0xf7, 0xff, 0xf8, 0x9f, 0xff, 0xff, 0xff, 0xff, /* 33 */
  101. };
  102. static inline signed char decode_lo (int sig)
  103. {
  104. unsigned char offset = (((sig >> 1) & 0x01) |
  105. ((sig >> 3) & 0x06) |
  106. ((sig >> 5) & 0x18) |
  107. ((sig >> 7) & 0x60));
  108. unsigned char idx = lo_offset[offset];
  109. if(sig & 1)
  110. idx &= 0xf;
  111. else
  112. idx >>= 4;
  113. if(idx == 0xf)
  114. return(-1);
  115. unsigned char base = (sig >> 11) | ((sig >> 9) & 1);
  116. zassert(base < 8, -1, "sig=%x offset=%x idx=%x base=%x\n",
  117. sig, offset, idx, base);
  118. idx += lo_base[base];
  119. zassert(idx <= 0x50, -1, "sig=%x offset=%x base=%x idx=%x\n",
  120. sig, offset, base, idx);
  121. unsigned char c = characters[idx];
  122. dprintf(2, " %02x(%x(%02x)/%x(%02x)) => %02x",
  123. idx, base, lo_base[base], offset, lo_offset[offset],
  124. (unsigned char)c);
  125. return(c);
  126. }
  127. static inline signed char decode_hi (int sig)
  128. {
  129. unsigned char rev = (sig & 0x4400) != 0;
  130. if(rev)
  131. sig = (((sig >> 12) & 0x000f) |
  132. ((sig >> 4) & 0x00f0) |
  133. ((sig << 4) & 0x0f00) |
  134. ((sig << 12) & 0xf000));
  135. dprintf(2, " rev=%x", rev != 0);
  136. unsigned char idx;
  137. switch(sig) {
  138. case 0x0014: idx = 0x0; break;
  139. case 0x0025: idx = 0x1; break;
  140. case 0x0034: idx = 0x2; break;
  141. case 0x0134: idx = 0x3; break;
  142. case 0x0143: idx = 0x4; break;
  143. case 0x0243: idx = 0x5; break;
  144. case 0x0341: idx = 0x6; break;
  145. case 0x0352: idx = 0x7; break;
  146. case 0x1024: idx = 0x8; break;
  147. case 0x1114: idx = 0x9; break;
  148. case 0x1134: idx = 0xa; break;
  149. case 0x1242: idx = 0xb; break;
  150. case 0x1243: idx = 0xc; break;
  151. case 0x1441: idx = 0xd; rev = 0; break;
  152. default: return(-1);
  153. }
  154. if(rev)
  155. idx += 0xe;
  156. unsigned char c = characters[0x51 + idx];
  157. dprintf(2, " %02x => %02x", idx, c);
  158. return(c);
  159. }
  160. static inline unsigned char calc_check (unsigned char c)
  161. {
  162. if(!(c & 0x80))
  163. return(0x18);
  164. c &= 0x7f;
  165. if(c < 0x3d)
  166. return((c < 0x30 && c != 0x17) ? 0x10 : 0x20);
  167. if(c < 0x50)
  168. return((c == 0x4d) ? 0x20 : 0x10);
  169. return((c < 0x67) ? 0x20 : 0x10);
  170. }
  171. static inline signed char decode6 (zbar_decoder_t *dcode)
  172. {
  173. /* build edge signature of character */
  174. unsigned s = dcode->code128.s6;
  175. dprintf(2, " s=%d", s);
  176. if(s < 5)
  177. return(-1);
  178. /* calculate similar edge measurements */
  179. int sig = (get_color(dcode) == ZBAR_BAR)
  180. ? ((decode_e(get_width(dcode, 0) + get_width(dcode, 1), s, 11) << 12) |
  181. (decode_e(get_width(dcode, 1) + get_width(dcode, 2), s, 11) << 8) |
  182. (decode_e(get_width(dcode, 2) + get_width(dcode, 3), s, 11) << 4) |
  183. (decode_e(get_width(dcode, 3) + get_width(dcode, 4), s, 11)))
  184. : ((decode_e(get_width(dcode, 5) + get_width(dcode, 4), s, 11) << 12) |
  185. (decode_e(get_width(dcode, 4) + get_width(dcode, 3), s, 11) << 8) |
  186. (decode_e(get_width(dcode, 3) + get_width(dcode, 2), s, 11) << 4) |
  187. (decode_e(get_width(dcode, 2) + get_width(dcode, 1), s, 11)));
  188. if(sig < 0)
  189. return(-1);
  190. dprintf(2, " sig=%04x", sig);
  191. /* lookup edge signature */
  192. signed char c = (sig & 0x4444) ? decode_hi(sig) : decode_lo(sig);
  193. if(c == -1)
  194. return(-1);
  195. /* character validation */
  196. unsigned bars = (get_color(dcode) == ZBAR_BAR)
  197. ? (get_width(dcode, 0) + get_width(dcode, 2) + get_width(dcode, 4))
  198. : (get_width(dcode, 1) + get_width(dcode, 3) + get_width(dcode, 5));
  199. bars = bars * 11 * 4 / s;
  200. unsigned char chk = calc_check(c);
  201. dprintf(2, " bars=%d chk=%d", bars, chk);
  202. if(chk - 7 > bars || bars > chk + 7)
  203. return(-1);
  204. return(c & 0x7f);
  205. }
  206. static inline unsigned char validate_checksum (zbar_decoder_t *dcode)
  207. {
  208. code128_decoder_t *dcode128 = &dcode->code128;
  209. if(dcode128->character < 3)
  210. return(1);
  211. /* add in irregularly weighted start character */
  212. unsigned idx = (dcode128->direction) ? dcode128->character - 1 : 0;
  213. unsigned sum = dcode->buf[idx];
  214. if(sum >= 103)
  215. sum -= 103;
  216. /* calculate sum in reverse to avoid multiply operations */
  217. unsigned i, acc = 0;
  218. for(i = dcode128->character - 3; i; i--) {
  219. zassert(sum < 103, -1, "dir=%x i=%x sum=%x acc=%x %s\n",
  220. dcode128->direction, i, sum, acc,
  221. _zbar_decoder_buf_dump(dcode->buf, dcode128->character));
  222. idx = (dcode128->direction) ? dcode128->character - 1 - i : i;
  223. acc += dcode->buf[idx];
  224. if(acc >= 103)
  225. acc -= 103;
  226. zassert(acc < 103, -1, "dir=%x i=%x sum=%x acc=%x %s\n",
  227. dcode128->direction, i, sum, acc,
  228. _zbar_decoder_buf_dump(dcode->buf, dcode128->character));
  229. sum += acc;
  230. if(sum >= 103)
  231. sum -= 103;
  232. }
  233. /* and compare to check character */
  234. idx = (dcode128->direction) ? 1 : dcode128->character - 2;
  235. unsigned char check = dcode->buf[idx];
  236. dprintf(2, " chk=%02x(%02x)", sum, check);
  237. unsigned char err = (sum != check);
  238. if(err)
  239. dprintf(1, " [checksum error]\n");
  240. return(err);
  241. }
  242. /* expand and decode character set C */
  243. static inline unsigned postprocess_c (zbar_decoder_t *dcode,
  244. unsigned start,
  245. unsigned end,
  246. unsigned dst)
  247. {
  248. /* expand buffer to accomodate 2x set C characters (2 digits per-char) */
  249. unsigned delta = end - start;
  250. unsigned newlen = dcode->code128.character + delta;
  251. size_buf(dcode, newlen);
  252. /* relocate unprocessed data to end of buffer */
  253. memmove(dcode->buf + start + delta, dcode->buf + start,
  254. dcode->code128.character - start);
  255. dcode->code128.character = newlen;
  256. unsigned i, j;
  257. for(i = 0, j = dst; i < delta; i++, j += 2) {
  258. /* convert each set C character into two ASCII digits */
  259. unsigned char code = dcode->buf[start + delta + i];
  260. dcode->buf[j] = '0';
  261. if(code >= 50) {
  262. code -= 50;
  263. dcode->buf[j] += 5;
  264. }
  265. if(code >= 30) {
  266. code -= 30;
  267. dcode->buf[j] += 3;
  268. }
  269. if(code >= 20) {
  270. code -= 20;
  271. dcode->buf[j] += 2;
  272. }
  273. if(code >= 10) {
  274. code -= 10;
  275. dcode->buf[j] += 1;
  276. }
  277. zassert(dcode->buf[j] <= '9', delta,
  278. "start=%x end=%x i=%x j=%x %s\n", start, end, i, j,
  279. _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
  280. zassert(code <= 9, delta,
  281. "start=%x end=%x i=%x j=%x %s\n", start, end, i, j,
  282. _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
  283. dcode->buf[j + 1] = '0' + code;
  284. }
  285. return(delta);
  286. }
  287. /* resolve scan direction and convert to ASCII */
  288. static inline unsigned char postprocess (zbar_decoder_t *dcode)
  289. {
  290. code128_decoder_t *dcode128 = &dcode->code128;
  291. dprintf(2, "\n postproc len=%d", dcode128->character);
  292. unsigned i, j;
  293. unsigned char code = 0;
  294. if(dcode128->direction) {
  295. /* reverse buffer */
  296. dprintf(2, " (rev)");
  297. for(i = 0; i < dcode128->character / 2; i++) {
  298. unsigned j = dcode128->character - 1 - i;
  299. code = dcode->buf[i];
  300. dcode->buf[i] = dcode->buf[j];
  301. dcode->buf[j] = code;
  302. }
  303. zassert(dcode->buf[dcode128->character - 1] == STOP_REV, 1,
  304. "dir=%x %s\n", dcode128->direction,
  305. _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
  306. }
  307. else
  308. zassert(dcode->buf[dcode128->character - 1] == STOP_FWD, 1,
  309. "dir=%x %s\n", dcode128->direction,
  310. _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
  311. code = dcode->buf[0];
  312. zassert(code >= START_A && code <= START_C, 1, "%s\n",
  313. _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
  314. unsigned char charset = code - START_A;
  315. unsigned cexp = (code == START_C) ? 1 : 0;
  316. dprintf(2, " start=%c", 'A' + charset);
  317. for(i = 1, j = 0; i < dcode128->character - 2; i++) {
  318. unsigned char code = dcode->buf[i];
  319. zassert(!(code & 0x80), 1,
  320. "i=%x j=%x code=%02x charset=%x cexp=%x %s\n",
  321. i, j, code, charset, cexp,
  322. _zbar_decoder_buf_dump(dcode->buf, dcode->code128.character));
  323. if((charset & 0x2) && (code < 100))
  324. /* defer character set C for expansion */
  325. continue;
  326. else if(code < 0x60) {
  327. /* convert character set B to ASCII */
  328. code = code + 0x20;
  329. if((!charset || (charset == 0x81)) && (code >= 0x60))
  330. /* convert character set A to ASCII */
  331. code -= 0x60;
  332. dcode->buf[j++] = code;
  333. if(charset & 0x80)
  334. charset &= 0x7f;
  335. }
  336. else {
  337. dprintf(2, " %02x", code);
  338. if(charset & 0x2) {
  339. /* expand character set C to ASCII */
  340. zassert(cexp, 1, "i=%x j=%x code=%02x charset=%x cexp=%x %s\n",
  341. i, j, code, charset, cexp,
  342. _zbar_decoder_buf_dump(dcode->buf,
  343. dcode->code128.character));
  344. unsigned delta = postprocess_c(dcode, cexp, i, j);
  345. i += delta;
  346. j += delta * 2;
  347. cexp = 0;
  348. }
  349. if(code < CODE_C) {
  350. if(code == SHIFT)
  351. charset |= 0x80;
  352. else if(code == FNC2)
  353. /* FIXME FNC2 - message append */;
  354. else if(code == FNC3)
  355. /* FIXME FNC3 - initialize */;
  356. }
  357. else if(code == FNC1)
  358. /* FIXME FNC1 - Code 128 subsets or ASCII 0x1d */;
  359. else if(code >= START_A) {
  360. dprintf(1, " [truncated]\n");
  361. return(1);
  362. }
  363. else {
  364. zassert(code >= CODE_C && code <= CODE_A, 1,
  365. "i=%x j=%x code=%02x charset=%x cexp=%x %s\n",
  366. i, j, code, charset, cexp,
  367. _zbar_decoder_buf_dump(dcode->buf,
  368. dcode->code128.character));
  369. unsigned char newset = CODE_A - code;
  370. if(newset != charset)
  371. charset = newset;
  372. else
  373. /* FIXME FNC4 - extended ASCII */;
  374. }
  375. if(charset & 0x2)
  376. cexp = i + 1;
  377. }
  378. }
  379. if(charset & 0x2) {
  380. zassert(cexp, 1, "i=%x j=%x code=%02x charset=%x cexp=%x %s\n",
  381. i, j, code, charset, cexp,
  382. _zbar_decoder_buf_dump(dcode->buf,
  383. dcode->code128.character));
  384. j += postprocess_c(dcode, cexp, i, j) * 2;
  385. }
  386. dcode->buflen = j;
  387. dcode->buf[j] = '\0';
  388. dcode->code128.character = j;
  389. return(0);
  390. }
  391. zbar_symbol_type_t _zbar_decode_code128 (zbar_decoder_t *dcode)
  392. {
  393. code128_decoder_t *dcode128 = &dcode->code128;
  394. /* update latest character width */
  395. dcode128->s6 -= get_width(dcode, 6);
  396. dcode128->s6 += get_width(dcode, 0);
  397. if(/* process every 6th element of active symbol */
  398. (dcode128->character >= 0 &&
  399. (++dcode128->element) != 6) ||
  400. /* decode color based on direction */
  401. (get_color(dcode) != dcode128->direction))
  402. return(0);
  403. dcode128->element = 0;
  404. dprintf(2, " code128[%c%02d+%x]:",
  405. (dcode128->direction) ? '<' : '>',
  406. dcode128->character, dcode128->element);
  407. signed char c = decode6(dcode);
  408. if(dcode128->character < 0) {
  409. dprintf(2, " c=%02x", c);
  410. if(c < START_A || c > STOP_REV || c == STOP_FWD) {
  411. dprintf(2, " [invalid]\n");
  412. return(0);
  413. }
  414. unsigned qz = get_width(dcode, 6);
  415. if(qz && qz < (dcode->code128.s6 * 3) / 4) {
  416. dprintf(2, " [invalid qz %d]\n", qz);
  417. return(0);
  418. }
  419. /* lock shared resources */
  420. if(get_lock(dcode, ZBAR_CODE128)) {
  421. dprintf(2, " [locked %d]\n", dcode->lock);
  422. dcode128->character = -1;
  423. return(0);
  424. }
  425. /* decoded valid start/stop */
  426. /* initialize state */
  427. dcode128->character = 0;
  428. if(c == STOP_REV) {
  429. dcode128->direction = ZBAR_BAR;
  430. dcode128->element = 7;
  431. }
  432. else
  433. dcode128->direction = ZBAR_SPACE;
  434. dprintf(2, " dir=%x [valid start]", dcode128->direction);
  435. }
  436. else if((c < 0) ||
  437. ((dcode128->character >= BUFFER_MIN) &&
  438. size_buf(dcode, dcode128->character + 1))) {
  439. dprintf(1, (c < 0) ? " [aborted]\n" : " [overflow]\n");
  440. dcode->lock = 0;
  441. dcode128->character = -1;
  442. return(0);
  443. }
  444. zassert(dcode->buf_alloc > dcode128->character, 0,
  445. "alloc=%x idx=%x c=%02x %s\n",
  446. dcode->buf_alloc, dcode128->character, c,
  447. _zbar_decoder_buf_dump(dcode->buf, dcode->buf_alloc));
  448. dcode->buf[dcode128->character++] = c;
  449. if(dcode128->character > 2 &&
  450. ((dcode128->direction)
  451. ? c >= START_A && c <= START_C
  452. : c == STOP_FWD)) {
  453. /* FIXME STOP_FWD should check extra bar (and QZ!) */
  454. zbar_symbol_type_t sym = ZBAR_CODE128;
  455. if(validate_checksum(dcode) || postprocess(dcode))
  456. sym = ZBAR_NONE;
  457. else if(dcode128->character < CFG(*dcode128, ZBAR_CFG_MIN_LEN) ||
  458. (CFG(*dcode128, ZBAR_CFG_MAX_LEN) > 0 &&
  459. dcode128->character > CFG(*dcode128, ZBAR_CFG_MAX_LEN))) {
  460. dprintf(2, " [invalid len]\n");
  461. sym = ZBAR_NONE;
  462. }
  463. else
  464. dprintf(2, " [valid end]\n");
  465. dcode128->character = -1;
  466. if(!sym)
  467. dcode->lock = 0;
  468. return(sym);
  469. }
  470. dprintf(2, "\n");
  471. return(0);
  472. }