#include #include #include #include "ImageLoader.h" namespace sp { static ImageLoader _loader; Image::Image() : m_size (0, 0), m_channels (RGBA) { } void Image::create(unsigned width, unsigned height, const Color& color, enum Channels comp) { m_size.x = width; m_size.y = height; m_channels = comp; m_pixels.resize(m_size.x * m_size.y * getNumChannels()); for(size_t i = 0; i < m_pixels.size(); i += 4) { m_pixels[i+0] = color.r; m_pixels[i+1] = color.g; m_pixels[i+2] = color.b; m_pixels[i+3] = color.a; } } void Image::create(unsigned width, unsigned height, const void* pixels, PixelFormat format) { m_size.x = width; m_size.y = height; setPixels(pixels, format); } const Vector2u& Image::getSize() const { return m_size; } unsigned int Image::getWidth() const { return m_size.x; } unsigned int Image::getHeight() const { return m_size.y; } unsigned int Image::getNumChannels() const { switch(m_channels) { case Channels::RGBA : return 4; case Channels::RGB : return 3; case Channels::Alpha : default : break; } return 1; } unsigned int Image::getStride() const { return m_size.x * getNumChannels(); } PixelFormat Image::getFormat() const { switch(m_channels) { case Channels::RGBA : return PixelFormat::PF_RGBA; case Channels::RGB : return PixelFormat::PF_RGB; case Channels::Alpha : default : break; } return PixelFormat::PF_Alpha; } bool Image::hasAlpha() const { return m_channels != Channels::RGB; } bool Image::loadFromFile(const std::string& filename) { m_pixels.clear(); return _loader.loadFromFile(filename.c_str(), *this); } bool Image::loadFromMemory(const void *data, unsigned int size) { m_pixels.clear(); return _loader.loadFromMemory(data, size, *this); } void Image::saveToFile(const std::string& filename) const { _loader.saveToFile(*this, filename.c_str()); } void Image::setPixel(unsigned x, unsigned y, const Color& c) { unsigned char *base = m_pixels.data() + (getNumChannels() * ((y * m_size.x) + x)); if (m_channels == RGB || m_channels == RGBA) { base[0] = c.r; base[1] = c.g; base[2] = c.b; if (m_channels == RGBA) { base[3] = c.a; } } else if (m_channels == Alpha) { base[0] = c.a; } } Color Image::getPixel(unsigned x, unsigned y) const { Color c; const unsigned char *base = m_pixels.data() + (getNumChannels() * ((y * m_size.x) + x)); // RGB / RGBA formats. if (m_channels == RGB || m_channels == RGBA) { c.r = base[0]; c.g = base[1]; c.b = base[2]; if (m_channels == RGBA) { c.a = base[3]; } else { c.a = 255; } } // Alpha, single channel format. else if (m_channels == Alpha) { c = Color(0, 0, 0, base[0]); } return c; } void Image::flipY() { unsigned int stride = getStride(); // The quick and dirty way :) for(size_t y = 0; y < m_size.y / 2; y++) { int row0 = y * stride; int row1 = (m_size.y - y - 1) * stride; for(size_t x = 0; x < stride; x++) { unsigned char tmp = m_pixels[row0 + x]; m_pixels[row0 + x] = m_pixels[row1 + x]; m_pixels[row1 + x] = tmp; } } } void Image::setPixels(const void *pixels, PixelFormat format) { if (format == PixelFormat::PF_RGB) { m_channels = RGB; } else if (format == PixelFormat::PF_RGBA) { m_channels = RGBA; } else if (format == PixelFormat::PF_Alpha) { m_channels = Alpha; } m_pixels.resize(m_size.y * getStride()); memcpy(&m_pixels[0], pixels, m_pixels.size()); } const unsigned char* Image::getPixels() const { if (m_pixels.size()) { return &m_pixels[0]; } return NULL; } } // namespace sp