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
i25.c
00001 /*------------------------------------------------------------------------ 00002 * Copyright 2008-2009 (c) Jeff Brown <spadix@users.sourceforge.net> 00003 * 00004 * This file is part of the ZBar Bar Code Reader. 00005 * 00006 * The ZBar Bar Code Reader is free software; you can redistribute it 00007 * and/or modify it under the terms of the GNU Lesser Public License as 00008 * published by the Free Software Foundation; either version 2.1 of 00009 * the License, or (at your option) any later version. 00010 * 00011 * The ZBar Bar Code Reader is distributed in the hope that it will be 00012 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00013 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU Lesser Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser Public License 00017 * along with the ZBar Bar Code Reader; if not, write to the Free 00018 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, 00019 * Boston, MA 02110-1301 USA 00020 * 00021 * http://sourceforge.net/projects/zbar 00022 *------------------------------------------------------------------------*/ 00023 00024 #include <config.h> 00025 #include <string.h> /* memmove */ 00026 00027 #include <zbar.h> 00028 #include "decoder.h" 00029 00030 #ifdef DEBUG_I25 00031 # define DEBUG_LEVEL (DEBUG_I25) 00032 #endif 00033 #include "zbar_debug.h" 00034 00035 static inline unsigned char i25_decode1 (unsigned char enc, 00036 unsigned e, 00037 unsigned s) 00038 { 00039 unsigned char E = decode_e(e, s, 45); 00040 if(E > 7) 00041 return(0xff); 00042 enc <<= 1; 00043 if(E > 2) 00044 enc |= 1; 00045 return(enc); 00046 } 00047 00048 static inline unsigned char i25_decode10 (zbar_decoder_t *dcode, 00049 unsigned char offset) 00050 { 00051 i25_decoder_t *dcode25 = &dcode->i25; 00052 dprintf(2, " s=%d", dcode25->s10); 00053 if(dcode25->s10 < 10) 00054 return(0xff); 00055 00056 /* threshold bar width ratios */ 00057 unsigned char enc = 0, par = 0; 00058 signed char i; 00059 for(i = 8; i >= 0; i -= 2) { 00060 unsigned char j = offset + ((dcode25->direction) ? i : 8 - i); 00061 enc = i25_decode1(enc, get_width(dcode, j), dcode25->s10); 00062 if(enc == 0xff) 00063 return(0xff); 00064 if(enc & 1) 00065 par++; 00066 } 00067 00068 dprintf(2, " enc=%02x par=%x", enc, par); 00069 00070 /* parity check */ 00071 if(par != 2) { 00072 dprintf(2, " [bad parity]"); 00073 return(0xff); 00074 } 00075 00076 /* decode binary weights */ 00077 enc &= 0xf; 00078 if(enc & 8) { 00079 if(enc == 12) 00080 enc = 0; 00081 else if(--enc > 9) { 00082 dprintf(2, " [invalid encoding]"); 00083 return(0xff); 00084 } 00085 } 00086 00087 dprintf(2, " => %x", enc); 00088 return(enc); 00089 } 00090 00091 static inline signed char i25_decode_start (zbar_decoder_t *dcode) 00092 { 00093 i25_decoder_t *dcode25 = &dcode->i25; 00094 if(dcode25->s10 < 10) 00095 return(ZBAR_NONE); 00096 00097 unsigned char enc = 0; 00098 unsigned char i = 10; 00099 enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10); 00100 enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10); 00101 enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10); 00102 00103 if((get_color(dcode) == ZBAR_BAR) 00104 ? enc != 4 00105 : (enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10))) { 00106 dprintf(4, " i25: s=%d enc=%x [invalid]\n", dcode25->s10, enc); 00107 return(ZBAR_NONE); 00108 } 00109 00110 /* check leading quiet zone - spec is 10n(?) 00111 * we require 5.25n for w=2n to 6.75n for w=3n 00112 * (FIXME should really factor in w:n ratio) 00113 */ 00114 unsigned quiet = get_width(dcode, i++); 00115 if(quiet && quiet < dcode25->s10 * 3 / 8) { 00116 dprintf(3, " i25: s=%d enc=%x q=%d [invalid qz]\n", 00117 dcode25->s10, enc, quiet); 00118 return(ZBAR_NONE); 00119 } 00120 00121 dcode25->direction = get_color(dcode); 00122 dcode25->element = 1; 00123 dcode25->character = 0; 00124 return(ZBAR_PARTIAL); 00125 } 00126 00127 static inline signed char i25_decode_end (zbar_decoder_t *dcode) 00128 { 00129 i25_decoder_t *dcode25 = &dcode->i25; 00130 00131 /* check trailing quiet zone */ 00132 unsigned quiet = get_width(dcode, 0); 00133 if((quiet && quiet < dcode25->width * 3 / 8) || 00134 decode_e(get_width(dcode, 1), dcode25->width, 45) > 2 || 00135 decode_e(get_width(dcode, 2), dcode25->width, 45) > 2) { 00136 dprintf(3, " s=%d q=%d [invalid qz]\n", dcode25->width, quiet); 00137 return(ZBAR_NONE); 00138 } 00139 00140 /* check exit condition */ 00141 unsigned char E = decode_e(get_width(dcode, 3), dcode25->width, 45); 00142 if((!dcode25->direction) 00143 ? E - 3 > 4 00144 : (E > 2 || 00145 decode_e(get_width(dcode, 4), dcode25->width, 45) > 2)) 00146 return(ZBAR_NONE); 00147 00148 if(dcode25->direction) { 00149 /* reverse buffer */ 00150 dprintf(2, " (rev)"); 00151 int i; 00152 for(i = 0; i < dcode25->character / 2; i++) { 00153 unsigned j = dcode25->character - 1 - i; 00154 char c = dcode->buf[i]; 00155 dcode->buf[i] = dcode->buf[j]; 00156 dcode->buf[j] = c; 00157 } 00158 } 00159 00160 if(dcode25->character < CFG(*dcode25, ZBAR_CFG_MIN_LEN) || 00161 (CFG(*dcode25, ZBAR_CFG_MAX_LEN) > 0 && 00162 dcode25->character > CFG(*dcode25, ZBAR_CFG_MAX_LEN))) { 00163 dprintf(2, " [invalid len]\n"); 00164 dcode->lock = 0; 00165 dcode25->character = -1; 00166 return(ZBAR_NONE); 00167 } 00168 00169 dcode->buflen = dcode25->character; 00170 dcode->buf[dcode25->character] = '\0'; 00171 dprintf(2, " [valid end]\n"); 00172 dcode25->character = -1; 00173 return(ZBAR_I25); 00174 } 00175 00176 zbar_symbol_type_t _zbar_decode_i25 (zbar_decoder_t *dcode) 00177 { 00178 i25_decoder_t *dcode25 = &dcode->i25; 00179 00180 #if (ENABLE_I25) 00181 #else 00182 return(ZBAR_NONE); 00183 #endif 00184 00185 /* update latest character width */ 00186 dcode25->s10 -= get_width(dcode, 10); 00187 dcode25->s10 += get_width(dcode, 0); 00188 00189 if(dcode25->character < 0 && 00190 !i25_decode_start(dcode)) 00191 return(ZBAR_NONE); 00192 00193 if(--dcode25->element == 6 - dcode25->direction) 00194 return(i25_decode_end(dcode)); 00195 else if(dcode25->element) 00196 return(ZBAR_NONE); 00197 00198 /* FIXME check current character width against previous */ 00199 dcode25->width = dcode25->s10; 00200 00201 dprintf(2, " i25[%c%02d+%x]", 00202 (dcode25->direction) ? '<' : '>', 00203 dcode25->character, dcode25->element); 00204 00205 /* lock shared resources */ 00206 if(!dcode25->character && get_lock(dcode, ZBAR_I25)) { 00207 dcode25->character = -1; 00208 dprintf(2, " [locked %d]\n", dcode->lock); 00209 return(ZBAR_PARTIAL); 00210 } 00211 00212 unsigned char c = i25_decode10(dcode, 1); 00213 dprintf(2, " c=%x", c); 00214 00215 if(c > 9 || 00216 ((dcode25->character >= BUFFER_MIN) && 00217 size_buf(dcode, dcode25->character + 2))) { 00218 dprintf(2, (c > 9) ? " [aborted]\n" : " [overflow]\n"); 00219 dcode->lock = 0; 00220 dcode25->character = -1; 00221 return(ZBAR_NONE); 00222 } 00223 dcode->buf[dcode25->character++] = c + '0'; 00224 00225 c = i25_decode10(dcode, 0); 00226 dprintf(2, " c=%x", c); 00227 if(c > 9) { 00228 dprintf(2, " [aborted]\n"); 00229 dcode->lock = 0; 00230 dcode25->character = -1; 00231 return(ZBAR_NONE); 00232 } 00233 else 00234 dprintf(2, "\n"); 00235 00236 dcode->buf[dcode25->character++] = c + '0'; 00237 dcode25->element = 10; 00238 return((dcode25->character == 2) ? ZBAR_PARTIAL : ZBAR_NONE); 00239 } 00240
Generated on Tue Jul 12 2022 18:54:12 by 1.7.2