rays 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.doc/ext/rays/bitmap.cpp +70 -233
  3. data/.doc/ext/rays/bounds.cpp +339 -57
  4. data/.doc/ext/rays/color.cpp +58 -48
  5. data/.doc/ext/rays/color_space.cpp +174 -0
  6. data/.doc/ext/rays/font.cpp +31 -53
  7. data/.doc/ext/rays/image.cpp +64 -67
  8. data/.doc/ext/rays/matrix.cpp +22 -50
  9. data/.doc/ext/rays/native.cpp +9 -2
  10. data/.doc/ext/rays/painter.cpp +276 -259
  11. data/.doc/ext/rays/point.cpp +186 -52
  12. data/.doc/ext/rays/rays.cpp +25 -20
  13. data/.doc/ext/rays/shader.cpp +61 -0
  14. data/.doc/ext/rays/texture.cpp +47 -59
  15. data/{README → README.md} +0 -0
  16. data/Rakefile +6 -5
  17. data/VERSION +1 -1
  18. data/ext/rays/bitmap.cpp +88 -248
  19. data/ext/rays/bounds.cpp +437 -141
  20. data/ext/rays/color.cpp +79 -69
  21. data/ext/rays/color_space.cpp +185 -0
  22. data/ext/rays/extconf.rb +14 -63
  23. data/ext/rays/font.cpp +44 -65
  24. data/ext/rays/image.cpp +82 -81
  25. data/ext/rays/matrix.cpp +32 -60
  26. data/ext/rays/native.cpp +9 -2
  27. data/ext/rays/painter.cpp +345 -321
  28. data/ext/rays/point.cpp +212 -69
  29. data/ext/rays/rays.cpp +29 -23
  30. data/ext/rays/shader.cpp +63 -0
  31. data/ext/rays/texture.cpp +64 -74
  32. data/include/rays/bitmap.h +21 -12
  33. data/include/rays/bounds.h +67 -9
  34. data/include/rays/color.h +23 -7
  35. data/include/rays/{colorspace.h → color_space.h} +6 -3
  36. data/include/rays/exception.h +17 -11
  37. data/include/rays/font.h +4 -3
  38. data/include/rays/image.h +11 -6
  39. data/include/rays/matrix.h +15 -12
  40. data/include/rays/opengl.h +54 -1
  41. data/include/rays/painter.h +98 -108
  42. data/include/rays/point.h +45 -5
  43. data/include/rays/rays.h +2 -2
  44. data/include/rays/ruby/bitmap.h +2 -16
  45. data/include/rays/ruby/bounds.h +4 -16
  46. data/include/rays/ruby/color.h +3 -16
  47. data/include/rays/ruby/color_space.h +27 -0
  48. data/include/rays/ruby/font.h +2 -16
  49. data/include/rays/ruby/image.h +2 -16
  50. data/include/rays/ruby/matrix.h +2 -16
  51. data/include/rays/ruby/painter.h +2 -16
  52. data/include/rays/ruby/point.h +3 -16
  53. data/include/rays/ruby/shader.h +27 -0
  54. data/include/rays/ruby/texture.h +2 -16
  55. data/include/rays/ruby.h +1 -0
  56. data/include/rays/shader.h +48 -0
  57. data/include/rays/texture.h +13 -2
  58. data/include/rays.h +2 -1
  59. data/lib/rays/bitmap.rb +20 -11
  60. data/lib/rays/bounds.rb +29 -68
  61. data/lib/rays/color.rb +39 -0
  62. data/lib/rays/color_space.rb +33 -0
  63. data/lib/rays/font.rb +29 -0
  64. data/lib/rays/image.rb +22 -0
  65. data/lib/rays/module.rb +11 -7
  66. data/lib/rays/painter.rb +103 -40
  67. data/lib/rays/point.rb +19 -36
  68. data/lib/rays/shader.rb +13 -0
  69. data/lib/rays/texture.rb +9 -0
  70. data/lib/rays.rb +4 -0
  71. data/rays.gemspec +3 -4
  72. data/src/bounds.cpp +272 -63
  73. data/src/color.cpp +168 -21
  74. data/src/{colorspace.cpp → color_space.cpp} +38 -1
  75. data/src/exception.cpp +24 -15
  76. data/src/frame_buffer.cpp +275 -0
  77. data/src/frame_buffer.h +79 -0
  78. data/src/image.cpp +80 -36
  79. data/src/ios/bitmap.mm +340 -0
  80. data/src/ios/font.mm +206 -0
  81. data/src/{cocoa → ios}/helper.h +2 -2
  82. data/src/{cocoa → ios}/helper.mm +0 -0
  83. data/src/ios/opengl.mm +21 -0
  84. data/src/ios/program.cpp +122 -0
  85. data/src/{cocoa → ios}/rays.mm +8 -7
  86. data/src/matrix.cpp +10 -22
  87. data/src/opengl.cpp +64 -0
  88. data/src/{cocoa → osx}/bitmap.mm +121 -70
  89. data/src/{cocoa → osx}/font.mm +32 -24
  90. data/src/osx/helper.h +26 -0
  91. data/src/osx/helper.mm +25 -0
  92. data/src/osx/opengl.mm +103 -0
  93. data/src/osx/rays.mm +43 -0
  94. data/src/painter.cpp +596 -422
  95. data/src/point.cpp +154 -11
  96. data/src/program.cpp +513 -0
  97. data/src/program.h +73 -0
  98. data/src/render_buffer.cpp +120 -0
  99. data/src/render_buffer.h +47 -0
  100. data/src/shader.cpp +117 -0
  101. data/src/texture.cpp +104 -134
  102. data/test/helper.rb +10 -3
  103. data/test/test_bitmap.rb +18 -0
  104. data/test/test_bounds.rb +81 -35
  105. data/test/test_color.rb +29 -2
  106. data/test/test_image.rb +63 -0
  107. data/test/test_painter.rb +120 -0
  108. data/test/test_point.rb +30 -9
  109. data/test/test_shader.rb +37 -0
  110. data/test/test_texture.rb +18 -0
  111. metadata +75 -58
  112. data/.gitignore +0 -14
  113. data/ChangeLog +0 -8
