-
-
Notifications
You must be signed in to change notification settings - Fork 990
/
image_modifications.hpp
550 lines (468 loc) · 12.1 KB
/
image_modifications.hpp
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
/*
Copyright (C) 2009 - 2016 by Ignacio R. Morelle <shadowm2006@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
/** @file */
#ifndef IMAGE_MODIFICATIONS_HPP_INCLUDED
#define IMAGE_MODIFICATIONS_HPP_INCLUDED
#include "color_range.hpp"
#include "lua_jailbreak_exception.hpp"
#include "sdl/surface.hpp"
#include "sdl/utils.hpp"
#include <queue>
namespace image {
class modification;
/// A modified priority queue used to order image modifications.
/// The priorities for this queue are to order modifications by priority(),
/// then by the order they are added to the queue.
class modification_queue {
// Invariant for this class:
// At the beginning and end of each member function call, there
// are no empty vectors in priorities_.
public:
modification_queue()
: priorities_()
{
}
~modification_queue() {}
bool empty() const { return priorities_.empty(); }
void push(modification * mod);
void pop();
size_t size() const;
modification * top() const;
private: // data
/// Map from a mod's priority() to the mods having that priority.
typedef std::map<int, std::vector<modification *>, std::greater<int> > map_type;
/// Map from a mod's priority() to the mods having that priority.
map_type priorities_;
};
/// Base abstract class for an image-path modification
class modification
{
public:
/** Exception thrown by the operator() when an error occurs. */
struct imod_exception
: public lua_jailbreak_exception
{
/**
* Constructor.
*
* @pre message_stream.str()[message_stream.str().size() - 1] == '\n'
*
* @param message_stream Stream with the error message regarding
* the failed operation.
*/
imod_exception(const std::stringstream& message_stream);
/**
* Constructor.
*
* @pre message[message.size() - 1] == '\n'
*
* @param message String with the error message regarding
* the failed operation.
*/
imod_exception(const std::string& message);
~imod_exception() throw() {}
/** The error message regarding the failed operation. */
const std::string message;
private:
IMPLEMENT_LUA_JAILBREAK_EXCEPTION(imod_exception)
};
/// Decodes modifications from a modification string
static modification_queue decode(const std::string&);
virtual ~modification() {}
///Applies the image-path modification on the specified surface
virtual surface operator()(const surface& src) const = 0;
/// Specifies the priority of the modification
virtual int priority() const { return 0; }
};
/**
* Recolor (RC/TC/PAL) modification.
* It is used not only for color-range-based recoloring ("~RC(magenta>teal)")
* but also for team-color-based color range selection and recoloring
* ("~TC(3,magenta)") and palette switches ("~PAL(000000,005000 > FFFFFF,FF00FF)").
*/
class rc_modification : public modification
{
public:
/**
* Default constructor.
*/
rc_modification()
: rc_map_()
{}
/**
* RC-map based constructor.
* @param recolor_map The palette switch map.
*/
rc_modification(const color_range_map& recolor_map)
: rc_map_(recolor_map)
{}
virtual surface operator()(const surface& src) const;
// The rc modification has a higher priority
virtual int priority() const { return 1; }
bool no_op() const { return rc_map_.empty(); }
const color_range_map& map() const { return rc_map_;}
color_range_map& map() { return rc_map_;}
private:
color_range_map rc_map_;
};
/**
* Mirror (FL) modification.
*/
class fl_modification : public modification
{
public:
/**
* Constructor.
* @param horiz Horizontal mirror flag.
* @param vert Vertical mirror flag.
*/
fl_modification(bool horiz = false, bool vert = false)
: horiz_(horiz)
, vert_(vert)
{}
virtual surface operator()(const surface& src) const;
void set_horiz(bool val) { horiz_ = val; }
void set_vert(bool val) { vert_ = val; }
bool get_horiz() const { return horiz_; }
bool get_vert() const { return vert_; }
/** Toggle horizontal mirror flag.
* @return The new flag state after toggling. */
bool toggle_horiz() { return((horiz_ = !horiz_)); }
/** Toggle vertical mirror flag.
* @return The new flag state after toggling. */
bool toggle_vert() { return((vert_ = !vert_)); }
bool no_op() const { return ((!horiz_) && (!vert_)); }
private:
bool horiz_;
bool vert_;
};
/**
* Rotate (ROTATE) modification.
*/
class rotate_modification : public modification
{
public:
/**
* Constructor.
*
* @pre zoom >= offset Otherwise the result will have empty pixels.
* @pre offset > 0 Otherwise the procedure will not return.
*
* @param degrees Amount of rotation (in degrees).
* Positive values are clockwise; negative are counter-clockwise.
* @param zoom The zoom level to calculate the rotation from.
* Greater values result in better results and increased runtime.
* This parameter will be ignored if @a degrees is a multiple of 90.
* @param offset Determines the step size of the scanning of the zoomed source.
* Different offsets can produce better results, try them out.
* Greater values result in decreased runtime.
* This parameter will be ignored if @a degrees is a multiple of 90.
* If @a offset is greater than @a zoom the result will have empty pixels.
*/
rotate_modification(int degrees = 90, int zoom = 16, int offset = 8)
: degrees_(degrees), zoom_(zoom), offset_(offset)
{}
virtual surface operator()(const surface& src) const;
bool no_op() const { return degrees_ % 360 == 0; }
private:
int degrees_;
int zoom_;
int offset_;
};
/**
* Grayscale (GS) modification.
*/
class gs_modification : public modification
{
public:
virtual surface operator()(const surface& src) const;
};
/**
* Black and white (BW) modification.
*/
class bw_modification : public modification
{
public:
bw_modification(int threshold): threshold_(threshold) {}
virtual surface operator()(const surface& src) const;
private:
int threshold_;
};
/**
* Give to the image a sepia tint (SEPIA)
*/
struct sepia_modification : modification
{
virtual surface operator()(const surface &src) const;
};
/**
* Make an image negative (NEG)
*/
class negative_modification : public modification
{
public:
negative_modification(int r, int g, int b): red_(r), green_(g), blue_(b) {}
virtual surface operator()(const surface &src) const;
private:
int red_, green_, blue_;
};
/**
* Plot Alpha (Alpha) modification
*/
class plot_alpha_modification : public modification
{
public:
virtual surface operator()(const surface& src) const;
};
/**
* Wipe Alpha (Wipe_Alpha) modification
*/
class wipe_alpha_modification : public modification
{
public:
virtual surface operator()(const surface& src) const;
};
/**
* Adjust Alpha (ADJUST_ALPHA) modification
*/
class adjust_alpha_modification : public modification
{
public:
adjust_alpha_modification(const std::string& formula)
: formula_(formula)
{}
virtual surface operator()(const surface& src) const;
private:
std::string formula_;
};
/**
* Crop (CROP) modification.
*/
class crop_modification : public modification
{
public:
crop_modification(const SDL_Rect& slice)
: slice_(slice)
{}
virtual surface operator()(const surface& src) const;
const SDL_Rect& get_slice() const;
private:
SDL_Rect slice_;
};
/**
* Scale (BLIT) modification.
*/
class blit_modification : public modification
{
public:
blit_modification(const surface& surf, int x, int y)
: surf_(surf), x_(x), y_(y)
{}
virtual surface operator()(const surface& src) const;
const surface& get_surface() const;
int get_x() const;
int get_y() const;
private:
surface surf_;
int x_;
int y_;
};
/**
* Mask (MASK) modification.
*/
class mask_modification : public modification
{
public:
mask_modification(const surface& mask, int x, int y)
: mask_(mask), x_(x), y_(y)
{}
virtual surface operator()(const surface& src) const;
const surface& get_mask() const;
int get_x() const;
int get_y() const;
private:
surface mask_;
int x_;
int y_;
};
/**
* LIGHT (L) modification.
*/
class light_modification : public modification
{
public:
light_modification(const surface& surf)
: surf_(surf)
{}
virtual surface operator()(const surface& src) const;
const surface& get_surface() const;
private:
surface surf_;
};
/**
* Scaling modifications base class.
*/
class scale_modification : public modification
{
public:
scale_modification(int width, int height, std::string fn, bool use_nn)
: w_(width), h_(height), nn_(use_nn), fn_(fn)
{}
virtual surface operator()(const surface& src) const;
virtual std::pair<int,int> calculate_size(const surface& src) const = 0;
int get_w() const;
int get_h() const;
private:
int w_, h_;
bool nn_;
protected:
const std::string fn_;
};
/**
* Scale exact modification. (SCALE, SCALE_SHARP)
*/
class scale_exact_modification : public scale_modification
{
public:
scale_exact_modification(int width, int height, std::string fn, bool use_nn)
: scale_modification(width, height, fn, use_nn)
{}
virtual std::pair<int,int> calculate_size(const surface& src) const;
};
/**
* Scale into (SCALE_INTO) modification. (SCALE_INTO, SCALE_INTO_SHARP)
* Preserves aspect ratio.
*/
class scale_into_modification : public scale_modification
{
public:
scale_into_modification(int width, int height, std::string fn, bool use_nn)
: scale_modification(width, height, fn, use_nn)
{}
virtual std::pair<int,int> calculate_size(const surface& src) const;
};
/**
* xBRZ scale (xBRZ) modification
*/
class xbrz_modification : public modification
{
public:
xbrz_modification(int z)
: z_(z)
{}
virtual surface operator()(const surface& src) const;
private:
int z_;
};
/**
* Opacity (O) modification
*/
class o_modification : public modification
{
public:
o_modification(float opacity)
: opacity_(opacity)
{}
virtual surface operator()(const surface& src) const;
float get_opacity() const;
private:
float opacity_;
};
/**
* Color-shift (CS, R, G, B) modification.
*/
class cs_modification : public modification
{
public:
cs_modification(int r, int g, int b)
: r_(r), g_(g), b_(b)
{}
virtual surface operator()(const surface& src) const;
int get_r() const;
int get_g() const;
int get_b() const;
private:
int r_, g_, b_;
};
/**
* Color blending (BLEND) modification
*/
class blend_modification : public modification
{
public:
blend_modification(int r, int g, int b, float a)
: r_(r), g_(g), b_(b), a_(a)
{}
virtual surface operator()(const surface& src) const;
int get_r() const;
int get_g() const;
int get_b() const;
float get_a() const;
private:
int r_, g_, b_;
float a_;
};
/**
* Gaussian-like blur (BL) modification.
*/
class bl_modification : public modification
{
public:
bl_modification(int depth)
: depth_(depth)
{}
virtual surface operator()(const surface& src) const;
int get_depth() const;
private:
int depth_;
};
/**
* Overlay with ToD brightening (BRIGHTEN).
*/
struct brighten_modification : modification
{
virtual surface operator()(const surface &src) const;
};
/**
* Overlay with ToD darkening (DARKEN).
*/
struct darken_modification : modification
{
virtual surface operator()(const surface &src) const;
};
/**
* Fill background with a color (BG).
*/
struct background_modification : modification
{
background_modification(color_t const &c): color_(c) {}
virtual surface operator()(const surface &src) const;
const color_t& get_color() const;
private:
color_t color_;
};
/**
* Channel swap (SWAP).
*/
class swap_modification : public modification
{
public:
swap_modification(channel r, channel g, channel b, channel a): red_(r), green_(g), blue_(b), alpha_(a) {}
virtual surface operator()(const surface& src) const;
private:
channel red_;
channel green_;
channel blue_;
channel alpha_;
};
} /* end namespace image */
#endif /* !defined(IMAGE_MODIFICATIONS_HPP_INCLUDED) */