A streamlined version (for embedded use) of Jeff Brown's ZBar library. Visit <http://zbar.sourceforge.net> for more details.

Dependents:   BarcodeReader_F103

Revision:
0:e33621169e44
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/decoder.c	Fri Jan 10 20:29:52 2020 +0000
@@ -0,0 +1,481 @@
+/*------------------------------------------------------------------------
+ *  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
+ *
+ *  This file is part of the ZBar Bar Code Reader.
+ *
+ *  The ZBar Bar Code Reader is free software; you can redistribute it
+ *  and/or modify it under the terms of the GNU Lesser Public License as
+ *  published by the Free Software Foundation; either version 2.1 of
+ *  the License, or (at your option) any later version.
+ *
+ *  The ZBar Bar Code Reader is distributed in the hope that it will be
+ *  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser Public License
+ *  along with the ZBar Bar Code Reader; if not, write to the Free
+ *  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *  Boston, MA  02110-1301  USA
+ *
+ *  http://sourceforge.net/projects/zbar
+ *------------------------------------------------------------------------*/
+#include <config.h>
+#include <stdlib.h> /* malloc, calloc, free */
+
+#include <stdio.h>  /* snprintf */
+
+#include <string.h> /* memset, strlen */
+
+#include <zbar.h>
+#include "decoder.h"
+
+#if defined(DEBUG_DECODER) || defined(DEBUG_EAN) || defined(DEBUG_CODE39) || defined(DEBUG_I25) || defined \
+        (DEBUG_CODE128) || defined(DEBUG_QR_FINDER) || (defined(DEBUG_PDF417) && (DEBUG_PDF417 >= 4))
+#define DEBUG_LEVEL 1
+#endif
+#include "debug.h"
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+zbar_decoder_t* zbar_decoder_create()
+{
+    zbar_decoder_t*     dcode = calloc(1, sizeof(zbar_decoder_t));
+    dcode->buf_alloc = BUFFER_MIN;
+    dcode->buf = malloc(dcode->buf_alloc);
+
+    /* initialize default configs */
+#ifdef ENABLE_EAN
+    dcode->ean.enable = 1;
+    dcode->ean.ean13_config = ((1 << ZBAR_CFG_ENABLE) | (1 << ZBAR_CFG_EMIT_CHECK));
+    dcode->ean.ean8_config = ((1 << ZBAR_CFG_ENABLE) | (1 << ZBAR_CFG_EMIT_CHECK));
+    dcode->ean.upca_config = 1 << ZBAR_CFG_EMIT_CHECK;
+    dcode->ean.upce_config = 1 << ZBAR_CFG_EMIT_CHECK;
+    dcode->ean.isbn10_config = 1 << ZBAR_CFG_EMIT_CHECK;
+    dcode->ean.isbn13_config = 1 << ZBAR_CFG_EMIT_CHECK;
+#endif
+#ifdef ENABLE_I25
+    dcode->i25.config = 1 << ZBAR_CFG_ENABLE;
+    CFG(dcode->i25, ZBAR_CFG_MIN_LEN) = 6;
+#endif
+#ifdef ENABLE_CODE39
+    dcode->code39.config = 1 << ZBAR_CFG_ENABLE;
+    CFG(dcode->code39, ZBAR_CFG_MIN_LEN) = 1;
+#endif
+#ifdef ENABLE_CODE128
+    dcode->code128.config = 1 << ZBAR_CFG_ENABLE;
+#endif
+#ifdef ENABLE_PDF417
+    dcode->pdf417.config = 1 << ZBAR_CFG_ENABLE;
+#endif
+#ifdef ENABLE_QRCODE
+    dcode->qrf.config = 1 << ZBAR_CFG_ENABLE;
+#endif
+    zbar_decoder_reset(dcode);
+    return(dcode);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void zbar_decoder_destroy(zbar_decoder_t* dcode)
+{
+    if (dcode->buf)
+        free(dcode->buf);
+    free(dcode);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void zbar_decoder_reset(zbar_decoder_t* dcode)
+{
+    memset(dcode, 0, (long) &dcode->buf_alloc - (long)dcode);
+#ifdef ENABLE_EAN
+    ean_reset(&dcode->ean);
+#endif
+#ifdef ENABLE_I25
+    i25_reset(&dcode->i25);
+#endif
+#ifdef ENABLE_CODE39
+    code39_reset(&dcode->code39);
+#endif
+#ifdef ENABLE_CODE128
+    code128_reset(&dcode->code128);
+#endif
+#ifdef ENABLE_PDF417
+    pdf417_reset(&dcode->pdf417);
+#endif
+#ifdef ENABLE_QRCODE
+    qr_finder_reset(&dcode->qrf);
+#endif
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void zbar_decoder_new_scan(zbar_decoder_t* dcode)
+{
+    /* soft reset decoder */
+
+    memset(dcode->w, 0, sizeof(dcode->w));
+    dcode->lock = 0;
+    dcode->idx = 0;
+#ifdef ENABLE_EAN
+    ean_new_scan(&dcode->ean);
+#endif
+#ifdef ENABLE_I25
+    i25_reset(&dcode->i25);
+#endif
+#ifdef ENABLE_CODE39
+    code39_reset(&dcode->code39);
+#endif
+#ifdef ENABLE_CODE128
+    code128_reset(&dcode->code128);
+#endif
+#ifdef ENABLE_PDF417
+    pdf417_reset(&dcode->pdf417);
+#endif
+#ifdef ENABLE_QRCODE
+    qr_finder_reset(&dcode->qrf);
+#endif
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+zbar_color_t zbar_decoder_get_color(const zbar_decoder_t* dcode)
+{
+    return(get_color(dcode));
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+const char* zbar_decoder_get_data(const zbar_decoder_t* dcode)
+{
+    return((char*)dcode->buf);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+unsigned int zbar_decoder_get_data_length(const zbar_decoder_t* dcode)
+{
+    return(dcode->buflen);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+zbar_decoder_handler_t* zbar_decoder_set_handler(zbar_decoder_t* dcode, zbar_decoder_handler_t handler)
+{
+    zbar_decoder_handler_t*     result = dcode->handler;
+    dcode->handler = handler;
+    return(result);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void zbar_decoder_set_userdata(zbar_decoder_t* dcode, void* userdata)
+{
+    dcode->userdata = userdata;
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+void* zbar_decoder_get_userdata(const zbar_decoder_t* dcode)
+{
+    return(dcode->userdata);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+zbar_symbol_type_t zbar_decoder_get_type(const zbar_decoder_t* dcode)
+{
+    return(dcode->type);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+zbar_symbol_type_t zbar_decode_width(zbar_decoder_t* dcode, unsigned w)
+{
+    dcode->w[dcode->idx & (DECODE_WINDOW - 1)] = w;
+    dprintf(1, "    decode[%x]: w=%d (%g)\n", dcode->idx, w, (w / 32.));
+
+    /* each decoder processes width stream in parallel */
+    zbar_symbol_type_t  sym = dcode->type = ZBAR_NONE;
+
+#ifdef ENABLE_EAN
+    if ((dcode->ean.enable) && (sym = _zbar_decode_ean(dcode)))
+        dcode->type = sym;
+#endif
+#ifdef ENABLE_CODE39
+    if (TEST_CFG(dcode->code39.config, ZBAR_CFG_ENABLE) && (sym = _zbar_decode_code39(dcode)) > ZBAR_PARTIAL)
+        dcode->type = sym;
+#endif
+#ifdef ENABLE_CODE128
+    if (TEST_CFG(dcode->code128.config, ZBAR_CFG_ENABLE) && (sym = _zbar_decode_code128(dcode)) > ZBAR_PARTIAL)
+        dcode->type = sym;
+#endif
+#ifdef ENABLE_I25
+    if (TEST_CFG(dcode->i25.config, ZBAR_CFG_ENABLE) && (sym = _zbar_decode_i25(dcode)) > ZBAR_PARTIAL)
+        dcode->type = sym;
+#endif
+#ifdef ENABLE_PDF417
+    if (TEST_CFG(dcode->pdf417.config, ZBAR_CFG_ENABLE) && (sym = _zbar_decode_pdf417(dcode)) > ZBAR_PARTIAL)
+        dcode->type = sym;
+#endif
+#ifdef ENABLE_QRCODE
+    if (TEST_CFG(dcode->qrf.config, ZBAR_CFG_ENABLE) && (sym = _zbar_find_qr(dcode)) > ZBAR_PARTIAL)
+        dcode->type = sym;
+#endif
+    dcode->idx++;
+    if (dcode->type) {
+        if (dcode->handler)
+            dcode->handler(dcode);
+        if (dcode->lock && dcode->type > ZBAR_PARTIAL)
+            dcode->lock = 0;
+    }
+
+    return(dcode->type);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+static inline int decoder_set_config_bool(zbar_decoder_t* dcode, zbar_symbol_type_t sym, zbar_config_t cfg, int val)
+{
+    unsigned*   config = NULL;
+    switch (sym) {
+    #ifdef ENABLE_EAN
+
+        case ZBAR_EAN13:
+            config = &dcode->ean.ean13_config;
+            break;
+
+        case ZBAR_EAN8:
+            config = &dcode->ean.ean8_config;
+            break;
+
+        case ZBAR_UPCA:
+            config = &dcode->ean.upca_config;
+            break;
+
+        case ZBAR_UPCE:
+            config = &dcode->ean.upce_config;
+            break;
+
+        case ZBAR_ISBN10:
+            config = &dcode->ean.isbn10_config;
+            break;
+
+        case ZBAR_ISBN13:
+            config = &dcode->ean.isbn13_config;
+            break;
+    #endif
+    #ifdef ENABLE_I25
+
+        case ZBAR_I25:
+            config = &dcode->i25.config;
+            break;
+    #endif
+    #ifdef ENABLE_CODE39
+
+        case ZBAR_CODE39:
+            config = &dcode->code39.config;
+            break;
+    #endif
+    #ifdef ENABLE_CODE128
+
+        case ZBAR_CODE128:
+            config = &dcode->code128.config;
+            break;
+    #endif
+    #ifdef ENABLE_PDF417
+
+        case ZBAR_PDF417:
+            config = &dcode->pdf417.config;
+            break;
+    #endif
+    #ifdef ENABLE_QRCODE
+
+        case ZBAR_QRCODE:
+            config = &dcode->qrf.config;
+            break;
+    #endif
+
+        /* FIXME handle addons */
+
+        default:
+            return(1);
+    }
+
+    if (!config || cfg >= ZBAR_CFG_NUM)
+        return(1);
+
+    if (!val)
+        *config &= ~(1 << cfg);
+    else
+    if (val == 1)
+        *config |= (1 << cfg);
+    else
+        return(1);
+
+#ifdef ENABLE_EAN
+    dcode->ean.enable = TEST_CFG
+        (
+            dcode->ean.ean13_config |
+                dcode->ean.ean8_config |
+                dcode->ean.upca_config |
+                dcode->ean.upce_config |
+                dcode->ean.isbn10_config |
+                dcode->ean.isbn13_config,
+            ZBAR_CFG_ENABLE
+        );
+#endif
+    return(0);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+static inline int decoder_set_config_int(zbar_decoder_t* dcode, zbar_symbol_type_t sym, zbar_config_t cfg, int val)
+{
+    switch (sym) {
+    #ifdef ENABLE_I25
+
+        case ZBAR_I25:
+            CFG(dcode->i25, cfg) = val;
+            break;
+    #endif
+    #ifdef ENABLE_CODE39
+
+        case ZBAR_CODE39:
+            CFG(dcode->code39, cfg) = val;
+            break;
+    #endif
+    #ifdef ENABLE_CODE128
+
+        case ZBAR_CODE128:
+            CFG(dcode->code128, cfg) = val;
+            break;
+    #endif
+    #ifdef ENABLE_PDF417
+
+        case ZBAR_PDF417:
+            CFG(dcode->pdf417, cfg) = val;
+            break;
+    #endif
+
+        default:
+            return(1);
+    }
+
+    return(0);
+}
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+int zbar_decoder_set_config(zbar_decoder_t* dcode, zbar_symbol_type_t sym, zbar_config_t cfg, int val)
+{
+    if (sym == ZBAR_NONE) {
+        zbar_decoder_set_config(dcode, ZBAR_EAN13, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_EAN8, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_UPCA, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_UPCE, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_ISBN10, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_ISBN13, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_I25, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_CODE39, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_CODE128, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_PDF417, cfg, val);
+        zbar_decoder_set_config(dcode, ZBAR_QRCODE, cfg, val);
+        return(0);
+    }
+
+    if (cfg >= 0 && cfg < ZBAR_CFG_NUM)
+        return(decoder_set_config_bool(dcode, sym, cfg, val));
+    else
+    if (cfg >= ZBAR_CFG_MIN_LEN && cfg <= ZBAR_CFG_MAX_LEN)
+        return(decoder_set_config_int(dcode, sym, cfg, val));
+    else
+        return(1);
+}
+
+static char*    decoder_dump = NULL;
+static unsigned decoder_dumplen = 0;
+
+/**
+ * @brief
+ * @note
+ * @param
+ * @retval
+ */
+const char* _zbar_decoder_buf_dump(unsigned char* buf, unsigned int buflen)
+{
+    int dumplen = (buflen * 3) + 12;
+    if (!decoder_dump || dumplen > decoder_dumplen) {
+        if (decoder_dump)
+            free(decoder_dump);
+        decoder_dump = malloc(dumplen);
+        decoder_dumplen = dumplen;
+    }
+
+    char*   p = decoder_dump + snprintf(decoder_dump, 12, "buf[%04x]=", (buflen > 0xffff) ? 0xffff : buflen);
+    int     i;
+    for (i = 0; i < buflen; i++)
+        p += snprintf(p, 4, "%s%02x", (i) ? " " : "", buf[i]);
+    return(decoder_dump);
+}