data/src/bounds.cpp CHANGED
@@ -1,29 +1,43 @@
1
1
  #include "rays/bounds.h"
2
2
 
3
3
 
4
+ #include <algorithm>
5
+ #include "rays/exception.h"
6
+
7
+
4
8
  namespace Rays
5
9
  {
6
10
 
7
11
 
8
12
  Bounds::Bounds (coord size)
9
13
  {
10
- set(size);
14
+ reset(size);
11
15
  }
12
16
 
13
17
  Bounds::Bounds (coord width, coord height, coord depth)
14
18
  {
15
- set(width, height, depth);
19
+ reset(width, height, depth);
16
20
  }
17
21
 
18
22
  Bounds::Bounds (coord x, coord y, coord width, coord height)
19
23
  {
20
- set(x, y, width, height);
24
+ reset(x, y, width, height);
21
25
  }
22
26
 
23
27
  Bounds::Bounds (
24
28
  coord x, coord y, coord z, coord width, coord height, coord depth)
25
29
  {
26
- set(x, y, z, width, height, depth);
30
+ reset(x, y, z, width, height, depth);
31
+ }
32
+
33
+ Bounds::Bounds (const Point& size)
34
+ {
35
+ reset(size);
36
+ }
37
+
38
+ Bounds::Bounds (const Point& position, const Point& size)
39
+ {
40
+ reset(position, size);
27
41
  }
28
42
 
29
43
  Bounds
@@ -32,69 +46,183 @@ namespace Rays
32
46
  return *this;
33
47
  }
34
48
 
