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:00:37 2016 +0000
Revision:
0:56c5742b9e2b
First revicion

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_I25
RyoheiHagimoto 0:56c5742b9e2b 31 # define DEBUG_LEVEL (DEBUG_I25)
RyoheiHagimoto 0:56c5742b9e2b 32 #endif
RyoheiHagimoto 0:56c5742b9e2b 33 #include "zbar_debug.h"
RyoheiHagimoto 0:56c5742b9e2b 34
RyoheiHagimoto 0:56c5742b9e2b 35 static inline unsigned char i25_decode1 (unsigned char enc,
RyoheiHagimoto 0:56c5742b9e2b 36 unsigned e,
RyoheiHagimoto 0:56c5742b9e2b 37 unsigned s)
RyoheiHagimoto 0:56c5742b9e2b 38 {
RyoheiHagimoto 0:56c5742b9e2b 39 unsigned char E = decode_e(e, s, 45);
RyoheiHagimoto 0:56c5742b9e2b 40 if(E > 7)
RyoheiHagimoto 0:56c5742b9e2b 41 return(0xff);
RyoheiHagimoto 0:56c5742b9e2b 42 enc <<= 1;
RyoheiHagimoto 0:56c5742b9e2b 43 if(E > 2)
RyoheiHagimoto 0:56c5742b9e2b 44 enc |= 1;
RyoheiHagimoto 0:56c5742b9e2b 45 return(enc);
RyoheiHagimoto 0:56c5742b9e2b 46 }
RyoheiHagimoto 0:56c5742b9e2b 47
RyoheiHagimoto 0:56c5742b9e2b 48 static inline unsigned char i25_decode10 (zbar_decoder_t *dcode,
RyoheiHagimoto 0:56c5742b9e2b 49 unsigned char offset)
RyoheiHagimoto 0:56c5742b9e2b 50 {
RyoheiHagimoto 0:56c5742b9e2b 51 i25_decoder_t *dcode25 = &dcode->i25;
RyoheiHagimoto 0:56c5742b9e2b 52 dprintf(2, " s=%d", dcode25->s10);
RyoheiHagimoto 0:56c5742b9e2b 53 if(dcode25->s10 < 10)
RyoheiHagimoto 0:56c5742b9e2b 54 return(0xff);
RyoheiHagimoto 0:56c5742b9e2b 55
RyoheiHagimoto 0:56c5742b9e2b 56 /* threshold bar width ratios */
RyoheiHagimoto 0:56c5742b9e2b 57 unsigned char enc = 0, par = 0;
RyoheiHagimoto 0:56c5742b9e2b 58 signed char i;
RyoheiHagimoto 0:56c5742b9e2b 59 for(i = 8; i >= 0; i -= 2) {
RyoheiHagimoto 0:56c5742b9e2b 60 unsigned char j = offset + ((dcode25->direction) ? i : 8 - i);
RyoheiHagimoto 0:56c5742b9e2b 61 enc = i25_decode1(enc, get_width(dcode, j), dcode25->s10);
RyoheiHagimoto 0:56c5742b9e2b 62 if(enc == 0xff)
RyoheiHagimoto 0:56c5742b9e2b 63 return(0xff);
RyoheiHagimoto 0:56c5742b9e2b 64 if(enc & 1)
RyoheiHagimoto 0:56c5742b9e2b 65 par++;
RyoheiHagimoto 0:56c5742b9e2b 66 }
RyoheiHagimoto 0:56c5742b9e2b 67
RyoheiHagimoto 0:56c5742b9e2b 68 dprintf(2, " enc=%02x par=%x", enc, par);
RyoheiHagimoto 0:56c5742b9e2b 69
RyoheiHagimoto 0:56c5742b9e2b 70 /* parity check */
RyoheiHagimoto 0:56c5742b9e2b 71 if(par != 2) {
RyoheiHagimoto 0:56c5742b9e2b 72 dprintf(2, " [bad parity]");
RyoheiHagimoto 0:56c5742b9e2b 73 return(0xff);
RyoheiHagimoto 0:56c5742b9e2b 74 }
RyoheiHagimoto 0:56c5742b9e2b 75
RyoheiHagimoto 0:56c5742b9e2b 76 /* decode binary weights */
RyoheiHagimoto 0:56c5742b9e2b 77 enc &= 0xf;
RyoheiHagimoto 0:56c5742b9e2b 78 if(enc & 8) {
RyoheiHagimoto 0:56c5742b9e2b 79 if(enc == 12)
RyoheiHagimoto 0:56c5742b9e2b 80 enc = 0;
RyoheiHagimoto 0:56c5742b9e2b 81 else if(--enc > 9) {
RyoheiHagimoto 0:56c5742b9e2b 82 dprintf(2, " [invalid encoding]");
RyoheiHagimoto 0:56c5742b9e2b 83 return(0xff);
RyoheiHagimoto 0:56c5742b9e2b 84 }
RyoheiHagimoto 0:56c5742b9e2b 85 }
RyoheiHagimoto 0:56c5742b9e2b 86
RyoheiHagimoto 0:56c5742b9e2b 87 dprintf(2, " => %x", enc);
RyoheiHagimoto 0:56c5742b9e2b 88 return(enc);
RyoheiHagimoto 0:56c5742b9e2b 89 }
RyoheiHagimoto 0:56c5742b9e2b 90
RyoheiHagimoto 0:56c5742b9e2b 91 static inline signed char i25_decode_start (zbar_decoder_t *dcode)
RyoheiHagimoto 0:56c5742b9e2b 92 {
RyoheiHagimoto 0:56c5742b9e2b 93 i25_decoder_t *dcode25 = &dcode->i25;
RyoheiHagimoto 0:56c5742b9e2b 94 if(dcode25->s10 < 10)
RyoheiHagimoto 0:56c5742b9e2b 95 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 96
RyoheiHagimoto 0:56c5742b9e2b 97 unsigned char enc = 0;
RyoheiHagimoto 0:56c5742b9e2b 98 unsigned char i = 10;
RyoheiHagimoto 0:56c5742b9e2b 99 enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10);
RyoheiHagimoto 0:56c5742b9e2b 100 enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10);
RyoheiHagimoto 0:56c5742b9e2b 101 enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10);
RyoheiHagimoto 0:56c5742b9e2b 102
RyoheiHagimoto 0:56c5742b9e2b 103 if((get_color(dcode) == ZBAR_BAR)
RyoheiHagimoto 0:56c5742b9e2b 104 ? enc != 4
RyoheiHagimoto 0:56c5742b9e2b 105 : (enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10))) {
RyoheiHagimoto 0:56c5742b9e2b 106 dprintf(4, " i25: s=%d enc=%x [invalid]\n", dcode25->s10, enc);
RyoheiHagimoto 0:56c5742b9e2b 107 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 108 }
RyoheiHagimoto 0:56c5742b9e2b 109
RyoheiHagimoto 0:56c5742b9e2b 110 /* check leading quiet zone - spec is 10n(?)
RyoheiHagimoto 0:56c5742b9e2b 111 * we require 5.25n for w=2n to 6.75n for w=3n
RyoheiHagimoto 0:56c5742b9e2b 112 * (FIXME should really factor in w:n ratio)
RyoheiHagimoto 0:56c5742b9e2b 113 */
RyoheiHagimoto 0:56c5742b9e2b 114 unsigned quiet = get_width(dcode, i++);
RyoheiHagimoto 0:56c5742b9e2b 115 if(quiet && quiet < dcode25->s10 * 3 / 8) {
RyoheiHagimoto 0:56c5742b9e2b 116 dprintf(3, " i25: s=%d enc=%x q=%d [invalid qz]\n",
RyoheiHagimoto 0:56c5742b9e2b 117 dcode25->s10, enc, quiet);
RyoheiHagimoto 0:56c5742b9e2b 118 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 119 }
RyoheiHagimoto 0:56c5742b9e2b 120
RyoheiHagimoto 0:56c5742b9e2b 121 dcode25->direction = get_color(dcode);
RyoheiHagimoto 0:56c5742b9e2b 122 dcode25->element = 1;
RyoheiHagimoto 0:56c5742b9e2b 123 dcode25->character = 0;
RyoheiHagimoto 0:56c5742b9e2b 124 return(ZBAR_PARTIAL);
RyoheiHagimoto 0:56c5742b9e2b 125 }
RyoheiHagimoto 0:56c5742b9e2b 126
RyoheiHagimoto 0:56c5742b9e2b 127 static inline signed char i25_decode_end (zbar_decoder_t *dcode)
RyoheiHagimoto 0:56c5742b9e2b 128 {
RyoheiHagimoto 0:56c5742b9e2b 129 i25_decoder_t *dcode25 = &dcode->i25;
RyoheiHagimoto 0:56c5742b9e2b 130
RyoheiHagimoto 0:56c5742b9e2b 131 /* check trailing quiet zone */
RyoheiHagimoto 0:56c5742b9e2b 132 unsigned quiet = get_width(dcode, 0);
RyoheiHagimoto 0:56c5742b9e2b 133 if((quiet && quiet < dcode25->width * 3 / 8) ||
RyoheiHagimoto 0:56c5742b9e2b 134 decode_e(get_width(dcode, 1), dcode25->width, 45) > 2 ||
RyoheiHagimoto 0:56c5742b9e2b 135 decode_e(get_width(dcode, 2), dcode25->width, 45) > 2) {
RyoheiHagimoto 0:56c5742b9e2b 136 dprintf(3, " s=%d q=%d [invalid qz]\n", dcode25->width, quiet);
RyoheiHagimoto 0:56c5742b9e2b 137 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 138 }
RyoheiHagimoto 0:56c5742b9e2b 139
RyoheiHagimoto 0:56c5742b9e2b 140 /* check exit condition */
RyoheiHagimoto 0:56c5742b9e2b 141 unsigned char E = decode_e(get_width(dcode, 3), dcode25->width, 45);
RyoheiHagimoto 0:56c5742b9e2b 142 if((!dcode25->direction)
RyoheiHagimoto 0:56c5742b9e2b 143 ? E - 3 > 4
RyoheiHagimoto 0:56c5742b9e2b 144 : (E > 2 ||
RyoheiHagimoto 0:56c5742b9e2b 145 decode_e(get_width(dcode, 4), dcode25->width, 45) > 2))
RyoheiHagimoto 0:56c5742b9e2b 146 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 147
RyoheiHagimoto 0:56c5742b9e2b 148 if(dcode25->direction) {
RyoheiHagimoto 0:56c5742b9e2b 149 /* reverse buffer */
RyoheiHagimoto 0:56c5742b9e2b 150 dprintf(2, " (rev)");
RyoheiHagimoto 0:56c5742b9e2b 151 int i;
RyoheiHagimoto 0:56c5742b9e2b 152 for(i = 0; i < dcode25->character / 2; i++) {
RyoheiHagimoto 0:56c5742b9e2b 153 unsigned j = dcode25->character - 1 - i;
RyoheiHagimoto 0:56c5742b9e2b 154 char c = dcode->buf[i];
RyoheiHagimoto 0:56c5742b9e2b 155 dcode->buf[i] = dcode->buf[j];
RyoheiHagimoto 0:56c5742b9e2b 156 dcode->buf[j] = c;
RyoheiHagimoto 0:56c5742b9e2b 157 }
RyoheiHagimoto 0:56c5742b9e2b 158 }
RyoheiHagimoto 0:56c5742b9e2b 159
RyoheiHagimoto 0:56c5742b9e2b 160 if(dcode25->character < CFG(*dcode25, ZBAR_CFG_MIN_LEN) ||
RyoheiHagimoto 0:56c5742b9e2b 161 (CFG(*dcode25, ZBAR_CFG_MAX_LEN) > 0 &&
RyoheiHagimoto 0:56c5742b9e2b 162 dcode25->character > CFG(*dcode25, ZBAR_CFG_MAX_LEN))) {
RyoheiHagimoto 0:56c5742b9e2b 163 dprintf(2, " [invalid len]\n");
RyoheiHagimoto 0:56c5742b9e2b 164 dcode->lock = 0;
RyoheiHagimoto 0:56c5742b9e2b 165 dcode25->character = -1;
RyoheiHagimoto 0:56c5742b9e2b 166 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 167 }
RyoheiHagimoto 0:56c5742b9e2b 168
RyoheiHagimoto 0:56c5742b9e2b 169 dcode->buflen = dcode25->character;
RyoheiHagimoto 0:56c5742b9e2b 170 dcode->buf[dcode25->character] = '\0';
RyoheiHagimoto 0:56c5742b9e2b 171 dprintf(2, " [valid end]\n");
RyoheiHagimoto 0:56c5742b9e2b 172 dcode25->character = -1;
RyoheiHagimoto 0:56c5742b9e2b 173 return(ZBAR_I25);
RyoheiHagimoto 0:56c5742b9e2b 174 }
RyoheiHagimoto 0:56c5742b9e2b 175
RyoheiHagimoto 0:56c5742b9e2b 176 zbar_symbol_type_t _zbar_decode_i25 (zbar_decoder_t *dcode)
RyoheiHagimoto 0:56c5742b9e2b 177 {
RyoheiHagimoto 0:56c5742b9e2b 178 i25_decoder_t *dcode25 = &dcode->i25;
RyoheiHagimoto 0:56c5742b9e2b 179
RyoheiHagimoto 0:56c5742b9e2b 180 #if (ENABLE_I25)
RyoheiHagimoto 0:56c5742b9e2b 181 #else
RyoheiHagimoto 0:56c5742b9e2b 182 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 183 #endif
RyoheiHagimoto 0:56c5742b9e2b 184
RyoheiHagimoto 0:56c5742b9e2b 185 /* update latest character width */
RyoheiHagimoto 0:56c5742b9e2b 186 dcode25->s10 -= get_width(dcode, 10);
RyoheiHagimoto 0:56c5742b9e2b 187 dcode25->s10 += get_width(dcode, 0);
RyoheiHagimoto 0:56c5742b9e2b 188
RyoheiHagimoto 0:56c5742b9e2b 189 if(dcode25->character < 0 &&
RyoheiHagimoto 0:56c5742b9e2b 190 !i25_decode_start(dcode))
RyoheiHagimoto 0:56c5742b9e2b 191 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 192
RyoheiHagimoto 0:56c5742b9e2b 193 if(--dcode25->element == 6 - dcode25->direction)
RyoheiHagimoto 0:56c5742b9e2b 194 return(i25_decode_end(dcode));
RyoheiHagimoto 0:56c5742b9e2b 195 else if(dcode25->element)
RyoheiHagimoto 0:56c5742b9e2b 196 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 197
RyoheiHagimoto 0:56c5742b9e2b 198 /* FIXME check current character width against previous */
RyoheiHagimoto 0:56c5742b9e2b 199 dcode25->width = dcode25->s10;
RyoheiHagimoto 0:56c5742b9e2b 200
RyoheiHagimoto 0:56c5742b9e2b 201 dprintf(2, " i25[%c%02d+%x]",
RyoheiHagimoto 0:56c5742b9e2b 202 (dcode25->direction) ? '<' : '>',
RyoheiHagimoto 0:56c5742b9e2b 203 dcode25->character, dcode25->element);
RyoheiHagimoto 0:56c5742b9e2b 204
RyoheiHagimoto 0:56c5742b9e2b 205 /* lock shared resources */
RyoheiHagimoto 0:56c5742b9e2b 206 if(!dcode25->character && get_lock(dcode, ZBAR_I25)) {
RyoheiHagimoto 0:56c5742b9e2b 207 dcode25->character = -1;
RyoheiHagimoto 0:56c5742b9e2b 208 dprintf(2, " [locked %d]\n", dcode->lock);
RyoheiHagimoto 0:56c5742b9e2b 209 return(ZBAR_PARTIAL);
RyoheiHagimoto 0:56c5742b9e2b 210 }
RyoheiHagimoto 0:56c5742b9e2b 211
RyoheiHagimoto 0:56c5742b9e2b 212 unsigned char c = i25_decode10(dcode, 1);
RyoheiHagimoto 0:56c5742b9e2b 213 dprintf(2, " c=%x", c);
RyoheiHagimoto 0:56c5742b9e2b 214
RyoheiHagimoto 0:56c5742b9e2b 215 if(c > 9 ||
RyoheiHagimoto 0:56c5742b9e2b 216 ((dcode25->character >= BUFFER_MIN) &&
RyoheiHagimoto 0:56c5742b9e2b 217 size_buf(dcode, dcode25->character + 2))) {
RyoheiHagimoto 0:56c5742b9e2b 218 dprintf(2, (c > 9) ? " [aborted]\n" : " [overflow]\n");
RyoheiHagimoto 0:56c5742b9e2b 219 dcode->lock = 0;
RyoheiHagimoto 0:56c5742b9e2b 220 dcode25->character = -1;
RyoheiHagimoto 0:56c5742b9e2b 221 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 222 }
RyoheiHagimoto 0:56c5742b9e2b 223 dcode->buf[dcode25->character++] = c + '0';
RyoheiHagimoto 0:56c5742b9e2b 224
RyoheiHagimoto 0:56c5742b9e2b 225 c = i25_decode10(dcode, 0);
RyoheiHagimoto 0:56c5742b9e2b 226 dprintf(2, " c=%x", c);
RyoheiHagimoto 0:56c5742b9e2b 227 if(c > 9) {
RyoheiHagimoto 0:56c5742b9e2b 228 dprintf(2, " [aborted]\n");
RyoheiHagimoto 0:56c5742b9e2b 229 dcode->lock = 0;
RyoheiHagimoto 0:56c5742b9e2b 230 dcode25->character = -1;
RyoheiHagimoto 0:56c5742b9e2b 231 return(ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 232 }
RyoheiHagimoto 0:56c5742b9e2b 233 else
RyoheiHagimoto 0:56c5742b9e2b 234 dprintf(2, "\n");
RyoheiHagimoto 0:56c5742b9e2b 235
RyoheiHagimoto 0:56c5742b9e2b 236 dcode->buf[dcode25->character++] = c + '0';
RyoheiHagimoto 0:56c5742b9e2b 237 dcode25->element = 10;
RyoheiHagimoto 0:56c5742b9e2b 238 return((dcode25->character == 2) ? ZBAR_PARTIAL : ZBAR_NONE);
RyoheiHagimoto 0:56c5742b9e2b 239 }
RyoheiHagimoto 0:56c5742b9e2b 240