Zoltan Hudak / zbar

Dependents:   BarcodeReader_F103

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Symbol.h Source File

Symbol.h

Go to the documentation of this file.
00001 //------------------------------------------------------------------------
00002 //  Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
00003 //
00004 //  This file is part of the ZBar Bar Code Reader.
00005 //
00006 //  The ZBar Bar Code Reader is free software; you can redistribute it
00007 //  and/or modify it under the terms of the GNU Lesser Public License as
00008 //  published by the Free Software Foundation; either version 2.1 of
00009 //  the License, or (at your option) any later version.
00010 //
00011 //  The ZBar Bar Code Reader is distributed in the hope that it will be
00012 //  useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00013 //  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU Lesser Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU Lesser Public License
00017 //  along with the ZBar Bar Code Reader; if not, write to the Free
00018 //  Software Foundation, Inc., 51 Franklin St, Fifth Floor,
00019 //  Boston, MA  02110-1301  USA
00020 //
00021 //  http://sourceforge.net/projects/zbar
00022 //------------------------------------------------------------------------
00023 #ifndef _ZBAR_SYMBOL_H_
00024 #define _ZBAR_SYMBOL_H_
00025 
00026 /// @file
00027 /// Symbol C++ wrapper
00028 
00029 #ifndef _ZBAR_H_
00030 # error "include zbar.h in your application, **not** zbar/Symbol.h"
00031 #endif
00032 
00033 #include <stdlib.h>
00034 #include <string>
00035 #include <ostream>
00036 #include <assert.h>
00037 
00038 namespace zbar {
00039 
00040 class SymbolIterator;
00041 
00042 /// container for decoded result symbols associated with an image
00043 /// or a composite symbol.
00044 
00045 class SymbolSet {
00046 public:
00047     /// constructor.
00048     SymbolSet (const zbar_symbol_set_t *syms = NULL)
00049         : _syms(syms)
00050     {
00051         ref();
00052     }
00053 
00054     /// copy constructor.
00055     SymbolSet (const SymbolSet& syms)
00056         : _syms(syms._syms)
00057     {
00058         ref();
00059     }
00060 
00061     /// destructor.
00062     ~SymbolSet ()
00063     {
00064         ref(-1);
00065     }
00066 
00067     /// manipulate reference count.
00068     void ref (int delta = 1) const
00069     {
00070         if(_syms)
00071             zbar_symbol_set_ref((zbar_symbol_set_t*)_syms, delta);
00072     }
00073 
00074     /// cast to C symbol set.
00075     operator const zbar_symbol_set_t* () const
00076     {
00077         return(_syms);
00078     }
00079 
00080     int get_size ()
00081     {
00082         return((_syms) ? zbar_symbol_set_get_size(_syms) : 0);
00083     }
00084 
00085     /// create a new SymbolIterator over decoded results.
00086     SymbolIterator symbol_begin() const;
00087 
00088     /// return a SymbolIterator suitable for ending iteration.
00089     const SymbolIterator symbol_end() const;
00090 
00091 private:
00092     const zbar_symbol_set_t *_syms;
00093 };
00094 
00095 /// decoded barcode symbol result object.  stores type, data, and
00096 /// image location of decoded symbol
00097 
00098 class Symbol {
00099 public:
00100 
00101     /// image pixel location (x, y) coordinate tuple.
00102     class Point {
00103     public:
00104         int x;  ///< x-coordinate.
00105         int y;  ///< y-coordinate.
00106 
00107         Point () { }
00108 
00109         Point(int x, int y)
00110             : x(x), y(y)
00111         { }
00112 
00113         /// copy constructor.
00114         Point (const Point& pt)
00115         {
00116             x = pt.x;
00117             y = pt.y;
00118         }
00119     };
00120 
00121     /// iteration over Point objects in a symbol location polygon.
00122     class PointIterator
00123         : public std::iterator<std::input_iterator_tag, Point> {
00124 
00125     public:
00126         /// constructor.
00127         PointIterator (const Symbol *sym = NULL,
00128                        int index = 0)
00129             : _sym(sym),
00130               _index(index)
00131         {
00132             sym->ref(1);
00133             if(!sym ||
00134                (unsigned)_index >= zbar_symbol_get_loc_size(*_sym))
00135                 _index = -1;
00136         }
00137 
00138         /// constructor.
00139         PointIterator (const PointIterator& iter)
00140             : _sym(iter._sym),
00141               _index(iter._index)
00142         {
00143             _sym->ref();
00144         }
00145 
00146         /// destructor.
00147         ~PointIterator ()
00148         {
00149             _sym->ref(-1);
00150         }
00151 
00152         /// advance iterator to next Point.
00153         PointIterator& operator++ ()
00154         {
00155             unsigned int i = ++_index;
00156             if(i >= zbar_symbol_get_loc_size(*_sym))
00157                 _index = -1;
00158             return(*this);
00159         }
00160 
00161         /// retrieve currently referenced Point.
00162         const Point operator* () const
00163         {
00164             assert(_index >= 0);
00165             return(Point(zbar_symbol_get_loc_x(*_sym, _index),
00166                          zbar_symbol_get_loc_y(*_sym, _index)));
00167         }
00168 
00169         /// test if two iterators refer to the same Point in the same
00170         /// Symbol.
00171         bool operator== (const PointIterator& iter) const
00172         {
00173             return(_index == iter._index &&
00174                    ((_index < 0) || _sym == iter._sym));
00175         }
00176 
00177         /// test if two iterators refer to the same Point in the same
00178         /// Symbol.
00179         bool operator!= (const PointIterator& iter) const
00180         {
00181             return(!(*this == iter));
00182         }
00183 
00184     private:
00185         const Symbol *_sym;
00186         int _index;
00187     };
00188 
00189     /// constructor.
00190     Symbol (const zbar_symbol_t *sym = NULL)
00191         : _xmlbuf(NULL),
00192           _xmllen(0)
00193     {
00194         init(sym);
00195         ref();
00196     }
00197 
00198     /// copy constructor.
00199     Symbol (const Symbol& sym)
00200         : _sym(sym._sym),
00201           _type(sym._type),
00202           _data(sym._data),
00203           _xmlbuf(NULL),
00204           _xmllen(0)
00205     {
00206         ref();
00207     }
00208 
00209     /// destructor.
00210     ~Symbol () {
00211         if(_xmlbuf)
00212             free(_xmlbuf);
00213         ref(-1);
00214     }
00215 
00216     void ref (int delta = 1) const
00217     {
00218         if(_sym)
00219             zbar_symbol_ref((zbar_symbol_t*)_sym, delta);
00220     }
00221 
00222     /// cast to C symbol.
00223     operator const zbar_symbol_t* () const
00224     {
00225         return(_sym);
00226     }
00227 
00228     /// test if two Symbol objects refer to the same C symbol.
00229     bool operator== (const Symbol& sym) const
00230     {
00231         return(_sym == sym._sym);
00232     }
00233 
00234     /// test if two Symbol objects refer to the same C symbol.
00235     bool operator!= (const Symbol& sym) const
00236     {
00237         return(!(*this == sym));
00238     }
00239 
00240     /// retrieve type of decoded symbol.
00241     zbar_symbol_type_t get_type () const
00242     {
00243         return(_type);
00244     }
00245 
00246     /// retrieve the string name of the symbol type.
00247     const std::string get_type_name () const
00248     {
00249         return(zbar_get_symbol_name(_type));
00250     }
00251 
00252     /// retrieve the string name for any addon.
00253     const std::string get_addon_name () const
00254     {
00255         return(zbar_get_addon_name(_type));
00256     }
00257 
00258     /// retrieve data decoded from symbol.
00259     const std::string get_data () const
00260     {
00261         return(_data);
00262     }
00263 
00264     /// retrieve length of binary data
00265     unsigned get_data_length () const
00266     {
00267         return((_sym) ? zbar_symbol_get_data_length(_sym) : 0);
00268     }
00269 
00270     /// retrieve inter-frame coherency count.
00271     /// see zbar_symbol_get_count()
00272     /// @since 1.5
00273     int get_count () const
00274     {
00275         return((_sym) ? zbar_symbol_get_count(_sym) : -1);
00276     }
00277 
00278     SymbolSet get_components () const
00279     {
00280         return(SymbolSet((_sym) ? zbar_symbol_get_components(_sym) : NULL));
00281     }
00282 
00283     /// create a new PointIterator at the start of the location
00284     /// polygon.
00285     PointIterator point_begin() const
00286     {
00287         return(PointIterator(this));
00288     }
00289 
00290     /// return a PointIterator suitable for ending iteration.
00291     const PointIterator point_end() const
00292     {
00293         return(PointIterator());
00294     }
00295 
00296     /// see zbar_symbol_get_loc_size().
00297     int get_location_size () const
00298     {
00299         return((_sym) ? zbar_symbol_get_loc_size(_sym) : 0);
00300     }
00301 
00302     /// see zbar_symbol_get_loc_x().
00303     int get_location_x (unsigned index) const
00304     {
00305         return((_sym) ? zbar_symbol_get_loc_x(_sym, index) : -1);
00306     }
00307 
00308     /// see zbar_symbol_get_loc_y().
00309     int get_location_y (unsigned index) const
00310     {
00311         return((_sym) ? zbar_symbol_get_loc_y(_sym, index) : -1);
00312     }
00313 
00314     /// see zbar_symbol_xml().
00315     const std::string xml () const
00316     {
00317         if(!_sym)
00318             return("");
00319         return(zbar_symbol_xml(_sym, (char**)&_xmlbuf, (unsigned*)&_xmllen));
00320     }
00321 
00322 protected:
00323 
00324     friend class SymbolIterator;
00325 
00326     /// (re)initialize Symbol from C symbol object.
00327     void init (const zbar_symbol_t *sym = NULL)
00328     {
00329         _sym = sym;
00330         if(sym) {
00331             _type = zbar_symbol_get_type(sym);
00332             _data = std::string(zbar_symbol_get_data(sym),
00333                                 zbar_symbol_get_data_length(sym));
00334         }
00335         else {
00336             _type = ZBAR_NONE;
00337             _data = "";
00338         }
00339     }
00340 
00341 private:
00342     const zbar_symbol_t *_sym;
00343     zbar_symbol_type_t _type;
00344     std::string _data;
00345     char *_xmlbuf;
00346     unsigned _xmllen;
00347 };
00348 
00349 /// iteration over Symbol result objects in a scanned Image or SymbolSet.
00350 class SymbolIterator
00351     : public std::iterator<std::input_iterator_tag, Symbol> {
00352 
00353 public:
00354     /// default constructor.
00355     SymbolIterator ()
00356     { }
00357 
00358     /// constructor.
00359     SymbolIterator (const SymbolSet &syms)
00360         : _syms(syms)
00361     {
00362         const zbar_symbol_set_t *zsyms = _syms;
00363         if(zsyms)
00364             _sym.init(zbar_symbol_set_first_symbol(zsyms));
00365     }
00366 
00367     /// copy constructor.
00368     SymbolIterator (const SymbolIterator& iter)
00369         : _syms(iter._syms)
00370     {
00371         const zbar_symbol_set_t *zsyms = _syms;
00372         if(zsyms)
00373             _sym.init(zbar_symbol_set_first_symbol(zsyms));
00374     }
00375 
00376     ~SymbolIterator ()
00377     {
00378         _sym.init();
00379     }
00380 
00381     /// advance iterator to next Symbol.
00382     SymbolIterator& operator++ ()
00383     {
00384         const zbar_symbol_t *zsym = _sym;
00385         if(zsym)
00386             _sym.init(zbar_symbol_next(zsym));
00387         else {
00388             const zbar_symbol_set_t *zsyms = _syms;
00389             if(zsyms)
00390                 _sym.init(zbar_symbol_set_first_symbol(zsyms));
00391         }
00392         return(*this);
00393     }
00394 
00395     /// retrieve currently referenced Symbol.
00396     const Symbol operator* () const
00397     {
00398         return(_sym);
00399     }
00400 
00401     /// access currently referenced Symbol.
00402     const Symbol* operator-> () const
00403     {
00404         return(&_sym);
00405     }
00406 
00407     /// test if two iterators refer to the same Symbol
00408     bool operator== (const SymbolIterator& iter) const
00409     {
00410         // it is enough to test the symbols, as they belong
00411         // to only one set (also simplifies invalid case)
00412         return(_sym == iter._sym);
00413     }
00414 
00415     /// test if two iterators refer to the same Symbol
00416     bool operator!= (const SymbolIterator& iter) const
00417     {
00418         return(!(*this == iter));
00419     }
00420 
00421     const SymbolIterator end () const {
00422         return(SymbolIterator());
00423     }
00424 
00425 private:
00426     SymbolSet _syms;
00427     Symbol _sym;
00428 };
00429 
00430 inline SymbolIterator SymbolSet::symbol_begin () const {
00431     return(SymbolIterator(*this));
00432 }
00433 
00434 inline const SymbolIterator SymbolSet::symbol_end () const {
00435     return(SymbolIterator());
00436 }
00437 
00438 /// @relates Symbol
00439 /// stream the string representation of a Symbol.
00440 static inline std::ostream& operator<< (std::ostream& out,
00441                                         const Symbol& sym)
00442 {
00443     out << sym.get_type_name()
00444         << sym.get_addon_name()
00445         << ":" << sym.get_data();
00446     return(out);
00447 }
00448 
00449 }
00450 
00451 #endif