ZBar bar code reader . http://zbar.sourceforge.net/ ZBar is licensed under the GNU LGPL 2.1 to enable development of both open source and commercial projects.

Dependents:   GR-PEACH_Camera_in_barcode levkov_ov7670

LICENSE

The ZBar Bar Code Reader is Copyright (C) 2007-2009 Jeff Brown <spadix@users.sourceforge.net> The QR Code reader is Copyright (C) 1999-2009 Timothy B. Terriberry <tterribe@xiph.org>

You can redistribute this library and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

ISAAC is based on the public domain implementation by Robert J. Jenkins Jr., and is itself public domain.

Portions of the bit stream reader are copyright (C) The Xiph.Org Foundation 1994-2008, and are licensed under a BSD-style license.

The Reed-Solomon decoder is derived from an implementation (C) 1991-1995 Henry Minsky (hqm@ua.com, hqm@ai.mit.edu), and is licensed under the LGPL with permission.

Committer:
RyoheiHagimoto
Date:
Tue Apr 19 02:19:39 2016 +0000
Revision:
1:500d42699c34
Parent:
0:56c5742b9e2b
Add copying.txt and license.txt

Who changed what in which revision?

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