ext/rays/bitmap.cpp in rays-0.1.46 vs ext/rays/bitmap.cpp in rays-0.1.47
- old
+ new
@@ -70,11 +70,269 @@
return value(THIS->color_space());
}
RUCY_END
+static inline Value
+to_rgb_value (uint8_t r, uint8_t g, uint8_t b)
+{
+ return value(
+ ((uint) r) << 16 |
+ ((uint) g) << 8 |
+ ((uint) b));
+}
+
+static inline Value
+to_rgba_value (uint8_t r, uint8_t g, uint8_t b, uint8_t a)
+{
+ return value(
+ ((uint) a) << 24 |
+ ((uint) r) << 16 |
+ ((uint) g) << 8 |
+ ((uint) b));
+}
+
+static void
+get_pixels (auto* pixels, const Rays::Bitmap& bmp)
+{
+ int w = bmp.width(), h = bmp.height();
+
+ const auto& cs = bmp.color_space();
+ pixels->clear();
+ pixels->reserve(w * h * (cs.is_float() ? cs.Bpp() / cs.Bpc() : 1));
+
+ switch (cs.type())
+ {
+ case Rays::GRAY_8:
+ case Rays::ALPHA_8:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, ++p)
+ pixels->push_back(value(*p));
+ }
+ break;
+
+ case Rays::GRAY_16:
+ case Rays::ALPHA_16:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint16_t>(0, y);
+ for (int x = 0; x < w; ++x, ++p)
+ pixels->push_back(value(*p));
+ }
+ break;
+
+ case Rays::GRAY_32:
+ case Rays::ALPHA_32:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint32_t>(0, y);
+ for (int x = 0; x < w; ++x, ++p)
+ pixels->push_back(value(*p));
+ }
+ break;
+
+ case Rays::GRAY_float:
+ case Rays::ALPHA_float:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<float>(0, y);
+ for (int x = 0; x < w; ++x, ++p)
+ pixels->push_back(value(*p));
+ }
+ break;
+
+ case Rays::RGB_888:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 3)
+ pixels->push_back(to_rgb_value(p[0], p[1], p[2]));
+ }
+ break;
+
+ case Rays::RGBA_8888:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ pixels->push_back(to_rgba_value(p[0], p[1], p[2], p[3]));
+ }
+ break;
+
+ case Rays::RGBX_8888:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ pixels->push_back(to_rgb_value(p[0], p[1], p[2]));
+ }
+ break;
+
+ case Rays::ARGB_8888:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ pixels->push_back(to_rgba_value(p[1], p[2], p[3], p[0]));
+ }
+ break;
+
+ case Rays::XRGB_8888:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ pixels->push_back(to_rgb_value(p[1], p[2], p[3]));
+ }
+ break;
+
+ case Rays::BGR_888:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 3)
+ pixels->push_back(to_rgb_value(p[2], p[1], p[0]));
+ }
+ break;
+
+ case Rays::BGRA_8888:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ pixels->push_back(to_rgba_value(p[2], p[1], p[0], p[3]));
+ }
+ break;
+
+ case Rays::BGRX_8888:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ pixels->push_back(to_rgb_value(p[2], p[1], p[0]));
+ }
+ break;
+
+ case Rays::ABGR_8888:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ pixels->push_back(to_rgba_value(p[3], p[2], p[1], p[0]));
+ }
+ break;
+
+ case Rays::XBGR_8888:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ pixels->push_back(to_rgb_value(p[3], p[2], p[1]));
+ }
+ break;
+
+ case Rays::RGB_float:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 3)
+ {
+ pixels->push_back(value(p[0]));
+ pixels->push_back(value(p[1]));
+ pixels->push_back(value(p[2]));
+ }
+ }
+ break;
+
+ case Rays::RGBA_float:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ {
+ pixels->push_back(value(p[0]));
+ pixels->push_back(value(p[1]));
+ pixels->push_back(value(p[2]));
+ pixels->push_back(value(p[3]));
+ }
+ }
+ break;
+
+ case Rays::ARGB_float:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ {
+ pixels->push_back(value(p[1]));
+ pixels->push_back(value(p[2]));
+ pixels->push_back(value(p[3]));
+ pixels->push_back(value(p[0]));
+ }
+ }
+ break;
+
+ case Rays::BGR_float:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 3)
+ {
+ pixels->push_back(value(p[2]));
+ pixels->push_back(value(p[1]));
+ pixels->push_back(value(p[0]));
+ }
+ }
+ break;
+
+ case Rays::BGRA_float:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ {
+ pixels->push_back(value(p[2]));
+ pixels->push_back(value(p[1]));
+ pixels->push_back(value(p[0]));
+ pixels->push_back(value(p[3]));
+ }
+ }
+ break;
+
+ case Rays::ABGR_float:
+ for (int y = 0; y < h; ++y)
+ {
+ const auto* p = bmp.at<uint8_t>(0, y);
+ for (int x = 0; x < w; ++x, p += 4)
+ {
+ pixels->push_back(value(p[3]));
+ pixels->push_back(value(p[2]));
+ pixels->push_back(value(p[1]));
+ pixels->push_back(value(p[0]));
+ }
+ }
+ break;
+
+ default:
+ argument_error(__FILE__, __LINE__);
+ }
+}
+
static
+RUCY_DEF0(pixels)
+{
+ CHECK;
+
+ std::vector<VALUE> pixels;
+ get_pixels(&pixels, *THIS);
+ return value(pixels.size(), (const Value*) &pixels[0]);
+}
+RUCY_END
+
+static
RUCY_DEF3(set_at, x, y, color)
{
CHECK;
bool is_array = color.is_array();
@@ -111,9 +369,10 @@
cBitmap.define_private_method("initialize", initialize);
cBitmap.define_private_method("initialize_copy", initialize_copy);
cBitmap.define_method("width", width);
cBitmap.define_method("height", height);
cBitmap.define_method("color_space", color_space);
+ cBitmap.define_method("pixels", pixels);
cBitmap.define_method("[]=", set_at);
cBitmap.define_method("[]", get_at);
}