implement filter module
Stefan Schuermans

Stefan Schuermans commited on 2014-03-22 00:36:13
Showing 10 changed files, with 384 additions and 2 deletions.

... ...
@@ -0,0 +1,70 @@
1
+<html>
2
+  <head>
3
+    <title>Blinker - Filter</title>
4
+  </head>
5
+  <body>
6
+    <h1>Blinker - Filter</h1>
7
+    <p>
8
+      The filter module filters the frames of the input stream based on their
9
+      format.
10
+      It passes all frames matching the filter criteria unmodified.
11
+      Frames not matching the filter criteria are translated to no frame
12
+      at the output.
13
+    </p>
14
+    <p>
15
+      There are different filter criteria that can be active or not. If a
16
+      criteria file is not present, it does not affect the filtering. A frame
17
+      is only forwarded if it passes all criteria. If no criteria are specified
18
+      all frames are passed.
19
+    </p>
20
+    <h2>Configuration</h2>
21
+    <p>
22
+      The configuration of the filter module with name <code>NAME</code>
23
+      is located in the <code>filters/NAME</code> subdirectory.
24
+    </p>
25
+    <h3>Input Stream</h3>
26
+    <p>
27
+      The file <code>instream</code> contains the name of the stream to
28
+      receive.
29
+      The frames received from this stream are filtered and passed to the
30
+      output stream.
31
+    </p>
32
+    <h3>Format</h3>
33
+    <p>
34
+      The file <code>format</code> describes the required format of the
35
+      stream, i.e. its dimensions, the number of channels and the color depth
36
+      on each channel.
37
+      If present, the file must contain a string
38
+      <code>&lt;width&gt;x&lt;height&gt;-&lt;channels&gt;/&lt;colors&gt;</code>,
39
+      e.g. <code>18x8-1/256</code> for 18 pixels width, 8 pixels height
40
+      in 256 grayscales.
41
+    </p>
42
+    <h3>Size</h3>
43
+    <p>
44
+      The file <code>size</code> describes the required size of the
45
+      stream, i.e. its dimensions.
46
+      If present, the file must contain a string
47
+      <code>&lt;width&gt;x&lt;height&gt;</code>,
48
+      e.g. <code>18x8</code> for 18 pixels width, 8 pixels height.
49
+    </p>
50
+    <h3>Minimum and Maximum Files</h3>
51
+    <p>
52
+      The files <code>width_min</code>, <code>width_max</code>,
53
+                <code>height_min</code>, <code>height_min</code>,
54
+                <code>channels_min</code>, <code>channels_max</code>,
55
+                <code>colors_min</code>, <code>colors_max</code>
56
+      can be used to limit the minimum and maximum values of the movie
57
+      format parameters (namely width, height, number of channels and
58
+      number of colors per channel). If present, the file has to contain
59
+      a single unsigned integer number. The limit will be enforced in this
60
+      case. Otherwise, there is no restriction regarding the respective
61
+      parameter.
62
+    </p>
63
+    <h3>Output Stream</h3>
64
+    <p>
65
+      The file <code>outstream</code> contains the name of the stream to
66
+      send the filtered frames to.
67
+    </p>
68
+  </body>
69
+</html>
70
+
... ...
@@ -98,6 +98,7 @@
98 98
       The following module types are available for instantiation:
99 99
       <ul>
100 100
         <li><a href="canvas.html">Canvas</a></li>
101
+        <li><a href="filter.html">Filter</a></li>
101 102
         <li><a href="flexipix.html">FlexiPix</a></li>
102 103
         <li><a href="loveletter.html">Loveletter</a></li>
103 104
         <li><a href="opprinter.html">Operator Connection Printer</a></li>
