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 2008-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_CODE39
RyoheiHagimoto 0:56c5742b9e2b 31 # define DEBUG_LEVEL (DEBUG_CODE39)
RyoheiHagimoto 0:56c5742b9e2b 32 #endif
RyoheiHagimoto 0:56c5742b9e2b 33 #include "zbar_debug.h"
RyoheiHagimoto 0:56c5742b9e2b 34
RyoheiHagimoto 0:56c5742b9e2b 35 #define NUM_CHARS (0x2c)
RyoheiHagimoto 0:56c5742b9e2b 36
RyoheiHagimoto 0:56c5742b9e2b 37 static const unsigned char code39_hi[32] = {
RyoheiHagimoto 0:56c5742b9e2b 38 0x80 | 0x00, /* 2 next */
RyoheiHagimoto 0:56c5742b9e2b 39 0x40 | 0x02, /* 4 */
RyoheiHagimoto 0:56c5742b9e2b 40 0x80 | 0x06, /* 2 next */
RyoheiHagimoto 0:56c5742b9e2b 41 0xc0 | 0x08, /* 2 skip */
RyoheiHagimoto 0:56c5742b9e2b 42 0x40 | 0x0a, /* 4 */
RyoheiHagimoto 0:56c5742b9e2b 43 0x80 | 0x0e, /* 2 next */
RyoheiHagimoto 0:56c5742b9e2b 44 0xc0 | 0x10, /* 2 skip */
RyoheiHagimoto 0:56c5742b9e2b 45 0x00 | 0x12, /* direct */
RyoheiHagimoto 0:56c5742b9e2b 46
RyoheiHagimoto 0:56c5742b9e2b 47 0x80 | 0x13, /* 2 next */
RyoheiHagimoto 0:56c5742b9e2b 48 0xc0 | 0x15, /* 2 skip */
RyoheiHagimoto 0:56c5742b9e2b 49 0x80 | 0x17, /* 2 next */
RyoheiHagimoto 0:56c5742b9e2b 50 0xff,
RyoheiHagimoto 0:56c5742b9e2b 51 0xc0 | 0x19, /* 2 skip */
RyoheiHagimoto 0:56c5742b9e2b 52 0x00 | 0x1b, /* direct */
RyoheiHagimoto 0:56c5742b9e2b 53 0xff,
RyoheiHagimoto 0:56c5742b9e2b 54 0xff,
RyoheiHagimoto 0:56c5742b9e2b 55
RyoheiHagimoto 0:56c5742b9e2b 56 0x40 | 0x1c, /* 4 */
RyoheiHagimoto 0:56c5742b9e2b 57 0x80 | 0x20, /* 2 next */
RyoheiHagimoto 0:56c5742b9e2b 58 0xc0 | 0x22, /* 2 skip */
RyoheiHagimoto 0:56c5742b9e2b 59 0x00 | 0x24, /* direct */
RyoheiHagimoto 0:56c5742b9e2b 60 0x80 | 0x25, /* 2 next */
RyoheiHagimoto 0:56c5742b9e2b 61 0xff,
RyoheiHagimoto 0:56c5742b9e2b 62 0x00 | 0x27, /* direct */
RyoheiHagimoto 0:56c5742b9e2b 63 0xff,
RyoheiHagimoto 0:56c5742b9e2b 64
RyoheiHagimoto 0:56c5742b9e2b 65 0xc0 | 0x28, /* 2 skip */
RyoheiHagimoto 0:56c5742b9e2b 66 0x00 | 0x2a, /* direct */
RyoheiHagimoto 0:56c5742b9e2b 67 0xff,
RyoheiHagimoto 0:56c5742b9e2b 68 0xff,
RyoheiHagimoto 0:56c5742b9e2b 69 0x00 | 0x2b, /* direct */
RyoheiHagimoto 0:56c5742b9e2b 70 0xff,
RyoheiHagimoto 0:56c5742b9e2b 71 0xff,
RyoheiHagimoto 0:56c5742b9e2b 72 0xff,
RyoheiHagimoto 0:56c5742b9e2b 73 };
RyoheiHagimoto 0:56c5742b9e2b 74
RyoheiHagimoto 0:56c5742b9e2b 75 typedef struct char39_s {
RyoheiHagimoto 0:56c5742b9e2b 76 unsigned char chk, rev, fwd;
RyoheiHagimoto 0:56c5742b9e2b 77 } char39_t;
RyoheiHagimoto 0:56c5742b9e2b 78
RyoheiHagimoto 0:56c5742b9e2b 79 static const char39_t code39_encodings[NUM_CHARS] = {
RyoheiHagimoto 0:56c5742b9e2b 80 { 0x07, 0x1a, 0x20 }, /* 00 */
RyoheiHagimoto 0:56c5742b9e2b 81 { 0x0d, 0x10, 0x03 }, /* 01 */
RyoheiHagimoto 0:56c5742b9e2b 82 { 0x13, 0x17, 0x22 }, /* 02 */
RyoheiHagimoto 0:56c5742b9e2b 83 { 0x16, 0x1d, 0x23 }, /* 03 */
RyoheiHagimoto 0:56c5742b9e2b 84 { 0x19, 0x0d, 0x05 }, /* 04 */
RyoheiHagimoto 0:56c5742b9e2b 85 { 0x1c, 0x13, 0x06 }, /* 05 */
RyoheiHagimoto 0:56c5742b9e2b 86 { 0x25, 0x07, 0x0c }, /* 06 */
RyoheiHagimoto 0:56c5742b9e2b 87 { 0x2a, 0x2a, 0x27 }, /* 07 */
RyoheiHagimoto 0:56c5742b9e2b 88 { 0x31, 0x04, 0x0e }, /* 08 */
RyoheiHagimoto 0:56c5742b9e2b 89 { 0x34, 0x00, 0x0f }, /* 09 */
RyoheiHagimoto 0:56c5742b9e2b 90 { 0x43, 0x15, 0x25 }, /* 0a */
RyoheiHagimoto 0:56c5742b9e2b 91 { 0x46, 0x1c, 0x26 }, /* 0b */
RyoheiHagimoto 0:56c5742b9e2b 92 { 0x49, 0x0b, 0x08 }, /* 0c */
RyoheiHagimoto 0:56c5742b9e2b 93 { 0x4c, 0x12, 0x09 }, /* 0d */
RyoheiHagimoto 0:56c5742b9e2b 94 { 0x52, 0x19, 0x2b }, /* 0e */
RyoheiHagimoto 0:56c5742b9e2b 95 { 0x58, 0x0f, 0x00 }, /* 0f */
RyoheiHagimoto 0:56c5742b9e2b 96 { 0x61, 0x02, 0x11 }, /* 10 */
RyoheiHagimoto 0:56c5742b9e2b 97 { 0x64, 0x09, 0x12 }, /* 11 */
RyoheiHagimoto 0:56c5742b9e2b 98 { 0x70, 0x06, 0x13 }, /* 12 */
RyoheiHagimoto 0:56c5742b9e2b 99 { 0x85, 0x24, 0x16 }, /* 13 */
RyoheiHagimoto 0:56c5742b9e2b 100 { 0x8a, 0x29, 0x28 }, /* 14 */
RyoheiHagimoto 0:56c5742b9e2b 101 { 0x91, 0x21, 0x18 }, /* 15 */
RyoheiHagimoto 0:56c5742b9e2b 102 { 0x94, 0x2b, 0x19 }, /* 16 */
RyoheiHagimoto 0:56c5742b9e2b 103 { 0xa2, 0x28, 0x29 }, /* 17 */
RyoheiHagimoto 0:56c5742b9e2b 104 { 0xa8, 0x27, 0x2a }, /* 18 */
RyoheiHagimoto 0:56c5742b9e2b 105 { 0xc1, 0x1f, 0x1b }, /* 19 */
RyoheiHagimoto 0:56c5742b9e2b 106 { 0xc4, 0x26, 0x1c }, /* 1a */
RyoheiHagimoto 0:56c5742b9e2b 107 { 0xd0, 0x23, 0x1d }, /* 1b */
RyoheiHagimoto 0:56c5742b9e2b 108 { 0x03, 0x14, 0x1e }, /* 1c */
RyoheiHagimoto 0:56c5742b9e2b 109 { 0x06, 0x1b, 0x1f }, /* 1d */
RyoheiHagimoto 0:56c5742b9e2b 110 { 0x09, 0x0a, 0x01 }, /* 1e */
RyoheiHagimoto 0:56c5742b9e2b 111 { 0x0c, 0x11, 0x02 }, /* 1f */
RyoheiHagimoto 0:56c5742b9e2b 112 { 0x12, 0x18, 0x21 }, /* 20 */
RyoheiHagimoto 0:56c5742b9e2b 113 { 0x18, 0x0e, 0x04 }, /* 21 */
RyoheiHagimoto 0:56c5742b9e2b 114 { 0x21, 0x01, 0x0a }, /* 22 */
RyoheiHagimoto 0:56c5742b9e2b 115 { 0x24, 0x08, 0x0b }, /* 23 */
RyoheiHagimoto 0:56c5742b9e2b 116 { 0x30, 0x05, 0x0d }, /* 24 */
RyoheiHagimoto 0:56c5742b9e2b 117 { 0x42, 0x16, 0x24 }, /* 25 */
RyoheiHagimoto 0:56c5742b9e2b 118 { 0x48, 0x0c, 0x07 }, /* 26 */
RyoheiHagimoto 0:56c5742b9e2b 119 { 0x60, 0x03, 0x10 }, /* 27 */
RyoheiHagimoto 0:56c5742b9e2b 120 { 0x81, 0x1e, 0x14 }, /* 28 */
RyoheiHagimoto 0:56c5742b9e2b 121 { 0x84, 0x25, 0x15 }, /* 29 */
RyoheiHagimoto 0:56c5742b9e2b 122 { 0x90, 0x22, 0x17 }, /* 2a */
RyoheiHagimoto 0:56c5742b9e2b 123 { 0xc0, 0x20, 0x1a }, /* 2b */
RyoheiHagimoto 0:56c5742b9e2b 124 };
RyoheiHagimoto 0:56c5742b9e2b 125
RyoheiHagimoto 0:56c5742b9e2b 126 static const unsigned char code39_characters[NUM_CHARS] =
RyoheiHagimoto 0:56c5742b9e2b 127 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%*";
RyoheiHagimoto 0:56c5742b9e2b 128
RyoheiHagimoto 0:56c5742b9e2b 129 static inline unsigned char code39_decode1 (unsigned char enc,
RyoheiHagimoto 0:56c5742b9e2b 130 unsigned e,
RyoheiHagimoto 0:56c5742b9e2b 131 unsigned s)
RyoheiHagimoto 0:56c5742b9e2b 132 {
RyoheiHagimoto 0:56c5742b9e2b 133 unsigned char E = decode_e(e, s, 36);
RyoheiHagimoto 0:56c5742b9e2b 134 if(E > 7)
RyoheiHagimoto 0:56c5742b9e2b 135 return(0xff);
RyoheiHagimoto 0:56c5742b9e2b 136 enc <<= 1;
RyoheiHagimoto 0:56c5742b9e2b 137 if(E > 2) {
RyoheiHagimoto 0:56c5742b9e2b 138 enc |= 1;
RyoheiHagimoto 0:56c5742b9e2b 139 dprintf(2, "1");
RyoheiHagimoto 0:56c5742b9e2b 140 }
RyoheiHagimoto 0:56c5742b9e2b 141 else
RyoheiHagimoto 0:56c5742b9e2b 142 dprintf(2, "0");
RyoheiHagimoto 0:56c5742b9e2b 143 return(enc);
RyoheiHagimoto 0:56c5742b9e2b 144 }
RyoheiHagimoto 0:56c5742b9e2b 145
RyoheiHagimoto 0:56c5742b9e2b 146 static inline signed char code39_decode9 (zbar_decoder_t *dcode)
RyoheiHagimoto 0:56c5742b9e2b 147 {
RyoheiHagimoto 0:56c5742b9e2b 148 code39_decoder_t *dcode39 = &dcode->code39;
RyoheiHagimoto 0:56c5742b9e2b 149
RyoheiHagimoto 0:56c5742b9e2b 150 dprintf(2, " s=%d ", dcode39->s9);
RyoheiHagimoto 0:56c5742b9e2b 151 if(dcode39->s9 < 9)
RyoheiHagimoto 0:56c5742b9e2b 152 return(-1);
RyoheiHagimoto 0:56c5742b9e2b 153
RyoheiHagimoto 0:56c5742b9e2b 154 /* threshold bar width ratios */
RyoheiHagimoto 0:56c5742b9e2b 155 unsigned char i, enc = 0;
RyoheiHagimoto 0:56c5742b9e2b 156 for(i = 0; i < 5; i++) {
RyoheiHagimoto 0:56c5742b9e2b 157 enc = code39_decode1(enc, get_width(dcode, i), dcode39->s9);
RyoheiHagimoto 0:56c5742b9e2b 158 if(enc == 0xff)
RyoheiHagimoto 0:56c5742b9e2b 159 return(-1);
RyoheiHagimoto 0:56c5742b9e2b 160 }
RyoheiHagimoto 0:56c5742b9e2b 161 zassert(enc < 0x20, -1, " enc=%x s9=%x\n", enc, dcode39->s9);
RyoheiHagimoto 0:56c5742b9e2b 162
RyoheiHagimoto 0:56c5742b9e2b 163 /* lookup first 5 encoded widths for coarse decode */
RyoheiHagimoto 0:56c5742b9e2b 164 unsigned char idx = code39_hi[enc];
RyoheiHagimoto 0:56c5742b9e2b 165 if(idx == 0xff)
RyoheiHagimoto 0:56c5742b9e2b 166 return(-1);
RyoheiHagimoto 0:56c5742b9e2b 167
RyoheiHagimoto 0:56c5742b9e2b 168 /* encode remaining widths (NB first encoded width is lost) */
RyoheiHagimoto 0:56c5742b9e2b 169 for(; i < 9; i++) {
RyoheiHagimoto 0:56c5742b9e2b 170 enc = code39_decode1(enc, get_width(dcode, i), dcode39->s9);
RyoheiHagimoto 0:56c5742b9e2b 171 if(enc == 0xff)
RyoheiHagimoto 0:56c5742b9e2b 172 return(-1);
RyoheiHagimoto 0:56c5742b9e2b 173 }
RyoheiHagimoto 0:56c5742b9e2b 174
RyoheiHagimoto 0:56c5742b9e2b 175 if((idx & 0xc0) == 0x80)
RyoheiHagimoto 0:56c5742b9e2b 176 idx = (idx & 0x3f) + ((enc >> 3) & 1);
RyoheiHagimoto 0:56c5742b9e2b 177 else if((idx & 0xc0) == 0xc0)
RyoheiHagimoto 0:56c5742b9e2b 178 idx = (idx & 0x3f) + ((enc >> 2) & 1);
RyoheiHagimoto 0:56c5742b9e2b 179 else if(idx & 0xc0)
RyoheiHagimoto 0:56c5742b9e2b 180 idx = (idx & 0x3f) + ((enc >> 2) & 3);
RyoheiHagimoto 0:56c5742b9e2b 181 zassert(idx < 0x2c, -1, " idx=%x enc=%x s9=%x\n", idx, enc, dcode39->s9);
RyoheiHagimoto 0:56c5742b9e2b 182
RyoheiHagimoto 0:56c5742b9e2b 183 const char39_t *c = &code39_encodings[idx];
RyoheiHagimoto 0:56c5742b9e2b 184 dprintf(2, " i=%02x chk=%02x c=%02x/%02x", idx, c->chk, c->fwd, c->rev);
RyoheiHagimoto 0:56c5742b9e2b 185 if(enc != c->chk)
RyoheiHagimoto 0:56c5742b9e2b 186 return(-1);
RyoheiHagimoto 0:56c5742b9e2b 187
RyoheiHagimoto 0:56c5742b9e2b 188 dcode39->width = dcode39->s9;
RyoheiHagimoto 0:56c5742b9e2b 189 return((dcode39->direction) ? c->rev : c->fwd);
RyoheiHagimoto 0:56c5742b9e2b 190 }
RyoheiHagimoto 0:56c5742b9e2b 191
RyoheiHagimoto 0:56c5742b9e2b 192 static inline signed char code39_decode_start (zbar_decoder_t *dcode)
RyoheiHagimoto 0:56c5742b9e2b 193 {
RyoheiHagimoto 0:56c5742b9e2b 194 code39_decoder_t *dcode39 = &dcode->code39;
RyoheiHagimoto 0:56c5742b9e2b 195
RyoheiHagimoto 0:56c5742b9e2b 196 signed char c = code39_decode9(dcode);
RyoheiHagimoto 0:56c5742b9e2b 197 if(c == 0x19)
RyoheiHagimoto 0:56c5742b9e2b 198 dcode39->direction ^= 1;
RyoheiHagimoto 0:56c5742b9e2b 199 else if(c != 0x2b) {
RyoheiHagimoto 0:56c5742b9e2b 200 dprintf(2, "\n");
RyoheiHagimoto 0:56c5742b9e2b 201 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 202 }
RyoheiHagimoto 0:56c5742b9e2b 203
RyoheiHagimoto 0:56c5742b9e2b 204 /* check leading quiet zone - spec is 10x */
RyoheiHagimoto 0:56c5742b9e2b 205 unsigned quiet = get_width(dcode, 9);
RyoheiHagimoto 0:56c5742b9e2b 206 if(quiet && quiet < dcode39->s9 / 2) {
RyoheiHagimoto 0:56c5742b9e2b 207 dprintf(2, " [invalid quiet]\n");
RyoheiHagimoto 0:56c5742b9e2b 208 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 209 }
RyoheiHagimoto 0:56c5742b9e2b 210
RyoheiHagimoto 0:56c5742b9e2b 211 dcode39->element = 9;
RyoheiHagimoto 0:56c5742b9e2b 212 dcode39->character = 0;
RyoheiHagimoto 0:56c5742b9e2b 213 dprintf(1, " dir=%x [valid start]\n", dcode39->direction);
RyoheiHagimoto 0:56c5742b9e2b 214 return(ZBAR_PARTIAL);
RyoheiHagimoto 0:56c5742b9e2b 215 }
RyoheiHagimoto 0:56c5742b9e2b 216
RyoheiHagimoto 0:56c5742b9e2b 217 static inline void code39_postprocess (zbar_decoder_t *dcode)
RyoheiHagimoto 0:56c5742b9e2b 218 {
RyoheiHagimoto 0:56c5742b9e2b 219 code39_decoder_t *dcode39 = &dcode->code39;
RyoheiHagimoto 0:56c5742b9e2b 220 int i;
RyoheiHagimoto 0:56c5742b9e2b 221 if(dcode39->direction) {
RyoheiHagimoto 0:56c5742b9e2b 222 /* reverse buffer */
RyoheiHagimoto 0:56c5742b9e2b 223 dprintf(2, " (rev)");
RyoheiHagimoto 0:56c5742b9e2b 224 for(i = 0; i < dcode39->character / 2; i++) {
RyoheiHagimoto 0:56c5742b9e2b 225 unsigned j = dcode39->character - 1 - i;
RyoheiHagimoto 0:56c5742b9e2b 226 char code = dcode->buf[i];
RyoheiHagimoto 0:56c5742b9e2b 227 dcode->buf[i] = dcode->buf[j];
RyoheiHagimoto 0:56c5742b9e2b 228 dcode->buf[j] = code;
RyoheiHagimoto 0:56c5742b9e2b 229 }
RyoheiHagimoto 0:56c5742b9e2b 230 }
RyoheiHagimoto 0:56c5742b9e2b 231 for(i = 0; i < dcode39->character; i++)
RyoheiHagimoto 0:56c5742b9e2b 232 dcode->buf[i] = ((dcode->buf[i] < 0x2b)
RyoheiHagimoto 0:56c5742b9e2b 233 ? code39_characters[(unsigned)dcode->buf[i]]
RyoheiHagimoto 0:56c5742b9e2b 234 : '?');
RyoheiHagimoto 0:56c5742b9e2b 235 dcode->buflen = i;
RyoheiHagimoto 0:56c5742b9e2b 236 dcode->buf[i] = '\0';
RyoheiHagimoto 0:56c5742b9e2b 237 }
RyoheiHagimoto 0:56c5742b9e2b 238
RyoheiHagimoto 0:56c5742b9e2b 239 zbar_symbol_type_t _zbar_decode_code39 (zbar_decoder_t *dcode)
RyoheiHagimoto 0:56c5742b9e2b 240 {
RyoheiHagimoto 0:56c5742b9e2b 241 code39_decoder_t *dcode39 = &dcode->code39;
RyoheiHagimoto 0:56c5742b9e2b 242
RyoheiHagimoto 0:56c5742b9e2b 243 /* update latest character width */
RyoheiHagimoto 0:56c5742b9e2b 244 dcode39->s9 -= get_width(dcode, 9);
RyoheiHagimoto 0:56c5742b9e2b 245 dcode39->s9 += get_width(dcode, 0);
RyoheiHagimoto 0:56c5742b9e2b 246
RyoheiHagimoto 0:56c5742b9e2b 247 if(dcode39->character < 0) {
RyoheiHagimoto 0:56c5742b9e2b 248 if(get_color(dcode) != ZBAR_BAR)
RyoheiHagimoto 0:56c5742b9e2b 249 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 250 dprintf(2, " code39:");
RyoheiHagimoto 0:56c5742b9e2b 251 return(code39_decode_start(dcode));
RyoheiHagimoto 0:56c5742b9e2b 252 }
RyoheiHagimoto 0:56c5742b9e2b 253
RyoheiHagimoto 0:56c5742b9e2b 254 if(++dcode39->element < 9)
RyoheiHagimoto 0:56c5742b9e2b 255 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 256
RyoheiHagimoto 0:56c5742b9e2b 257 dprintf(2, " code39[%c%02d+%x]",
RyoheiHagimoto 0:56c5742b9e2b 258 (dcode39->direction) ? '<' : '>',
RyoheiHagimoto 0:56c5742b9e2b 259 dcode39->character, dcode39->element);
RyoheiHagimoto 0:56c5742b9e2b 260
RyoheiHagimoto 0:56c5742b9e2b 261 if(dcode39->element == 10) {
RyoheiHagimoto 0:56c5742b9e2b 262 unsigned space = get_width(dcode, 0);
RyoheiHagimoto 0:56c5742b9e2b 263 if(dcode39->character &&
RyoheiHagimoto 0:56c5742b9e2b 264 dcode->buf[dcode39->character - 1] == 0x2b) { /* STOP */
RyoheiHagimoto 0:56c5742b9e2b 265 /* trim STOP character */
RyoheiHagimoto 0:56c5742b9e2b 266 dcode39->character--;
RyoheiHagimoto 0:56c5742b9e2b 267 zbar_symbol_type_t sym = ZBAR_CODE39;
RyoheiHagimoto 0:56c5742b9e2b 268
RyoheiHagimoto 0:56c5742b9e2b 269 /* trailing quiet zone check */
RyoheiHagimoto 0:56c5742b9e2b 270 if(space && space < dcode39->width / 2) {
RyoheiHagimoto 0:56c5742b9e2b 271 dprintf(2, " [invalid qz]\n");
RyoheiHagimoto 0:56c5742b9e2b 272 sym = ZBAR_NONE;
RyoheiHagimoto 0:56c5742b9e2b 273 }
RyoheiHagimoto 0:56c5742b9e2b 274 else if(dcode39->character < CFG(*dcode39, ZBAR_CFG_MIN_LEN) ||
RyoheiHagimoto 0:56c5742b9e2b 275 (CFG(*dcode39, ZBAR_CFG_MAX_LEN) > 0 &&
RyoheiHagimoto 0:56c5742b9e2b 276 dcode39->character > CFG(*dcode39, ZBAR_CFG_MAX_LEN))) {
RyoheiHagimoto 0:56c5742b9e2b 277 dprintf(2, " [invalid len]\n");
RyoheiHagimoto 0:56c5742b9e2b 278 sym = ZBAR_NONE;
RyoheiHagimoto 0:56c5742b9e2b 279 }
RyoheiHagimoto 0:56c5742b9e2b 280 else {
RyoheiHagimoto 0:56c5742b9e2b 281 /* FIXME checksum (needs config enable) */
RyoheiHagimoto 0:56c5742b9e2b 282 code39_postprocess(dcode);
RyoheiHagimoto 0:56c5742b9e2b 283 dprintf(2, " [valid end]\n");
RyoheiHagimoto 0:56c5742b9e2b 284 }
RyoheiHagimoto 0:56c5742b9e2b 285 dcode39->character = -1;
RyoheiHagimoto 0:56c5742b9e2b 286 if(!sym)
RyoheiHagimoto 0:56c5742b9e2b 287 dcode->lock = 0;
RyoheiHagimoto 0:56c5742b9e2b 288 return(sym);
RyoheiHagimoto 0:56c5742b9e2b 289 }
RyoheiHagimoto 0:56c5742b9e2b 290 if(space > dcode39->width / 2) {
RyoheiHagimoto 0:56c5742b9e2b 291 /* inter-character space check failure */
RyoheiHagimoto 0:56c5742b9e2b 292 dcode->lock = 0;
RyoheiHagimoto 0:56c5742b9e2b 293 dcode39->character = -1;
RyoheiHagimoto 0:56c5742b9e2b 294 dprintf(2, " ics>%d [invalid ics]", dcode39->width);
RyoheiHagimoto 0:56c5742b9e2b 295 }
RyoheiHagimoto 0:56c5742b9e2b 296 dcode39->element = 0;
RyoheiHagimoto 0:56c5742b9e2b 297 dprintf(2, "\n");
RyoheiHagimoto 0:56c5742b9e2b 298 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 299 }
RyoheiHagimoto 0:56c5742b9e2b 300
RyoheiHagimoto 0:56c5742b9e2b 301 signed char c = code39_decode9(dcode);
RyoheiHagimoto 0:56c5742b9e2b 302 dprintf(2, " c=%d", c);
RyoheiHagimoto 0:56c5742b9e2b 303
RyoheiHagimoto 0:56c5742b9e2b 304 /* lock shared resources */
RyoheiHagimoto 0:56c5742b9e2b 305 if(!dcode39->character && get_lock(dcode, ZBAR_CODE39)) {
RyoheiHagimoto 0:56c5742b9e2b 306 dcode39->character = -1;
RyoheiHagimoto 0:56c5742b9e2b 307 dprintf(1, " [locked %d]\n", dcode->lock);
RyoheiHagimoto 0:56c5742b9e2b 308 return(ZBAR_PARTIAL);
RyoheiHagimoto 0:56c5742b9e2b 309 }
RyoheiHagimoto 0:56c5742b9e2b 310
RyoheiHagimoto 0:56c5742b9e2b 311 if(c < 0 ||
RyoheiHagimoto 0:56c5742b9e2b 312 ((dcode39->character >= BUFFER_MIN) &&
RyoheiHagimoto 0:56c5742b9e2b 313 size_buf(dcode, dcode39->character + 1))) {
RyoheiHagimoto 0:56c5742b9e2b 314 dprintf(1, (c < 0) ? " [aborted]\n" : " [overflow]\n");
RyoheiHagimoto 0:56c5742b9e2b 315 dcode->lock = 0;
RyoheiHagimoto 0:56c5742b9e2b 316 dcode39->character = -1;
RyoheiHagimoto 0:56c5742b9e2b 317 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 318 }
RyoheiHagimoto 0:56c5742b9e2b 319 else {
RyoheiHagimoto 0:56c5742b9e2b 320 zassert(c < 0x2c, ZBAR_NONE, "c=%02x s9=%x\n", c, dcode39->s9);
RyoheiHagimoto 0:56c5742b9e2b 321 dprintf(2, "\n");
RyoheiHagimoto 0:56c5742b9e2b 322 }
RyoheiHagimoto 0:56c5742b9e2b 323
RyoheiHagimoto 0:56c5742b9e2b 324 dcode->buf[dcode39->character++] = c;
RyoheiHagimoto 0:56c5742b9e2b 325
RyoheiHagimoto 0:56c5742b9e2b 326 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 327 }
RyoheiHagimoto 0:56c5742b9e2b 328