Zoltan Hudak / zbar

Dependents:   BarcodeReader_F103

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers decoder.c Source File

decoder.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 #include <config.h>
00024 #include <stdlib.h> /* malloc, calloc, free */
00025 
00026 #include <stdio.h>  /* snprintf */
00027 
00028 #include <string.h> /* memset, strlen */
00029 
00030 #include <zbar.h>
00031 #include "decoder.h"
00032 
00033 #if defined(DEBUG_DECODER) || defined(DEBUG_EAN) || defined(DEBUG_CODE39) || defined(DEBUG_I25) || defined \
00034         (DEBUG_CODE128) || defined(DEBUG_QR_FINDER) || (defined(DEBUG_PDF417) && (DEBUG_PDF417 >= 4))
00035 #define DEBUG_LEVEL 1
00036 #endif
00037 #include "debug.h"
00038 
00039 /**
00040  * @brief
00041  * @note
00042  * @param
00043  * @retval
00044  */
00045 zbar_decoder_t* zbar_decoder_create()
00046 {
00047     zbar_decoder_t*     dcode = calloc(1, sizeof(zbar_decoder_t));
00048     dcode->buf_alloc = BUFFER_MIN;
00049     dcode->buf = malloc(dcode->buf_alloc);
00050 
00051     /* initialize default configs */
00052 #ifdef ENABLE_EAN
00053     dcode->ean.enable = 1;
00054     dcode->ean.ean13_config = ((1 << ZBAR_CFG_ENABLE) | (1 << ZBAR_CFG_EMIT_CHECK));
00055     dcode->ean.ean8_config = ((1 << ZBAR_CFG_ENABLE) | (1 << ZBAR_CFG_EMIT_CHECK));
00056     dcode->ean.upca_config = 1 << ZBAR_CFG_EMIT_CHECK;
00057     dcode->ean.upce_config = 1 << ZBAR_CFG_EMIT_CHECK;
00058     dcode->ean.isbn10_config = 1 << ZBAR_CFG_EMIT_CHECK;
00059     dcode->ean.isbn13_config = 1 << ZBAR_CFG_EMIT_CHECK;
00060 #endif
00061 #ifdef ENABLE_I25
00062     dcode->i25.config = 1 << ZBAR_CFG_ENABLE;
00063     CFG(dcode->i25, ZBAR_CFG_MIN_LEN) = 6;
00064 #endif
00065 #ifdef ENABLE_CODE39
00066     dcode->code39.config = 1 << ZBAR_CFG_ENABLE;
00067     CFG(dcode->code39, ZBAR_CFG_MIN_LEN) = 1;
00068 #endif
00069 #ifdef ENABLE_CODE128
00070     dcode->code128.config = 1 << ZBAR_CFG_ENABLE;
00071 #endif
00072 #ifdef ENABLE_PDF417
00073     dcode->pdf417.config = 1 << ZBAR_CFG_ENABLE;
00074 #endif
00075 #ifdef ENABLE_QRCODE
00076     dcode->qrf.config = 1 << ZBAR_CFG_ENABLE;
00077 #endif
00078     zbar_decoder_reset(dcode);
00079     return(dcode);
00080 }
00081 
00082 /**
00083  * @brief
00084  * @note
00085  * @param
00086  * @retval
00087  */
00088 void zbar_decoder_destroy(zbar_decoder_t* dcode)
00089 {
00090     if (dcode->buf)
00091         free(dcode->buf);
00092     free(dcode);
00093 }
00094 
00095 /**
00096  * @brief
00097  * @note
00098  * @param
00099  * @retval
00100  */
00101 void zbar_decoder_reset(zbar_decoder_t* dcode)
00102 {
00103     memset(dcode, 0, (long) &dcode->buf_alloc - (long)dcode);
00104 #ifdef ENABLE_EAN
00105     ean_reset(&dcode->ean);
00106 #endif
00107 #ifdef ENABLE_I25
00108     i25_reset(&dcode->i25);
00109 #endif
00110 #ifdef ENABLE_CODE39
00111     code39_reset(&dcode->code39);
00112 #endif
00113 #ifdef ENABLE_CODE128
00114     code128_reset(&dcode->code128);
00115 #endif
00116 #ifdef ENABLE_PDF417
00117     pdf417_reset(&dcode->pdf417);
00118 #endif
00119 #ifdef ENABLE_QRCODE
00120     qr_finder_reset(&dcode->qrf);
00121 #endif
00122 }
00123 
00124 /**
00125  * @brief
00126  * @note
00127  * @param
00128  * @retval
00129  */
00130 void zbar_decoder_new_scan(zbar_decoder_t* dcode)
00131 {
00132     /* soft reset decoder */
00133 
00134     memset(dcode->w, 0, sizeof(dcode->w));
00135     dcode->lock = 0;
00136     dcode->idx = 0;
00137 #ifdef ENABLE_EAN
00138     ean_new_scan(&dcode->ean);
00139 #endif
00140 #ifdef ENABLE_I25
00141     i25_reset(&dcode->i25);
00142 #endif
00143 #ifdef ENABLE_CODE39
00144     code39_reset(&dcode->code39);
00145 #endif
00146 #ifdef ENABLE_CODE128
00147     code128_reset(&dcode->code128);
00148 #endif
00149 #ifdef ENABLE_PDF417
00150     pdf417_reset(&dcode->pdf417);
00151 #endif
00152 #ifdef ENABLE_QRCODE
00153     qr_finder_reset(&dcode->qrf);
00154 #endif
00155 }
00156 
00157 /**
00158  * @brief
00159  * @note
00160  * @param
00161  * @retval
00162  */
00163 zbar_color_t zbar_decoder_get_color(const zbar_decoder_t* dcode)
00164 {
00165     return(get_color(dcode));
00166 }
00167 
00168 /**
00169  * @brief
00170  * @note
00171  * @param
00172  * @retval
00173  */
00174 const char* zbar_decoder_get_data(const zbar_decoder_t* dcode)
00175 {
00176     return((char*)dcode->buf);
00177 }
00178 
00179 /**
00180  * @brief
00181  * @note
00182  * @param
00183  * @retval
00184  */
00185 unsigned int zbar_decoder_get_data_length(const zbar_decoder_t* dcode)
00186 {
00187     return(dcode->buflen);
00188 }
00189 
00190 /**
00191  * @brief
00192  * @note
00193  * @param
00194  * @retval
00195  */
00196 zbar_decoder_handler_t* zbar_decoder_set_handler(zbar_decoder_t* dcode, zbar_decoder_handler_t handler)
00197 {
00198     zbar_decoder_handler_t*     result = dcode->handler;
00199     dcode->handler = handler;
00200     return(result);
00201 }
00202 
00203 /**
00204  * @brief
00205  * @note
00206  * @param
00207  * @retval
00208  */
00209 void zbar_decoder_set_userdata(zbar_decoder_t* dcode, void* userdata)
00210 {
00211     dcode->userdata = userdata;
00212 }
00213 
00214 /**
00215  * @brief
00216  * @note
00217  * @param
00218  * @retval
00219  */
00220 void* zbar_decoder_get_userdata(const zbar_decoder_t* dcode)
00221 {
00222     return(dcode->userdata);
00223 }
00224 
00225 /**
00226  * @brief
00227  * @note
00228  * @param
00229  * @retval
00230  */
00231 zbar_symbol_type_t zbar_decoder_get_type(const zbar_decoder_t* dcode)
00232 {
00233     return(dcode->type);
00234 }
00235 
00236 /**
00237  * @brief
00238  * @note
00239  * @param
00240  * @retval
00241  */
00242 zbar_symbol_type_t zbar_decode_width(zbar_decoder_t* dcode, unsigned w)
00243 {
00244     dcode->w[dcode->idx & (DECODE_WINDOW - 1)] = w;
00245     dprintf(1, "    decode[%x]: w=%d (%g)\n", dcode->idx, w, (w / 32.));
00246 
00247     /* each decoder processes width stream in parallel */
00248     zbar_symbol_type_t  sym = dcode->type = ZBAR_NONE;
00249 
00250 #ifdef ENABLE_EAN
00251     if ((dcode->ean.enable) && (sym = _zbar_decode_ean(dcode)))
00252         dcode->type = sym;
00253 #endif
00254 #ifdef ENABLE_CODE39
00255     if (TEST_CFG(dcode->code39.config, ZBAR_CFG_ENABLE) && (sym = _zbar_decode_code39(dcode)) > ZBAR_PARTIAL)
00256         dcode->type = sym;
00257 #endif
00258 #ifdef ENABLE_CODE128
00259     if (TEST_CFG(dcode->code128.config, ZBAR_CFG_ENABLE) && (sym = _zbar_decode_code128(dcode)) > ZBAR_PARTIAL)
00260         dcode->type = sym;
00261 #endif
00262 #ifdef ENABLE_I25
00263     if (TEST_CFG(dcode->i25.config, ZBAR_CFG_ENABLE) && (sym = _zbar_decode_i25(dcode)) > ZBAR_PARTIAL)
00264         dcode->type = sym;
00265 #endif
00266 #ifdef ENABLE_PDF417
00267     if (TEST_CFG(dcode->pdf417.config, ZBAR_CFG_ENABLE) && (sym = _zbar_decode_pdf417(dcode)) > ZBAR_PARTIAL)
00268         dcode->type = sym;
00269 #endif
00270 #ifdef ENABLE_QRCODE
00271     if (TEST_CFG(dcode->qrf.config, ZBAR_CFG_ENABLE) && (sym = _zbar_find_qr(dcode)) > ZBAR_PARTIAL)
00272         dcode->type = sym;
00273 #endif
00274     dcode->idx++;
00275     if (dcode->type) {
00276         if (dcode->handler)
00277             dcode->handler(dcode);
00278         if (dcode->lock && dcode->type > ZBAR_PARTIAL)
00279             dcode->lock = 0;
00280     }
00281 
00282     return(dcode->type);
00283 }
00284 
00285 /**
00286  * @brief
00287  * @note
00288  * @param
00289  * @retval
00290  */
00291 static inline int decoder_set_config_bool(zbar_decoder_t* dcode, zbar_symbol_type_t sym, zbar_config_t cfg, int val)
00292 {
00293     unsigned*   config = NULL;
00294     switch (sym) {
00295     #ifdef ENABLE_EAN
00296 
00297         case ZBAR_EAN13:
00298             config = &dcode->ean.ean13_config;
00299             break;
00300 
00301         case ZBAR_EAN8:
00302             config = &dcode->ean.ean8_config;
00303             break;
00304 
00305         case ZBAR_UPCA:
00306             config = &dcode->ean.upca_config;
00307             break;
00308 
00309         case ZBAR_UPCE:
00310             config = &dcode->ean.upce_config;
00311             break;
00312 
00313         case ZBAR_ISBN10:
00314             config = &dcode->ean.isbn10_config;
00315             break;
00316 
00317         case ZBAR_ISBN13:
00318             config = &dcode->ean.isbn13_config;
00319             break;
00320     #endif
00321     #ifdef ENABLE_I25
00322 
00323         case ZBAR_I25:
00324             config = &dcode->i25.config;
00325             break;
00326     #endif
00327     #ifdef ENABLE_CODE39
00328 
00329         case ZBAR_CODE39:
00330             config = &dcode->code39.config;
00331             break;
00332     #endif
00333     #ifdef ENABLE_CODE128
00334 
00335         case ZBAR_CODE128:
00336             config = &dcode->code128.config;
00337             break;
00338     #endif
00339     #ifdef ENABLE_PDF417
00340 
00341         case ZBAR_PDF417:
00342             config = &dcode->pdf417.config;
00343             break;
00344     #endif
00345     #ifdef ENABLE_QRCODE
00346 
00347         case ZBAR_QRCODE:
00348             config = &dcode->qrf.config;
00349             break;
00350     #endif
00351 
00352         /* FIXME handle addons */
00353 
00354         default:
00355             return(1);
00356     }
00357 
00358     if (!config || cfg >= ZBAR_CFG_NUM)
00359         return(1);
00360 
00361     if (!val)
00362         *config &= ~(1 << cfg);
00363     else
00364     if (val == 1)
00365         *config |= (1 << cfg);
00366     else
00367         return(1);
00368 
00369 #ifdef ENABLE_EAN
00370     dcode->ean.enable = TEST_CFG
00371         (
00372             dcode->ean.ean13_config |
00373                 dcode->ean.ean8_config |
00374                 dcode->ean.upca_config |
00375                 dcode->ean.upce_config |
00376                 dcode->ean.isbn10_config |
00377                 dcode->ean.isbn13_config,
00378             ZBAR_CFG_ENABLE
00379         );
00380 #endif
00381     return(0);
00382 }
00383 
00384 /**
00385  * @brief
00386  * @note
00387  * @param
00388  * @retval
00389  */
00390 static inline int decoder_set_config_int(zbar_decoder_t* dcode, zbar_symbol_type_t sym, zbar_config_t cfg, int val)
00391 {
00392     switch (sym) {
00393     #ifdef ENABLE_I25
00394 
00395         case ZBAR_I25:
00396             CFG(dcode->i25, cfg) = val;
00397             break;
00398     #endif
00399     #ifdef ENABLE_CODE39
00400 
00401         case ZBAR_CODE39:
00402             CFG(dcode->code39, cfg) = val;
00403             break;
00404     #endif
00405     #ifdef ENABLE_CODE128
00406 
00407         case ZBAR_CODE128:
00408             CFG(dcode->code128, cfg) = val;
00409             break;
00410     #endif
00411     #ifdef ENABLE_PDF417
00412 
00413         case ZBAR_PDF417:
00414             CFG(dcode->pdf417, cfg) = val;
00415             break;
00416     #endif
00417 
00418         default:
00419             return(1);
00420     }
00421 
00422     return(0);
00423 }
00424 
00425 /**
00426  * @brief
00427  * @note
00428  * @param
00429  * @retval
00430  */
00431 int zbar_decoder_set_config(zbar_decoder_t* dcode, zbar_symbol_type_t sym, zbar_config_t cfg, int val)
00432 {
00433     if (sym == ZBAR_NONE) {
00434         zbar_decoder_set_config(dcode, ZBAR_EAN13, cfg, val);
00435         zbar_decoder_set_config(dcode, ZBAR_EAN8, cfg, val);
00436         zbar_decoder_set_config(dcode, ZBAR_UPCA, cfg, val);
00437         zbar_decoder_set_config(dcode, ZBAR_UPCE, cfg, val);
00438         zbar_decoder_set_config(dcode, ZBAR_ISBN10, cfg, val);
00439         zbar_decoder_set_config(dcode, ZBAR_ISBN13, cfg, val);
00440         zbar_decoder_set_config(dcode, ZBAR_I25, cfg, val);
00441         zbar_decoder_set_config(dcode, ZBAR_CODE39, cfg, val);
00442         zbar_decoder_set_config(dcode, ZBAR_CODE128, cfg, val);
00443         zbar_decoder_set_config(dcode, ZBAR_PDF417, cfg, val);
00444         zbar_decoder_set_config(dcode, ZBAR_QRCODE, cfg, val);
00445         return(0);
00446     }
00447 
00448     if (cfg >= 0 && cfg < ZBAR_CFG_NUM)
00449         return(decoder_set_config_bool(dcode, sym, cfg, val));
00450     else
00451     if (cfg >= ZBAR_CFG_MIN_LEN && cfg <= ZBAR_CFG_MAX_LEN)
00452         return(decoder_set_config_int(dcode, sym, cfg, val));
00453     else
00454         return(1);
00455 }
00456 
00457 static char*    decoder_dump = NULL;
00458 static unsigned decoder_dumplen = 0;
00459 
00460 /**
00461  * @brief
00462  * @note
00463  * @param
00464  * @retval
00465  */
00466 const char* _zbar_decoder_buf_dump(unsigned char* buf, unsigned int buflen)
00467 {
00468     int dumplen = (buflen * 3) + 12;
00469     if (!decoder_dump || dumplen > decoder_dumplen) {
00470         if (decoder_dump)
00471             free(decoder_dump);
00472         decoder_dump = malloc(dumplen);
00473         decoder_dumplen = dumplen;
00474     }
00475 
00476     char*   p = decoder_dump + snprintf(decoder_dump, 12, "buf[%04x]=", (buflen > 0xffff) ? 0xffff : buflen);
00477     int     i;
00478     for (i = 0; i < buflen; i++)
00479         p += snprintf(p, 4, "%s%02x", (i) ? " " : "", buf[i]);
00480     return(decoder_dump);
00481 }