Skip to content

Commit

Permalink
Return only asked symbology
Browse files Browse the repository at this point in the history
By default zbar is configured to detect some symbologies, so we need
to disable them before selecting the desired one.

(closes #10)
  • Loading branch information
Fabien Bochu committed Mar 9, 2017
1 parent 33e5f7c commit c76ab6e
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 11 deletions.
3 changes: 1 addition & 2 deletions ChangeLog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ ChangeLog
1.1.1 (unreleased)
------------------

- Nothing changed yet.

- Only return asked symbologie

1.1.0 (2017-01-24)
------------------
Expand Down
13 changes: 10 additions & 3 deletions src/zbarlight/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
from PIL import Image
import pkg_resources

from ._zbarlight import zbar_code_scanner
from ._zbarlight import Symbologies, zbar_code_scanner


__version__ = pkg_resources.get_distribution('zbarlight').version
__ALL__ = ['scan_codes', 'qr_code_scanner']


class UnknownSymbologieError(Exception):
pass


def scan_codes(code_type, image):
"""Get *code_type* codes from a PIL Image
Expand All @@ -35,7 +39,10 @@ def scan_codes(code_type, image):
converted_image = image.convert('L') # Convert image to gray scale (8 bits per pixel).
raw = converted_image.tobytes() # Get image data.
width, height = converted_image.size # Get image size.
return zbar_code_scanner('{0}.enable'.format(code_type).encode(), raw, width, height)
symbologie = Symbologies.get(code_type.upper())
if not symbologie:
raise UnknownSymbologieError('Unknown Symbologie: %s' % code_type)
return zbar_code_scanner(symbologie, raw, width, height)


def qr_code_scanner(image, width, height):
Expand All @@ -54,7 +61,7 @@ def qr_code_scanner(image, width, height):
The QR code value or None
"""
warnings.warn('qr_code_scanner() is deprecated use scan_codes() instead.', DeprecationWarning)
result = zbar_code_scanner(b'qrcode.enable', image, width, height)
result = zbar_code_scanner(Symbologies['QRCODE'], image, width, height)
if isinstance(result, list) and len(result) == 1:
return result[0]
return None
30 changes: 24 additions & 6 deletions src/zbarlight/_zbarlight.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

/* Extract QR code from raw image (using zbar) */
static char** _zbar_code_scanner(
const char *config_str,
const int symbologie,
const void *raw_image_data,
unsigned long raw_image_data_length,
unsigned int width,
Expand All @@ -24,7 +24,8 @@ static char** _zbar_code_scanner(
char **data = NULL;

zbar_image_scanner_t *scanner = zbar_image_scanner_create();
zbar_image_scanner_parse_config(scanner, config_str);
zbar_image_scanner_set_config(scanner, 0, ZBAR_CFG_ENABLE, 0); /* disable all symbologies */
zbar_image_scanner_set_config(scanner, symbologie, ZBAR_CFG_ENABLE, 1);

zbar_image_t *image = zbar_image_create();
zbar_image_set_format(image, format);
Expand Down Expand Up @@ -55,20 +56,20 @@ static char** _zbar_code_scanner(
/* Python wrapper for _zbar_code_scanner() */
static PyObject* zbar_code_scanner(PyObject *self, PyObject *args) {
PyObject *python_image = NULL;
char *config_str = NULL;
int symbologie = 0;
char *raw_image_data = NULL;
Py_ssize_t raw_image_data_length = 0;
unsigned int width = 0;
unsigned int height = 0;
char **result = NULL;
PyObject *data = NULL;

if (!PyArg_ParseTuple(args, "SSII", &config_str, &python_image, &width, &height)) {
if (!PyArg_ParseTuple(args, "ISII", &symbologie, &python_image, &width, &height)) {
return NULL;
}
PyBytes_AsStringAndSize(python_image, &raw_image_data, &raw_image_data_length);

result = _zbar_code_scanner(config_str, raw_image_data, raw_image_data_length, width, height);
result = _zbar_code_scanner(symbologie, raw_image_data, raw_image_data_length, width, height);
if (result == NULL) {
Py_RETURN_NONE;
}
Expand Down Expand Up @@ -113,7 +114,24 @@ static struct PyModuleDef zbarlight_moduledef = {
#endif

PyObject* PyInit__zbarlight(void) { /* Python 3 way */
return PY_INIT_FCT();
PyObject* module = PY_INIT_FCT();
PyObject * symbologies = Py_BuildValue(
"{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i}",
"EAN8", ZBAR_EAN8,
"UPCE", ZBAR_UPCE,
"ISBN10", ZBAR_ISBN10,
"UPCA", ZBAR_UPCA,
"EAN13", ZBAR_EAN13,
"ISBN13", ZBAR_ISBN13,
"I25", ZBAR_I25,
"CODE39", ZBAR_CODE39,
"PDF417", ZBAR_PDF417,
"QRCODE", ZBAR_QRCODE,
"CODE128", ZBAR_CODE128
);

PyModule_AddObject(module, "Symbologies", symbologies);
return module;
}

void init_zbarlight(void) { /* Python 2 way */
Expand Down
15 changes: 15 additions & 0 deletions tests/test_scan_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,22 @@ def test_two_qr_code(self):

def test_one_qr_code_and_one_ean(self):
image = self.get_image('one_qr_code_and_one_ean')

# Only read QRcode
self.assertEqual(
sorted(zbarlight.scan_codes('qrcode', image)),
sorted([b'zbarlight test qr code']),
)

# Only read EAN code
self.assertEqual(
sorted(zbarlight.scan_codes('ean13', image)),
sorted([b'0012345678905']),
)

def test_unknown_symbology(self):
image = self.get_image('no_qr_code')
self.assertRaises(
zbarlight.UnknownSymbologieError,
zbarlight.scan_codes, 'not-a-zbar-symbologie', image,
)

0 comments on commit c76ab6e

Please sign in to comment.