49
+ bool
50
+ Bounds::is_intersect (const Bounds& other, int dimension) const
51
+ {
52
+ if (dimension < 1 || 3 < dimension)
53
+ argument_error(__FILE__, __LINE__);
54
+
55
+ Point size = (*this & other).size();
56
+ for (int i = 0; i < dimension; ++i)
57
+ if (size[i] <= 0) return false;
58
+
59
+ return true;
60
+ }
61
+
62
+ bool
63
+ Bounds::is_include (coord x, coord y, coord z, int dimension) const
64
+ {
65
+ return is_include(Point(x, y, z), dimension);
66
+ }
67
+
68
+ bool
69
+ Bounds::is_include (const Point& point, int dimension) const
70
+ {
71
+ if (dimension < 1 || 3 < dimension)
72
+ argument_error(__FILE__, __LINE__);
73
+
74
+ const Point &pos = position(), &size_ = size();
75
+ for (int i = 0; i < dimension; ++i)
76
+ {
77
+ coord value = point[i], min_ = pos[i], max_ = min_ + size_[i];
78
+ if (value < min_ || max_ <= value)
79
+ return false;
80
+ }
81
+
82
+ return true;
83
+ }
84
+
85
+ Bounds&
86
+ Bounds::reset (coord size)
87
+ {
88
+ return reset(size, size, 0);
89
+ }
90
+
91
+ Bounds&
92
+ Bounds::reset (coord width, coord height, coord depth)
93
+ {
94
+ this->x =
95
+ this->y =
96
+ this->z = 0;
97
+ this->w = width;
98
+ this->h = height;
99
+ this->d = depth;
100
+ return *this;
101
+ }
102
+
103
+ Bounds&
104
+ Bounds::reset (coord x, coord y, coord width, coord height)
105
+ {
106
+ return reset(x, y, 0, width, height, 0);
107
+ }
108
+
109
+ Bounds&
110
+ Bounds::reset (coord x, coord y, coord z, coord width, coord height, coord depth)
111
+ {
112
+ this->x = x;
113
+ this->y = y;
114
+ this->z = z;
115
+ this->w = width;
116
+ this->h = height;
117
+ this->d = depth;
118
+ return *this;
119
+ }
120
+
35
121
  Bounds&
36
- Bounds::set (coord size)
122
+ Bounds::reset (const Point& size)
37
123
  {
38
- return set(size, size, 0);
124
+ this->x = this->y = this->z = 0;
125
+ this->w = size.x;
126
+ this->h = size.y;
127
+ this->d = size.z;
128
+ return *this;
39
129
  }
40
130
 
41
131
  Bounds&
42
- Bounds::set (coord width, coord height, coord depth)
132
+ Bounds::reset (const Point& position, const Point& size)
133
+ {
134
+ this->x = position.x;
135
+ this->y = position.y;
136
+ this->z = position.z;
137
+ this->w = size.x;
138
+ this->h = size.y;
139
+ this->d = size.z;
140
+ return *this;
141
+ }
142
+
143
+ Bounds&
144
+ Bounds::move_to (coord x, coord y, coord z)
43
145
  {
44
- this->x =
45
- this->y =
46
- this->z = 0;
47
- this->width = width;
48
- this->height = height;
49
- this->depth = depth;
146
+ this->x = x;
147
+ this->y = y;
148
+ this->z = z;
50
149
  return *this;
51
150
  }
52
151
 
53
152
  Bounds&
54
- Bounds::set (coord x, coord y, coord width, coord height)
153
+ Bounds::move_to (const Point& point)
55
154
  {
56
- return set(x, y, 0, width, height, 0);
155
+ return move_to(point.x, point.y, point.z);
57
156
  }
58
157
 
59
158
  Bounds&
60
- Bounds::set (coord x, coord y, coord z, coord width, coord height, coord depth)
159
+ Bounds::move_by (coord x, coord y, coord z)
61
160
  {
62
- this->x = x;
63
- this->y = y;
64
- this->z = z;
65
- this->width = width;
66
- this->height = height;
67
- this->depth = depth;
161
+ this->x += x;
162
+ this->y += y;
163
+ this->z += z;
68
164
  return *this;
69
165
  }
