zbar-windows/zbar/decoder.c
2021-10-07 16:38:06 +08:00

593 lines
16 KiB
C

/*------------------------------------------------------------------------
* Copyright 2007-2010 (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 <stdio.h> /* snprintf */
#include <stdlib.h> /* malloc, calloc, free */
#include <string.h> /* memset, strlen */
#include <zbar.h>
#if defined(DEBUG_DECODER) || defined(DEBUG_EAN) || defined(DEBUG_CODE93) || \
defined(DEBUG_CODE39) || defined(DEBUG_CODABAR) || defined(DEBUG_I25) || \
defined(DEBUG_DATABAR) || defined(DEBUG_CODE128) || \
defined(DEBUG_SQ_FINDER) || defined(DEBUG_QR_FINDER) || \
(defined(DEBUG_PDF417) && (DEBUG_PDF417 >= 4))
#define DEBUG_LEVEL 1
#endif
#include "debug.h"
#include "decoder.h"
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 */
#if ENABLE_EAN == 1
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;
#ifdef FIXME_ADDON_SYNC
dcode->ean.ean2_config = 1 << ZBAR_CFG_ENABLE;
dcode->ean.ean5_config = 1 << ZBAR_CFG_ENABLE;
#endif
#endif
#if ENABLE_I25 == 1
dcode->i25.config = 1 << ZBAR_CFG_ENABLE;
CFG(dcode->i25, ZBAR_CFG_MIN_LEN) = 6;
#endif
#if ENABLE_DATABAR == 1
dcode->databar.config =
((1 << ZBAR_CFG_ENABLE) | (1 << ZBAR_CFG_EMIT_CHECK));
dcode->databar.config_exp =
((1 << ZBAR_CFG_ENABLE) | (1 << ZBAR_CFG_EMIT_CHECK));
dcode->databar.csegs = 4;
dcode->databar.segs = calloc(4, sizeof(*dcode->databar.segs));
#endif
#if ENABLE_CODABAR == 1
dcode->codabar.config = 1 << ZBAR_CFG_ENABLE;
CFG(dcode->codabar, ZBAR_CFG_MIN_LEN) = 4;
#endif
#if ENABLE_CODE39 == 1
dcode->code39.config = 1 << ZBAR_CFG_ENABLE;
CFG(dcode->code39, ZBAR_CFG_MIN_LEN) = 1;
#endif
#if ENABLE_CODE93 == 1
dcode->code93.config = 1 << ZBAR_CFG_ENABLE;
#endif
#if ENABLE_CODE128 == 1
dcode->code128.config = 1 << ZBAR_CFG_ENABLE;
#endif
#if ENABLE_PDF417 == 1
dcode->pdf417.config = 1 << ZBAR_CFG_ENABLE;
#endif
#if ENABLE_QRCODE == 1
dcode->qrf.config = 1 << ZBAR_CFG_ENABLE;
#endif
#if ENABLE_SQCODE == 1
dcode->sqf.config = 1 << ZBAR_CFG_ENABLE;
#endif
zbar_decoder_reset(dcode);
return (dcode);
}
void zbar_decoder_destroy(zbar_decoder_t *dcode)
{
#if ENABLE_DATABAR == 1
if (dcode->databar.segs)
free(dcode->databar.segs);
#endif
if (dcode->buf)
free(dcode->buf);
free(dcode);
}
void zbar_decoder_reset(zbar_decoder_t *dcode)
{
memset(dcode, 0, (long)&dcode->buf_alloc - (long)dcode);
#if ENABLE_EAN == 1
ean_reset(&dcode->ean);
#endif
#if ENABLE_I25 == 1
i25_reset(&dcode->i25);
#endif
#if ENABLE_DATABAR == 1
databar_reset(&dcode->databar);
#endif
#if ENABLE_CODABAR == 1
codabar_reset(&dcode->codabar);
#endif
#if ENABLE_CODE39 == 1
code39_reset(&dcode->code39);
#endif
#if ENABLE_CODE93 == 1
code93_reset(&dcode->code93);
#endif
#if ENABLE_CODE128 == 1
code128_reset(&dcode->code128);
#endif
#if ENABLE_PDF417 == 1
pdf417_reset(&dcode->pdf417);
#endif
#if ENABLE_QRCODE == 1
qr_finder_reset(&dcode->qrf);
#endif
}
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;
dcode->s6 = 0;
#if ENABLE_EAN == 1
ean_new_scan(&dcode->ean);
#endif
#if ENABLE_I25 == 1
i25_reset(&dcode->i25);
#endif
#if ENABLE_DATABAR == 1
databar_new_scan(&dcode->databar);
#endif
#if ENABLE_CODABAR == 1
codabar_reset(&dcode->codabar);
#endif
#if ENABLE_CODE39 == 1
code39_reset(&dcode->code39);
#endif
#if ENABLE_CODE93 == 1
code93_reset(&dcode->code93);
#endif
#if ENABLE_CODE128 == 1
code128_reset(&dcode->code128);
#endif
#if ENABLE_PDF417 == 1
pdf417_reset(&dcode->pdf417);
#endif
#if ENABLE_QRCODE == 1
qr_finder_reset(&dcode->qrf);
#endif
}
zbar_color_t zbar_decoder_get_color(const zbar_decoder_t *dcode)
{
return (get_color(dcode));
}
const char *zbar_decoder_get_data(const zbar_decoder_t *dcode)
{
return ((char *)dcode->buf);
}
unsigned int zbar_decoder_get_data_length(const zbar_decoder_t *dcode)
{
return (dcode->buflen);
}
int zbar_decoder_get_direction(const zbar_decoder_t *dcode)
{
return (dcode->direction);
}
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);
}
void zbar_decoder_set_userdata(zbar_decoder_t *dcode, void *userdata)
{
dcode->userdata = userdata;
}
void *zbar_decoder_get_userdata(const zbar_decoder_t *dcode)
{
return (dcode->userdata);
}
zbar_symbol_type_t zbar_decoder_get_type(const zbar_decoder_t *dcode)
{
return (dcode->type);
}
unsigned int zbar_decoder_get_modifiers(const zbar_decoder_t *dcode)
{
return (dcode->modifiers);
}
zbar_symbol_type_t zbar_decode_width(zbar_decoder_t *dcode, unsigned w)
{
zbar_symbol_type_t tmp, sym = ZBAR_NONE;
dcode->w[dcode->idx & (DECODE_WINDOW - 1)] = w;
dbprintf(1, " decode[%x]: w=%d (%g)\n", dcode->idx, w, (w / 32.));
/* update shared character width */
dcode->s6 -= get_width(dcode, 7);
dcode->s6 += get_width(dcode, 1);
/* each decoder processes width stream in parallel */
#if ENABLE_QRCODE == 1
if (TEST_CFG(dcode->qrf.config, ZBAR_CFG_ENABLE) &&
(tmp = _zbar_find_qr(dcode)) > ZBAR_PARTIAL)
sym = tmp;
#endif
#if ENABLE_EAN == 1
if ((dcode->ean.enable) && (tmp = _zbar_decode_ean(dcode)))
sym = tmp;
#endif
#if ENABLE_CODE39 == 1
if (TEST_CFG(dcode->code39.config, ZBAR_CFG_ENABLE) &&
(tmp = _zbar_decode_code39(dcode)) > ZBAR_PARTIAL)
sym = tmp;
#endif
#if ENABLE_CODE93 == 1
if (TEST_CFG(dcode->code93.config, ZBAR_CFG_ENABLE) &&
(tmp = _zbar_decode_code93(dcode)) > ZBAR_PARTIAL)
sym = tmp;
#endif
#if ENABLE_CODE128 == 1
if (TEST_CFG(dcode->code128.config, ZBAR_CFG_ENABLE) &&
(tmp = _zbar_decode_code128(dcode)) > ZBAR_PARTIAL)
sym = tmp;
#endif
#if ENABLE_DATABAR == 1
if (TEST_CFG(dcode->databar.config | dcode->databar.config_exp,
ZBAR_CFG_ENABLE) &&
(tmp = _zbar_decode_databar(dcode)) > ZBAR_PARTIAL)
sym = tmp;
#endif
#if ENABLE_CODABAR == 1
if (TEST_CFG(dcode->codabar.config, ZBAR_CFG_ENABLE) &&
(tmp = _zbar_decode_codabar(dcode)) > ZBAR_PARTIAL)
sym = tmp;
#endif
#if ENABLE_I25 == 1
if (TEST_CFG(dcode->i25.config, ZBAR_CFG_ENABLE) &&
(tmp = _zbar_decode_i25(dcode)) > ZBAR_PARTIAL)
sym = tmp;
#endif
#if ENABLE_PDF417 == 1
if (TEST_CFG(dcode->pdf417.config, ZBAR_CFG_ENABLE) &&
(tmp = _zbar_decode_pdf417(dcode)) > ZBAR_PARTIAL)
sym = tmp;
#endif
dcode->idx++;
dcode->type = sym;
if (sym) {
if (dcode->lock && sym > ZBAR_PARTIAL && sym != ZBAR_QRCODE)
release_lock(dcode, sym);
if (dcode->handler)
dcode->handler(dcode);
}
return (sym);
}
static inline const unsigned int *
decoder_get_configp(const zbar_decoder_t *dcode, zbar_symbol_type_t sym)
{
const unsigned int *config;
switch (sym) {
#if ENABLE_EAN == 1
case ZBAR_EAN13:
config = &dcode->ean.ean13_config;
break;
case ZBAR_EAN2:
config = &dcode->ean.ean2_config;
break;
case ZBAR_EAN5:
config = &dcode->ean.ean5_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
#if ENABLE_I25 == 1
case ZBAR_I25:
config = &dcode->i25.config;
break;
#endif
#if ENABLE_DATABAR == 1
case ZBAR_DATABAR:
config = &dcode->databar.config;
break;
case ZBAR_DATABAR_EXP:
config = &dcode->databar.config_exp;
break;
#endif
#if ENABLE_CODABAR == 1
case ZBAR_CODABAR:
config = &dcode->codabar.config;
break;
#endif
#if ENABLE_CODE39 == 1
case ZBAR_CODE39:
config = &dcode->code39.config;
break;
#endif
#if ENABLE_CODE93 == 1
case ZBAR_CODE93:
config = &dcode->code93.config;
break;
#endif
#if ENABLE_CODE128 == 1
case ZBAR_CODE128:
config = &dcode->code128.config;
break;
#endif
#if ENABLE_PDF417 == 1
case ZBAR_PDF417:
config = &dcode->pdf417.config;
break;
#endif
#if ENABLE_QRCODE == 1
case ZBAR_QRCODE:
config = &dcode->qrf.config;
break;
#endif
#if ENABLE_SQCODE == 1
case ZBAR_SQCODE:
config = &dcode->sqf.config;
break;
#endif
default:
config = NULL;
}
return (config);
}
unsigned int zbar_decoder_get_configs(const zbar_decoder_t *dcode,
zbar_symbol_type_t sym)
{
const unsigned *config = decoder_get_configp(dcode, sym);
if (!config)
return (0);
return (*config);
}
static inline int decoder_set_config_bool(zbar_decoder_t *dcode,
zbar_symbol_type_t sym,
zbar_config_t cfg, int val)
{
unsigned *config = (void *)decoder_get_configp(dcode, sym);
if (!config || cfg >= ZBAR_CFG_NUM)
return (1);
if (!val)
*config &= ~(1 << cfg);
else if (val == 1)
*config |= (1 << cfg);
else
return (1);
#if ENABLE_EAN == 1
dcode->ean.enable =
TEST_CFG(dcode->ean.ean13_config | dcode->ean.ean2_config |
dcode->ean.ean5_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);
}
static inline int decoder_set_config_int(zbar_decoder_t *dcode,
zbar_symbol_type_t sym,
zbar_config_t cfg, int val)
{
switch (sym) {
#if ENABLE_I25 == 1
case ZBAR_I25:
CFG(dcode->i25, cfg) = val;
break;
#endif
#if ENABLE_CODABAR == 1
case ZBAR_CODABAR:
CFG(dcode->codabar, cfg) = val;
break;
#endif
#if ENABLE_CODE39 == 1
case ZBAR_CODE39:
CFG(dcode->code39, cfg) = val;
break;
#endif
#if ENABLE_CODE93 == 1
case ZBAR_CODE93:
CFG(dcode->code93, cfg) = val;
break;
#endif
#if ENABLE_CODE128 == 1
case ZBAR_CODE128:
CFG(dcode->code128, cfg) = val;
break;
#endif
#if ENABLE_PDF417 == 1
case ZBAR_PDF417:
CFG(dcode->pdf417, cfg) = val;
break;
#endif
default:
return (1);
}
return (0);
}
int zbar_decoder_get_config(zbar_decoder_t *dcode, zbar_symbol_type_t sym,
zbar_config_t cfg, int *val)
{
const unsigned *config = decoder_get_configp(dcode, sym);
/* Return error if symbol doesn't have config */
if (sym <= ZBAR_PARTIAL || sym > ZBAR_CODE128 || sym == ZBAR_COMPOSITE)
return 1;
/* Return decoder boolean configs */
if (cfg < ZBAR_CFG_NUM) {
*val = (*config & (1 << cfg)) != 0;
return 0;
}
/* Return decoder integer configs */
if (cfg >= ZBAR_CFG_MIN_LEN && cfg <= ZBAR_CFG_MAX_LEN) {
switch (sym) {
#if ENABLE_I25 == 1
case ZBAR_I25:
*val = CFG(dcode->i25, cfg);
return 0;
#endif
#if ENABLE_CODABAR == 1
case ZBAR_CODABAR:
*val = CFG(dcode->codabar, cfg);
return 0;
#endif
#if ENABLE_CODE39 == 1
case ZBAR_CODE39:
*val = CFG(dcode->code39, cfg);
return 0;
#endif
#if ENABLE_CODE93 == 1
case ZBAR_CODE93:
*val = CFG(dcode->code93, cfg);
return 0;
#endif
#if ENABLE_CODE128 == 1
case ZBAR_CODE128:
*val = CFG(dcode->code128, cfg);
return 0;
#endif
#if ENABLE_PDF417 == 1
case ZBAR_PDF417:
*val = CFG(dcode->pdf417, cfg);
return 0;
#endif
default:
return 1;
}
}
return 1;
}
int zbar_decoder_set_config(zbar_decoder_t *dcode, zbar_symbol_type_t sym,
zbar_config_t cfg, int val)
{
if (sym == ZBAR_NONE) {
static const zbar_symbol_type_t all[] = { ZBAR_EAN13,
ZBAR_EAN2,
ZBAR_EAN5,
ZBAR_EAN8,
ZBAR_UPCA,
ZBAR_UPCE,
ZBAR_ISBN10,
ZBAR_ISBN13,
ZBAR_I25,
ZBAR_DATABAR,
ZBAR_DATABAR_EXP,
ZBAR_CODABAR,
ZBAR_CODE39,
ZBAR_CODE93,
ZBAR_CODE128,
ZBAR_QRCODE,
ZBAR_SQCODE,
ZBAR_PDF417,
0 };
const zbar_symbol_type_t *symp;
for (symp = all; *symp; symp++)
zbar_decoder_set_config(dcode, *symp, 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;
const char *_zbar_decoder_buf_dump(unsigned char *buf, unsigned int buflen)
{
int dumplen = (buflen * 3) + 12;
char *p;
int i;
if (!decoder_dump || dumplen > decoder_dumplen) {
if (decoder_dump)
free(decoder_dump);
decoder_dump = malloc(dumplen);
decoder_dumplen = dumplen;
}
p = decoder_dump +
snprintf(decoder_dump, 12,
"buf[%04x]=", (buflen > 0xffff) ? 0xffff : buflen);
for (i = 0; i < buflen; i++)
p += snprintf(p, 4, "%s%02x", (i) ? " " : "", buf[i]);
return (decoder_dump);
}