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