The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
image_modifications.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2009 - 2025
3 by Iris Morelle <shadowm2006@gmail.com>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#pragma once
17
18#include "color_range.hpp"
20#include "sdl/point.hpp"
21#include "sdl/rect.hpp"
22#include "sdl/surface.hpp"
23#include "sdl/utils.hpp"
24
25#include <functional>
26#include <map>
27#include <memory>
28
29namespace image {
30
31class modification;
32
33/**
34 * A modified priority queue used to order image modifications.
35 * The priorities for this queue are to order modifications by priority(),
36 * then by the order they are added to the queue.
37 *
38 * Invariant for this class:
39 *
40 * At the beginning and end of each member function call,
41 * there are no empty vectors in priorities_.
42 */
44{
45public:
46 bool empty() const { return priorities_.empty(); }
47
48 /** Adds @a mod to the queue. */
49 void push(std::unique_ptr<modification>&& mod);
50
51 /** Removes the top element from the queue. */
52 void pop();
53
54 /** Returns the number of elements in the queue. */
55 std::size_t size() const;
56
57 /** Returns a const reference to the top element in the queue. */
58 const modification& top() const;
59
60private:
61 /** Map from a mod's priority() to the mods having that priority. */
62 std::map<int, std::vector<std::unique_ptr<modification>>, std::greater<int>> priorities_;
63};
64
65/** Base abstract class for an image-path modification */
67{
68public:
69
70 /** Exception thrown by the operator() when an error occurs. */
71 struct imod_exception final
73 {
74 /**
75 * Constructor.
76 *
77 * @pre message_stream.str()[message_stream.str().size() - 1] == '\n'
78 *
79 * @param message_stream Stream with the error message regarding
80 * the failed operation.
81 */
82 imod_exception(const std::stringstream& message_stream);
83
84 /**
85 * Constructor.
86 *
87 * @pre message[message.size() - 1] == '\n'
88 *
89 * @param message String with the error message regarding
90 * the failed operation.
91 */
92 imod_exception(const std::string& message);
93
94 ~imod_exception() noexcept {}
95
96 /** The error message regarding the failed operation. */
97 const std::string message;
98
99 private:
100
102 };
103
104 /** Decodes modifications from a modification string */
105 static modification_queue decode(const std::string&);
106
107 virtual ~modification() {}
108
109 /** Applies the image-path modification on the specified surface */
110 virtual void operator()(surface& src) const = 0;
111
112 /** Specifies the priority of the modification */
113 virtual int priority() const { return 0; }
114};
115
116/**
117 * Recolor (RC/TC/PAL) modification.
118 * It is used not only for color-range-based recoloring ("~RC(magenta>teal)")
119 * but also for team-color-based color range selection and recoloring
120 * ("~TC(3,magenta)") and palette switches ("~PAL(000000,005000 > FFFFFF,FF00FF)").
121 */
123{
124public:
125 /**
126 * Default constructor.
127 */
129 : rc_map_()
130 {}
131 /**
132 * RC-map based constructor.
133 * @param recolor_map The palette switch map.
134 */
138 virtual void operator()(surface& src) const override;
139
140 // The rc modification has a higher priority
141 virtual int priority() const override { return 1; }
142
143 bool no_op() const { return rc_map_.empty(); }
144
145 const color_mapping& map() const { return rc_map_;}
147
148private:
150};
151
152/**
153 * Mirror (FL) modification.
154 */
156{
157public:
158 /**
159 * Constructor.
160 * @param horiz Horizontal mirror flag.
161 * @param vert Vertical mirror flag.
162 */
163 fl_modification(bool horiz = false, bool vert = false)
164 : horiz_(horiz)
165 , vert_(vert)
166 {}
167 virtual void operator()(surface& src) const override;
168
169 void set_horiz(bool val) { horiz_ = val; }
170 void set_vert(bool val) { vert_ = val; }
171 bool get_horiz() const { return horiz_; }
172 bool get_vert() const { return vert_; }
173 /** Toggle horizontal mirror flag.
174 * @return The new flag state after toggling. */
175 bool toggle_horiz() { return((horiz_ = !horiz_)); }
176 /** Toggle vertical mirror flag.
177 * @return The new flag state after toggling. */
178 bool toggle_vert() { return((vert_ = !vert_)); }
179
180 bool no_op() const { return ((!horiz_) && (!vert_)); }
181
182private:
183 bool horiz_;
184 bool vert_;
185};
186
187/**
188 * Rotate (ROTATE) modification.
189 */
191{
192public:
193 /**
194 * Constructor.
195 *
196 * @pre zoom >= offset Otherwise the result will have empty pixels.
197 * @pre offset > 0 Otherwise the procedure will not return.
198 *
199 * @param degrees Amount of rotation (in degrees).
200 * Positive values are clockwise; negative are counter-clockwise.
201 * @param zoom The zoom level to calculate the rotation from.
202 * Greater values result in better results and increased runtime.
203 * This parameter will be ignored if @a degrees is a multiple of 90.
204 * @param offset Determines the step size of the scanning of the zoomed source.
205 * Different offsets can produce better results, try them out.
206 * Greater values result in decreased runtime.
207 * This parameter will be ignored if @a degrees is a multiple of 90.
208 * If @a offset is greater than @a zoom the result will have empty pixels.
209 */
210 rotate_modification(int degrees = 90, int zoom = 16, int offset = 8)
211 : degrees_(degrees), zoom_(zoom), offset_(offset)
212 {}
213 virtual void operator()(surface& src) const override;
214
215 bool no_op() const { return degrees_ % 360 == 0; }
216
217private:
219 int zoom_;
221};
222
223/**
224 * Grayscale (GS) modification.
225 */
227{
228public:
229 virtual void operator()(surface& src) const override;
230};
231
232/**
233 * Crop transparent padding (CROP_TRANSPARENCY) modification.
234 */
236{
237public:
238 virtual void operator()(surface& src) const override;
239};
240
241/**
242 * Black and white (BW) modification.
243 */
245{
246public:
247 bw_modification(int threshold): threshold_(threshold) {}
248 virtual void operator()(surface& src) const override;
249private:
251};
252
253/**
254 * Give to the image a sepia tint (SEPIA)
255 */
257{
258 virtual void operator()(surface& src) const override;
259};
260
261/**
262 * Make an image negative (NEG)
263 */
265{
266public:
267 negative_modification(int r, int g, int b): red_(r), green_(g), blue_(b) {}
268 virtual void operator()(surface& src) const override;
269private:
271};
272
273/**
274 * Plot Alpha (Alpha) modification
275 */
277{
278public:
279 virtual void operator()(surface& src) const override;
280};
281
282/**
283 * Wipe Alpha (Wipe_Alpha) modification
284 */
286{
287public:
288 virtual void operator()(surface& src) const override;
289};
290
291/**
292 * Adjust Alpha (ADJUST_ALPHA) modification
293 */
295{
296public:
297 adjust_alpha_modification(const std::string& formula)
298 : formula_(formula)
299 {}
300
301 virtual void operator()(surface& src) const override;
302
303private:
304 std::string formula_;
305};
306
307/**
308 * Adjust Channels (CHAN) modification
309 */
311{
312public:
313 adjust_channels_modification(const std::vector<std::string>& formulas)
314 : formulas_(formulas)
315 {
316 if(formulas_.empty()) {
317 formulas_.push_back("red");
318 }
319 if(formulas_.size() == 1) {
320 formulas_.push_back("green");
321 }
322 if(formulas_.size() == 2) {
323 formulas_.push_back("blue");
324 }
325 if(formulas_.size() == 3) {
326 formulas_.push_back("alpha");
327 }
328 }
329
330 virtual void operator()(surface& src) const override;
331
332private:
333 std::vector<std::string> formulas_;
334};
335
336/**
337 * Crop (CROP) modification.
338 */
340{
341public:
343 : slice_(slice)
344 {}
345 virtual void operator()(surface& src) const override;
346
347 const rect& get_slice() const
348 {
349 return slice_;
350 }
351
352private:
354};
355
356/**
357 * Scale (BLIT) modification.
358 */
359
361{
362public:
363 blit_modification(const surface& surf, int x, int y)
364 : surf_(surf), x_(x), y_(y)
365 {}
366 virtual void operator()(surface& src) const override;
367
368 const surface& get_surface() const
369 {
370 return surf_;
371 }
372
373 int get_x() const
374 {
375 return x_;
376 }
377
378 int get_y() const
379 {
380 return y_;
381 }
382
383private:
385 int x_;
386 int y_;
387};
388
389/**
390 * Mask (MASK) modification.
391 */
392
394{
395public:
396 mask_modification(const surface& mask, int x, int y)
397 : mask_(mask), x_(x), y_(y)
398 {}
399 virtual void operator()(surface& src) const override;
400
401 const surface& get_mask() const
402 {
403 return mask_;
404 }
405
406 int get_x() const
407 {
408 return x_;
409 }
410
411 int get_y() const
412 {
413 return y_;
414 }
415
416private:
418 int x_;
419 int y_;
420};
421
422/**
423 * LIGHT (L) modification.
424 */
425
427{
428public:
430 : surf_(surf)
431 {}
432 virtual void operator()(surface& src) const override;
433
434 const surface& get_surface() const
435 {
436 return surf_;
437 }
438
439private:
441};
442
443/**
444 * Scaling (SCALE[_INTO], SCALE[_INTO]_SHARP) modifications.
445 */
447{
448public:
449 // Bit-unique scaling flags
450 enum SCALE_FLAGS : uint8_t {
451 SCALE_LINEAR = 0b00000,
452 SCALE_SHARP = 0b00001,
453 FIT_TO_SIZE = 0b00010,
455 X_BY_FACTOR = 0b01000,
456 Y_BY_FACTOR = 0b10000,
457 };
458
459 scale_modification(point target_size, uint8_t flags)
460 : target_size_(target_size)
461 , flags_(flags)
462 {}
463
464 virtual void operator()(surface& src) const override;
465
466 int get_w() const { return target_size_.x; }
467 int get_h() const { return target_size_.y; }
468
469private:
471
473};
474
475/**
476 * xBRZ scale (xBRZ) modification
477 */
479{
480public:
482 : z_(z)
483 {}
484
485 virtual void operator()(surface& src) const override;
486
487private:
488 int z_;
489};
490
491/**
492 * PAD modification.
493 * Expands the image by adding transparent pixels to its top, right, bottom, and left sides.
494 */
496{
497public:
498 pad_modification(int top, int right, int bottom, int left)
499 : top_{top}
500 , right_{right}
501 , bottom_{bottom}
502 , left_{left}
503 {
504 }
505
506 virtual void operator()(surface& src) const override;
507
508private:
509 int top_;
512 int left_;
513};
514
515/**
516 * Opacity (O) modification
517 */
519{
520public:
521 o_modification(float opacity)
522 : opacity_(opacity)
523 {}
524 virtual void operator()(surface& src) const override;
525
526 float get_opacity() const
527 {
528 return opacity_;
529 }
530
531private:
532 float opacity_;
533};
534
535/**
536 * Color-shift (CS, R, G, B) modification.
537 */
539{
540public:
541 cs_modification(int r, int g, int b)
542 : r_(r), g_(g), b_(b)
543 {}
544 virtual void operator()(surface& src) const override;
545
546 int get_r() const { return r_; }
547 int get_g() const { return g_; }
548 int get_b() const { return b_; }
549
550private:
551 int r_, g_, b_;
552};
553
554/**
555 * Color blending (BLEND) modification
556 */
558{
559public:
560 blend_modification(int r, int g, int b, float a)
561 : r_(r), g_(g), b_(b), a_(a)
562 {}
563 virtual void operator()(surface& src) const override;
564
565 int get_r() const { return r_; }
566 int get_g() const { return g_; }
567 int get_b() const { return b_; }
568 float get_a() const { return a_; }
569
570private:
571 int r_, g_, b_;
572 float a_;
573};
574
575/**
576 * Gaussian-like blur (BL) modification.
577 */
579{
580public:
582 : depth_(depth)
583 {}
584 virtual void operator()(surface& src) const override;
585
586 int get_depth() const
587 {
588 return depth_;
589 }
590
591private:
593};
594
595/**
596 * Fill background with a color (BG).
597 */
599{
601 virtual void operator()(surface& src) const override;
602
603 const color_t& get_color() const
604 {
605 return color_;
606 }
607
608private:
610};
611
612/**
613 * Channel swap (SWAP).
614 */
616{
617public:
619 virtual void operator()(surface& src) const override;
620private:
625};
626
627} /* end namespace image */
Adjust Alpha (ADJUST_ALPHA) modification.
adjust_alpha_modification(const std::string &formula)
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Adjust Channels (CHAN) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
adjust_channels_modification(const std::vector< std::string > &formulas)
Gaussian-like blur (BL) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Color blending (BLEND) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
blend_modification(int r, int g, int b, float a)
Scale (BLIT) modification.
blit_modification(const surface &surf, int x, int y)
const surface & get_surface() const
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Black and white (BW) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Crop (CROP) modification.
crop_modification(const rect &slice)
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Crop transparent padding (CROP_TRANSPARENCY) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Color-shift (CS, R, G, B) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
cs_modification(int r, int g, int b)
Mirror (FL) modification.
bool toggle_horiz()
Toggle horizontal mirror flag.
bool toggle_vert()
Toggle vertical mirror flag.
fl_modification(bool horiz=false, bool vert=false)
Constructor.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Grayscale (GS) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
light_modification(const surface &surf)
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
const surface & get_surface() const
Mask (MASK) modification.
mask_modification(const surface &mask, int x, int y)
const surface & get_mask() const
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
A modified priority queue used to order image modifications.
void push(std::unique_ptr< modification > &&mod)
Adds mod to the queue.
const modification & top() const
Returns a const reference to the top element in the queue.
std::map< int, std::vector< std::unique_ptr< modification > >, std::greater< int > > priorities_
Map from a mod's priority() to the mods having that priority.
void pop()
Removes the top element from the queue.
std::size_t size() const
Returns the number of elements in the queue.
Base abstract class for an image-path modification.
static modification_queue decode(const std::string &)
Decodes modifications from a modification string.
virtual int priority() const
Specifies the priority of the modification.
virtual void operator()(surface &src) const =0
Applies the image-path modification on the specified surface.
Make an image negative (NEG)
negative_modification(int r, int g, int b)
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Opacity (O) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
pad_modification(int top, int right, int bottom, int left)
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Plot Alpha (Alpha) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Recolor (RC/TC/PAL) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
const color_mapping & map() const
rc_modification()
Default constructor.
rc_modification(color_mapping &&recolor_map)
RC-map based constructor.
virtual int priority() const override
Specifies the priority of the modification.
Rotate (ROTATE) modification.
rotate_modification(int degrees=90, int zoom=16, int offset=8)
Constructor.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Scaling (SCALE[_INTO], SCALE[_INTO]_SHARP) modifications.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
scale_modification(point target_size, uint8_t flags)
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
swap_modification(channel r, channel g, channel b, channel a)
Wipe Alpha (Wipe_Alpha) modification.
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
xBRZ scale (xBRZ) modification
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Base class for exceptions that want to be thrown 'through' lua.
std::unordered_map< color_t, color_t > color_mapping
#define IMPLEMENT_LUA_JAILBREAK_EXCEPTION(type)
Helper macro for classes deriving from lua_jailbreak_exception.
Functions to load and save images from/to disk.
STL namespace.
Contains the SDL_Rect helper code.
surface surf
Image.
rect src
Non-transparent portion of the surface to compose.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition color.hpp:51
Fill background with a color (BG).
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Exception thrown by the operator() when an error occurs.
const std::string message
The error message regarding the failed operation.
Give to the image a sepia tint (SEPIA)
virtual void operator()(surface &src) const override
Applies the image-path modification on the specified surface.
Holds a 2D point.
Definition point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition rect.hpp:49
channel
Definition utils.hpp:103
#define g
#define c
#define b