//------------------------------------------------------------------------ // Copyright 2007-2010 (c) Jeff Brown // // 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 #include #include #include 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 { public: /// constructor. PointIterator (const Symbol *sym = NULL, int index = 0) : _sym(sym), _index(index) { 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) { _sym->ref(); } /// destructor. ~PointIterator () { _sym->ref(-1); } /// assignment. PointIterator& operator= (const PointIterator& iter) { iter._sym->ref(); _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(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 1.5 int get_count () const { return((_sym) ? zbar_symbol_get_count(_sym) : -1); } 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 { 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); } } #endif