Oxygine  1
2g game engine
ImageDataOperations.h
1 #pragma once
2 #include "oxygine-include.h"
3 #include "ImageData.h"
4 
5 namespace oxygine
6 {
7  namespace operations
8  {
9  //based on memcpy
10  void copy(const ImageData& src, const ImageData& dest);
11 
12  //based on memmove, could be used for overlapped images, slower than copy
13  void move(const ImageData& src, const ImageData& dest);
14 
15  void blit(const ImageData& src, const ImageData& dest);
16  void blitColored(const ImageData& src, const ImageData& dest, const Color& c);
17  void blitPremultiply(const ImageData& src, const ImageData& dest);
18  void premultiply(const ImageData& dest);
19  void flipY(const ImageData& src, const ImageData& dest);
20  void blend(const ImageData& src, const ImageData& dest);
21 
22  inline void blend_srcAlpha_invSrcAlpha(const Pixel& pS, Pixel& pD)
23  {
24  const unsigned int& s = pS.rgba;
25  unsigned int& d = pD.rgba;
26 
27  unsigned int dst_rb = d & 0xFF00FF;
28  unsigned int dst_ag = (d >> 8) & 0xFF00FF;
29 
30  unsigned int src_rb = s & 0xFF00FF;
31  unsigned int src_ag = (s >> 8) & 0xFF00FF;
32 
33  unsigned int d_rb = src_rb - dst_rb;
34  unsigned int d_ag = src_ag - dst_ag;
35 
36  d_rb *= pS.a;
37  d_ag *= pS.a;
38  d_rb >>= 8;
39  d_ag >>= 8;
40 
41  const unsigned int rb = (d_rb + dst_rb) & 0x00FF00FF;
42  const unsigned int ag = ((d_ag + dst_ag) << 8) & 0xFF00FF00;
43 
44  d = rb | ag;
45  }
46 
47 
48  template <class Op>
49  void applyOperation(const Op& op, const ImageData& src, const ImageData& dest);
50 
51 
52  class op_fill
53  {
54  public:
55  op_fill() {color.rgba = 0xffffffff;}
56 
57  Pixel color;
58 
59  template<class Src, class Dest>
60  void operator()(const Src& s, Dest& d, const unsigned char* srcData, unsigned char* destData) const
61  {
62  d.setPixel(destData, color);
63  }
64  };
65 
66  class op_noise
67  {
68  public:
69  op_noise(int v): _v(v) {}
70 
71  template<class Src, class Dest>
72  void operator()(const Src& srcPixelFormat, Dest& destPixelFormat, const unsigned char* srcData, unsigned char* destData) const
73  {
74  Pixel p;
75 
76  p.r = 255;
77  p.g = 255;
78  p.b = 255;
79 
80  int v = rand() % 1000;
81  //p.r = p.g = p.b = p.a = v > 600 ? 255:0;//for add
82  p.r = p.g = p.b = p.a = v > _v ? 255 : 0; //for alpha
83 
84 
85  destPixelFormat.setPixel(destData, p);
86  }
87 
88  int _v;
89  };
90 
92  {
93  public:
94  template<class Src, class Dest>
95  void operator()(const Src& srcPixelFormat, Dest& destPixelFormat, const unsigned char* srcData, unsigned char* destData) const
96  {
97  Pixel p;
98  srcPixelFormat.getPixel(srcData, p);
99 
100  //we need correct "snapped" to pixel format alpha
101  unsigned char na = destPixelFormat.snap_a(p.a);
102 
103  p.r = (p.r * na) / 255;
104  p.g = (p.g * na) / 255;
105  p.b = (p.b * na) / 255;
106 
107  destPixelFormat.setPixel(destData, p);
108  }
109  };
110 
111  class op_blit
112  {
113  public:
114  template<class Src, class Dest>
115  void operator()(const Src& srcPixelFormat, Dest& destPixelFormat, const unsigned char* srcData, unsigned char* destData) const
116  {
117  Pixel p;
118  srcPixelFormat.getPixel(srcData, p);
119  destPixelFormat.setPixel(destData, p);
120  }
121  };
122 
124  {
125  public:
126  op_blit_colored(const Pixel& clr): color(clr) {}
127 
128  template<class Src, class Dest>
129  void operator()(const Src& srcPixelFormat, Dest& destPixelFormat, const unsigned char* srcData, unsigned char* destData) const
130  {
131  Pixel src;
132  srcPixelFormat.getPixel(srcData, src);
133 
134  Pixel dest;
135  dest.r = (src.r * color.r) / 255;
136  dest.g = (src.g * color.g) / 255;
137  dest.b = (src.b * color.b) / 255;
138  dest.a = (src.a * color.a) / 255;
139 
140  destPixelFormat.setPixel(destData, dest);
141  }
142 
143  Pixel color;
144  };
145 
146 
147 
149  {
150  public:
151  template<class Src, class Dest>
152  void operator()(const Src& srcPixelFormat, Dest& destPixelFormat, const unsigned char* srcData, unsigned char* destData) const
153  {
154  Pixel s;
155  srcPixelFormat.getPixel(srcData, s);
156 
157  Pixel d;
158  destPixelFormat.getPixel(destData, d);
159 
160 #define M(v) std::min(v, 255);
161  unsigned char a = s.a;
162  unsigned char ia = 255 - a;
163  Pixel r;
164  r.r = M((d.r * ia) / 255 + (s.r * a) / 255);
165  r.g = M((d.g * ia) / 255 + (s.g * a) / 255);
166  r.b = M((d.b * ia) / 255 + (s.b * a) / 255);
167  r.a = M((d.a * ia) / 255 + (s.a * a) / 255);
168 #undef M
169 
170  destPixelFormat.setPixel(destData, r);
171  }
172  };
173 
174 
176  {
177  public:
178  template<class Src, class Dest>
179  void operator()(const Src& srcPixelFormat, Dest& destPixelFormat, const unsigned char* srcData, unsigned char* destData) const
180  {
181  Pixel pS;
182  srcPixelFormat.getPixel(srcData, pS);
183 
184  Pixel pD;
185  destPixelFormat.getPixel(destData, pD);
186 
187  blend_srcAlpha_invSrcAlpha(pS, pD);
188  destPixelFormat.setPixel(destData, pD);
189  }
190  };
191 
192 
193  bool check(const ImageData& src, const ImageData& dest);
194 
195 
196  template <class Op, class Src, class Dest>
197  void applyOperationT(const Op& op, const Src& srcPixelFormat, Dest& destPixelFormat, const ImageData& src, const ImageData& dest)
198  {
199  if (!check(src, dest))
200  return;
201 
202  const unsigned char* srcBuffer = (unsigned char*)src.data;
203  unsigned char* destBuffer = (unsigned char*)dest.data;
204 
205  int w = dest.w;
206  int h = dest.h;
207 
208  for (int y = 0; y != h; ++y)
209  {
210  const unsigned char* srcLine = srcBuffer;
211  unsigned char* destLine = destBuffer;
212 
213  for (int x = 0; x != w; ++x)
214  {
215  op(srcPixelFormat, destPixelFormat, srcLine, destLine);
216 
217  destLine += dest.bytespp;
218  srcLine += src.bytespp;
219  }
220 
221  srcBuffer += src.pitch;
222  destBuffer += dest.pitch;
223  }
224  }
225 
226 
227  template <class Op, class Dest>
228  void applyOperationT(const Op& op, Dest& destPixelFormat, const ImageData& dest)
229  {
230  if (!check(dest, dest))
231  return;
232 
233  unsigned char* destBuffer = (unsigned char*)dest.data;
234 
235  int w = dest.w;
236  int h = dest.h;
237 
238  for (int y = 0; y != h; ++y)
239  {
240  unsigned char* destLine = destBuffer;
241 
242  for (int x = 0; x != w; ++x)
243  {
244  op(destPixelFormat, destPixelFormat, destLine, destLine);
245  destLine += dest.bytespp;
246  }
247 
248  destBuffer += dest.pitch;
249  }
250  }
251 
252 
253 
254 
255 #define FORMAT_OP1(format) case TF_##format: \
256  { \
257  Pixel##format d; \
258  applyOperationT(op, s, d, src, dest); \
259  } \
260  break;
261 
262  template<class Src, class Op>
263  void SwitchSrcDestT(const Op& op, const Src& s, const ImageData& src, const ImageData& dest)
264  {
265 #define FORMAT_CASE FORMAT_OP1
266  ALL_FORMATS_SWITCH(dest.format);
267 #undef FORMAT_CASE
268  }
269 
270 
271 #define FORMAT_OP2(format) case TF_##format: \
272  { \
273  Pixel##format s; \
274  SwitchSrcDestT(op, s, src, dest); \
275  } \
276  break;
277 
278 
279  template <class Op>
280  void applyOperation(const Op& op, const ImageData& src, const ImageData& dest)
281  {
282 #define FORMAT_CASE FORMAT_OP2
283  ALL_FORMATS_SWITCH(src.format);
284 #undef FORMAT_CASE
285  }
286 
287 
288 #define FORMAT_OP3(format) case TF_##format: \
289  { \
290  Pixel##format d; \
291  applyOperationT(op, d, dest); \
292  } \
293  break;
294 
295  template <class Op>
296  void applyOperation(const Op& op, const ImageData& dest)
297  {
298 #define FORMAT_CASE FORMAT_OP3
299  ALL_FORMATS_SWITCH(dest.format);
300 #undef FORMAT_CASE
301  }
302  }
303 }
Definition: ImageDataOperations.h:175
Definition: ImageDataOperations.h:91
Definition: ImageData.h:54
–oxgl-end–!
Definition: Actor.h:14
Definition: ImageDataOperations.h:123
Definition: ImageDataOperations.h:66
Definition: ImageDataOperations.h:148
Definition: ImageDataOperations.h:52
Definition: ImageDataOperations.h:111