... ...
@@ -0,0 +1,210 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#include <stdlib.h>
7
+#include <string>
8
+
9
+#include <BlinkenLib/BlinkenFrame.h>
10
+
11
+#include "Directory.h"
12
+#include "File.h"
13
+#include "Filter.h"
14
+#include "Format.h"
15
+#include "FormatFile.h"
16
+#include "InStreamFile.h"
17
+#include "Mgrs.h"
18
+#include "Module.h"
19
+#include "OutStreamFile.h"
20
+#include "Size.h"
21
+#include "SizeFile.h"
22
+#include "StreamRecv.h"
23
+#include "UInt.h"
24
+#include "UIntFile.h"
25
+
26
+namespace Blinker {
27
+
28
+/**
29
+ * @brief constructor
30
+ * @param[in] name module name
31
+ * @param[in] mgrs managers
32
+ * @param[in] dirBase base directory
33
+ */
34
+Filter::Filter(const std::string &name, Mgrs &mgrs,
35
+               const Directory &dirBase):
36
+  Module(name, mgrs, dirBase),
37
+  m_fileInStream(dirBase.getFile("instream"), mgrs.m_streamMgr),
38
+  m_fileFormat(dirBase.getFile("format")),
39
+  m_fileSize(dirBase.getFile("size")),
40
+  m_fileWidthMin(dirBase.getFile("width_min")),
41
+  m_fileWidthMax(dirBase.getFile("width_max")),
42
+  m_fileHeightMin(dirBase.getFile("height_min")),
43
+  m_fileHeightMax(dirBase.getFile("height_max")),
44
+  m_fileChannelsMin(dirBase.getFile("channels_min")),
45
+  m_fileChannelsMax(dirBase.getFile("channels_max")),
46
+  m_fileColorsMin(dirBase.getFile("colors_min")),
47
+  m_fileColorsMax(dirBase.getFile("colors_max")),
48
+  m_fileOutStream(dirBase.getFile("outstream"), mgrs.m_streamMgr)
49
+{
50
+  // set up
51
+  getSettingsIfChanged(true);
52
+  m_fileInStream.setStreamRecv(this);
53
+}
54
+
55
+/// virtual destructor
56
+Filter::~Filter()
57
+{
58
+  // clean up
59
+  m_fileInStream.setStreamRecv(NULL);
60
+}
61
+
62
+/// check for update of configuration
63
+void Filter::updateConfig()
64
+{
65
+  // stream name or format file was modified -> re-get stream or format
66
+  if (m_fileInStream.checkModified())
67
+    m_fileInStream.update();
68
+  getSettingsIfChanged(false);
69
+  if (m_fileOutStream.checkModified())
70
+    m_fileOutStream.update();
71
+}
72
+
73
+/**
74
+ * @brief set current frame
75
+ * @param[in] stream stream name
76
+ * @param[in] pFrame current frame (NULL for none)
77
+ */
78
+void Filter::setFrame(const std::string &stream, stBlinkenFrame *pFrame)
79
+{
80
+  procFrame(pFrame);
81
+  (void)stream; // unused
82
+}
83
+
84
+/**
85
+ * @brief (re-)get settings that changed
86
+ * @param[in] force if true: (re-)get all settings w/o checking for change
87
+ */
88
+void Filter::getSettingsIfChanged(bool force)
89
+{
90
+  bool change = false;
91
+
92
+  // re-read modified files
93
+  if (force || m_fileFormat.checkModified()) {
94
+    m_fileFormat.update();
95
+    change = true;
96
+  }
97
+  if (force || m_fileSize.checkModified()) {
98
+    m_fileSize.update();
99
+    change = true;
100
+  }
101
+  if (force || m_fileWidthMin.checkModified()) {
102
+    m_fileWidthMin.update();
103
+    change = true;
104
+  }
105
+  if (force || m_fileWidthMax.checkModified()) {
106
+    m_fileWidthMax.update();
107
+    change = true;
108
+  }
109
+  if (force || m_fileHeightMin.checkModified()) {
110
+    m_fileHeightMin.update();
111
+    change = true;
112
+  }
113
+  if (force || m_fileHeightMax.checkModified()) {
114
+    m_fileHeightMax.update();
115
+    change = true;
116
+  }
117
+  if (force || m_fileChannelsMin.checkModified()) {
118
+    m_fileChannelsMin.update();
119
+    change = true;
120
+  }
121
+  if (force || m_fileChannelsMax.checkModified()) {
122
+    m_fileChannelsMax.update();
123
+    change = true;
124
+  }
125
+  if (force || m_fileColorsMin.checkModified()) {
126
+    m_fileColorsMin.update();
127
+    change = true;
128
+  }
129
+  if (force || m_fileColorsMax.checkModified()) {
130
+    m_fileColorsMax.update();
131
+    change = true;
132
+  }
133
+
134
+  // send current frame to output stream if anything changed
135
+  if (change)
136
+    sendFrame();
137
+}
138
+
139
+/// send current frame to output stream
140
+void Filter::sendFrame()
141
+{
142
+  // get current frame from input stream and process it
143
+  procFrame(m_fileInStream.getCurFrame());
144
+}
145
+
146
+/**
147
+ * @brief process frame
148
+ * @param[in] pFrame frame to process (NULL for none)
149
+ */
150
+void Filter::procFrame(stBlinkenFrame *pFrame)
151
+{
152
+  unsigned int width, height, channels, maxval, colors;
153
+
154
+  // leave the following do/while loop with break to pass "no frame"
155
+  do {
156
+
157
+    // no input frame -> pass "no frame"
158
+    if (!pFrame)
159
+      break;
160
+
161
+    // get frame format
162
+    width = BlinkenFrameGetWidth(pFrame);
163
+    height = BlinkenFrameGetHeight(pFrame);
164
+    channels = BlinkenFrameGetChannels(pFrame);
165
+    maxval = BlinkenFrameGetMaxval(pFrame);
166
+    colors = maxval + 1;
167
+
168
+    // if frame does not satisfy any filter -> pass "no frame" (via break)
169
+
170
+    // format setting present -> check that format matches
171
+    if (m_fileFormat.m_valid &&
172
+        (width != m_fileFormat.m_obj.m_width ||
173
+         height != m_fileFormat.m_obj.m_height ||
174
+         channels != m_fileFormat.m_obj.m_channels ||
175
+         maxval != m_fileFormat.m_obj.m_maxval))
176
+      break;
177
+
178
+    // size setting present -> check that size matches
179
+    if (m_fileSize.m_valid &&
180
+        (width != m_fileSize.m_obj.m_width ||
181
+         height != m_fileSize.m_obj.m_height))
182
+      break;
183
+
184
+    // if present, check min/max settings for width/height/channels/colors
185
+    if ((m_fileWidthMin.m_valid && width < m_fileWidthMin.m_obj.m_uint) ||
186
+        (m_fileWidthMax.m_valid && width > m_fileWidthMax.m_obj.m_uint) ||
187
+        (m_fileHeightMin.m_valid && height < m_fileHeightMin.m_obj.m_uint) ||
188
+        (m_fileHeightMax.m_valid && height > m_fileHeightMax.m_obj.m_uint) ||
189
+        (m_fileChannelsMin.m_valid &&
190
+         channels < m_fileChannelsMin.m_obj.m_uint) ||
191
+        (m_fileChannelsMax.m_valid &&
192
+         channels > m_fileChannelsMax.m_obj.m_uint) ||
193
+        (m_fileColorsMin.m_valid && colors < m_fileColorsMin.m_obj.m_uint) ||
194
+        (m_fileColorsMax.m_valid && colors > m_fileColorsMax.m_obj.m_uint))
195
+      break;
196
+
197
+    // frame satisfied all filters
198
+
199
+    // pass frame to output stream
200
+    m_fileOutStream.setFrame(pFrame);
201
+
202
+    return;
203
+  } while (0);
204
+
205
+  // do/while loop has been left with break -> pass "no frame"
206
+  m_fileOutStream.setFrame(NULL);
207
+}
208
+
209
+} // namespace Blinker
210
+
... ...
@@ -0,0 +1,96 @@
1
+/* Blinker
2
+   Copyright 2011-2014 Stefan Schuermans <stefan@blinkenarea.org>
3
+   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4
+   a blinkenarea.org project */
5
+
6
+#ifndef BLINKER_FILTER_H
7
+#define BLINKER_FILTER_H
8
+
9
+#include <string>
10
+
11
+#include <BlinkenLib/BlinkenFrame.h>
12
+
13
+#include "Directory.h"
14
+#include "File.h"
15
+#include "Format.h"
16
+#include "FormatFile.h"
17
+#include "InStreamFile.h"
18
+#include "Mgrs.h"
19
+#include "Module.h"
20
+#include "OutStreamFile.h"
21
+#include "Size.h"
22
+#include "SizeFile.h"
23
+#include "StreamRecv.h"
24
+#include "UInt.h"
25
+#include "UIntFile.h"
26
+
27
+namespace Blinker {
28
+
29
+/// a stream resizer
30
+class Filter: public Module, public StreamRecv
31
+{
32
+public:
33
+  /**
34
+   * @brief constructor
35
+   * @param[in] name module name
36
+   * @param[in] mgrs managers
37
+   * @param[in] dirBase base directory
38
+   */
39
+  Filter(const std::string &name, Mgrs &mgrs, const Directory &dirBase);
40
+
41
+  /// virtual destructor
42
+  virtual ~Filter();
43
+
44
+private:
45
+  /// copy constructor disabled
46
+  Filter(const Filter &that);
47
+
48
+  /// assignment operator disabled
49
+  const Filter & operator=(const Filter &that);
50
+
51
+public:
52
+  /// check for update of configuration
53
+  virtual void updateConfig();
54
+
55
+  /**
56
+   * @brief set current frame
57
+   * @param[in] stream stream name
58
+   * @param[in] pFrame current frame (NULL for none)
59
+   */
60
+  virtual void setFrame(const std::string &stream, stBlinkenFrame *pFrame);
61
+
62
+protected:
63
+  /**
64
+   * @brief (re-)get settings that changed
65
+   * @param[in] force if true: (re-)get all settings w/o checking for change
66
+   */
67
+  void getSettingsIfChanged(bool force);
68
+
69
+  /// send current frame to output stream
70
+  void sendFrame();
71
+
72
+  /**
73
+   * @brief process frame
74
+   * @param[in] pFrame frame to process (NULL for none)
75
+   */
76
+  void procFrame(stBlinkenFrame *pFrame);
77
+
78
+protected:
79
+  InStreamFile  m_fileInStream;    ///< input stream name file
80
+  FormatFile    m_fileFormat;      ///< format file
81
+  SizeFile      m_fileSize;        ///< size file
82
+  UIntFile      m_fileWidthMin;    ///< minimum width file
83
+  UIntFile      m_fileWidthMax;    ///< maximum width file
84
+  UIntFile      m_fileHeightMin;   ///< minimum height file
85
+  UIntFile      m_fileHeightMax;   ///< maximum height file
86
+  UIntFile      m_fileChannelsMin; ///< minimum channels file
87
+  UIntFile      m_fileChannelsMax; ///< maximum channels file
88
+  UIntFile      m_fileColorsMin;   ///< minimum colors per channel file
89
+  UIntFile      m_fileColorsMax;   ///< maximum colors per channel file
90
+  OutStreamFile m_fileOutStream;   ///< output stream name file
91
+}; // class Filter
92
+
93
+} // namespace Blinker
94
+
95
+#endif // #ifndef BLINKER_FILTER_H
96
+
... ...
@@ -8,6 +8,7 @@
8 8
 
9 9
 #include "Canvas.h"
10 10
 #include "Directory.h"
11
+#include "Filter.h"
11 12
 #include "FlexiPix.h"
12 13
 #include "Loveletter.h"
13 14
 #include "Mgrs.h"
... ...
@@ -45,6 +46,7 @@ void run(const std::string &dirConfig)
45 46
   ModuleMgr<TYPE> CLASS(#CLASS, mgrs, cfg.getSubdir(#CLASS))
46 47
 
47 48
   MODULEMGR(Canvas,           canvases);
49
+  MODULEMGR(Filter,           filters);
48 50
   MODULEMGR(FlexiPix,         flexipixes);
49 51
   MODULEMGR(Loveletter,       loveletters);
50 52
   MODULEMGR(OpPrinter,        opprinters);
51 53