The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
filter.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2012 - 2016 by Mark de Wever <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "wesmage/filter.hpp"
16 
18 #include "wesmage/exit.hpp"
19 
20 #include "utils/functional.hpp"
21 
22 #include <iostream>
23 
24 /** Contains the definition of a filter. */
25 struct tfilter
26 {
27  /**
28  * The functor to call for the filter.
29  *
30  * @p surf The surface to apply the filter to.
31  * @p parameters A string with the parameters for the
32  * functor. The code is expected to be
33  * supplied on the command line. So it should
34  * be validated.
35  */
36  typedef std::function<void(
37  surface& surf
38  , const std::string& parameters
39  )>
41 
43  const std::string& name__
44  , const std::string& description__
45  , const tfunctor& functor__)
46  : name(name__)
47  , description(description__)
48  , functor(functor__)
49  {
50  }
51 
52  /**
53  * The name of the filter.
54  *
55  * This value must be unique.
56  */
58 
59  /**
60  * Description of the filter.
61  *
62  * The exact format of the string is documented at @ref filter_list.
63  */
65 
66  /** The functor to call for the filter. */
68 };
69 
70 /**
71  * The list of the available filters.
72  *
73  * The map contains:
74  * * @p first The name of the filter.
75  * * @p second The filter itself.
76  */
77 static std::map<std::string, tfilter> filters;
78 
79 /** Helper structure to register a filter to the @ref filters. */
81 {
82  tregister_filter(const std::pair<std::string, tfilter>& filter)
83  {
84  filters.insert(filter);
85  }
86 };
87 
88 /**
89  * Register macro for a filter.
90  *
91  * @param name The name of the filter.
92  * @param description A pipe-symbol separated list with the
93  * description. The name is automatically
94  * prefixed, so the item should start with a
95  * pipe-symbol. When the list is splitted in
96  * to a vector of string its contents should
97  * be compatible with the constructor of
98  * @ref tfilter_description.
99  */
100 #define REGISTER(name, description) \
101  tregister_filter register_filter_##name(std::make_pair( \
102  #name \
103  , tfilter(#name, #name description, std::bind(name, _1, _2))));
104 
105 static void
107 {
108  unsigned width, height;
109  const int count = sscanf(parameters.c_str(), "%u,%u", &width, &height);
110 
111  if(count != 2) {
112  std::cerr << "Error: Arguments to scale »"
113  << parameters
114  << "« are not compatible.\n";
115  throw texit(EXIT_FAILURE);
116  }
117 
118  surf = scale_surface(surf, width, height);
119 }
121 "|Scales the size of an image."
122 "|new_width"
123  "|unsigned"
124  "|The width in pixel of the image after scaling."
125 "|new_height"
126  "|unsigned"
127  "|The height in pixel of the image after scaling.")
128 
129 static void
130 brighten(surface& surf, const std::string& parameters)
131 {
132  float amount;
133  const int count = sscanf(parameters.c_str(), "%f", &amount);
134 
135  if(count != 1) {
136  std::cerr << "Error: Arguments to brighten »"
137  << parameters
138  << "« are not compatible.\n";
139 
140  throw texit(EXIT_FAILURE);
141  }
142 
143  surf = brighten_image(surf, amount);
144 }
145 REGISTER(brighten,
146 "|Brightens an image."
147 "|amount"
148  "|float"
149  "|The amount the image should be brightened. The value of the every "
150  "color channel is multiplied by this value. Value less than zero "
151  "are set to zero. The alpha channel is not modified.")
152 
153 static void
154 blend(surface& surf, const std::string& parameters)
155 {
156  float amount;
157  unsigned color;
158  const int count = sscanf(parameters.c_str(), "%f,%x", &amount, &color);
159 
160  if(count != 2) {
161  std::cerr << "Error: Arguments to blend »"
162  << parameters
163  << "« are not compatible.\n";
164 
165  throw texit(EXIT_FAILURE);
166  }
167 
168  surf = blend_surface(surf, amount, color);
169 }
170 REGISTER(blend,
171 "|Blends an image with another color."
172 "|amount"
173  "|float"
174  "|The amount every pixel needs to be blended with its original value. "
175  "The formula is:\n"
176  "result = amount * color + (1 - amount) * original\n"
177  "The value needs to be in the range [0, 1]."
178 "|color"
179  "|unsigned"
180  "|The color to blend with. The value should be given as 32-bit "
181  "hexadecimal value. The first fields should look like AARRGGBB, "
182  "where AA is the alpha channel, RR is the red channel, GG is the "
183  "green channel and BB is the blue channel. (Note the alpha channel "
184  "is ignored.")
185 
186 void
187 filter_apply(surface& surf, const std::string& filter)
188 {
189  std::vector<std::string> f = utils::split(filter, ':', utils::STRIP_SPACES);
190 
191  if(f.size() != 2) {
192  std::cerr << "Error: Filter »"
193  << filter
194  << "« doesn't contain the expected separator »:«\n";
195 
196  throw texit(EXIT_FAILURE);
197  }
198 
200 
201  if(itor == filters.end()) {
202  std::cerr << "Error: Filter »" << f[0] << "« is unknown.\n";
203  throw texit(EXIT_FAILURE);
204  }
205 
206  itor->second.functor(surf, f[1]);
207 }
208 
210  : name()
211  , description()
212  , parameters()
213 {
214  std::vector<std::string> elements(utils::split(fmt, '|'));
215 
216  /* Validate there is at least a header part. */
217  assert(elements.size() >= 2);
218 
219  name = elements[0];
220  description = elements[1];
221 
222  /* Validate every parameter indeed has three fields. */
223  assert((elements.size() - 2) % 3 == 0);
224 
225  for(size_t i = 2; i < elements.size(); i += 3) {
226 
228  {
229  elements[i]
230  , elements[i + 1]
231  , elements[i + 2]
232  };
233 
234  parameters.push_back(parameter);
235  }
236 }
237 
238 std::vector<tfilter_description>
240 {
241  std::vector<tfilter_description> result;
242  typedef std::pair<std::string, tfilter> thack;
243  for(const thack& filter : filters) {
244  result.push_back(filter.second.description);
245  }
246  return result;
247 }
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1806
GLenum GLenum GLenum GLenum GLenum scale
Definition: glew.h:10669
#define REGISTER(name, description)
Register macro for a filter.
Definition: filter.cpp:100
static std::map< std::string, tfilter > filters
The list of the available filters.
Definition: filter.cpp:77
static void scale(surface &surf, const std::string &parameters)
Definition: filter.cpp:106
tfilter_description(const std::string &fmt)
Constructor.
Definition: filter.cpp:209
std::string name
The name of the filter.
Definition: filter.cpp:57
tfilter(const std::string &name__, const std::string &description__, const tfunctor &functor__)
Definition: filter.cpp:42
STL namespace.
surface scale_surface(const surface &surf, int w, int h)
Definition: utils.cpp:443
STRIP_SPACES : strips leading and trailing blank spaces.
GLuint64EXT * result
Definition: glew.h:10727
Helper structure to describe what a filter does.
Definition: filter.hpp:36
tfilter_description description
Description of the filter.
Definition: filter.cpp:64
surface blend_surface(const surface &surf, const double amount, const Uint32 color, const bool optimize)
Blends a surface with a color.
Definition: utils.cpp:1840
tfunctor functor
The functor to call for the filter.
Definition: filter.cpp:67
unsigned color
Definition: filter.cpp:157
Describes a filter parameter.
Definition: filter.hpp:72
surf
Definition: filter.cpp:143
GLuint GLuint GLsizei count
Definition: glew.h:1221
const std::string &parameters float amount
Definition: filter.cpp:132
This exception when throw should terminate the application.
Definition: sdl2.cpp:35
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
const std::string & parameters
Definition: filter.cpp:155
size_t i
Definition: function.cpp:1057
surface brighten_image(const surface &surf, fixed_t amount, bool optimize)
Definition: utils.cpp:1160
Exit exception.
Contains the definition of a filter.
Definition: filter.cpp:25
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
Definition: glew.h:1220
GLuint const GLchar * name
Definition: glew.h:1782
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:3448
std::vector< tfilter_description > filter_list()
Returns the list of available filters.
Definition: filter.cpp:239
Filters for wesmage.
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1220
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
std::function< void(surface &surf, const std::string &parameters)> tfunctor
The functor to call for the filter.
Definition: filter.cpp:40
std::string::const_iterator iterator
Definition: tokenizer.hpp:21
void filter_apply(surface &surf, const std::string &filter)
GLsizei const GLcharARB ** string
Definition: glew.h:4503
std::string description
Description of the filter.
Definition: filter.hpp:69
Helper structure to register a filter to the filters.
Definition: filter.cpp:80
GLclampf f
Definition: glew.h:3024
tregister_filter(const std::pair< std::string, tfilter > &filter)
Definition: filter.cpp:82