rays 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
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