diff options
Diffstat (limited to 'include/zbar/Symbol.h')
-rw-r--r-- | include/zbar/Symbol.h | 532 |
1 files changed, 532 insertions, 0 deletions
diff --git a/include/zbar/Symbol.h b/include/zbar/Symbol.h new file mode 100644 index 0000000..f3a5668 --- /dev/null +++ b/include/zbar/Symbol.h @@ -0,0 +1,532 @@ +//------------------------------------------------------------------------ +// 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 +//------------------------------------------------------------------------ +#ifndef _ZBAR_SYMBOL_H_ +#define _ZBAR_SYMBOL_H_ + +/// @file +/// Symbol C++ wrapper + +#ifndef _ZBAR_H_ +#error "include zbar.h in your application, **not** zbar/Symbol.h" +#endif + +#include <assert.h> +#include <ostream> +#include <stdlib.h> +#include <string> + +namespace zbar +{ +class SymbolIterator; + +/// container for decoded result symbols associated with an image +/// or a composite symbol. + +class SymbolSet +{ +public: + /// constructor. + SymbolSet(const zbar_symbol_set_t *syms = NULL) : _syms(syms) + { + ref(); + } + + /// copy constructor. + SymbolSet(const SymbolSet &syms) : _syms(syms._syms) + { + ref(); + } + + /// destructor. + ~SymbolSet() + { + ref(-1); + } + + /// assignment. + SymbolSet &operator=(const SymbolSet &syms) + { + syms.ref(); + ref(-1); + _syms = syms._syms; + return (*this); + } + + /// truth testing. + bool operator!() const + { + return (!_syms || !get_size()); + } + + /// manipulate reference count. + void ref(int delta = 1) const + { + if (_syms) + zbar_symbol_set_ref((zbar_symbol_set_t *)_syms, delta); + } + + /// cast to C symbol set. + operator const zbar_symbol_set_t *() const + { + return (_syms); + } + + int get_size() const + { + return ((_syms) ? zbar_symbol_set_get_size(_syms) : 0); + } + + /// create a new SymbolIterator over decoded results. + SymbolIterator symbol_begin() const; + + /// return a SymbolIterator suitable for ending iteration. + const SymbolIterator symbol_end() const; + +private: + const zbar_symbol_set_t *_syms; +}; + +/// decoded barcode symbol result object. stores type, data, and +/// image location of decoded symbol + +class Symbol +{ +public: + /// image pixel location (x, y) coordinate tuple. + class Point + { + public: + int x; ///< x-coordinate. + int y; ///< y-coordinate. + + Point() + { + } + + Point(int x, int y) : x(x), y(y) + { + } + + /// copy constructor. + Point(const Point &pt) : x(pt.x), y(pt.y) + { + } + + /// assignment. + Point &operator=(const Point &pt) + { + x = pt.x; + y = pt.y; + return (*this); + } + }; + + /// iteration over Point objects in a symbol location polygon. + class PointIterator : public std::iterator<std::input_iterator_tag, Point> + { + public: + /// constructor. + PointIterator(const Symbol *sym = NULL, int index = 0) + : _sym(sym), _index(index) + { + if (sym) + sym->ref(1); + if (!sym || (unsigned)_index >= zbar_symbol_get_loc_size(*_sym)) + _index = -1; + } + + /// copy constructor. + PointIterator(const PointIterator &iter) + : _sym(iter._sym), _index(iter._index) + { + if (_sym) + _sym->ref(); + } + + /// destructor. + ~PointIterator() + { + if (_sym) + _sym->ref(-1); + } + + /// assignment. + PointIterator &operator=(const PointIterator &iter) + { + if (iter._sym) + iter._sym->ref(); + if (_sym) + _sym->ref(-1); + _sym = iter._sym; + _index = iter._index; + return (*this); + } + + /// truth testing. + bool operator!() const + { + return (!_sym || _index < 0); + } + + /// advance iterator to next Point. + PointIterator &operator++() + { + unsigned int i = ++_index; + if (!_sym || i >= zbar_symbol_get_loc_size(*_sym)) + _index = -1; + return (*this); + } + + /// retrieve currently referenced Point. + const Point operator*() const + { + assert(!!*this); + if (!*this) + return (Point()); + return (Point(zbar_symbol_get_loc_x(*_sym, _index), + zbar_symbol_get_loc_y(*_sym, _index))); + } + + /// test if two iterators refer to the same Point in the same + /// Symbol. + bool operator==(const PointIterator &iter) const + { + return (_index == iter._index && + ((_index < 0) || _sym == iter._sym)); + } + + /// test if two iterators refer to the same Point in the same + /// Symbol. + bool operator!=(const PointIterator &iter) const + { + return (!(*this == iter)); + } + + private: + const Symbol *_sym; + int _index; + }; + + /// constructor. + Symbol(const zbar_symbol_t *sym = NULL) : _xmlbuf(NULL), _xmllen(0) + { + init(sym); + ref(); + } + + /// copy constructor. + Symbol(const Symbol &sym) + : _sym(sym._sym), _type(sym._type), _data(sym._data), _xmlbuf(NULL), + _xmllen(0) + { + ref(); + } + + /// destructor. + ~Symbol() + { + if (_xmlbuf) + free(_xmlbuf); + ref(-1); + } + + /// assignment. + Symbol &operator=(const Symbol &sym) + { + sym.ref(1); + ref(-1); + _sym = sym._sym; + _type = sym._type; + _data = sym._data; + return (*this); + } + + Symbol &operator=(const zbar_symbol_t *sym) + { + if (sym) + zbar_symbol_ref(sym, 1); + ref(-1); + init(sym); + return (*this); + } + + /// truth testing. + bool operator!() const + { + return (!_sym); + } + + void ref(int delta = 1) const + { + if (_sym) + zbar_symbol_ref((zbar_symbol_t *)_sym, delta); + } + + /// cast to C symbol. + operator const zbar_symbol_t *() const + { + return (_sym); + } + + /// test if two Symbol objects refer to the same C symbol. + bool operator==(const Symbol &sym) const + { + return (_sym == sym._sym); + } + + /// test if two Symbol objects refer to the same C symbol. + bool operator!=(const Symbol &sym) const + { + return (!(*this == sym)); + } + + /// retrieve type of decoded symbol. + zbar_symbol_type_t get_type() const + { + return (_type); + } + + /// retrieve the string name of the symbol type. + const std::string get_type_name() const + { + return (zbar_get_symbol_name(_type)); + } + + /// retrieve the string name for any addon. + /// @deprecated in 0.11 + const std::string get_addon_name() const + { + return (zbar_get_addon_name(_type)); + } + + /// retrieve data decoded from symbol. + const std::string get_data() const + { + return (_data); + } + + /// retrieve length of binary data + unsigned get_data_length() const + { + return ((_sym) ? zbar_symbol_get_data_length(_sym) : 0); + } + + /// retrieve inter-frame coherency count. + /// see zbar_symbol_get_count() + /// @since 0.5 + int get_count() const + { + return ((_sym) ? zbar_symbol_get_count(_sym) : -1); + } + + /// retrieve loosely defined relative quality metric. + /// see zbar_symbol_get_quality() + /// @since 0.11 + int get_quality() const + { + return ((_sym) ? zbar_symbol_get_quality(_sym) : 0); + } + + SymbolSet get_components() const + { + return (SymbolSet((_sym) ? zbar_symbol_get_components(_sym) : NULL)); + } + + /// create a new PointIterator at the start of the location + /// polygon. + PointIterator point_begin() const + { + return (PointIterator(this)); + } + + /// return a PointIterator suitable for ending iteration. + const PointIterator point_end() const + { + return (PointIterator()); + } + + /// see zbar_symbol_get_loc_size(). + int get_location_size() const + { + return ((_sym) ? zbar_symbol_get_loc_size(_sym) : 0); + } + + /// see zbar_symbol_get_loc_x(). + int get_location_x(unsigned index) const + { + return ((_sym) ? zbar_symbol_get_loc_x(_sym, index) : -1); + } + + /// see zbar_symbol_get_loc_y(). + int get_location_y(unsigned index) const + { + return ((_sym) ? zbar_symbol_get_loc_y(_sym, index) : -1); + } + + /// see zbar_symbol_get_orientation(). + /// @since 0.11 + int get_orientation() const + { + return (zbar_symbol_get_orientation(_sym)); + } + + /// see zbar_symbol_xml(). + const std::string xml() const + { + if (!_sym) + return (""); + return (zbar_symbol_xml(_sym, (char **)&_xmlbuf, (unsigned *)&_xmllen)); + } + +protected: + /// (re)initialize Symbol from C symbol object. + void init(const zbar_symbol_t *sym = NULL) + { + _sym = sym; + if (sym) { + _type = zbar_symbol_get_type(sym); + _data = std::string(zbar_symbol_get_data(sym), + zbar_symbol_get_data_length(sym)); + } else { + _type = ZBAR_NONE; + _data = ""; + } + } + +private: + const zbar_symbol_t *_sym; + zbar_symbol_type_t _type; + std::string _data; + char *_xmlbuf; + unsigned _xmllen; +}; + +/// iteration over Symbol result objects in a scanned Image or SymbolSet. +class SymbolIterator : public std::iterator<std::input_iterator_tag, Symbol> +{ +public: + /// default constructor. + SymbolIterator() + { + } + + /// constructor. + SymbolIterator(const SymbolSet &syms) : _syms(syms) + { + const zbar_symbol_set_t *zsyms = _syms; + if (zsyms) + _sym = zbar_symbol_set_first_symbol(zsyms); + } + + /// copy constructor. + SymbolIterator(const SymbolIterator &iter) : _syms(iter._syms) + { + const zbar_symbol_set_t *zsyms = _syms; + if (zsyms) + _sym = zbar_symbol_set_first_symbol(zsyms); + } + + ~SymbolIterator() + { + } + + /// assignment. + SymbolIterator &operator=(const SymbolIterator &iter) + { + _syms = iter._syms; + _sym = iter._sym; + return (*this); + } + + bool operator!() const + { + return (!_syms || !_sym); + } + + /// advance iterator to next Symbol. + SymbolIterator &operator++() + { + if (!!_sym) + _sym = zbar_symbol_next(_sym); + else if (!!_syms) + _sym = zbar_symbol_set_first_symbol(_syms); + return (*this); + } + + /// retrieve currently referenced Symbol. + const Symbol operator*() const + { + return (_sym); + } + + /// access currently referenced Symbol. + const Symbol *operator->() const + { + return (&_sym); + } + + /// test if two iterators refer to the same Symbol + bool operator==(const SymbolIterator &iter) const + { + // it is enough to test the symbols, as they belong + // to only one set (also simplifies invalid case) + return (_sym == iter._sym); + } + + /// test if two iterators refer to the same Symbol + bool operator!=(const SymbolIterator &iter) const + { + return (!(*this == iter)); + } + + const SymbolIterator end() const + { + return (SymbolIterator()); + } + +private: + SymbolSet _syms; + Symbol _sym; +}; + +inline SymbolIterator SymbolSet::symbol_begin() const +{ + return (SymbolIterator(*this)); +} + +inline const SymbolIterator SymbolSet::symbol_end() const +{ + return (SymbolIterator()); +} + +/// @relates Symbol +/// stream the string representation of a Symbol. +static inline std::ostream &operator<<(std::ostream &out, const Symbol &sym) +{ + out << sym.get_type_name() << ":" << sym.get_data(); + return (out); +} + +} // namespace zbar + +#endif |