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
ean.c
00001 /*------------------------------------------------------------------------ 00002 * Copyright 2007-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 <zbar.h> 00026 #include "../decoder.h" 00027 00028 #ifdef ENABLE_EAN 00029 00030 #ifdef DEBUG_EAN 00031 # define DEBUG_LEVEL (DEBUG_EAN) 00032 #endif 00033 #include "../debug.h" 00034 00035 /* partial decode symbol location */ 00036 typedef enum symbol_partial_e { 00037 EAN_LEFT = 0x0000, 00038 EAN_RIGHT = 0x1000, 00039 } symbol_partial_t; 00040 00041 /* convert compact encoded D2E1E2 to character (bit4 is parity) */ 00042 static const unsigned char digits[] = { /* E1 E2 */ 00043 0x06, 0x10, 0x04, 0x13, /* 2 2-5 */ 00044 0x19, 0x08, 0x11, 0x05, /* 3 2-5 (d2 <= thr) */ 00045 0x09, 0x12, 0x07, 0x15, /* 4 2-5 (d2 <= thr) */ 00046 0x16, 0x00, 0x14, 0x03, /* 5 2-5 */ 00047 0x18, 0x01, 0x02, 0x17, /* E1E2=43,44,33,34 (d2 > thr) */ 00048 }; 00049 00050 static const unsigned char parity_decode[] = { 00051 0xf0, /* [xx] BBBBBB = RIGHT half EAN-13 */ 00052 00053 /* UPC-E check digit encoding */ 00054 0xff, 00055 0xff, 00056 0x0f, /* [07] BBBAAA = 0 */ 00057 0xff, 00058 0x1f, /* [0b] BBABAA = 1 */ 00059 0x2f, /* [0d] BBAABA = 2 */ 00060 0xf3, /* [0e] BBAAAB = 3 */ 00061 0xff, 00062 0x4f, /* [13] BABBAA = 4 */ 00063 0x7f, /* [15] BABABA = 7 */ 00064 0xf8, /* [16] BABAAB = 8 */ 00065 0x5f, /* [19] BAABBA = 5 */ 00066 0xf9, /* [1a] BAABAB = 9 */ 00067 0xf6, /* [1c] BAAABB = 6 */ 00068 0xff, 00069 00070 /* LEFT half EAN-13 leading digit */ 00071 0xff, 00072 0x6f, /* [23] ABBBAA = 6 */ 00073 0x9f, /* [25] ABBABA = 9 */ 00074 0xf5, /* [26] ABBAAB = 5 */ 00075 0x8f, /* [29] ABABBA = 8 */ 00076 0xf7, /* [2a] ABABAB = 7 */ 00077 0xf4, /* [2c] ABAABB = 4 */ 00078 0xff, 00079 0x3f, /* [31] AABBBA = 3 */ 00080 0xf2, /* [32] AABBAB = 2 */ 00081 0xf1, /* [34] AABABB = 1 */ 00082 0xff, 00083 0xff, 00084 0xff, 00085 0xff, 00086 0x0f, /* [3f] AAAAAA = 0 */ 00087 }; 00088 00089 #ifdef DEBUG_EAN 00090 static unsigned char debug_buf[0x18]; 00091 00092 static inline const unsigned char *dsprintbuf(ean_decoder_t *ean) 00093 { 00094 int i; 00095 for(i = 0; i < 7; i++) 00096 debug_buf[i] = ((ean->buf[0] < 0 || ean->buf[i] < 0) 00097 ? '-' 00098 : ean->buf[i] + '0'); 00099 debug_buf[i] = ' '; 00100 for(; i < 13; i++) 00101 debug_buf[i + 1] = ((ean->buf[7] < 0 || ean->buf[i] < 0) 00102 ? '-' 00103 : ean->buf[i] + '0'); 00104 debug_buf[i + 1] = ' '; 00105 for(; i < 18; i++) 00106 debug_buf[i + 2] = ((ean->buf[13] < 0 || ean->buf[i] < 0) 00107 ? '-' 00108 : ean->buf[i] + '0'); 00109 debug_buf[i + 2] = '\0'; 00110 return(debug_buf); 00111 } 00112 #endif 00113 00114 /* evaluate previous N (>= 2) widths as auxiliary pattern, 00115 * using preceding 4 as character width 00116 */ 00117 static inline signed char aux_end (zbar_decoder_t *dcode, 00118 unsigned char fwd) 00119 { 00120 /* reference width from previous character */ 00121 unsigned s = calc_s(dcode, 4 + fwd, 4); 00122 00123 /* check quiet zone */ 00124 unsigned qz = get_width(dcode, 0); 00125 if(!fwd && qz && qz < s * 3 / 4) { 00126 dprintf(2, " [invalid quiet]"); 00127 return(-1); 00128 } 00129 00130 dprintf(2, " ("); 00131 signed char code = 0; 00132 unsigned char i; 00133 for(i = 1 - fwd; i < 3 + fwd; i++) { 00134 unsigned e = get_width(dcode, i) + get_width(dcode, i + 1); 00135 dprintf(2, " %d", e); 00136 code = (code << 2) | decode_e(e, s, 7); 00137 if(code < 0) { 00138 dprintf(2, " [invalid end guard]"); 00139 return(-1); 00140 } 00141 } 00142 dprintf(2, ") s=%d aux=%x", s, code); 00143 return(code); 00144 } 00145 00146 /* determine possible auxiliary pattern 00147 * using current 4 as possible character 00148 */ 00149 static inline signed char aux_start (zbar_decoder_t *dcode) 00150 { 00151 /* FIXME NB add-on has no guard in reverse */ 00152 unsigned e2 = get_width(dcode, 5) + get_width(dcode, 6); 00153 if(decode_e(e2, dcode->ean.s4, 7)) { 00154 dprintf(2, " [invalid any]"); 00155 return(/*FIXME (get_color(dcode) == ZBAR_SPACE) ? STATE_ADDON : */-1); 00156 } 00157 00158 unsigned e1 = get_width(dcode, 4) + get_width(dcode, 5); 00159 unsigned char E1 = decode_e(e1, dcode->ean.s4, 7); 00160 00161 if(get_color(dcode) == ZBAR_BAR) { 00162 /* check for quiet-zone */ 00163 unsigned qz = get_width(dcode, 7); 00164 if(!qz || qz >= dcode->ean.s4 * 3 / 4) { 00165 if(!E1) { 00166 dprintf(2, " [valid normal]"); 00167 return(0); /* normal symbol start */ 00168 } 00169 else if(E1 == 1) { 00170 dprintf(2, " [valid add-on]"); 00171 return(STATE_ADDON); /* add-on symbol start */ 00172 } 00173 } 00174 dprintf(2, " [invalid start]"); 00175 return(-1); 00176 } 00177 00178 if(!E1) { 00179 /* attempting decode from SPACE => validate center guard */ 00180 unsigned e3 = get_width(dcode, 6) + get_width(dcode, 7); 00181 if(!decode_e(e3, dcode->ean.s4, 7)) { 00182 dprintf(2, " [valid center]"); 00183 return(0); /* start after center guard */ 00184 } 00185 } 00186 dprintf(2, " [invalid center]"); 00187 return(/*STATE_ADDON*/-1); 00188 } 00189 00190 /* attempt to decode previous 4 widths (2 bars and 2 spaces) as a character */ 00191 static inline signed char decode4 (zbar_decoder_t *dcode) 00192 { 00193 /* calculate similar edge measurements */ 00194 unsigned e1 = ((get_color(dcode) == ZBAR_BAR) 00195 ? get_width(dcode, 0) + get_width(dcode, 1) 00196 : get_width(dcode, 2) + get_width(dcode, 3)); 00197 unsigned e2 = get_width(dcode, 1) + get_width(dcode, 2); 00198 dprintf(2, "\n e1=%d e2=%d", e1, e2); 00199 00200 /* create compacted encoding for direct lookup */ 00201 signed char code = ((decode_e(e1, dcode->ean.s4, 7) << 2) | 00202 decode_e(e2, dcode->ean.s4, 7)); 00203 if(code < 0) 00204 return(-1); 00205 dprintf(2, " code=%x", code); 00206 00207 /* 4 combinations require additional determinant (D2) 00208 E1E2 == 34 (0110) 00209 E1E2 == 43 (1001) 00210 E1E2 == 33 (0101) 00211 E1E2 == 44 (1010) 00212 */ 00213 if((1 << code) & 0x0660) { 00214 /* use sum of bar widths */ 00215 unsigned d2 = ((get_color(dcode) == ZBAR_BAR) 00216 ? get_width(dcode, 0) + get_width(dcode, 2) 00217 : get_width(dcode, 1) + get_width(dcode, 3)); 00218 d2 *= 7; 00219 unsigned char mid = (((1 << code) & 0x0420) 00220 ? 3 /* E1E2 in 33,44 */ 00221 : 4); /* E1E2 in 34,43 */ 00222 unsigned char alt = d2 > (mid * dcode->ean.s4); 00223 if(alt) 00224 code = ((code >> 1) & 3) | 0x10; /* compress code space */ 00225 dprintf(2, " (d2=%d(%d) alt=%d)", d2, mid * dcode->ean.s4, alt); 00226 } 00227 dprintf(2, " char=%02x", digits[(unsigned char)code]); 00228 zassert(code < 0x14, -1, "code=%02x e1=%x e2=%x s4=%x color=%x\n", 00229 code, e1, e2, dcode->ean.s4, get_color(dcode)); 00230 return(code); 00231 } 00232 00233 static inline zbar_symbol_type_t ean_part_end4 (ean_pass_t *pass, 00234 unsigned char fwd) 00235 { 00236 /* extract parity bits */ 00237 unsigned char par = ((pass->raw[1] & 0x10) >> 1 | 00238 (pass->raw[2] & 0x10) >> 2 | 00239 (pass->raw[3] & 0x10) >> 3 | 00240 (pass->raw[4] & 0x10) >> 4); 00241 00242 dprintf(2, " par=%x", par); 00243 if(par && par != 0xf) 00244 /* invalid parity combination */ 00245 return(ZBAR_NONE); 00246 00247 if(!par == fwd) { 00248 /* reverse sampled digits */ 00249 unsigned char tmp = pass->raw[1]; 00250 pass->raw[1] = pass->raw[4]; 00251 pass->raw[4] = tmp; 00252 tmp = pass->raw[2]; 00253 pass->raw[2] = pass->raw[3]; 00254 pass->raw[3] = tmp; 00255 } 00256 00257 dprintf(2, "\n"); 00258 dprintf(1, "decode4=%x%x%x%x\n", 00259 pass->raw[1] & 0xf, pass->raw[2] & 0xf, 00260 pass->raw[3] & 0xf, pass->raw[4] & 0xf); 00261 if(!par) 00262 return(ZBAR_EAN8 | EAN_RIGHT); 00263 return(ZBAR_EAN8 | EAN_LEFT); 00264 } 00265 00266 static inline zbar_symbol_type_t ean_part_end7 (ean_decoder_t *ean, 00267 ean_pass_t *pass, 00268 unsigned char fwd) 00269 { 00270 /* calculate parity index */ 00271 unsigned char par = ((fwd) 00272 ? ((pass->raw[1] & 0x10) << 1 | 00273 (pass->raw[2] & 0x10) | 00274 (pass->raw[3] & 0x10) >> 1 | 00275 (pass->raw[4] & 0x10) >> 2 | 00276 (pass->raw[5] & 0x10) >> 3 | 00277 (pass->raw[6] & 0x10) >> 4) 00278 : ((pass->raw[1] & 0x10) >> 4 | 00279 (pass->raw[2] & 0x10) >> 3 | 00280 (pass->raw[3] & 0x10) >> 2 | 00281 (pass->raw[4] & 0x10) >> 1 | 00282 (pass->raw[5] & 0x10) | 00283 (pass->raw[6] & 0x10) << 1)); 00284 00285 /* lookup parity combination */ 00286 pass->raw[0] = parity_decode[par >> 1]; 00287 if(par & 1) 00288 pass->raw[0] >>= 4; 00289 pass->raw[0] &= 0xf; 00290 dprintf(2, " par=%02x(%x)", par, pass->raw[0]); 00291 00292 if(pass->raw[0] == 0xf) 00293 /* invalid parity combination */ 00294 return(ZBAR_NONE); 00295 00296 if(!par == fwd) { 00297 /* reverse sampled digits */ 00298 unsigned char i; 00299 for(i = 1; i < 4; i++) { 00300 unsigned char tmp = pass->raw[i]; 00301 pass->raw[i] = pass->raw[7 - i]; 00302 pass->raw[7 - i] = tmp; 00303 } 00304 } 00305 00306 dprintf(2, "\n"); 00307 dprintf(1, "decode=%x%x%x%x%x%x%x(%02x)\n", 00308 pass->raw[0] & 0xf, pass->raw[1] & 0xf, 00309 pass->raw[2] & 0xf, pass->raw[3] & 0xf, 00310 pass->raw[4] & 0xf, pass->raw[5] & 0xf, 00311 pass->raw[6] & 0xf, par); 00312 00313 if(TEST_CFG(ean->ean13_config, ZBAR_CFG_ENABLE)) { 00314 if(!par) 00315 return(ZBAR_EAN13 | EAN_RIGHT); 00316 if(par & 0x20) 00317 return(ZBAR_EAN13 | EAN_LEFT); 00318 } 00319 if(par && !(par & 0x20)) 00320 return(ZBAR_UPCE); 00321 00322 return(ZBAR_NONE); 00323 } 00324 00325 /* update state for one of 4 parallel passes */ 00326 static inline zbar_symbol_type_t decode_pass (zbar_decoder_t *dcode, 00327 ean_pass_t *pass) 00328 { 00329 pass->state++; 00330 unsigned char idx = pass->state & STATE_IDX; 00331 unsigned char fwd = pass->state & 1; 00332 00333 if(get_color(dcode) == ZBAR_SPACE && 00334 (idx == 0x10 || idx == 0x11) && 00335 TEST_CFG(dcode->ean.ean8_config, ZBAR_CFG_ENABLE) && 00336 !aux_end(dcode, fwd)) { 00337 dprintf(2, " fwd=%x", fwd); 00338 zbar_symbol_type_t part = ean_part_end4(pass, fwd); 00339 pass->state = -1; 00340 return(part); 00341 } 00342 00343 if(!(idx & 0x03) && idx <= 0x14) { 00344 if(!dcode->ean.s4) 00345 return(0); 00346 /* validate guard bars before decoding first char of symbol */ 00347 if(!pass->state) { 00348 pass->state = aux_start(dcode); 00349 if(pass->state < 0) 00350 return(0); 00351 idx = pass->state & STATE_IDX; 00352 } 00353 signed char code = decode4(dcode); 00354 if(code < 0) 00355 pass->state = -1; 00356 else { 00357 dprintf(2, "\n raw[%x]=%02x =>", idx >> 2, 00358 digits[(unsigned char)code]); 00359 pass->raw[(idx >> 2) + 1] = digits[(unsigned char)code]; 00360 dprintf(2, " raw=%d%d%d%d%d%d%d", 00361 pass->raw[0] & 0xf, pass->raw[1] & 0xf, 00362 pass->raw[2] & 0xf, pass->raw[3] & 0xf, 00363 pass->raw[4] & 0xf, pass->raw[5] & 0xf, 00364 pass->raw[6] & 0xf); 00365 } 00366 } 00367 00368 if(get_color(dcode) == ZBAR_SPACE && 00369 (idx == 0x18 || idx == 0x19)) { 00370 zbar_symbol_type_t part = ZBAR_NONE; 00371 dprintf(2, " fwd=%x", fwd); 00372 if(!aux_end(dcode, fwd)) 00373 part = ean_part_end7(&dcode->ean, pass, fwd); 00374 pass->state = -1; 00375 return(part); 00376 } 00377 return(0); 00378 } 00379 00380 static inline signed char ean_verify_checksum (ean_decoder_t *ean, 00381 int n) 00382 { 00383 unsigned char chk = 0; 00384 unsigned char i; 00385 for(i = 0; i < n; i++) { 00386 unsigned char d = ean->buf[i]; 00387 zassert(d < 10, -1, "i=%x d=%x chk=%x %s\n", i, d, chk, 00388 _zbar_decoder_buf_dump((void*)ean->buf, 18)); 00389 chk += d; 00390 if((i ^ n) & 1) { 00391 chk += d << 1; 00392 if(chk >= 20) 00393 chk -= 20; 00394 } 00395 if(chk >= 10) 00396 chk -= 10; 00397 } 00398 zassert(chk < 10, -1, "chk=%x n=%x %s", chk, n, 00399 _zbar_decoder_buf_dump((void*)ean->buf, 18)); 00400 if(chk) 00401 chk = 10 - chk; 00402 unsigned char d = ean->buf[n]; 00403 zassert(d < 10, -1, "n=%x d=%x chk=%x %s\n", n, d, chk, 00404 _zbar_decoder_buf_dump((void*)ean->buf, 18)); 00405 if(chk != d) { 00406 dprintf(1, "\nchecksum mismatch %d != %d (%s)\n", 00407 chk, d, dsprintbuf(ean)); 00408 return(-1); 00409 } 00410 return(0); 00411 } 00412 00413 static inline unsigned char isbn10_calc_checksum (ean_decoder_t *ean) 00414 { 00415 unsigned int chk = 0; 00416 unsigned char w; 00417 for(w = 10; w > 1; w--) { 00418 unsigned char d = ean->buf[13 - w]; 00419 zassert(d < 10, '?', "w=%x d=%x chk=%x %s\n", w, d, chk, 00420 _zbar_decoder_buf_dump((void*)ean->buf, 18)); 00421 chk += d * w; 00422 } 00423 chk = chk % 11; 00424 if(!chk) 00425 return('0'); 00426 chk = 11 - chk; 00427 if(chk < 10) 00428 return(chk + '0'); 00429 return('X'); 00430 } 00431 00432 static inline void ean_expand_upce (ean_decoder_t *ean, 00433 ean_pass_t *pass) 00434 { 00435 int i = 0; 00436 /* parity encoded digit is checksum */ 00437 ean->buf[12] = pass->raw[i++]; 00438 00439 unsigned char decode = pass->raw[6] & 0xf; 00440 ean->buf[0] = 0; 00441 ean->buf[1] = 0; 00442 ean->buf[2] = pass->raw[i++] & 0xf; 00443 ean->buf[3] = pass->raw[i++] & 0xf; 00444 ean->buf[4] = (decode < 3) ? decode : pass->raw[i++] & 0xf; 00445 ean->buf[5] = (decode < 4) ? 0 : pass->raw[i++] & 0xf; 00446 ean->buf[6] = (decode < 5) ? 0 : pass->raw[i++] & 0xf; 00447 ean->buf[7] = 0; 00448 ean->buf[8] = 0; 00449 ean->buf[9] = (decode < 3) ? pass->raw[i++] & 0xf : 0; 00450 ean->buf[10] = (decode < 4) ? pass->raw[i++] & 0xf : 0; 00451 ean->buf[11] = (decode < 5) ? pass->raw[i++] & 0xf : decode; 00452 } 00453 00454 static inline zbar_symbol_type_t integrate_partial (ean_decoder_t *ean, 00455 ean_pass_t *pass, 00456 zbar_symbol_type_t part) 00457 { 00458 /* copy raw data into holding buffer */ 00459 /* if same partial is not consistent, reset others */ 00460 dprintf(2, " integrate part=%x (%s)", part, dsprintbuf(ean)); 00461 signed char i, j; 00462 if(part & ZBAR_ADDON) { 00463 /* FIXME TBD */ 00464 for(i = (part == ZBAR_ADDON5) ? 4 : 1; i >= 0; i--) { 00465 unsigned char digit = pass->raw[i] & 0xf; 00466 if(ean->addon && ean->buf[i + 13] != digit) { 00467 /* partial mismatch - reset collected parts */ 00468 ean->left = ean->right = ean->addon = ZBAR_NONE; 00469 } 00470 ean->buf[i + 13] = digit; 00471 } 00472 ean->addon = part; 00473 } 00474 else { 00475 if((ean->left && ((part & ZBAR_SYMBOL) != ean->left)) || 00476 (ean->right && ((part & ZBAR_SYMBOL) != ean->right))) { 00477 /* partial mismatch - reset collected parts */ 00478 dprintf(2, " rst(type %x %x)", ean->left, ean->right); 00479 ean->left = ean->right = ean->addon = ZBAR_NONE; 00480 } 00481 00482 if(part & EAN_RIGHT) { 00483 part &= ZBAR_SYMBOL; 00484 j = (part == ZBAR_EAN13) ? 12 : 7; 00485 for(i = (part == ZBAR_EAN13) ? 6 : 4; i; i--, j--) { 00486 unsigned char digit = pass->raw[i] & 0xf; 00487 if(ean->right && ean->buf[j] != digit) { 00488 /* partial mismatch - reset collected parts */ 00489 dprintf(2, " rst(right)"); 00490 ean->left = ean->right = ean->addon = ZBAR_NONE; 00491 } 00492 ean->buf[j] = digit; 00493 } 00494 ean->right = part; 00495 } 00496 else if(part != ZBAR_UPCE) /* EAN_LEFT */ { 00497 j = (part == ZBAR_EAN13) ? 6 : 3; 00498 for(i = (part == ZBAR_EAN13) ? 6 : 4; j >= 0; i--, j--) { 00499 unsigned char digit = pass->raw[i] & 0xf; 00500 if(ean->left && ean->buf[j] != digit) { 00501 /* partial mismatch - reset collected parts */ 00502 dprintf(2, " rst(left)"); 00503 ean->left = ean->right = ean->addon = ZBAR_NONE; 00504 } 00505 ean->buf[j] = digit; 00506 } 00507 ean->left = part; 00508 } 00509 else /* ZBAR_UPCE */ 00510 ean_expand_upce(ean, pass); 00511 } 00512 00513 if((part & ZBAR_SYMBOL) != ZBAR_UPCE) { 00514 part = (ean->left & ean->right); 00515 if(!part) 00516 part = ZBAR_PARTIAL; 00517 } 00518 00519 if(((part == ZBAR_EAN13 || 00520 part == ZBAR_UPCE) && ean_verify_checksum(ean, 12)) || 00521 (part == ZBAR_EAN8 && ean_verify_checksum(ean, 7))) 00522 /* invalid parity */ 00523 part = ZBAR_NONE; 00524 00525 if(part == ZBAR_EAN13) { 00526 /* special case EAN-13 subsets */ 00527 if(!ean->buf[0] && TEST_CFG(ean->upca_config, ZBAR_CFG_ENABLE)) 00528 part = ZBAR_UPCA; 00529 else if(ean->buf[0] == 9 && ean->buf[1] == 7) { 00530 /* ISBN-10 has priority over ISBN-13(?) */ 00531 if(ean->buf[2] == 8 && 00532 TEST_CFG(ean->isbn10_config, ZBAR_CFG_ENABLE)) 00533 part = ZBAR_ISBN10; 00534 else if((ean->buf[2] == 8 || ean->buf[2] == 9) && 00535 TEST_CFG(ean->isbn13_config, ZBAR_CFG_ENABLE)) 00536 part = ZBAR_ISBN13; 00537 } 00538 } 00539 else if(part == ZBAR_UPCE) { 00540 if(TEST_CFG(ean->upce_config, ZBAR_CFG_ENABLE)) { 00541 /* UPC-E was decompressed for checksum verification, 00542 * but user requested compressed result 00543 */ 00544 ean->buf[0] = ean->buf[1] = 0; 00545 for(i = 2; i < 8; i++) 00546 ean->buf[i] = pass->raw[i - 1] & 0xf; 00547 ean->buf[i] = pass->raw[0] & 0xf; 00548 } 00549 else if(TEST_CFG(ean->upca_config, ZBAR_CFG_ENABLE)) 00550 /* UPC-E reported as UPC-A has priority over EAN-13 */ 00551 part = ZBAR_UPCA; 00552 else if(TEST_CFG(ean->ean13_config, ZBAR_CFG_ENABLE)) 00553 part = ZBAR_EAN13; 00554 else 00555 part = ZBAR_NONE; 00556 } 00557 00558 if(part > ZBAR_PARTIAL) 00559 part |= ean->addon; 00560 00561 dprintf(2, " %x/%x=%x", ean->left, ean->right, part); 00562 return(part); 00563 } 00564 00565 /* copy result to output buffer */ 00566 static inline void postprocess (zbar_decoder_t *dcode, 00567 zbar_symbol_type_t sym) 00568 { 00569 ean_decoder_t *ean = &dcode->ean; 00570 zbar_symbol_type_t base = sym & ZBAR_SYMBOL; 00571 int i = 0, j = 0; 00572 if(base > ZBAR_PARTIAL) { 00573 if(base == ZBAR_UPCA) 00574 i = 1; 00575 else if(base == ZBAR_UPCE) { 00576 i = 1; 00577 base--; 00578 } 00579 else if(base == ZBAR_ISBN13) 00580 base = ZBAR_EAN13; 00581 else if(base == ZBAR_ISBN10) 00582 i = 3; 00583 00584 if(base == ZBAR_ISBN10 || 00585 !TEST_CFG(ean_get_config(ean, sym), ZBAR_CFG_EMIT_CHECK)) 00586 base--; 00587 00588 for(; j < base && ean->buf[i] >= 0; i++, j++) 00589 dcode->buf[j] = ean->buf[i] + '0'; 00590 00591 if((sym & ZBAR_SYMBOL) == ZBAR_ISBN10 && j == 9 && 00592 TEST_CFG(ean->isbn10_config, ZBAR_CFG_EMIT_CHECK)) 00593 /* recalculate ISBN-10 check digit */ 00594 dcode->buf[j++] = isbn10_calc_checksum(ean); 00595 } 00596 if(sym & ZBAR_ADDON) 00597 for(i = 13; ean->buf[i] >= 0; i++, j++) 00598 dcode->buf[j] = ean->buf[i] + '0'; 00599 dcode->buflen = j; 00600 dcode->buf[j] = '\0'; 00601 } 00602 00603 zbar_symbol_type_t _zbar_decode_ean (zbar_decoder_t *dcode) 00604 { 00605 /* process upto 4 separate passes */ 00606 zbar_symbol_type_t sym = ZBAR_NONE; 00607 unsigned char pass_idx = dcode->idx & 3; 00608 00609 /* update latest character width */ 00610 dcode->ean.s4 -= get_width(dcode, 4); 00611 dcode->ean.s4 += get_width(dcode, 0); 00612 00613 unsigned char i; 00614 for(i = 0; i < 4; i++) { 00615 ean_pass_t *pass = &dcode->ean.pass[i]; 00616 if(pass->state >= 0 || 00617 i == pass_idx) 00618 { 00619 dprintf(2, " ean[%x/%x]: idx=%x st=%d s=%d", 00620 pass_idx, i, dcode->idx, pass->state, dcode->ean.s4); 00621 zbar_symbol_type_t part = decode_pass(dcode, pass); 00622 if(part) { 00623 /* update accumulated data from new partial decode */ 00624 sym = integrate_partial(&dcode->ean, pass, part); 00625 if(sym) { 00626 /* this pass valid => _reset_ all passes */ 00627 dprintf(2, " sym=%x", sym); 00628 dcode->ean.pass[0].state = dcode->ean.pass[1].state = -1; 00629 dcode->ean.pass[2].state = dcode->ean.pass[3].state = -1; 00630 if(sym > ZBAR_PARTIAL) { 00631 if(!get_lock(dcode, ZBAR_EAN13)) 00632 postprocess(dcode, sym); 00633 else { 00634 dprintf(1, " [locked %d]", dcode->lock); 00635 sym = ZBAR_PARTIAL; 00636 } 00637 } 00638 } 00639 } 00640 dprintf(2, "\n"); 00641 } 00642 } 00643 return(sym); 00644 } 00645 00646 #endif
Generated on Tue Jul 12 2022 21:31:48 by
1.7.2