Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: BarcodeReader_F103
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 #ifdef ENABLE_I25 00028 00029 #include <zbar.h> 00030 #include "../decoder.h" 00031 00032 #ifdef DEBUG_I25 00033 # define DEBUG_LEVEL (DEBUG_I25) 00034 #endif 00035 #include "../debug.h" 00036 00037 static inline unsigned char i25_decode1 (unsigned char enc, 00038 unsigned e, 00039 unsigned s) 00040 { 00041 unsigned char E = decode_e(e, s, 45); 00042 if(E > 7) 00043 return(0xff); 00044 enc <<= 1; 00045 if(E > 2) 00046 enc |= 1; 00047 return(enc); 00048 } 00049 00050 static inline unsigned char i25_decode10 (zbar_decoder_t *dcode, 00051 unsigned char offset) 00052 { 00053 i25_decoder_t *dcode25 = &dcode->i25; 00054 dprintf(2, " s=%d", dcode25->s10); 00055 if(dcode25->s10 < 10) 00056 return(0xff); 00057 00058 /* threshold bar width ratios */ 00059 unsigned char enc = 0, par = 0; 00060 signed char i; 00061 for(i = 8; i >= 0; i -= 2) { 00062 unsigned char j = offset + ((dcode25->direction) ? i : 8 - i); 00063 enc = i25_decode1(enc, get_width(dcode, j), dcode25->s10); 00064 if(enc == 0xff) 00065 return(0xff); 00066 if(enc & 1) 00067 par++; 00068 } 00069 00070 dprintf(2, " enc=%02x par=%x", enc, par); 00071 00072 /* parity check */ 00073 if(par != 2) { 00074 dprintf(2, " [bad parity]"); 00075 return(0xff); 00076 } 00077 00078 /* decode binary weights */ 00079 enc &= 0xf; 00080 if(enc & 8) { 00081 if(enc == 12) 00082 enc = 0; 00083 else if(--enc > 9) { 00084 dprintf(2, " [invalid encoding]"); 00085 return(0xff); 00086 } 00087 } 00088 00089 dprintf(2, " => %x", enc); 00090 return(enc); 00091 } 00092 00093 static inline signed char i25_decode_start (zbar_decoder_t *dcode) 00094 { 00095 i25_decoder_t *dcode25 = &dcode->i25; 00096 if(dcode25->s10 < 10) 00097 return(ZBAR_NONE); 00098 00099 unsigned char enc = 0; 00100 unsigned char i = 10; 00101 enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10); 00102 enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10); 00103 enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10); 00104 00105 if((get_color(dcode) == ZBAR_BAR) 00106 ? enc != 4 00107 : (enc = i25_decode1(enc, get_width(dcode, i++), dcode25->s10))) { 00108 dprintf(4, " i25: s=%d enc=%x [invalid]\n", dcode25->s10, enc); 00109 return(ZBAR_NONE); 00110 } 00111 00112 /* check leading quiet zone - spec is 10n(?) 00113 * we require 5.25n for w=2n to 6.75n for w=3n 00114 * (FIXME should really factor in w:n ratio) 00115 */ 00116 unsigned quiet = get_width(dcode, i++); 00117 if(quiet && quiet < dcode25->s10 * 3 / 8) { 00118 dprintf(3, " i25: s=%d enc=%x q=%d [invalid qz]\n", 00119 dcode25->s10, enc, quiet); 00120 return(ZBAR_NONE); 00121 } 00122 00123 dcode25->direction = get_color(dcode); 00124 dcode25->element = 1; 00125 dcode25->character = 0; 00126 return(ZBAR_PARTIAL); 00127 } 00128 00129 static inline signed char i25_decode_end (zbar_decoder_t *dcode) 00130 { 00131 i25_decoder_t *dcode25 = &dcode->i25; 00132 00133 /* check trailing quiet zone */ 00134 unsigned quiet = get_width(dcode, 0); 00135 if((quiet && quiet < dcode25->width * 3 / 8) || 00136 decode_e(get_width(dcode, 1), dcode25->width, 45) > 2 || 00137 decode_e(get_width(dcode, 2), dcode25->width, 45) > 2) { 00138 dprintf(3, " s=%d q=%d [invalid qz]\n", dcode25->width, quiet); 00139 return(ZBAR_NONE); 00140 } 00141 00142 /* check exit condition */ 00143 unsigned char E = decode_e(get_width(dcode, 3), dcode25->width, 45); 00144 if((!dcode25->direction) 00145 ? E - 3 > 4 00146 : (E > 2 || 00147 decode_e(get_width(dcode, 4), dcode25->width, 45) > 2)) 00148 return(ZBAR_NONE); 00149 00150 if(dcode25->direction) { 00151 /* reverse buffer */ 00152 dprintf(2, " (rev)"); 00153 int i; 00154 for(i = 0; i < dcode25->character / 2; i++) { 00155 unsigned j = dcode25->character - 1 - i; 00156 char c = dcode->buf[i]; 00157 dcode->buf[i] = dcode->buf[j]; 00158 dcode->buf[j] = c; 00159 } 00160 } 00161 00162 if(dcode25->character < CFG(*dcode25, ZBAR_CFG_MIN_LEN) || 00163 (CFG(*dcode25, ZBAR_CFG_MAX_LEN) > 0 && 00164 dcode25->character > CFG(*dcode25, ZBAR_CFG_MAX_LEN))) { 00165 dprintf(2, " [invalid len]\n"); 00166 dcode->lock = 0; 00167 dcode25->character = -1; 00168 return(ZBAR_NONE); 00169 } 00170 00171 dcode->buflen = dcode25->character; 00172 dcode->buf[dcode25->character] = '\0'; 00173 dprintf(2, " [valid end]\n"); 00174 dcode25->character = -1; 00175 return(ZBAR_I25); 00176 } 00177 00178 zbar_symbol_type_t _zbar_decode_i25 (zbar_decoder_t *dcode) 00179 { 00180 i25_decoder_t *dcode25 = &dcode->i25; 00181 00182 /* update latest character width */ 00183 dcode25->s10 -= get_width(dcode, 10); 00184 dcode25->s10 += get_width(dcode, 0); 00185 00186 if(dcode25->character < 0 && 00187 !i25_decode_start(dcode)) 00188 return(ZBAR_NONE); 00189 00190 if(--dcode25->element == 6 - dcode25->direction) 00191 return(i25_decode_end(dcode)); 00192 else if(dcode25->element) 00193 return(ZBAR_NONE); 00194 00195 /* FIXME check current character width against previous */ 00196 dcode25->width = dcode25->s10; 00197 00198 dprintf(2, " i25[%c%02d+%x]", 00199 (dcode25->direction) ? '<' : '>', 00200 dcode25->character, dcode25->element); 00201 00202 /* lock shared resources */ 00203 if(!dcode25->character && get_lock(dcode, ZBAR_I25)) { 00204 dcode25->character = -1; 00205 dprintf(2, " [locked %d]\n", dcode->lock); 00206 return(ZBAR_PARTIAL); 00207 } 00208 00209 unsigned char c = i25_decode10(dcode, 1); 00210 dprintf(2, " c=%x", c); 00211 00212 if(c > 9 || 00213 ((dcode25->character >= BUFFER_MIN) && 00214 size_buf(dcode, dcode25->character + 2))) { 00215 dprintf(2, (c > 9) ? " [aborted]\n" : " [overflow]\n"); 00216 dcode->lock = 0; 00217 dcode25->character = -1; 00218 return(ZBAR_NONE); 00219 } 00220 dcode->buf[dcode25->character++] = c + '0'; 00221 00222 c = i25_decode10(dcode, 0); 00223 dprintf(2, " c=%x", c); 00224 if(c > 9) { 00225 dprintf(2, " [aborted]\n"); 00226 dcode->lock = 0; 00227 dcode25->character = -1; 00228 return(ZBAR_NONE); 00229 } 00230 else 00231 dprintf(2, "\n"); 00232 00233 dcode->buf[dcode25->character++] = c + '0'; 00234 dcode25->element = 10; 00235 return((dcode25->character == 2) ? ZBAR_PARTIAL : ZBAR_NONE); 00236 } 00237 00238 #endif
Generated on Tue Jul 12 2022 21:31:48 by
1.7.2