pdf417.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*------------------------------------------------------------------------
  2. * Copyright 2008-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 <zbar.h>
  25. #include "decoder.h"
  26. #include "pdf417_hash.h"
  27. #ifdef DEBUG_PDF417
  28. # define DEBUG_LEVEL (DEBUG_PDF417)
  29. #endif
  30. #include "debug.h"
  31. #define PDF417_STOP 0xbff
  32. static inline signed short pdf417_decode8 (zbar_decoder_t *dcode)
  33. {
  34. /* build edge signature of character
  35. * from similar edge measurements
  36. */
  37. unsigned s = dcode->pdf417.s8;
  38. dprintf(2, " s=%d ", s);
  39. if(s < 8)
  40. return(-1);
  41. long sig = 0;
  42. signed char e;
  43. unsigned char i;
  44. for(i = 0; i < 7; i++) {
  45. if(get_color(dcode) == ZBAR_SPACE)
  46. e = decode_e(get_width(dcode, i) +
  47. get_width(dcode, i + 1), s, 17);
  48. else
  49. e = decode_e(get_width(dcode, 7 - i) +
  50. get_width(dcode, 6 - i), s, 17);
  51. dprintf(4, "%x", e);
  52. if(e < 0 || e > 8)
  53. return(-1);
  54. sig = (sig << 3) ^ e;
  55. }
  56. dprintf(2, " sig=%06lx", sig);
  57. /* determine cluster number */
  58. int clst = ((sig & 7) - ((sig >> 3) & 7) +
  59. ((sig >> 12) & 7) - ((sig >> 15) & 7));
  60. if(clst < 0)
  61. clst += 9;
  62. dprintf(2, " k=%d", clst);
  63. zassert(clst >= 0 && clst < 9, -1, "dir=%x sig=%lx k=%x %s\n",
  64. dcode->pdf417.direction, sig, clst,
  65. _zbar_decoder_buf_dump(dcode->buf, dcode->pdf417.character));
  66. if(clst != 0 && clst != 3 && clst != 6) {
  67. if(get_color(dcode) && clst == 7 && sig == 0x080007)
  68. return(PDF417_STOP);
  69. return(-1);
  70. }
  71. signed short g[3];
  72. sig &= 0x3ffff;
  73. g[0] = pdf417_hash[(sig - (sig >> 10)) & PDF417_HASH_MASK];
  74. g[1] = pdf417_hash[((sig >> 8) - sig) & PDF417_HASH_MASK];
  75. g[2] = pdf417_hash[((sig >> 14) - (sig >> 1)) & PDF417_HASH_MASK];
  76. zassert(g[0] >= 0 && g[1] >= 0 && g[2] >= 0, -1,
  77. "dir=%x sig=%lx k=%x g0=%03x g1=%03x g2=%03x %s\n",
  78. dcode->pdf417.direction, sig, clst, g[0], g[1], g[2],
  79. _zbar_decoder_buf_dump(dcode->buf, dcode->pdf417.character));
  80. unsigned short c = (g[0] + g[1] + g[2]) & PDF417_HASH_MASK;
  81. dprintf(2, " g0=%x g1=%x g2=%x c=%03d(%d)",
  82. g[0], g[1], g[2], c & 0x3ff, c >> 10);
  83. return(c);
  84. }
  85. static inline signed char pdf417_decode_start(zbar_decoder_t *dcode)
  86. {
  87. unsigned s = dcode->pdf417.s8;
  88. if(s < 8)
  89. return(0);
  90. int ei = decode_e(get_width(dcode, 0) + get_width(dcode, 1), s, 17);
  91. int ex = (get_color(dcode) == ZBAR_SPACE) ? 2 : 6;
  92. if(ei != ex)
  93. return(0);
  94. ei = decode_e(get_width(dcode, 1) + get_width(dcode, 2), s, 17);
  95. if(ei)
  96. return(0);
  97. ei = decode_e(get_width(dcode, 2) + get_width(dcode, 3), s, 17);
  98. ex = (get_color(dcode) == ZBAR_SPACE) ? 0 : 2;
  99. if(ei != ex)
  100. return(0);
  101. ei = decode_e(get_width(dcode, 3) + get_width(dcode, 4), s, 17);
  102. ex = (get_color(dcode) == ZBAR_SPACE) ? 0 : 2;
  103. if(ei != ex)
  104. return(0);
  105. ei = decode_e(get_width(dcode, 4) + get_width(dcode, 5), s, 17);
  106. if(ei)
  107. return(0);
  108. ei = decode_e(get_width(dcode, 5) + get_width(dcode, 6), s, 17);
  109. if(ei)
  110. return(0);
  111. ei = decode_e(get_width(dcode, 6) + get_width(dcode, 7), s, 17);
  112. ex = (get_color(dcode) == ZBAR_SPACE) ? 7 : 1;
  113. if(ei != ex)
  114. return(0);
  115. ei = decode_e(get_width(dcode, 7) + get_width(dcode, 8), s, 17);
  116. ex = (get_color(dcode) == ZBAR_SPACE) ? 8 : 1;
  117. if(get_color(dcode) == ZBAR_BAR) {
  118. /* stop character has extra bar */
  119. if(ei != 1)
  120. return(0);
  121. ei = decode_e(get_width(dcode, 8) + get_width(dcode, 9), s, 17);
  122. }
  123. dprintf(2, " pdf417[%c]: s=%d",
  124. (get_color(dcode)) ? '<' : '>', s);
  125. /* check quiet zone */
  126. if(ei >= 0 && ei < ex) {
  127. dprintf(2, " [invalid quiet]\n");
  128. return(0);
  129. }
  130. /* lock shared resources */
  131. if(get_lock(dcode, ZBAR_PDF417)) {
  132. dprintf(2, " [locked %d]\n", dcode->lock);
  133. return(0);
  134. }
  135. pdf417_decoder_t *dcode417 = &dcode->pdf417;
  136. dcode417->direction = get_color(dcode);
  137. dcode417->element = 0;
  138. dcode417->character = 0;
  139. dprintf(2, " [valid start]\n");
  140. return(ZBAR_PARTIAL);
  141. }
  142. zbar_symbol_type_t _zbar_decode_pdf417 (zbar_decoder_t *dcode)
  143. {
  144. pdf417_decoder_t *dcode417 = &dcode->pdf417;
  145. /* update latest character width */
  146. dcode417->s8 -= get_width(dcode, 8);
  147. dcode417->s8 += get_width(dcode, 0);
  148. if(dcode417->character < 0) {
  149. pdf417_decode_start(dcode);
  150. dprintf(4, "\n");
  151. return(0);
  152. }
  153. /* process every 8th element of active symbol */
  154. if(++dcode417->element)
  155. return(0);
  156. dcode417->element = 0;
  157. dprintf(2, " pdf417[%c%02d]:",
  158. (dcode417->direction) ? '<' : '>', dcode417->character);
  159. if(get_color(dcode) != dcode417->direction) {
  160. int c = dcode417->character;
  161. dcode->lock = 0;
  162. dcode417->character = -1;
  163. zassert(get_color(dcode) == dcode417->direction, ZBAR_NONE,
  164. "color=%x dir=%x char=%d elem=0 %s\n",
  165. get_color(dcode), dcode417->direction, c,
  166. _zbar_decoder_buf_dump(dcode->buf, c));
  167. }
  168. signed short c = pdf417_decode8(dcode);
  169. if((c < 0) ||
  170. ((dcode417->character >= BUFFER_MIN) &&
  171. size_buf(dcode, dcode417->character + 1))) {
  172. dprintf(1, (c < 0) ? " [aborted]\n" : " [overflow]\n");
  173. dcode->lock = 0;
  174. dcode417->character = -1;
  175. return(0);
  176. }
  177. /* FIXME TBD infer dimensions, save codewords */
  178. if(c == PDF417_STOP) {
  179. dprintf(1, " [valid stop]");
  180. /* FIXME check trailing bar and qz */
  181. dcode->lock = 0;
  182. dcode417->character = -1;
  183. }
  184. dprintf(2, "\n");
  185. return(0);
  186. }