#include "rays/color_space.h" #include #include #include "rays/exception.h" namespace Rays { enum { FIRST = GRAY_8, LAST = ABGR_float, GRAY_FIRST = GRAY_8, GRAY_LAST = GRAY_float, RGB_FIRST = RGB_888, RGB_LAST = ABGR_float, FLOAT_SECOND = RGB_float, FLOAT_LAST = ABGR_float, }; ColorSpace::ColorSpace () : type_(COLORSPACE_UNKNOWN), premult(false) { } ColorSpace::ColorSpace (ColorSpaceType type, bool premultiplied) : type_(type), premult(premultiplied) { } ColorSpaceType ColorSpace::type () const { return type_; } int ColorSpace::bpc () const { static const int BPPS[] = { 0, // UNKNOWN 8, 16, 24, 32, 32, // GRAY 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // RGB(A), BGR(A) 32, 32, 32, 32, 32, 32, // RGB(A), BGR(A) float }; if (type_ < 0 || COLORSPACE_LAST <= type_) return BPPS[COLORSPACE_UNKNOWN]; return BPPS[type_]; } int ColorSpace::Bpc () const { return Xot::bit2byte(bpc()); } int ColorSpace::bpp () const { static const int BPPS[] = { 0, // UNKNOWN 8, 16, 24, 32, 32, // GRAY 24, 32, 32, 32, 32, // RGB(A) 24, 32, 32, 32, 32, // BGR(A) 96, 128, 128, // RGB(A) float 96, 128, 128, // BGR(A) float }; if (type_ < 0 || COLORSPACE_LAST <= type_) return BPPS[COLORSPACE_UNKNOWN]; return BPPS[type_]; } int ColorSpace::Bpp () const { return Xot::bit2byte(bpp()); } int ColorSpace::alpha_pos () const { return is_alpha_last() ? 3 : 0; } bool ColorSpace::is_gray () const { return GRAY_FIRST <= (int) type_ && (int) type_ <= GRAY_LAST; } bool ColorSpace::is_rgb () const { return (RGB_888 <= type_ && type_ <= XRGB_8888) || (RGB_float <= type_ && type_ <= ARGB_float); } bool ColorSpace::is_bgr () const { return (BGR_888 <= type_ && type_ <= XBGR_8888) || (BGR_float <= type_ && type_ <= ABGR_float); } bool ColorSpace::is_float () const { return type_ == GRAY_float || (FLOAT_SECOND <= (int) type_ && (int) type_ <= FLOAT_LAST); } bool ColorSpace::has_alpha () const { return type_ == RGBA_8888 || type_ == ARGB_8888 || type_ == BGRA_8888 || type_ == ABGR_8888 || type_ == RGBA_float || type_ == ARGB_float || type_ == BGRA_float || type_ == ABGR_float; } bool ColorSpace::has_skip () const { return type_ == RGBX_8888 || type_ == XRGB_8888 || type_ == BGRX_8888 || type_ == XBGR_8888; } bool ColorSpace::is_alpha_first () const { return type_ == ARGB_8888 || type_ == ABGR_8888 || type_ == ARGB_float || type_ == ABGR_float; } bool ColorSpace::is_alpha_last () const { return type_ == RGBA_8888 || type_ == BGRA_8888 || type_ == RGBA_float || type_ == BGRA_float; } bool ColorSpace::is_skip_first () const { return type_ == XRGB_8888 || type_ == XBGR_8888; } bool ColorSpace::is_skip_last () const { return type_ == RGBX_8888 || type_ == BGRX_8888; } bool ColorSpace::is_premult () const { return premult; } void ColorSpace::get_gl_enums (GLenum* format, GLenum* type, bool alpha_only) const { if (!format && !type) argument_error(__FILE__, __LINE__); if (!*this) invalid_state_error(__FILE__, __LINE__); if (format) { if (is_rgb()) *format = has_alpha() ? GL_RGBA : GL_RGB; #ifndef IOS else if (is_bgr()) *format = has_alpha() ? GL_BGRA : GL_BGR; #endif else if (is_gray()) *format = alpha_only ? GL_ALPHA : GL_LUMINANCE; else rays_error(__FILE__, __LINE__, "invalid color space."); } if (type) { if (is_float()) *type = GL_FLOAT; else switch (bpc()) { case 8: *type = GL_UNSIGNED_BYTE; break; case 16: *type = GL_UNSIGNED_SHORT; break; #ifndef IOS case 32: *type = GL_UNSIGNED_INT; break; #endif default: rays_error(__FILE__, __LINE__, "invalid bpc."); } } } ColorSpace::operator bool () const { return FIRST <= (int) type_ && (int) type_ <= LAST; } bool ColorSpace::operator ! () const { return !operator bool(); } }// Rays