70
166
 
71
- bool
72
- Bounds::get (coord* x, coord* y, coord* width, coord* height) const
167
+ Bounds&
168
+ Bounds::move_by (const Point& point)
73
169
  {
74
- return get(x, y, NULL, width, height, NULL);
170
+ return move_by(point.x, point.y, point.z);
75
171
  }
76
172
 
77
- bool
78
- Bounds::get (
79
- coord* x, coord* y, coord* z, coord* width, coord* height, coord* depth) const
80
- {
81
- if (!x && !y && !z && !width && !height && !depth)
82
- return false;
83
-
84
- if (x) *x = this->x;
85
- if (y) *y = this->y;
86
- if (z) *z = this->z;
87
- if (width) *width = this->width;
88
- if (height) *height = this->height;
89
- if (depth) *depth = this->depth;
90
- return true;
173
+ Bounds&
174
+ Bounds::resize_to (coord width, coord height, coord depth)
175
+ {
176
+ this->w = width;
177
+ this->h = height;
178
+ this->d = depth;
179
+ return *this;
180
+ }
181
+
182
+ Bounds&
183
+ Bounds::resize_to (const Point& point)
184
+ {
185
+ return resize_to(point.x, point.y, point.z);
186
+ }
187
+
188
+ Bounds&
189
+ Bounds::resize_by (coord width, coord height, coord depth)
190
+ {
191
+ this->w += width;
192
+ this->h += height;
193
+ this->d += depth;
194
+ return *this;
195
+ }
196
+
197
+ Bounds&
198
+ Bounds::resize_by (const Point& point)
199
+ {
200
+ return resize_by(point.x, point.y, point.z);
201
+ }
202
+
203
+ Bounds&
204
+ Bounds::inset_by (coord x, coord y, coord z)
205
+ {
206
+ this->x += x;
207
+ this->y += y;
208
+ this->z += z;
209
+ this->w -= x * 2;
210
+ this->h -= y * 2;
211
+ this->d -= z * 2;
212
+ return *this;
213
+ }
214
+
215
+ Bounds&
216
+ Bounds::inset_by (const Point& point)
217
+ {
218
+ return inset_by(point.x, point.y, point.z);
91
219
  }
92
220
 
93
221
  void
94
222
  Bounds::set_left (coord left)
95
223
  {
96
- width -= left - x;
97
- x = left;
224
+ w -= left - x;
225
+ x = left;
98
226
  }
99
227
 
100
228
  coord
@@ -106,20 +234,20 @@ namespace Rays
106
234
  void
107
235
  Bounds::set_right (coord right)
108
236
  {
109
- width = right - x + 1;
237
+ w = right - x + (right >= 0 ? 1 : -1);
110
238
  }
111
239
 
112
240
  coord
113
241
  Bounds::right () const
114
242
  {
115
- return x + width - 1;
243
+ return x + w - 1;
116
244
  }
117
245
 
118
246
  void
119
247
  Bounds::set_top (coord top)
120
248
  {
121
- height -= top - y;
122
- y = top;
249
+ h -= top - y;
250
+ y = top;
123
251
  }
124
252
 
125
253
  coord
@@ -131,20 +259,20 @@ namespace Rays
131
259
  void
132
260
  Bounds::set_bottom (coord bottom)
133
261
  {
134
- height = bottom - y + 1;
262
+ h = bottom - y + (bottom >= 0 ? 1 : -1);
135
263
  }
136
264
 
137
265
  coord
138
266
  Bounds::bottom () const
139
267
  {
140
- return y + height - 1;
268
+ return y + h - 1;
141
269
  }
142
270
 
143
271
  void
144
272
  Bounds::set_back (coord back)
145
273
  {
146
- depth -= back - z;
147
- z = back;
274
+ d -= back - z;
275
+ z = back;
148
276
  }
149
277
 
150
278
  coord
@@ -156,19 +284,19 @@ namespace Rays
156
284
  void
157
285
  Bounds::set_front (coord front)
158
286
  {
159
- depth = front - z + 1;
287
+ d = front - z + (front >= 0 ? 1 : -1);
160
288
  }
161
289
 
162
290
  coord
163
291
  Bounds::front () const
164
292
  {
165
- return z + depth - 1;
293
+ return z + d - 1;
166
294
  }
167
295
 
168
296
  Point&
169
297
  Bounds::position ()
170
298
  {
171
- return ((Point*) this)[0];
299
+ return (*this)[0];
172
300
  }
173
301
 
174
302
  const Point&
@@ -180,7 +308,7 @@ namespace Rays
180
308
  Point&
181
309
  Bounds::size ()
182
310
  {
183
- return ((Point*) this)[1];
311
+ return (*this)[1];
184
312
  }
185
313
 
186
314
  const Point&
@@ -189,21 +317,50 @@ namespace Rays
189
317
  return const_cast<This*>(this)->size();
190
318
  }
