Beatmup
pixel_arithmetic.h
Go to the documentation of this file.
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2019, lnstadrum
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 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #include "abstract_bitmap.h"
21 #include "../exception.h"
22 #include "../utils/utils.hpp"
23 #include <algorithm>
24 #undef max
25 
26 #if defined(BEATMUP_CHANNEL_ORDER_BGRA) && defined(BEATMUP_CHANNEL_ORDER_ARGB)
27  #error Color order definition conflict
28 #endif
29 
30 namespace Beatmup {
31 
32  struct pixint1;
33  struct pixint3;
34  struct pixint4;
35  struct pixfloat1;
36  struct pixfloat3;
37  struct pixfloat4;
38 
39  /**
40  Monochromatic integer arithmetic
41  */
42  struct pixint1 {
43  typedef int operating_type;
44  int x;
45  operator pixint3() const;
46  operator pixint4() const;
47  operator pixfloat1() const;
48  operator pixfloat3() const;
49  operator pixfloat4() const;
50  bool operator==(const pixint1 P) const;
51  void operator=(const pixint1 P);
52  void operator=(const pixfloat1 P);
53  void operator=(const pixint3 P);
54  void operator=(const pixfloat3 P);
55  void operator=(const pixint4 P);
56  void operator=(const pixfloat4 P);
57  pixint1 operator+(const int P) const;
58  pixfloat1 operator+(const float P) const;
59  pixint1 operator+(const pixint1 P) const;
60  pixfloat1 operator+(const pixfloat1 P) const;
61  pixint3 operator+(const pixint3 P) const;
62  pixfloat3 operator+(const pixfloat3 P) const;
63  pixint4 operator+(const pixint4 P) const;
64  pixfloat4 operator+(const pixfloat4 P) const;
65  pixint1 operator-(const int P) const;
66  pixfloat1 operator-(const float P) const;
67  pixint1 operator-(const pixint1 P) const;
68  pixfloat1 operator-(const pixfloat1 P) const;
69  pixint3 operator-(const pixint3 P) const;
70  pixfloat3 operator-(const pixfloat3 P) const;
71  pixint4 operator-(const pixint4 P) const;
72  pixfloat4 operator-(const pixfloat4 P) const;
73  pixint1 operator*(const int P) const;
74  pixfloat1 operator*(const float P) const;
75  pixint1 operator*(const pixint1 P) const;
76  pixfloat1 operator*(const pixfloat1 P) const;
77  pixint3 operator*(const pixint3 P) const;
78  pixfloat3 operator*(const pixfloat3 P) const;
79  pixint4 operator*(const pixint4 P) const;
80  pixfloat4 operator*(const pixfloat4 P) const;
81  pixint1 operator/(const int P) const;
82  pixfloat1 makeFloat() const;
83  void zero() { x = 0; }
84  int sum() const { return x; }
85  float mean() const { return (float)x; }
86  int max() const { return x; }
87  pixint1 abs() const { return pixint1{ x > 0 ? x : -x }; }
88  };
89 
90  /**
91  Monochromatic floating point arithmetic
92  */
93  struct pixfloat1 {
94  typedef float operating_type;
96  operator pixint1() const;
97  operator pixint3() const;
98  operator pixint4() const;
99  operator pixfloat3() const;
100  operator pixfloat4() const;
101  bool operator==(const pixfloat1 P) const;
102  void operator=(const pixint1 P);
103  void operator=(const pixfloat1 P);
104  void operator=(const pixint3 P);
105  void operator=(const pixfloat3 P);
106  void operator=(const pixint4 P);
107  void operator=(const pixfloat4 P);
108  pixfloat1 operator+(const int P) const;
109  pixfloat1 operator+(const float P) const;
110  pixfloat1 operator+(const pixint1 P) const;
111  pixfloat1 operator+(const pixfloat1 P) const;
112  pixfloat3 operator+(const pixint3 P) const;
113  pixfloat3 operator+(const pixfloat3 P) const;
114  pixfloat4 operator+(const pixint4 P) const;
115  pixfloat4 operator+(const pixfloat4 P) const;
116  pixfloat1 operator-(const int P) const;
117  pixfloat1 operator-(const float P) const;
118  pixfloat1 operator-(const pixint1 P) const;
119  pixfloat1 operator-(const pixfloat1 P) const;
120  pixfloat3 operator-(const pixint3 P) const;
121  pixfloat3 operator-(const pixfloat3 P) const;
122  pixfloat4 operator-(const pixint4 P) const;
123  pixfloat4 operator-(const pixfloat4 P) const;
124  pixfloat1 operator*(const int P) const;
125  pixfloat1 operator*(const float P) const;
126  pixfloat1 operator*(const pixint1 P) const;
127  pixfloat1 operator*(const pixfloat1 P) const;
128  pixfloat3 operator*(const pixint3 P) const;
129  pixfloat3 operator*(const pixfloat3 P) const;
130  pixfloat4 operator*(const pixint4 P) const;
131  pixfloat4 operator*(const pixfloat4 P) const;
132  pixfloat1 operator/(const int P) const;
133  pixfloat1 makeFloat() const;
134  void zero() { x = 0; }
135  float sum() const { return x; }
136  float mean() const { return x; }
137  float max() const { return x; }
138  pixfloat1 abs() const { return pixfloat1{ x > 0 ? x : -x }; }
139  };
140 
141  /**
142  Trichromatic integer arithmetic
143  */
144  struct pixint3 {
145  typedef int operating_type;
146  int r, g, b;
147  pixint3(): r(0), g(0), b(0) {}
148  pixint3(const color3i& _) : r(_.r), g(_.g), b(_.b) {}
149  pixint3(int r, int g, int b) : r(r), g(g), b(b) {}
150  operator pixint1() const;
151  operator pixint4() const;
152  operator pixfloat1() const;
153  operator pixfloat3() const;
154  operator pixfloat4() const;
155  bool operator==(const pixint3 P) const;
156  void operator=(const pixint1 P);
157  void operator=(const pixfloat1 P);
158  void operator=(const pixint3 P);
159  void operator=(const pixfloat3 P);
160  void operator=(const pixint4 P);
161  void operator=(const pixfloat4 P);
162  pixint3 operator+(const int P) const;
163  pixfloat3 operator+(const float P) const;
164  pixint3 operator+(const pixint1 P) const;
165  pixfloat3 operator+(const pixfloat1 P) const;
166  pixint3 operator+(const pixint3 P) const;
167  pixfloat3 operator+(const pixfloat3 P) const;
168  pixint4 operator+(const pixint4 P) const;
169  pixfloat4 operator+(const pixfloat4 P) const;
170  pixint3 operator-(const int P) const;
171  pixfloat3 operator-(const float P) const;
172  pixint3 operator-(const pixint1 P) const;
173  pixfloat3 operator-(const pixfloat1 P) const;
174  pixint3 operator-(const pixint3 P) const;
175  pixfloat3 operator-(const pixfloat3 P) const;
176  pixint4 operator-(const pixint4 P) const;
177  pixfloat4 operator-(const pixfloat4 P) const;
178  pixint3 operator*(const int P) const;
179  pixfloat3 operator*(const float P) const;
180  pixint3 operator*(const pixint1 P) const;
181  pixfloat3 operator*(const pixfloat1 P) const;
182  pixint3 operator*(const pixint3 P) const;
183  pixfloat3 operator*(const pixfloat3 P) const;
184  pixint4 operator*(const pixint4 P) const;
185  pixfloat4 operator*(const pixfloat4 P) const;
186  pixint3 operator/(const int P) const;
187  pixfloat3 makeFloat() const;
188  void zero() { r = g = b = 0; }
189  int sum() const { return r + g + b; }
190  float mean() const { return (float)(r + g + b) / 3; }
191  int max() const { return std::max(r, std::max(g, b)); }
192  pixint3 abs() const { return pixint3(r > 0 ? r : -r, g > 0 ? g : -g, b > 0 ? b : -b); }
193  };
194 
195  /**
196  Trichromatic floating point arithmetic
197  */
198  struct pixfloat3 {
199  typedef float operating_type;
201  pixfloat3(): r(0), g(0), b(0) {}
202  pixfloat3(const color3f& _) : r(_.r), g(_.g), b(_.b) {}
203  pixfloat3(float r, float g, float b) : r(r), g(g), b(b) {}
204  operator pixint1() const;
205  operator pixint3() const;
206  operator pixint4() const;
207  operator pixfloat1() const;
208  operator pixfloat4() const;
209  bool operator==(const pixfloat3 P) const;
210  void operator=(const pixint1 P);
211  void operator=(const pixfloat1 P);
212  void operator=(const pixint3 P);
213  void operator=(const pixfloat3 P);
214  void operator=(const pixint4 P);
215  void operator=(const pixfloat4 P);
216  pixfloat3 operator+(const int P) const;
217  pixfloat3 operator+(const float P) const;
218  pixfloat3 operator+(const pixint1 P) const;
219  pixfloat3 operator+(const pixfloat1 P) const;
220  pixfloat3 operator+(const pixint3 P) const;
221  pixfloat3 operator+(const pixfloat3 P) const;
222  pixfloat4 operator+(const pixint4 P) const;
223  pixfloat4 operator+(const pixfloat4 P) const;
224  pixfloat3 operator-(const int P) const;
225  pixfloat3 operator-(const float P) const;
226  pixfloat3 operator-(const pixint1 P) const;
227  pixfloat3 operator-(const pixfloat1 P) const;
228  pixfloat3 operator-(const pixint3 P) const;
229  pixfloat3 operator-(const pixfloat3 P) const;
230  pixfloat4 operator-(const pixint4 P) const;
231  pixfloat4 operator-(const pixfloat4 P) const;
232  pixfloat3 operator*(const int P) const;
233  pixfloat3 operator*(const float P) const;
234  pixfloat3 operator*(const pixint1 P) const;
235  pixfloat3 operator*(const pixfloat1 P) const;
236  pixfloat3 operator*(const pixint3 P) const;
237  pixfloat3 operator*(const pixfloat3 P) const;
238  pixfloat4 operator*(const pixint4 P) const;
239  pixfloat4 operator*(const pixfloat4 P) const;
240  pixfloat3 operator/(const int P) const;
241  pixfloat3 makeFloat() const;
242  void zero() { r = g = b = 0; }
243  float sum() const { return r + g + b; }
244  float mean() const { return (r + g + b) / 3; }
245  float max() const { return std::max(r, std::max(g, b)); }
246  pixfloat3 abs() const { return pixfloat3{ r > 0 ? r : -r, g > 0 ? g : -g, b > 0 ? b : -b }; }
247  };
248 
249  /**
250  4-channel integer arithmetic
251  */
252  struct pixint4 {
253  typedef int operating_type;
254 
255  union {
256  struct {
257 #ifdef BEATMUP_CHANNEL_ORDER_ARGB
258  int a, r, g, b;
259 #elif BEATMUP_CHANNEL_ORDER_BGRA
260  int b, g, r, a;
261 #else
262  int r, g, b, a;
263 #endif
264  };
265  int val[4];
266  };
267 
268  pixint4() : r(0), g(0), b(0), a(0) {}
269  pixint4(int r, int g, int b, int a) : r(r), g(g), b(b), a(a) {}
270  static pixint4 fromColor(const color4i& _) { return pixint4(_.r, _.g, _.b, _.a); }
271  operator pixint1() const;
272  operator pixint3() const;
273  operator pixfloat1() const;
274  operator pixfloat3() const;
275  operator pixfloat4() const;
276  bool operator==(const pixint4 P) const;
277  void operator=(const pixint1 P);
278  void operator=(const pixfloat1 P);
279  void operator=(const pixint3 P);
280  void operator=(const pixfloat3 P);
281  void operator=(const pixint4 P);
282  void operator=(const pixfloat4 P);
283  pixint4 operator+(const int P) const;
284  pixfloat4 operator+(const float P) const;
285  pixint4 operator+(const pixint1 P) const;
286  pixfloat4 operator+(const pixfloat1 P) const;
287  pixint4 operator+(const pixint3 P) const;
288  pixfloat4 operator+(const pixfloat3 P) const;
289  pixint4 operator+(const pixint4 P) const;
290  pixfloat4 operator+(const pixfloat4 P) const;
291  pixint4 operator-(const int P) const;
292  pixfloat4 operator-(const float P) const;
293  pixint4 operator-(const pixint1 P) const;
294  pixfloat4 operator-(const pixfloat1 P) const;
295  pixint4 operator-(const pixint3 P) const;
296  pixfloat4 operator-(const pixfloat3 P) const;
297  pixint4 operator-(const pixint4 P) const;
298  pixfloat4 operator-(const pixfloat4 P) const;
299  pixint4 operator*(const int P) const;
300  pixfloat4 operator*(const float P) const;
301  pixint4 operator*(const pixint1 P) const;
302  pixfloat4 operator*(const pixfloat1 P) const;
303  pixint4 operator*(const pixint3 P) const;
304  pixfloat4 operator*(const pixfloat3 P) const;
305  pixint4 operator*(const pixint4 P) const;
306  pixfloat4 operator*(const pixfloat4 P) const;
307  pixint4 operator/(const int P) const;
308  pixfloat4 makeFloat() const;
309  void zero() { r = g = b = a = 0; }
310  int sum() const { return r + g + b + a; }
311  float mean() const { return (float)(r + g + b + a) / 4; }
312  int max() const { return std::max(std::max(r, g), std::max(b, a)); }
313  pixint4 abs() const { return pixint4(r > 0 ? r : -r, g > 0 ? g : -g, b > 0 ? b : -b, a > 0 ? a : -a); }
314  };
315 
316  /**
317  4-channel floating point arithmetic
318  */
319  struct pixfloat4 {
320  typedef float operating_type;
321 
322  union {
323  struct {
324 #ifdef BEATMUP_CHANNEL_ORDER_ARGB
325  pixfloat a, r, g, b;
326 #elif BEATMUP_CHANNEL_ORDER_BGRA
327  pixfloat b, g, r, a;
328 #else
329  pixfloat r, g, b, a;
330 #endif
331  };
333  };
334 
335  pixfloat4() : r(0), g(0), b(0), a(0) {}
336  pixfloat4(const color4f& _) : r(_.r), g(_.g), b(_.b), a(_.a) {}
337  pixfloat4(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {}
338  pixfloat& operator[](int i) { return val[i]; }
339  pixfloat operator[](int i) const { return val[i]; }
340  operator pixint1() const;
341  operator pixint3() const;
342  operator pixint4() const;
343  operator pixfloat1() const;
344  operator pixfloat3() const;
345  operator color4i() const;
346  operator color4f() const;
347  bool operator==(const pixfloat4 P) const;
348  void operator=(const pixint1 P);
349  void operator=(const pixfloat1 P);
350  void operator=(const pixint3 P);
351  void operator=(const pixfloat3 P);
352  void operator=(const pixint4 P);
353  void operator=(const pixfloat4 P);
354  pixfloat4 operator+(const int P) const;
355  pixfloat4 operator+(const float P) const;
356  pixfloat4 operator+(const pixint1 P) const;
357  pixfloat4 operator+(const pixfloat1 P) const;
358  pixfloat4 operator+(const pixint3 P) const;
359  pixfloat4 operator+(const pixfloat3 P) const;
360  pixfloat4 operator+(const pixint4 P) const;
361  pixfloat4 operator+(const pixfloat4 P) const;
362  pixfloat4 operator-(const int P) const;
363  pixfloat4 operator-(const float P) const;
364  pixfloat4 operator-(const pixint1 P) const;
365  pixfloat4 operator-(const pixfloat1 P) const;
366  pixfloat4 operator-(const pixint3 P) const;
367  pixfloat4 operator-(const pixfloat3 P) const;
368  pixfloat4 operator-(const pixint4 P) const;
369  pixfloat4 operator-(const pixfloat4 P) const;
370  pixfloat4 operator*(const int P) const;
371  pixfloat4 operator*(const float P) const;
372  pixfloat4 operator*(const pixint1 P) const;
373  pixfloat4 operator*(const pixfloat1 P) const;
374  pixfloat4 operator*(const pixint3 P) const;
375  pixfloat4 operator*(const pixfloat3 P) const;
376  pixfloat4 operator*(const pixint4 P) const;
377  pixfloat4 operator*(const pixfloat4 P) const;
378  pixfloat4 operator/(const int P) const;
379  pixfloat4 makeFloat() const;
380  void zero() { r = g = b = a = 0; }
381  float sum() const { return r + g + b + a; }
382  float mean() const { return (r + g + b + a) / 4; }
383  float max() const { return std::max(std::max(r, g), std::max(b, a)); }
384  pixfloat4 abs() const { return pixfloat4(r > 0 ? r : -r, g > 0 ? g : -g, b > 0 ? b : -b, a > 0 ? a : -a); }
385  };
386 
387  /**
388  Converts a floating point pixel value to a 0..255 integer
389  */
391  int i = (int)roundf_fast(x * 255.0f);
392  return i > 0 ? (i < 255 ? i : 255) : 0;
393  }
394 
395  /**
396  Converts an integer value to 0..1 floating point pixel value
397  */
398  inline pixfloat int2pixfloat(int x) {
399  return x > 0 ? (x < 255 ? x / 255.0f : 1.0f) : 0.0f;
400  }
401 
402  /**
403  Clips a floating point pixel value to 0..1 range
404  */
406  return x > 0.0f ? (x < 1.0f ? x : 1.0f) : 0.0f;
407  }
408 
409  /**
410  Clips an integer pixel value to 0..255 range
411  */
412  inline pixbyte clipPixint(int x) {
413  return x > 0 ? (x < 255 ? x : 255) : 0;
414  }
415 
416  //////////////////////////////////////////////////////////
417  // Monochromatic integer //
418  //////////////////////////////////////////////////////////
419 
420  inline pixint1::operator pixint3() const {
421  return pixint3{ x, x, x };
422  }
423 
424  inline pixint1::operator pixint4() const {
425  return pixint4(x, x, x, 255);
426  }
427 
428  inline pixint1::operator pixfloat1() const {
429  return pixfloat1{ x / 255.0f };
430  }
431 
432  inline pixint1::operator pixfloat3() const {
433  float _ = x / 255.0f;
434  return pixfloat3{ _, _, _ };
435  }
436 
437  inline pixint1::operator pixfloat4() const {
438  float _ = x / 255.0f;
439  return pixfloat4{ _, _, _, 1 };
440  }
441 
442  inline bool pixint1::operator==(const pixint1 P) const {
443  return x == P.x;
444  }
445 
446  inline void pixint1::operator=(const pixint1 P) {
447  x = P.x;
448  }
449 
450  inline void pixint1::operator=(const pixint3 P) {
451  x = (P.r + P.g + P.b) / 3;
452  }
453 
454  inline void pixint1::operator=(const pixint4 P) {
455  x = (P.r + P.g + P.b) / 3;
456  }
457 
458  inline void pixint1::operator=(const pixfloat1 P) {
459  x = (int)roundf_fast(P.x * 255.0f);
460  }
461 
462  inline void pixint1::operator=(const pixfloat3 P) {
463  x = (int)roundf_fast((P.r + P.g + P.b) * 255.0f / 3);
464  }
465 
466  inline void pixint1::operator=(const pixfloat4 P) {
467  x = (int)roundf_fast((P.r + P.g + P.b) * 255.0f / 3);
468  }
469 
470  // addition
471  inline pixint1 pixint1::operator+(const int P) const {
472  return pixint1{ x + P };
473  }
474 
475  inline pixfloat1 pixint1::operator+(const float P) const {
476  return pixfloat1{ x / 255.0f + P };
477  }
478 
479  inline pixint1 pixint1::operator+(const pixint1 P) const {
480  return pixint1{ x + P.x };
481  }
482 
483  inline pixint3 pixint1::operator+(const pixint3 P) const {
484  return pixint3{ x + P.r, x + P.g, x + P.b };
485  }
486 
487  inline pixint4 pixint1::operator+(const pixint4 P) const {
488  return pixint4(x + P.r, x + P.g, x + P.b, 255 + P.a);
489  }
490 
491  inline pixfloat1 pixint1::operator+(const pixfloat1 P) const {
492  return pixfloat1{ x / 255.0f + P.x };
493  }
494 
495  inline pixfloat3 pixint1::operator+(const pixfloat3 P) const {
496  return pixfloat3{ x / 255.0f + P.r, x / 255.0f + P.g, x / 255.0f + P.b };
497  }
498 
499  inline pixfloat4 pixint1::operator+(const pixfloat4 P) const {
500  return pixfloat4(x / 255.0f + P.r, x / 255.0f + P.g, x / 255.0f + P.b, 1.0f + P.a);
501  }
502 
503  // substraction
504  inline pixint1 pixint1::operator-(const int P) const {
505  return pixint1{ x - P };
506  }
507 
508  inline pixfloat1 pixint1::operator-(const float P) const {
509  return pixfloat1{ x / 255.0f - P };
510  }
511 
512  inline pixint1 pixint1::operator-(const pixint1 P) const {
513  return pixint1{ x - P.x };
514  }
515 
516  inline pixint3 pixint1::operator-(const pixint3 P) const {
517  return pixint3{ x - P.r, x - P.g, x - P.b };
518  }
519 
520  inline pixint4 pixint1::operator-(const pixint4 P) const {
521  return pixint4(x - P.r, x - P.g, x - P.b, 255 - P.a);
522  }
523 
524  inline pixfloat1 pixint1::operator-(const pixfloat1 P) const {
525  return pixfloat1{ x / 255.0f - P.x };
526  }
527 
528  inline pixfloat3 pixint1::operator-(const pixfloat3 P) const {
529  return pixfloat3{ x / 255.0f - P.r, x / 255.0f - P.g, x / 255.0f - P.b };
530  }
531 
532  inline pixfloat4 pixint1::operator-(const pixfloat4 P) const {
533  return pixfloat4(x / 255.0f - P.r, x / 255.0f - P.g, x / 255.0f - P.b, 1.0f - P.a);
534  }
535 
536  // multiplication
537  inline pixint1 pixint1::operator*(const int P) const {
538  return pixint1{ x * P };
539  }
540 
541  inline pixfloat1 pixint1::operator*(const float P) const {
542  return pixfloat1{ x * P / 255.0f };
543  }
544 
545  inline pixint1 pixint1::operator*(const pixint1 P) const {
546  return pixint1{ x * P.x };
547  }
548 
549  inline pixint3 pixint1::operator*(const pixint3 P) const {
550  return pixint3{ x * P.r, x * P.g, x * P.b };
551  }
552 
553  inline pixint4 pixint1::operator*(const pixint4 P) const {
554  return pixint4(x * P.r, x * P.g, x * P.b, P.a);
555  }
556 
557  inline pixfloat1 pixint1::operator*(const pixfloat1 P) const {
558  return pixfloat1{ x * P.x / 255.0f };
559  }
560 
561  inline pixfloat3 pixint1::operator*(const pixfloat3 P) const {
562  return pixfloat3{ x * P.r / 255.0f, x * P.g / 255.0f, x * P.b / 255.0f };
563  }
564 
565  inline pixfloat4 pixint1::operator*(const pixfloat4 P) const {
566  return pixfloat4(x * P.r / 255.0f, x * P.g / 255.0f, x * P.b / 255.0f, P.a);
567  }
568 
569  // division
570  inline pixint1 pixint1::operator/(const int P) const {
571  return pixint1{ x / P };
572  }
573 
574  // promotion to pixfloat
575  inline pixfloat1 pixint1::makeFloat() const {
576  return pixfloat1{ x / 255.0f };
577  }
578 
579  //////////////////////////////////////////////////////////
580  // Monochromatic floating point //
581  //////////////////////////////////////////////////////////
582 
583  inline pixfloat1::operator pixint1() const {
584  return pixint1{ roundf_fast(x * 255) };
585  }
586 
587  inline pixfloat1::operator pixint3() const {
588  int _ = roundf_fast(x * 255);
589  return pixint3{ _, _, _ };
590  }
591 
592  inline pixfloat1::operator pixint4() const {
593  int _ = roundf_fast(x * 255);
594  return pixint4(_, _, _, 255);
595  }
596 
597  inline pixfloat1::operator pixfloat3() const {
598  return pixfloat3{ x, x, x };
599  }
600 
601  inline pixfloat1::operator pixfloat4() const {
602  return pixfloat4{ x, x, x, 1 };
603  }
604 
605  inline bool pixfloat1::operator==(const pixfloat1 P) const {
606  return x == P.x;
607  }
608 
609  inline void pixfloat1::operator=(const pixint1 P) {
610  x = P.x / 255.0f;
611  }
612 
613  inline void pixfloat1::operator=(const pixfloat1 P) {
614  x = P.x;
615  }
616 
617  inline void pixfloat1::operator=(const pixint3 P) {
618  x = (P.r + P.g + P.b) / 765.0f;
619  }
620 
621  inline void pixfloat1::operator=(const pixfloat3 P) {
622  x = (P.r + P.g + P.b) / 3;
623  }
624 
625  inline void pixfloat1::operator=(const pixint4 P) {
626  x = (P.r + P.g + P.b) / 765.0f;
627  }
628 
629  inline void pixfloat1::operator=(const pixfloat4 P) {
630  x = (P.r + P.g + P.b) / 3;
631  }
632 
633  // addition
634  inline pixfloat1 pixfloat1::operator+(const int P) const {
635  return pixfloat1{ x + P };
636  }
637 
638  inline pixfloat1 pixfloat1::operator+(const float P) const {
639  return pixfloat1{ x + P };
640  }
641 
642  inline pixfloat1 pixfloat1::operator+(const pixint1 P) const {
643  return pixfloat1{ x + P.x / 255.0f };
644  }
645 
646  inline pixfloat3 pixfloat1::operator+(const pixint3 P) const {
647  return pixfloat3{ x + P.r / 255.0f, x + P.g / 255.0f, x + P.b / 255.0f };
648  }
649 
650  inline pixfloat4 pixfloat1::operator+(const pixint4 P) const {
651  return pixfloat4(x + P.r / 255.0f, x + P.g / 255.0f, x + P.b / 255.0f, 1.0f + P.a / 255.0f);
652  }
653 
654  inline pixfloat1 pixfloat1::operator+(const pixfloat1 P) const {
655  return pixfloat1{ x + P.x };
656  }
657 
658  inline pixfloat3 pixfloat1::operator+(const pixfloat3 P) const {
659  return pixfloat3{ x + P.r, x + P.g, x + P.b };
660  }
661 
662  inline pixfloat4 pixfloat1::operator+(const pixfloat4 P) const {
663  return pixfloat4(x + P.r, x + P.g, x + P.b, 1.0f + P.a);
664  }
665 
666  // substraction
667  inline pixfloat1 pixfloat1::operator-(const int P) const {
668  return pixfloat1{ x - P / 255.0f };
669  }
670 
671  inline pixfloat1 pixfloat1::operator-(const float P) const {
672  return pixfloat1{ x - P };
673  }
674 
675  inline pixfloat1 pixfloat1::operator-(const pixint1 P) const {
676  return pixfloat1{ x - P.x / 255.0f };
677  }
678 
679  inline pixfloat3 pixfloat1::operator-(const pixint3 P) const {
680  return pixfloat3{ x - P.r / 255.0f, x - P.g / 255.0f, x - P.b / 255.0f };
681  }
682 
683  inline pixfloat4 pixfloat1::operator-(const pixint4 P) const {
684  return pixfloat4(x - P.r / 255.0f, x - P.g / 255.0f, x - P.b / 255.0f, 1.0f - P.a / 255.0f);
685  }
686 
687  inline pixfloat1 pixfloat1::operator-(const pixfloat1 P) const {
688  return pixfloat1{ x - P.x };
689  }
690 
691  inline pixfloat3 pixfloat1::operator-(const pixfloat3 P) const {
692  return pixfloat3{ x - P.r, x - P.g, x - P.b };
693  }
694 
695  inline pixfloat4 pixfloat1::operator-(const pixfloat4 P) const {
696  return pixfloat4(x - P.r, x - P.g, x - P.b, 1.0f - P.a);
697  }
698 
699  // multiplication
700  inline pixfloat1 pixfloat1::operator*(const int P) const {
701  return pixfloat1{ x * P };
702  }
703 
704  inline pixfloat1 pixfloat1::operator*(const float P) const {
705  return pixfloat1{ x * P };
706  }
707 
708  inline pixfloat1 pixfloat1::operator*(const pixint1 P) const {
709  return pixfloat1{ x * P.x / 255.0f };
710  }
711 
712  inline pixfloat3 pixfloat1::operator*(const pixint3 P) const {
713  return pixfloat3{ x * P.r / 255.0f, x * P.g / 255.0f, x * P.b / 255.0f };
714  }
715 
716  inline pixfloat4 pixfloat1::operator*(const pixint4 P) const {
717  return pixfloat4(x * P.r / 255.0f, x * P.g / 255.0f, x * P.b / 255.0f, P.a / 255.0f);
718  }
719 
720  inline pixfloat1 pixfloat1::operator*(const pixfloat1 P) const {
721  return pixfloat1{ x * P.x };
722  }
723 
724  inline pixfloat3 pixfloat1::operator*(const pixfloat3 P) const {
725  return pixfloat3{ x * P.r, x * P.g, x * P.b };
726  }
727 
728  inline pixfloat4 pixfloat1::operator*(const pixfloat4 P) const {
729  return pixfloat4(x * P.r, x * P.g, x * P.b, P.a);
730  }
731 
732  // division
733  inline pixfloat1 pixfloat1::operator/(const int P) const {
734  return pixfloat1{ x / P };
735  }
736 
737  // promotion to pixfloat
739  return *this;
740  }
741 
742  //////////////////////////////////////////////////////////
743  // Trichromatic integer //
744  //////////////////////////////////////////////////////////
745 
746  inline pixint3::operator pixint1() const {
747  return pixint1{(r + g + b) / 3};
748  }
749 
750  inline pixint3::operator pixint4() const {
751  return pixint4(r, g, b, 255);
752  }
753 
754  inline pixint3::operator pixfloat1() const {
755  return pixfloat1{ (r + g + b) / (3 * 255.0f) };
756  }
757 
758  inline pixint3::operator pixfloat3() const {
759  return pixfloat3{ r / 255.0f, g / 255.0f, b / 255.0f };
760  }
761 
762  inline pixint3::operator pixfloat4() const {
763  return pixfloat4{ r / 255.0f, g / 255.0f, b / 255.0f, 1 };
764  }
765 
766  inline bool pixint3::operator==(const pixint3 P) const {
767  return (r == P.r) && (g == P.g) && (b == P.b);
768  }
769 
770  inline void pixint3::operator=(const pixint1 P) {
771  r = g = b = P.x;
772  }
773 
774  inline void pixint3::operator=(const pixfloat1 P) {
775  r = g = b = (int)roundf_fast(P.x * 255.0f);
776  }
777 
778  inline void pixint3::operator=(const pixint3 P) {
779  r = P.r;
780  g = P.g;
781  b = P.b;
782  }
783 
784  inline void pixint3::operator=(const pixfloat3 P) {
785  r = (int)roundf_fast(P.r * 255.0f);
786  g = (int)roundf_fast(P.g * 255.0f);
787  b = (int)roundf_fast(P.b * 255.0f);
788  }
789 
790  inline void pixint3::operator=(const pixint4 P) {
791  r = P.r;
792  g = P.g;
793  b = P.b;
794  }
795 
796  inline void pixint3::operator=(const pixfloat4 P) {
797  r = (int)roundf_fast(P.r * 255.0f);
798  g = (int)roundf_fast(P.g * 255.0f);
799  b = (int)roundf_fast(P.b * 255.0f);
800  }
801 
802  // addition
803  inline pixint3 pixint3::operator+(const int P) const {
804  return pixint3{ r + P, g + P, b + P };
805  }
806 
807  inline pixfloat3 pixint3::operator+(const float P) const {
808  return pixfloat3{ r / 255.0f + P, g / 255.0f + P, b / 255.0f + P };
809  }
810 
811  inline pixint3 pixint3::operator+(const pixint1 P) const {
812  return pixint3{ r + P.x, g + P.x, b + P.x };
813  }
814 
815  inline pixint3 pixint3::operator+(const pixint3 P) const {
816  return pixint3{ r + P.r, g + P.g, b + P.b };
817  }
818 
819  inline pixint4 pixint3::operator+(const pixint4 P) const {
820  return pixint4(r + P.r, g + P.g, b + P.b, 255 + P.a);
821  }
822 
823  inline pixfloat3 pixint3::operator+(const pixfloat1 P) const {
824  return pixfloat3{ r / 255.0f + P.x, g / 255.0f + P.x, b / 255.0f + P.x };
825  }
826 
827  inline pixfloat3 pixint3::operator+(const pixfloat3 P) const {
828  return pixfloat3{ r / 255.0f + P.r, g / 255.0f + P.g, b / 255.0f + P.b };
829  }
830 
831  inline pixfloat4 pixint3::operator+(const pixfloat4 P) const {
832  return pixfloat4(r / 255.0f + P.r, g / 255.0f + P.g, b / 255.0f + P.b, 1.0f + P.a);
833  }
834 
835  // substraction
836  inline pixint3 pixint3::operator-(const int P) const {
837  return pixint3{ r - P, g - P, b - P };
838  }
839 
840  inline pixfloat3 pixint3::operator-(const float P) const {
841  return pixfloat3{ r / 255.0f - P, g / 255.0f - P, b / 255.0f - P };
842  }
843 
844  inline pixint3 pixint3::operator-(const pixint1 P) const {
845  return pixint3{ r - P.x, g - P.x, b - P.x };
846  }
847 
848  inline pixint3 pixint3::operator-(const pixint3 P) const {
849  return pixint3{ r - P.r, g - P.g, b - P.b };
850  }
851 
852  inline pixint4 pixint3::operator-(const pixint4 P) const {
853  return pixint4(r - P.r, g - P.g, b - P.b, 255 - P.a);
854  }
855 
856  inline pixfloat3 pixint3::operator-(const pixfloat1 P) const {
857  return pixfloat3{ r / 255.0f - P.x, g / 255.0f - P.x, b / 255.0f - P.x };
858  }
859 
860  inline pixfloat3 pixint3::operator-(const pixfloat3 P) const {
861  return pixfloat3{ r / 255.0f - P.r, g / 255.0f - P.g, b / 255.0f - P.b };
862  }
863 
864  inline pixfloat4 pixint3::operator-(const pixfloat4 P) const {
865  return pixfloat4(r / 255.0f - P.r, g / 255.0f - P.g, b / 255.0f - P.b, 1.0f - P.a);
866  }
867 
868  // multiplication
869  inline pixint3 pixint3::operator*(const int P) const {
870  return pixint3{ r * P, g * P, b * P };
871  }
872 
873  inline pixfloat3 pixint3::operator*(const float P) const {
874  return pixfloat3{ r * P / 255.0f, g * P / 255.0f, b * P / 255.0f };
875  }
876 
877  inline pixint3 pixint3::operator*(const pixint1 P) const {
878  return pixint3{ r * P.x / 255, g * P.x / 255, b * P.x / 255 };
879  }
880 
881  inline pixint3 pixint3::operator*(const pixint3 P) const {
882  return pixint3{ r * P.r / 255, g * P.g / 255, b * P.b / 255 };
883  }
884 
885  inline pixint4 pixint3::operator*(const pixint4 P) const {
886  return pixint4(r * P.r / 255, g * P.g / 255, b * P.b / 255, P.a);
887  }
888 
889  inline pixfloat3 pixint3::operator*(const pixfloat1 P) const {
890  return pixfloat3{ r * P.x / 255.0f, g * P.x / 255.0f, b * P.x / 255.0f };
891  }
892 
893  inline pixfloat3 pixint3::operator*(const pixfloat3 P) const {
894  return pixfloat3{ r * P.r / 255.0f, g * P.g / 255.0f, b * P.b / 255.0f };
895  }
896 
897  inline pixfloat4 pixint3::operator*(const pixfloat4 P) const {
898  return pixfloat4(r * P.r / 255.0f, g * P.g / 255.0f, b * P.b / 255.0f, P.a);
899  }
900 
901  // division
902  inline pixint3 pixint3::operator/(const int P) const {
903  return pixint3{ r / P, g / P, b / P };
904  }
905 
906  // promotion to pixfloat
907  inline pixfloat3 pixint3::makeFloat() const {
908  return pixfloat3{ r / 255.0f, g / 255.0f, b / 255.0f };
909  }
910 
911  //////////////////////////////////////////////////////////
912  // Trichromatic floating point //
913  //////////////////////////////////////////////////////////
914 
915  inline pixfloat3::operator pixint1() const {
916  return pixint1{ roundf_fast(255 * (r + g + b)) };
917  }
918 
919  inline pixfloat3::operator pixint3() const {
920  return pixint3{ roundf_fast(255 * r), roundf_fast(255 * g), roundf_fast(255 * b) };
921  }
922 
923  inline pixfloat3::operator pixint4() const {
924  return pixint4(roundf_fast(255 * r), roundf_fast(255 * g), roundf_fast(255 * b), 255);
925  }
926 
927  inline pixfloat3::operator pixfloat1() const {
928  return pixfloat1{ (r + g + b) / 3 };
929  }
930 
931  inline pixfloat3::operator pixfloat4() const {
932  return pixfloat4{ r, g, b, 1 };
933  }
934 
935  inline bool pixfloat3::operator==(const pixfloat3 P) const {
936  return (r == P.r) && (g == P.g) && (b == P.b);
937  }
938 
939  inline void pixfloat3::operator=(const pixint1 P) {
940  r = g = b = P.x / 255.0f;
941  }
942 
943  inline void pixfloat3::operator=(const pixfloat1 P) {
944  r = g = b = P.x;
945  }
946 
947  inline void pixfloat3::operator=(const pixint3 P) {
948  r = P.r / 255.0f;
949  g = P.g / 255.0f;
950  b = P.b / 255.0f;
951  }
952 
953  inline void pixfloat3::operator=(const pixfloat3 P) {
954  r = P.r;
955  g = P.g;
956  b = P.b;
957  }
958 
959  inline void pixfloat3::operator=(const pixint4 P) {
960  r = P.r / 255.0f;
961  g = P.g / 255.0f;
962  b = P.b / 255.0f;
963  }
964 
965  inline void pixfloat3::operator=(const pixfloat4 P) {
966  r = P.r;
967  g = P.g;
968  b = P.b;
969  }
970 
971  // addition
972  inline pixfloat3 pixfloat3::operator+(const int P) const {
973  return pixfloat3{ r + P, g + P, b + P };
974  }
975 
976  inline pixfloat3 pixfloat3::operator+(const float P) const {
977  return pixfloat3{ r + P, g + P, b + P };
978  }
979 
980  inline pixfloat3 pixfloat3::operator+(const pixint1 P) const {
981  pixfloat f = P.x / 255.0f;
982  return pixfloat3{ r + f, g + f, b + f };
983  }
984 
985  inline pixfloat3 pixfloat3::operator+(const pixint3 P) const {
986  return pixfloat3{ r + P.r / 255.0f, g + P.g / 255.0f, b + P.b / 255.0f };
987  }
988 
989  inline pixfloat4 pixfloat3::operator+(const pixint4 P) const {
990  return pixfloat4(r + P.r / 255.0f, g + P.g / 255.0f, b + P.b / 255.0f, 1.0f + P.a / 255.0f);
991  }
992 
993  inline pixfloat3 pixfloat3::operator+(const pixfloat1 P) const {
994  return pixfloat3{ r + P.x, g + P.x, b + P.x };
995  }
996 
997  inline pixfloat3 pixfloat3::operator+(const pixfloat3 P) const {
998  return pixfloat3{ r + P.r, g + P.g, b + P.b };
999  }
1000 
1001  inline pixfloat4 pixfloat3::operator+(const pixfloat4 P) const {
1002  return pixfloat4(r + P.r, g + P.g, b + P.b, 1.0f + P.a);
1003  }
1004 
1005  // substraction
1006  inline pixfloat3 pixfloat3::operator-(const int P) const {
1007  return pixfloat3{ r - P, g - P, b - P };
1008  }
1009 
1010  inline pixfloat3 pixfloat3::operator-(const float P) const {
1011  return pixfloat3{ r - P, g - P, b - P };
1012  }
1013 
1014  inline pixfloat3 pixfloat3::operator-(const pixint1 P) const {
1015  pixfloat f = P.x / 255.0f;
1016  return pixfloat3{ r - f, g - f, b - f };
1017  }
1018 
1019  inline pixfloat3 pixfloat3::operator-(const pixint3 P) const {
1020  return pixfloat3{ r - P.r / 255.0f, g - P.g / 255.0f, b - P.b / 255.0f };
1021  }
1022 
1023  inline pixfloat4 pixfloat3::operator-(const pixint4 P) const {
1024  return pixfloat4(r - P.r / 255.0f, g - P.g / 255.0f, b - P.b / 255.0f, 1.0f - P.a / 255.0f);
1025  }
1026 
1027  inline pixfloat3 pixfloat3::operator-(const pixfloat1 P) const {
1028  return pixfloat3{ r - P.x, g - P.x, b - P.x };
1029  }
1030 
1031  inline pixfloat3 pixfloat3::operator-(const pixfloat3 P) const {
1032  return pixfloat3{ r - P.r, g - P.g, b - P.b };
1033  }
1034 
1035  inline pixfloat4 pixfloat3::operator-(const pixfloat4 P) const {
1036  return pixfloat4(r - P.r, g - P.g, b - P.b, 1.0f - P.a);
1037  }
1038 
1039  // multiplication
1040  inline pixfloat3 pixfloat3::operator*(const int P) const {
1041  return pixfloat3{ r * P, g * P, b * P };
1042  }
1043 
1044  inline pixfloat3 pixfloat3::operator*(const float P) const {
1045  return pixfloat3{ r * P, g * P, b * P };
1046  }
1047 
1048  inline pixfloat3 pixfloat3::operator*(const pixint1 P) const {
1049  float f = P.x / 255.0f;
1050  return pixfloat3{ r * f, g * f, b * f };
1051  }
1052 
1053  inline pixfloat3 pixfloat3::operator*(const pixint3 P) const {
1054  return pixfloat3{ r * P.r / 255.0f, g * P.g / 255.0f, b * P.b / 255.0f };
1055  }
1056 
1057  inline pixfloat4 pixfloat3::operator*(const pixint4 P) const {
1058  return pixfloat4(r * P.r / 255.0f, g * P.g / 255.0f, b * P.b / 255.0f, P.a / 255.0f);
1059  }
1060 
1061  inline pixfloat3 pixfloat3::operator*(const pixfloat1 P) const {
1062  return pixfloat3{ r * P.x, g * P.x, b * P.x };
1063  }
1064 
1065  inline pixfloat3 pixfloat3::operator*(const pixfloat3 P) const {
1066  return pixfloat3{ r * P.r, g * P.g, b * P.b };
1067  }
1068 
1069  inline pixfloat4 pixfloat3::operator*(const pixfloat4 P) const {
1070  return pixfloat4(r * P.r, g * P.g, b * P.b, P.a);
1071  }
1072 
1073  // division
1074  inline pixfloat3 pixfloat3::operator/(const int P) const {
1075  return pixfloat3{ r / P, g / P, b / P };
1076  }
1077 
1078  // promotion to pixfloat
1080  return *this;
1081  }
1082 
1083  //////////////////////////////////////////////////////////
1084  // 4-channel integer //
1085  //////////////////////////////////////////////////////////
1086 
1087  inline pixint4::operator pixint1() const {
1088  return pixint1{ (r + g + b) / 4 };
1089  }
1090 
1091  inline pixint4::operator pixint3() const {
1092  return pixint3{ r, g, b };
1093  }
1094 
1095  inline pixint4::operator pixfloat1() const {
1096  return pixfloat1{ (r + g + b) / (4 * 255.0f) };
1097  }
1098 
1099  inline pixint4::operator pixfloat3() const {
1100  return pixfloat3{ r / 255.0f, g / 255.0f, b / 255.0f };
1101  }
1102 
1103  inline pixint4::operator pixfloat4() const {
1104  return pixfloat4{ r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f };
1105  }
1106 
1107  inline bool pixint4::operator==(const pixint4 P) const {
1108  return (r == P.r) && (g == P.g) && (b == P.b) && (a == P.a);
1109  }
1110 
1111  inline void pixint4::operator=(const pixint1 P) {
1112  r = g = b = P.x;
1113  a = 255;
1114  }
1115 
1116  inline void pixint4::operator=(const pixfloat1 P) {
1117  r = g = b = (int)roundf_fast(P.x * 255.0f);
1118  a = 255;
1119  }
1120 
1121  inline void pixint4::operator=(const pixint3 P) {
1122  r = P.r;
1123  g = P.g;
1124  b = P.b;
1125  a = 255;
1126  }
1127 
1128  inline void pixint4::operator=(const pixfloat3 P) {
1129  r = (int)roundf_fast(P.r * 255.0f);
1130  g = (int)roundf_fast(P.g * 255.0f);
1131  b = (int)roundf_fast(P.b * 255.0f);
1132  a = 255;
1133  }
1134 
1135  inline void pixint4::operator=(const pixint4 P) {
1136  r = P.r;
1137  g = P.g;
1138  b = P.b;
1139  a = P.a;
1140  }
1141 
1142  inline void pixint4::operator=(const pixfloat4 P) {
1143  r = (int)roundf_fast(P.r * 255.0f);
1144  g = (int)roundf_fast(P.g * 255.0f);
1145  b = (int)roundf_fast(P.b * 255.0f);
1146  a = (int)roundf_fast(P.a * 255.0f);
1147  }
1148 
1149  // addition
1150  inline pixint4 pixint4::operator+(const int P) const {
1151  return pixint4(r + P, g + P, b + P, a + P);
1152  }
1153 
1154  inline pixfloat4 pixint4::operator+(const float P) const {
1155  return pixfloat4(r / 255.0f + P, g / 255.0f + P, b / 255.0f + P, a / 255.0f + P);
1156  }
1157 
1158  inline pixint4 pixint4::operator+(const pixint1 P) const {
1159  return pixint4(r + P.x, g + P.x, b + P.x, a + 255);
1160  }
1161 
1162  inline pixint4 pixint4::operator+(const pixint3 P) const {
1163  return pixint4(r + P.r, g + P.g, b + P.b, a + 255);
1164  }
1165 
1166  inline pixint4 pixint4::operator+(const pixint4 P) const {
1167  return pixint4(r + P.r, g + P.g, b + P.b, a + P.a);
1168  }
1169 
1170  inline pixfloat4 pixint4::operator+(const pixfloat1 P) const {
1171  return pixfloat4(r / 255.0f + P.x, g / 255.0f + P.x, b / 255.0f + P.x, a / 255.0f + 1.0f);
1172  }
1173 
1174  inline pixfloat4 pixint4::operator+(const pixfloat3 P) const {
1175  return pixfloat4(r / 255.0f + P.r, g / 255.0f + P.g, b / 255.0f + P.b, a / 255.0f + 1.0f);
1176  }
1177 
1178  inline pixfloat4 pixint4::operator+(const pixfloat4 P) const {
1179  return pixfloat4(r / 255.0f + P.r, g / 255.0f + P.g, b / 255.0f + P.b, a / 255.0f + P.a);
1180  }
1181 
1182  // substraction
1183  inline pixint4 pixint4::operator-(const int P) const {
1184  return pixint4(r - P, g - P, b - P, a - P);
1185  }
1186 
1187  inline pixfloat4 pixint4::operator-(const float P) const {
1188  return pixfloat4(r / 255.0f - P, g / 255.0f - P, b / 255.0f - P, a / 255.0f - P);
1189  }
1190 
1191  inline pixint4 pixint4::operator-(const pixint1 P) const {
1192  return pixint4(r - P.x, g - P.x, b - P.x, a - 255);
1193  }
1194 
1195  inline pixint4 pixint4::operator-(const pixint3 P) const {
1196  return pixint4(r - P.r, g - P.g, b - P.b, a - 255);
1197  }
1198 
1199  inline pixint4 pixint4::operator-(const pixint4 P) const {
1200  return pixint4(r - P.r, g - P.g, b - P.b, a - P.a);
1201  }
1202 
1203  inline pixfloat4 pixint4::operator-(const pixfloat1 P) const {
1204  return pixfloat4(r / 255.0f - P.x, g / 255.0f - P.x, b / 255.0f - P.x, a / 255.0f - 1.0f);
1205  }
1206 
1207  inline pixfloat4 pixint4::operator-(const pixfloat3 P) const {
1208  return pixfloat4(r / 255.0f - P.r, g / 255.0f - P.g, b / 255.0f - P.b, a / 255.0f - 1.0f);
1209  }
1210 
1211  inline pixfloat4 pixint4::operator-(const pixfloat4 P) const {
1212  return pixfloat4(r / 255.0f - P.r, g / 255.0f - P.g, b / 255.0f - P.b, a / 255.0f - P.a);
1213  }
1214 
1215  // multiplication
1216  inline pixint4 pixint4::operator*(const int P) const {
1217  return pixint4(r * P, g * P, b * P, a * P);
1218  }
1219 
1220  inline pixfloat4 pixint4::operator*(const float P) const {
1221  return pixfloat4(r * P / 255.0f, g * P / 255.0f, b * P / 255.0f, a * P / 255.0f);
1222  }
1223 
1224  inline pixint4 pixint4::operator*(const pixint1 P) const {
1225  return pixint4(r * P.x / 255, g * P.x / 255, b * P.x / 255, a);
1226  }
1227 
1228  inline pixint4 pixint4::operator*(const pixint3 P) const {
1229  return pixint4(r * P.r / 255, g * P.g / 255, b * P.b / 255, a);
1230  }
1231 
1232  inline pixint4 pixint4::operator*(const pixint4 P) const {
1233  return pixint4(r * P.r / 255, g * P.g / 255, b * P.b / 255, a * P.a / 255);
1234  }
1235 
1236  inline pixfloat4 pixint4::operator*(const pixfloat1 P) const {
1237  return pixfloat4(r * P.x / 255.0f, g * P.x / 255.0f, b * P.x / 255.0f, a / 255.0f);
1238  }
1239 
1240  inline pixfloat4 pixint4::operator*(const pixfloat3 P) const {
1241  return pixfloat4(r * P.r / 255.0f, g * P.g / 255.0f, b * P.b / 255.0f, a / 255.0f);
1242  }
1243 
1244  inline pixfloat4 pixint4::operator*(const pixfloat4 P) const {
1245  return pixfloat4(r * P.r / 255.0f, g * P.g / 255.0f, b * P.b / 255.0f, a * P.a / 255.0f);
1246  }
1247 
1248  // division
1249  inline pixint4 pixint4::operator/(const int P) const {
1250  return pixint4(r / P, g / P, b / P, a / P);
1251  }
1252 
1253  // promotion to pixfloat
1255  return pixfloat4(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
1256  }
1257 
1258  //////////////////////////////////////////////////////////
1259  // 4-channel floating point //
1260  //////////////////////////////////////////////////////////
1261 
1262  inline pixfloat4::operator pixint1() const {
1263  return pixint1{ roundf_fast(85 * (r + g + b)) };
1264  }
1265 
1266  inline pixfloat4::operator pixint3() const {
1267  return pixint3{ roundf_fast(255 * r), roundf_fast(255 * g), roundf_fast(255 * b) };
1268  }
1269 
1270  inline pixfloat4::operator pixint4() const {
1271  return pixint4(roundf_fast(255 * r), roundf_fast(255 * g), roundf_fast(255 * b), roundf_fast(255 * a));
1272  }
1273  inline pixfloat4::operator pixfloat1() const {
1274  return pixfloat1{ (r + g + b) / 3 };
1275  }
1276 
1277  inline pixfloat4::operator pixfloat3() const {
1278  return pixfloat3{ r, g, b };
1279  }
1280 
1281  inline pixfloat4::operator color4f() const {
1282  return color4f{ r, g, b, a };
1283  }
1284 
1285  inline pixfloat4::operator color4i() const {
1287  }
1288 
1289  inline bool pixfloat4::operator==(const pixfloat4 P) const {
1290  return (r == P.r) && (g == P.g) && (b == P.b) && (a == P.a);
1291  }
1292 
1293  inline void pixfloat4::operator=(const pixint1 P) {
1294  r = g = b = P.x / 255.0f;
1295  a = 1.0f;
1296  }
1297 
1298  inline void pixfloat4::operator=(const pixfloat1 P) {
1299  r = g = b = P.x;
1300  a = 1.0f;
1301  }
1302 
1303  inline void pixfloat4::operator=(const pixint3 P) {
1304  r = P.r / 255.0f;
1305  g = P.g / 255.0f;
1306  b = P.b / 255.0f;
1307  a = 1.0f;
1308  }
1309 
1310  inline void pixfloat4::operator=(const pixfloat3 P) {
1311  r = P.r;
1312  g = P.g;
1313  b = P.b;
1314  a = 1.0f;
1315  }
1316 
1317  inline void pixfloat4::operator=(const pixint4 P) {
1318  r = P.r / 255.0f;
1319  g = P.g / 255.0f;
1320  b = P.b / 255.0f;
1321  a = P.a / 255.0f;
1322  }
1323 
1324  inline void pixfloat4::operator=(const pixfloat4 P) {
1325  r = P.r;
1326  g = P.g;
1327  b = P.b;
1328  a = P.a;
1329  }
1330 
1331  // addition
1332  inline pixfloat4 pixfloat4::operator+(const int P) const {
1333  return pixfloat4(r + P, g + P, b + P, a + P);
1334  }
1335 
1336  inline pixfloat4 pixfloat4::operator+(const float P) const {
1337  return pixfloat4(r + P, g + P, b + P, a + P);
1338  }
1339 
1340  inline pixfloat4 pixfloat4::operator+(const pixint1 P) const {
1341  pixfloat f = P.x / 255.0f;
1342  return pixfloat4(r + f, g + f, b + f, a + 1.0f);
1343  }
1344 
1345  inline pixfloat4 pixfloat4::operator+(const pixint3 P) const {
1346  return pixfloat4(r + P.r / 255.0f, g + P.g / 255.0f, b + P.b / 255.0f, a + 1.0f);
1347  }
1348 
1349  inline pixfloat4 pixfloat4::operator+(const pixint4 P) const {
1350  return pixfloat4(r + P.r / 255.0f, g + P.g / 255.0f, b + P.b / 255.0f, a + P.a / 255.0f);
1351  }
1352 
1353  inline pixfloat4 pixfloat4::operator+(const pixfloat1 P) const {
1354  return pixfloat4(r + P.x, g + P.x, b + P.x, a + 1.0f);
1355  }
1356 
1357  inline pixfloat4 pixfloat4::operator+(const pixfloat3 P) const {
1358  return pixfloat4(r + P.r, g + P.g, b + P.b, a + 1.0f);
1359  }
1360 
1361  inline pixfloat4 pixfloat4::operator+(const pixfloat4 P) const {
1362  return pixfloat4(r + P.r, g + P.g, b + P.b, a + P.a);
1363  }
1364 
1365  // substraction
1366  inline pixfloat4 pixfloat4::operator-(const int P) const {
1367  return pixfloat4(r - P, g - P, b - P, a - P);
1368  }
1369 
1370  inline pixfloat4 pixfloat4::operator-(const float P) const {
1371  return pixfloat4(r - P, g - P, b - P, a - P);
1372  }
1373 
1374  inline pixfloat4 pixfloat4::operator-(const pixint1 P) const {
1375  pixfloat f = P.x / 255.0f;
1376  return pixfloat4(r - f, g - f, b - f, a - 1.0f);
1377  }
1378 
1379  inline pixfloat4 pixfloat4::operator-(const pixint3 P) const {
1380  return pixfloat4(r - P.r / 255.0f, g - P.g / 255.0f, b - P.b / 255.0f, a - 1.0f);
1381  }
1382 
1383  inline pixfloat4 pixfloat4::operator-(const pixint4 P) const {
1384  return pixfloat4(r - P.r / 255.0f, g - P.g / 255.0f, b - P.b / 255.0f, a - P.a / 255.0f - 1.0f);
1385  }
1386 
1387  inline pixfloat4 pixfloat4::operator-(const pixfloat1 P) const {
1388  return pixfloat4(r - P.x, g - P.x, b - P.x, a - 1.0f);
1389  }
1390 
1391  inline pixfloat4 pixfloat4::operator-(const pixfloat3 P) const {
1392  return pixfloat4(r - P.r, g - P.g, b - P.b, a - 1.0f);
1393  }
1394 
1395  inline pixfloat4 pixfloat4::operator-(const pixfloat4 P) const {
1396  return pixfloat4(r - P.r, g - P.g, b - P.b, a - P.a);
1397  }
1398 
1399  // multiplication
1400  inline pixfloat4 pixfloat4::operator*(const int P) const {
1401  return pixfloat4(r * P, g * P, b * P, a * P);
1402  }
1403 
1404  inline pixfloat4 pixfloat4::operator*(const float P) const {
1405  return pixfloat4(r * P, g * P, b * P, a * P);
1406  }
1407 
1408  inline pixfloat4 pixfloat4::operator*(const pixint1 P) const {
1409  float f = P.x / 255.0f;
1410  return pixfloat4(r * f, g * f, b * f, a);
1411  }
1412 
1413  inline pixfloat4 pixfloat4::operator*(const pixint3 P) const {
1414  return pixfloat4(r * P.r / 255.0f, g * P.g / 255.0f, b * P.b / 255.0f, a);
1415  }
1416 
1417  inline pixfloat4 pixfloat4::operator*(const pixint4 P) const {
1418  return pixfloat4(r * P.r / 255.0f, g * P.g / 255.0f, b * P.b / 255.0f, a * P.a / 255.0f);
1419  }
1420 
1421  inline pixfloat4 pixfloat4::operator*(const pixfloat1 P) const {
1422  return pixfloat4(r * P.x, g * P.x, b * P.x, a);
1423  }
1424 
1425  inline pixfloat4 pixfloat4::operator*(const pixfloat3 P) const {
1426  return pixfloat4(r * P.r, g * P.g, b * P.b, a);
1427  }
1428 
1429  inline pixfloat4 pixfloat4::operator*(const pixfloat4 P) const {
1430  return pixfloat4(r * P.r, g * P.g, b * P.b, a * P.a);
1431  }
1432 
1433  // division
1434  inline pixfloat4 pixfloat4::operator/(const int P) const {
1435  return pixfloat4(r / P, g / P, b / P, a / P);
1436  }
1437 
1438  // promotion to pixfloat
1440  return *this;
1441  }
1442 
1443  //////////////////////////////////////////////////////////
1444  // GLOBAL OPERATORS //
1445  //////////////////////////////////////////////////////////
1446 
1447  inline pixint1 operator-(int x, pixint1 P) {
1448  return pixint1{ x - P.x };
1449  }
1450 }
uint8_t pixbyte
Definition: basic_types.h:34
CustomPoint< numeric > operator-(const CustomPoint< numeric > &point)
Point with negative coordinates.
Definition: geometry.h:594
pixbyte clipPixint(int x)
Clips an integer pixel value to 0..255 range.
float pixfloat
Definition: basic_types.h:35
pixfloat clipPixfloat(pixfloat x)
Clips a floating point pixel value to 0..1 range.
pixbyte pixfloat2pixbyte(pixfloat x)
Converts a floating point pixel value to a 0..255 integer.
pixfloat int2pixfloat(int x)
Converts an integer value to 0..1 floating point pixel value.
CustomPoint< numeric > max(const CustomPoint< numeric > &a, const CustomPoint< numeric > &b)
Definition: geometry.h:728
Monochromatic floating point arithmetic.
bool operator==(const pixfloat1 P) const
pixfloat1 operator/(const int P) const
pixfloat1 abs() const
void operator=(const pixint1 P)
pixfloat1 operator+(const int P) const
pixfloat1 operator-(const int P) const
pixfloat1 operator*(const int P) const
pixfloat1 makeFloat() const
Trichromatic floating point arithmetic.
bool operator==(const pixfloat3 P) const
pixfloat3 operator-(const int P) const
pixfloat3 makeFloat() const
pixfloat3(const color3f &_)
pixfloat3 operator/(const int P) const
pixfloat3 operator*(const int P) const
pixfloat3 operator+(const int P) const
pixfloat3 abs() const
void operator=(const pixint1 P)
pixfloat3(float r, float g, float b)
4-channel floating point arithmetic
void operator=(const pixint1 P)
bool operator==(const pixfloat4 P) const
pixfloat & operator[](int i)
pixfloat4 operator*(const int P) const
pixfloat operator[](int i) const
pixfloat4 operator+(const int P) const
pixfloat4(const color4f &_)
pixfloat4 makeFloat() const
pixfloat4 operator/(const int P) const
pixfloat4 operator-(const int P) const
pixfloat4 abs() const
pixfloat4(float r, float g, float b, float a)
Monochromatic integer arithmetic.
pixint1 operator-(const int P) const
void operator=(const pixint1 P)
pixint1 operator/(const int P) const
pixint1 operator+(const int P) const
pixfloat1 makeFloat() const
pixint1 abs() const
pixint1 operator*(const int P) const
float mean() const
bool operator==(const pixint1 P) const
Trichromatic integer arithmetic.
pixint3 operator-(const int P) const
pixfloat3 makeFloat() const
bool operator==(const pixint3 P) const
void operator=(const pixint1 P)
pixint3 operator*(const int P) const
pixint3 abs() const
pixint3 operator+(const int P) const
float mean() const
pixint3(int r, int g, int b)
pixint3(const color3i &_)
pixint3 operator/(const int P) const
4-channel integer arithmetic
void operator=(const pixint1 P)
pixint4 operator-(const int P) const
static pixint4 fromColor(const color4i &_)
pixint4 abs() const
pixint4 operator/(const int P) const
pixint4(int r, int g, int b, int a)
bool operator==(const pixint4 P) const
pixint4 operator*(const int P) const
pixfloat4 makeFloat() const
pixint4 operator+(const int P) const
float mean() const
#define roundf_fast(X)
rounding (nearest integer)
Definition: utils.hpp:22
jobject jlong jint jint jint jint g
jobject jlong jint jint jint jint jint b
jobject jlong jint jint jint r
jobject jlong jint jint jint jint jint jint a
jobject jlong jint x