You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
451 lines
11 KiB
451 lines
11 KiB
//------------------------------------------------------------------------ |
|
// Copyright 2007-2009 (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 <stdlib.h> |
|
#include <string> |
|
#include <ostream> |
|
#include <assert.h> |
|
|
|
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); |
|
} |
|
|
|
/// 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 () |
|
{ |
|
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; |
|
} |
|
}; |
|
|
|
/// 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) |
|
{ |
|
sym->ref(1); |
|
if(!sym || |
|
(unsigned)_index >= zbar_symbol_get_loc_size(*_sym)) |
|
_index = -1; |
|
} |
|
|
|
/// constructor. |
|
PointIterator (const PointIterator& iter) |
|
: _sym(iter._sym), |
|
_index(iter._index) |
|
{ |
|
_sym->ref(); |
|
} |
|
|
|
/// destructor. |
|
~PointIterator () |
|
{ |
|
_sym->ref(-1); |
|
} |
|
|
|
/// 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(_index >= 0); |
|
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); |
|
} |
|
|
|
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. |
|
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_xml(). |
|
const std::string xml () const |
|
{ |
|
if(!_sym) |
|
return(""); |
|
return(zbar_symbol_xml(_sym, (char**)&_xmlbuf, (unsigned*)&_xmllen)); |
|
} |
|
|
|
protected: |
|
|
|
friend class SymbolIterator; |
|
|
|
/// (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.init(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.init(zbar_symbol_set_first_symbol(zsyms)); |
|
} |
|
|
|
~SymbolIterator () |
|
{ |
|
_sym.init(); |
|
} |
|
|
|
/// advance iterator to next Symbol. |
|
SymbolIterator& operator++ () |
|
{ |
|
const zbar_symbol_t *zsym = _sym; |
|
if(zsym) |
|
_sym.init(zbar_symbol_next(zsym)); |
|
else { |
|
const zbar_symbol_set_t *zsyms = _syms; |
|
if(zsyms) |
|
_sym.init(zbar_symbol_set_first_symbol(zsyms)); |
|
} |
|
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_addon_name() |
|
<< ":" << sym.get_data(); |
|
return(out); |
|
} |
|
|
|
} |
|
|
|
#endif
|
|
|