191
319
 
192
- coord*
193
- Bounds::array ()
320
+ void
321
+ Bounds::set_center (coord x, coord y, coord z)
322
+ {
323
+ this->x = x - w / 2;
324
+ this->y = y - h / 2;
325
+ this->z = z - d / 2;
326
+ }
327
+
328
+ void
329
+ Bounds::set_center (const Point& point)
330
+ {
331
+ set_center(point.x, point.y, point.z);
332
+ }
333
+
334
+ Point
335
+ Bounds::center () const
336
+ {
337
+ return Point(x + w / 2, y + h / 2, z + d / 2);
338
+ }
339
+
340
+ String
341
+ Bounds::inspect () const
194
342
  {
195
- return (coord*) this;
343
+ return Xot::stringf("x=%f y=%f z=%f width=%f height=%f depth=%f", x, y, z, w, h, d);
344
+ }
345
+
346
+ Point&
347
+ Bounds::operator [] (size_t index)
348
+ {
349
+ if (index > 1)
350
+ argument_error(__FILE__, __LINE__);
351
+
352
+ return ((Point*) array)[index];
196
353
  }
197
354
 
198
- const coord*
199
- Bounds::array () const
355
+ const Point&
356
+ Bounds::operator [] (size_t index) const
200
357
  {
201
- return const_cast<Bounds*>(this)->array();
358
+ return const_cast<Bounds*>(this)->operator[](index);
202
359
  }
203
360
 
204
361
  Bounds::operator bool () const
205
362
  {
206
- return width >= 0 && height >= 0 && depth >= 0;
363
+ return w >= 0 && h >= 0 && d >= 0;
207
364
  }
208
365
 
209
366
  bool
@@ -212,6 +369,42 @@ namespace Rays
212
369
  return !operator bool();
213
370
  }
214
371
 
372
+ Bounds&
373
+ Bounds::operator &= (const Bounds& rhs)
374
+ {
375
+ if (!*this || !rhs)
376
+ argument_error(__FILE__, __LINE__);
377
+
378
+ coord x = std::max(this->x, rhs.x);
379
+ coord y = std::max(this->y, rhs.y);
380
+ coord z = std::max(this->z, rhs.z);
381
+ coord w = std::min(this->x + this->w, rhs.x + rhs.w) - x;
382
+ coord h = std::min(this->y + this->h, rhs.y + rhs.h) - y;
383
+ coord d = std::min(this->z + this->d, rhs.z + rhs.d) - z;
384
+
385
+ return reset(
386
+ x, y, z,
387
+ std::max(w, (coord) 0),
388
+ std::max(h, (coord) 0),
389
+ std::max(d, (coord) 0));
390
+ }
391
+
392
+ Bounds&
393
+ Bounds::operator |= (const Bounds& rhs)
394
+ {
395
+ if (!*this || !rhs)
396
+ argument_error(__FILE__, __LINE__);
397
+
398
+ coord x = std::min(this->x, rhs.x);
399
+ coord y = std::min(this->y, rhs.y);
400
+ coord z = std::min(this->z, rhs.z);
401
+ coord w = std::max(this->x + this->w, rhs.x + rhs.w) - x;
402
+ coord h = std::max(this->y + this->h, rhs.y + rhs.h) - y;
403
+ coord d = std::max(this->z + this->d, rhs.z + rhs.d) - z;
404
+
405
+ return reset(x, y, z, w, h, d);
406
+ }
407
+
215
408
  bool
