summaryrefslogtreecommitdiffstats
path: root/src/barcode/barcode.h
blob: 0ba4df5745df56d228d9f39c205fb1e3b1dbdb16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/***************************************************************************
    copyright            : (C) 2007 by Sebastian Held
    email                : sebastian.held@gmx.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *    ### based on BaToo: http://people.inf.ethz.ch/adelmanr/batoo/ ###    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of version 2 of the GNU General Public License as  *
 *   published by the Free Software Foundation;                            *
 *                                                                         *
 ***************************************************************************/

#ifndef BARCODE_H
#define BARCODE_H

#include <tqthread.h>
#include <tqimage.h>
#include <tqvaluevector.h>
#include <tqobject.h>
#include <tqmutex.h>
#include <math.h>

#include "barcode_v4l.h"

//#define BarcodeDecoder_DEBUG
//#define Decoder_EAN13_DEBUG
//#define Barcode_DEBUG

namespace barcodeRecognition {
	static int code_odd[][4] = { { 30, 20, 10, 10 },
		                        { 20, 20, 20, 10 },
		                        { 20, 10, 20, 20 },
		                        { 10, 40, 10, 10 },
		                        { 10, 10, 30, 20 },
		                        { 10, 20, 30, 10 },
		                        { 10, 10, 10, 40 },
		                        { 10, 30, 10, 20 },
		                        { 10, 20, 10, 30 },
		                        { 30, 10, 10, 20 } };

	static int code_even[][4] = { { 10, 10, 20, 30 },
		                         { 10, 20, 20, 20 },
		                         { 20, 20, 10, 20 },
		                         { 10, 10, 40, 10 },
		                         { 20, 30, 10, 10 },
		                         { 10, 30, 20, 10 },
		                         { 40, 10, 10, 10 },
		                         { 20, 10, 30, 10 },
		                         { 30, 10, 20, 10 },
		                         { 20, 10, 10, 30 } };

	static bool parity_pattern_list[][6] = { { false, false, false, false, false, false },
		                                       { false, false, true, false, true, true },
		                                       { false, false, true, true, false, true },
		                                       { false, false, true, true, true, false },
		                                       { false, true, false, false, true, true },
		                                       { false, true, true, false, false, true },
		                                       { false, true, true, true, false, false },
		                                       { false, true, false, true, false, true },
		                                       { false, true, false, true, true, false },
		                                       { false, true, true, false, true, false } };

  class Barcode_EAN13 {
  public:
    Barcode_EAN13();
    Barcode_EAN13( TQValueVector<int> code );
    bool isNull() const { return m_null; }
    bool isValid() const;
    TQValueVector<int> getNumbers() const;
    void setCode( TQValueVector<int> code );
    TQString toString() const;
    bool operator!= ( const Barcode_EAN13 &code );
  protected:
    TQValueVector<int> m_numbers;
    bool m_null;
  };

  class MatchMakerResult {
  public:
    MatchMakerResult( bool even, int digit );
    bool isEven() const {return m_even;}
    int getDigit() const {return m_digit;}
  protected:
    int m_digit;
    bool m_even;
  };

  class Decoder_EAN13 {
  public:
    enum { BOTH_TABLES = 0, EVEN_TABLE = 1, ODD_TABLE = 2 };
    static Barcode_EAN13 recognize( TQValueVector< TQValueVector<int> > fields );
    static TQValueVector<int> decode( TQValueVector< TQValueVector<int> > fields, int start_i, int end_i );
    static MatchMakerResult recognizeNumber( TQValueVector< TQValueVector<int> > fields, int code_table_to_use );
    static MatchMakerResult recognizeSystemCode( bool parity_pattern[6] );
  };

  /** \brief this thread handles barcode recognition using webcams
   *  @author Sebastian Held <sebastian.held@gmx.de>
   */
  class barcodeRecognitionThread : public TQObject, public TQThread {
    TQ_OBJECT
  
  public:
    barcodeRecognitionThread();
    ~barcodeRecognitionThread();
    virtual void run();
    void stop();
    void recognizeBarcode( TQImage img );
    bool isWebcamAvailable();
  signals:
    void recognized( TQString barcode );
    void gotImage( TQImage &img );
  protected:
    volatile bool m_stop;
    TQImage m_barcode_img;
    TQMutex m_stop_mutex, m_barcode_img_mutex;
    barcode_v4l *m_barcode_v4l;

    Barcode_EAN13 recognize( TQImage img );
    Barcode_EAN13 recognizeCode( TQImage img, int x1, int x2, int y );
    void addNumberToPossibleNumbers( TQValueVector<int> number, int possible_numbers[10][13][2], bool correct_code );
    void sortDigits( int possible_numbers[10][13][2] );
    Barcode_EAN13 extractBarcode( int possible_numbers[10][13][2] );
    TQValueVector<int> transformPathToBW( TQValueVector<TQRgb> line);
    TQValueVector< TQValueVector<int> > extractFieldInformation( TQValueVector<int> string );
    Barcode_EAN13 detectValidBarcode ( int possible_numbers[10][13][2], int max_amount_of_considered_codes );
    bool isValid( int numbers[13] );
    bool isValid( TQValueVector<int> numbers );
    void printArray( int array[10][13][2], int level );
  };
}

#endif