zbar-windows/python/symbol.c

231 lines
6.7 KiB
C

/*------------------------------------------------------------------------
* Copyright 2009-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 "zbarmodule.h"
static char symbol_doc[] =
PyDoc_STR("symbol result object.\n"
"\n"
"data and associated information about a successful decode.");
static int symbol_traverse(zbarSymbol *self, visitproc visit, void *arg)
{
return (0);
}
static int symbol_clear(zbarSymbol *self)
{
if (self->zsym) {
zbar_symbol_t *zsym = (zbar_symbol_t *)self->zsym;
self->zsym = NULL;
zbar_symbol_ref(zsym, -1);
}
Py_CLEAR(self->data);
Py_CLEAR(self->loc);
return (0);
}
static void symbol_dealloc(zbarSymbol *self)
{
symbol_clear(self);
((PyObject *)self)->ob_type->tp_free((PyObject *)self);
}
static zbarSymbolSet *symbol_get_components(zbarSymbol *self, void *closure)
{
const zbar_symbol_set_t *zsyms = zbar_symbol_get_components(self->zsym);
return (zbarSymbolSet_FromSymbolSet(zsyms));
}
static zbarSymbolIter *symbol_iter(zbarSymbol *self)
{
zbarSymbolSet *syms = symbol_get_components(self, NULL);
zbarSymbolIter *iter = zbarSymbolIter_FromSymbolSet(syms);
Py_XDECREF(syms);
return (iter);
}
static zbarEnumItem *symbol_get_type(zbarSymbol *self, void *closure)
{
return (zbarSymbol_LookupEnum(zbar_symbol_get_type(self->zsym)));
}
static PyObject *symbol_get_configs(zbarSymbol *self, void *closure)
{
unsigned int mask = zbar_symbol_get_configs(self->zsym);
struct module_state *st = GETMODSTATE();
return (zbarEnum_SetFromMask(st->config_enum, mask));
}
static PyObject *symbol_get_modifiers(zbarSymbol *self, void *closure)
{
unsigned int mask = zbar_symbol_get_modifiers(self->zsym);
struct module_state *st = GETMODSTATE();
return (zbarEnum_SetFromMask(st->modifier_enum, mask));
}
static PyObject *symbol_get_long(zbarSymbol *self, void *closure)
{
int val;
if (!closure)
val = zbar_symbol_get_quality(self->zsym);
else
val = zbar_symbol_get_count(self->zsym);
#if PY_MAJOR_VERSION >= 3
return (PyLong_FromLong(val));
#else
return (PyInt_FromLong(val));
#endif
}
static PyObject *symbol_get_data(zbarSymbol *self, void *closure)
{
if (!self->data) {
#if PY_MAJOR_VERSION >= 3
self->data = PyUnicode_FromStringAndSize(
zbar_symbol_get_data(self->zsym),
zbar_symbol_get_data_length(self->zsym));
#else
/* FIXME this could be a buffer now */
self->data =
PyString_FromStringAndSize(zbar_symbol_get_data(self->zsym),
zbar_symbol_get_data_length(self->zsym));
#endif
if (!self->data)
return (NULL);
}
Py_INCREF(self->data);
return (self->data);
}
static PyObject *symbol_get_location(zbarSymbol *self, void *closure)
{
if (!self->loc) {
/* build tuple of 2-tuples representing location polygon */
unsigned int n = zbar_symbol_get_loc_size(self->zsym);
self->loc = PyTuple_New(n);
unsigned int i;
for (i = 0; i < n; i++) {
PyObject *x, *y;
#if PY_MAJOR_VERSION >= 3
x = PyLong_FromLong(zbar_symbol_get_loc_x(self->zsym, i));
y = PyLong_FromLong(zbar_symbol_get_loc_y(self->zsym, i));
#else
x = PyInt_FromLong(zbar_symbol_get_loc_x(self->zsym, i));
y = PyInt_FromLong(zbar_symbol_get_loc_y(self->zsym, i));
#endif
PyTuple_SET_ITEM(self->loc, i, PyTuple_Pack(2, x, y));
}
}
Py_INCREF(self->loc);
return (self->loc);
}
static zbarEnumItem *symbol_get_orientation(zbarSymbol *self, void *closure)
{
struct module_state *st = GETMODSTATE();
return (zbarEnum_LookupValue(st->orient_enum,
zbar_symbol_get_orientation(self->zsym)));
}
static PyGetSetDef symbol_getset[] = {
{
"type",
(getter)symbol_get_type,
},
{
"configs",
(getter)symbol_get_configs,
},
{
"modifiers",
(getter)symbol_get_modifiers,
},
{ "quality", (getter)symbol_get_long, NULL, NULL, (void *)0 },
{ "count", (getter)symbol_get_long, NULL, NULL, (void *)1 },
{
"data",
(getter)symbol_get_data,
},
{
"location",
(getter)symbol_get_location,
},
{
"orientation",
(getter)symbol_get_orientation,
},
{
"components",
(getter)symbol_get_components,
},
{
NULL,
},
};
PyTypeObject zbarSymbol_Type = {
PyVarObject_HEAD_INIT(NULL, 0).tp_name = "zbar.Symbol",
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
.tp_doc = symbol_doc,
.tp_basicsize = sizeof(zbarSymbol),
.tp_traverse = (traverseproc)symbol_traverse,
.tp_clear = (inquiry)symbol_clear,
.tp_dealloc = (destructor)symbol_dealloc,
.tp_iter = (getiterfunc)symbol_iter,
.tp_getset = symbol_getset,
};
zbarSymbol *zbarSymbol_FromSymbol(const zbar_symbol_t *zsym)
{
/* FIXME symbol object recycle cache */
zbarSymbol *self = PyObject_GC_New(zbarSymbol, &zbarSymbol_Type);
if (!self)
return (NULL);
assert(zsym);
zbar_symbol_t *zs = (zbar_symbol_t *)zsym;
zbar_symbol_ref(zs, 1);
self->zsym = zsym;
self->data = NULL;
self->loc = NULL;
return (self);
}
zbarEnumItem *zbarSymbol_LookupEnum(zbar_symbol_type_t type)
{
#if PY_MAJOR_VERSION >= 3
PyObject *key = PyLong_FromLong(type);
#else
PyObject *key = PyInt_FromLong(type);
#endif
struct module_state *st = GETMODSTATE();
zbarEnumItem *e = (zbarEnumItem *)PyDict_GetItem(st->symbol_enum, key);
if (!e)
return ((zbarEnumItem *)key);
Py_INCREF((PyObject *)e);
Py_DECREF(key);
return (e);
}