216
409
  operator == (const Bounds& lhs, const Bounds& rhs)
217
410
  {
@@ -219,9 +412,9 @@ namespace Rays
219
412
  lhs.x == rhs.x &&
220
413
  lhs.y == rhs.y &&
221
414
  lhs.z == rhs.z &&
222
- lhs.width == rhs.width &&
223
- lhs.height == rhs.height &&
224
- lhs.depth == rhs.depth;
415
+ lhs.w == rhs.w &&
416
+ lhs.h == rhs.h &&
417
+ lhs.d == rhs.d;
225
418
  }
226
419
 
227
420
  bool
@@ -230,5 +423,21 @@ namespace Rays
230
423
  return !operator==(lhs, rhs);
231
424
  }
232
425
 
426
+ Bounds
427
+ operator & (const Bounds& lhs, const Bounds& rhs)
428
+ {
429
+ Bounds t = lhs;
430
+ t &= rhs;
431
+ return t;
432
+ }
433
+
434
+ Bounds
435
+ operator | (const Bounds& lhs, const Bounds& rhs)
436
+ {
437
+ Bounds t = lhs;
438
+ t |= rhs;
439
+ return t;
440
+ }
441
+
233
442
 
234
443
  }// Rays
data/src/color.cpp CHANGED
@@ -1,18 +1,45 @@
1
1
  #include "rays/color.h"
2
2
 
3
3
 
4
+ #include <limits.h>
5
+ #include <xot/util.h>
6
+ #include "rays/exception.h"
7
+ #include "rays/color_space.h"
8
+
9
+
4
10
  namespace Rays
5
11
  {
6
12
 
7
13
 
8
- Color::Color (float value, float alpha)
14
+ Color::Color (float gray, float alpha)
9
15
  {
10
- set(value, alpha);
16
+ reset(gray, alpha);
11
17
  }
12
18
 
13
19
  Color::Color (float red, float green, float blue, float alpha)
14
20
  {
15
- set(red, green, blue, alpha);
21
+ reset(red, green, blue, alpha);
22
+ }
23
+
24
+ Color::Color (void* pixel, const ColorSpace& cs)
25
+ {
26
+ reset(pixel, cs);
27
+ }
28
+
29
+ Color
30
+ Color8 (uchar gray, uchar alpha)
31
+ {
32
+ Color c;
33
+ c.reset8(gray, alpha);
34
+ return c;
35
+ }
36
+
37
+ Color
38
+ Color8 (uchar red, uchar green, uchar blue, uchar alpha)
39
+ {
40
+ Color c;
41
+ c.reset8(red, green, blue, alpha);
42
+ return c;
16
43
  }
17
44
 
18
45
  Color
@@ -22,13 +49,13 @@ namespace Rays
22
49
  }
23
50
 
24
51
  Color&
25
- Color::set (float value, float alpha)
52
+ Color::reset (float gray, float alpha)
26
53
  {
27
- return set(value, value, value, alpha);
54
+ return reset(gray, gray, gray, alpha);
28
55
  }
29
56
 
30
57
  Color&
31
- Color::set (float red, float green, float blue, float alpha)
58
+ Color::reset (float red, float green, float blue, float alpha)
32
59
  {
33
60
  this->red = red;
34
61
  this->green = green;
@@ -37,29 +64,149 @@ namespace Rays
37
64
  return *this;
38
65
  }
