aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-02-16 09:58:33 -0200
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-02-16 10:39:24 -0200
commit6873d05af1b0732ee3ed3450d87440ae854eda5f (patch)
tree6daf70a8271293d42723b3f5b6f118704a352061
parent9810d79890d38f8183d5e3cf4415be81e582f2ec (diff)
symbol.c: fix symbol hash logicstable-0.21
ZBar uses an array (scanner sym_configs) in order to store some decoder-specific configurations (currently, only ZBAR_CFG_UNCERTAINTY is stored there). As the value of zbar_symbol_type_e can be up to 0x700, it uses a poor man's hash table to map it into an array with NUM_SYMS elements (19 elements). The idea of using a hash to convert from zbar_symbol_type_e into an array index between 0 and NUM_SYMS - 1 is interesting, but it has a drawback: the latest added symbology (SQCODE) caused a collision, making one of the used vars to be a -1. As the hash code there doesn't provide any collision detection mechanism, it checks for problems with assert() calls. So, if one tries to set or retrieve ZBAR_CFG_UNCERTAINTY config for sqcode, it gets an abort(). While we could come up with some improved hash logic there that would avoid collisions, as the range of symbol codes that makes sense for that code is not bigger than 128, let's just use an static array with 129 elements (instead of the original one with 32 elements). I opted to preserve the values returned by the past hash table code for the symbologies that makes sense. In the case of the new SQCODE, I opted to set it to 1 (it could also be 0). Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
-rw-r--r--include/zbar.h5
-rw-r--r--zbar/symbol.c46
2 files changed, 39 insertions, 12 deletions
diff --git a/include/zbar.h b/include/zbar.h
index 5ef8fab..5a089ce 100644
--- a/include/zbar.h
+++ b/include/zbar.h
@@ -108,6 +108,11 @@ typedef enum zbar_symbol_type_e {
ZBAR_CODE93 = 93, /**< Code 93. @since 0.11 */
ZBAR_CODE128 = 128, /**< Code 128 */
+ /*
+ * Please see _zbar_get_symbol_hash() if adding
+ * anything after 128
+ */
+
/** mask for base symbol type.
* @deprecated in 0.11, remove this from existing code
*/
diff --git a/zbar/symbol.c b/zbar/symbol.c
index 49b6fd0..4a1b2c7 100644
--- a/zbar/symbol.c
+++ b/zbar/symbol.c
@@ -99,18 +99,40 @@ const char *zbar_get_orientation_name (zbar_orientation_t orient)
int _zbar_get_symbol_hash (zbar_symbol_type_t sym)
{
- static const signed char hash[0x20] = {
- 0x00, 0x01, 0x10, 0x11, -1, 0x11, 0x16, 0x0c,
- 0x05, 0x06, 0x08, -1, 0x04, 0x03, 0x07, 0x12,
- -1, -1, -1, -1, -1, -1, -1, 0x02,
- -1, 0x00, 0x12, 0x0c, 0x0b, 0x1d, 0x0a, 0x00,
- };
- int g0 = hash[sym & 0x1f];
- int g1 = hash[~(sym >> 4) & 0x1f];
- assert(g0 >= 0 && g1 >= 0);
- if(g0 < 0 || g1 < 0)
- return(0);
- return((g0 + g1) & 0x1f);
+ static const signed char hash[ZBAR_CODE128 + 1] = {
+ [0 ... ZBAR_CODE128] = -1,
+
+ /* [ZBAR_FOO] = 0, is empty */
+ [ZBAR_SQCODE] = 1,
+ [ZBAR_CODE128] = 2,
+ [ZBAR_EAN13] = 3,
+ [ZBAR_UPCA] = 4,
+ [ZBAR_EAN8] = 5,
+ [ZBAR_UPCE] = 6,
+ [ZBAR_ISBN13] = 7,
+ [ZBAR_ISBN10] = 8,
+ [ZBAR_CODE39] = 9,
+ [ZBAR_I25] = 10,
+ [ZBAR_PDF417] = 11,
+ [ZBAR_QRCODE] = 12,
+ [ZBAR_DATABAR] = 13,
+ [ZBAR_DATABAR_EXP] = 14,
+ [ZBAR_CODE93] = 15,
+ [ZBAR_EAN2] = 16,
+ [ZBAR_EAN5] = 17,
+ [ZBAR_COMPOSITE] = 18,
+ [ZBAR_CODABAR] = 19,
+
+ /* Please update NUM_SYMS accordingly */
+ };
+ int h;
+
+ assert (sym >= ZBAR_PARTIAL && sym <= ZBAR_CODE128);
+
+ h = hash[sym];
+ assert (h >= 0 && h < NUM_SYMS);
+
+ return h;
}
void _zbar_symbol_free (zbar_symbol_t *sym)

Privacy Policy