39
66
 
40
- bool
41
- Color::get (float* red, float* green, float* blue, float* alpha) const
67
+ Color&
68
+ Color::reset8 (uchar gray, uchar alpha)
69
+ {
70
+ float g = uchar2float(gray);
71
+ float a = uchar2float(alpha);
72
+ return reset(g, g, g, a);
73
+ }
74
+
75
+ Color&
76
+ Color::reset8 (uchar red, uchar green, uchar blue, uchar alpha)
77
+ {
78
+ this->red = uchar2float(red);
79
+ this->green = uchar2float(green);
80
+ this->blue = uchar2float(blue);
81
+ this->alpha = uchar2float(alpha);
82
+ return *this;
83
+ }
84
+
85
+ Color&
86
+ Color::reset (const void* pixel, const ColorSpace& cs)
87
+ {
88
+ if (!pixel || !cs)
89
+ argument_error(__FILE__, __LINE__);
90
+
91
+ if (cs.is_float())
92
+ {
93
+ float* p = (float*) pixel;
94
+ switch (cs.type())
95
+ {
96
+ case GRAY_float: reset(p[0]); break;
97
+ case RGB_float: reset(p[0], p[1], p[2]); break;
98
+ case RGBA_float: reset(p[0], p[1], p[2], p[3]); break;
99
+ case ARGB_float: reset(p[1], p[2], p[3], p[0]); break;
100
+ case BGR_float: reset(p[2], p[1], p[0]); break;
101
+ case BGRA_float: reset(p[2], p[1], p[0], p[3]); break;
102
+ case ABGR_float: reset(p[3], p[2], p[1], p[0]); break;
103
+ default: rays_error(__FILE__, __LINE__);
104
+ }
105
+ }
106
+ else
107
+ {
108
+ uchar* p = (uchar*) pixel;
109
+ switch (cs.type())
110
+ {
111
+ case GRAY_8: reset8(*((uchar*) pixel) / (float) UCHAR_MAX); break;
112
+ case GRAY_16: reset8(*((ushort*) pixel) / (float) USHRT_MAX); break;
113
+ case GRAY_32: reset8((float) (*((uint*) pixel) / (double) UINT_MAX)); break;
114
+ case RGB_888: reset8(p[0], p[1], p[2]); break;
115
+ case RGBA_8888: reset8(p[0], p[1], p[2], p[3]); break;
116
+ case ARGB_8888: reset8(p[1], p[2], p[3], p[0]); break;
117
+ case RGBX_8888: reset8(p[0], p[1], p[2]); break;
118
+ case XRGB_8888: reset8(p[1], p[2], p[3]); break;
119
+ case BGR_888: reset8(p[2], p[1], p[0]); break;
120
+ case BGRA_8888: reset8(p[2], p[1], p[0], p[3]); break;
121
+ case ABGR_8888: reset8(p[3], p[2], p[1], p[0]); break;
122
+ case BGRX_8888: reset8(p[2], p[1], p[0]); break;
123
+ case XBGR_8888: reset8(p[3], p[2], p[1]); break;
124
+ default: rays_error(__FILE__, __LINE__);
125
+ }
126
+ }
127
+
128
+ return *this;
129
+ }
130
+
131
+ static float
132
+ to_gray (const float* c)
42
133
  {
43
- if (!red && !green && !blue && !alpha)
44
- return false;
134
+ return (c[0] + c[1] + c[2]) / 3;
135
+ }
45
136
 
46
- if (red) *red = this->red;
47
- if (green) *green = this->green;
48
- if (blue) *blue = this->blue;
49
- if (alpha) *alpha = this->alpha;
50
- return true;
137
+ static uint
138
+ to_gray (const float* c, uint max)
139
+ {
140
+ return Xot::clip<uint>(0, max, to_gray(c) * max);
51
141
  }
52
142
 
53
- float*
54
- Color::array ()
143
+ static void
144
+ get_rgba (float* red, float* green, float* blue, float* alpha, const float* c)
55
145
  {
56
- return (float*) this;
146
+ if ((!red && !green && !blue && !alpha) || !c)
147
+ argument_error(__FILE__, __LINE__);
148
+
149
+ if (red) *red = c[0];
150
+ if (green) *green = c[1];
151
+ if (blue) *blue = c[2];
152
+ if (alpha) *alpha = c[3];
153
+ }
154
+
155
+ static void
156
+ get_rgba (uchar* red, uchar* green, uchar* blue, uchar* alpha, const float* c)
157
+ {
158
+ if ((!red && !green && !blue && !alpha) || !c)
159
+ argument_error(__FILE__, __LINE__);
160
+
161
+ if (red) *red = Color::float2uchar(c[0]);
162
+ if (green) *green = Color::float2uchar(c[1]);
163
+ if (blue) *blue = Color::float2uchar(c[2]);
164
+ if (alpha) *alpha = Color::float2uchar(c[3]);
57
165
  }
58
166
 
59
- const float*
60
- Color::array () const
167
+ void
168
+ Color::get (void* pixel, const ColorSpace& cs) const
61
169
  {
62
- return const_cast<Color*>(this)->array();
170
+ if (!pixel || !cs)
171
+ argument_error(__FILE__, __LINE__);
172
+
173
+ const float* c = array;
174
+ if (cs.is_float())
175
+ {
176
+ float* p = (float*) pixel;
177
+ switch (cs.type())
178
+ {
179
+ case GRAY_float: p[0] = to_gray(c); break;
180
+ case RGB_float: get_rgba(p+0, p+1, p+2, NULL, c); break;
181
+ case RGBA_float: get_rgba(p+0, p+1, p+2, p+3, c); break;
182
+ case ARGB_float: get_rgba(p+1, p+2, p+3, p+0, c); break;
183
+ case BGR_float: get_rgba(p+2, p+1, p+0, NULL, c); break;
184
+ case BGRA_float: get_rgba(p+2, p+1, p+0, p+3, c); break;
185
+ case ABGR_float: get_rgba(p+3, p+2, p+1, p+0, c); break;
186
+ default: rays_error(__FILE__, __LINE__);
187
+ }
188
+ }
189
+ else
190
+ {
191
+ uchar* p = (uchar*) pixel;
192
+ switch (cs.type())
193
+ {
194
+ case GRAY_8: *(uchar*) p = (uchar) to_gray(c, UCHAR_MAX); break;
195
+ case GRAY_16: *(ushort*) p = (ushort) to_gray(c, USHRT_MAX); break;
196
+ case GRAY_32: *(uint*) p = (uint) to_gray(c, UINT_MAX); break;
197
+ case RGB_888: get_rgba(p+0, p+1, p+2, NULL, c); break;
198
+ case RGBA_8888: get_rgba(p+0, p+1, p+2, p+3, c); break;
199
+ case ARGB_8888: get_rgba(p+1, p+2, p+3, p+0, c); break;
200
+ case RGBX_8888: get_rgba(p+0, p+1, p+2, NULL, c); break;
201
+ case XRGB_8888: get_rgba(p+1, p+2, p+3, NULL, c); break;
202
+ case BGR_888: get_rgba(p+2, p+1, p+0, NULL, c); break;
203
+ case BGRA_8888: get_rgba(p+2, p+1, p+0, p+3, c); break;
204
+ case ABGR_8888: get_rgba(p+3, p+2, p+1, p+0, c); break;
205
+ case BGRX_8888: get_rgba(p+2, p+1, p+0, NULL, c); break;
206
+ case XBGR_8888: get_rgba(p+3, p+2, p+1, NULL, c); break;
207
+ default: rays_error(__FILE__, __LINE__);
208
+ }
209
+ }
63
210
  }
64
211
 
65
212
  Color::operator bool () const