Add support for BGR formats to Pixmap, and RGB conversion.
The Cairo image surface backend uses the BGR format for "RGB24" for some reason, and we need to handle that.pull/33/head
parent
6d5d88f01e
commit
803665404e
|
@ -216,6 +216,9 @@ void OpenGl1Renderer::SelectTexture(std::shared_ptr<const Pixmap> pm) {
|
|||
case Pixmap::Format::RGBA: format = GL_RGBA; break;
|
||||
case Pixmap::Format::RGB: format = GL_RGB; break;
|
||||
case Pixmap::Format::A: format = GL_ALPHA; break;
|
||||
case Pixmap::Format::BGRA:
|
||||
case Pixmap::Format::BGR:
|
||||
ssassert(false, "Unexpected pixmap format");
|
||||
}
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, pm->width, pm->height, 0,
|
||||
format, GL_UNSIGNED_BYTE, &pm->data[0]);
|
||||
|
|
|
@ -65,7 +65,9 @@ std::shared_ptr<Pixmap> LoadPng(const std::string &name) {
|
|||
size_t Pixmap::GetBytesPerPixel() const {
|
||||
switch(format) {
|
||||
case Format::RGBA: return 4;
|
||||
case Format::BGRA: return 4;
|
||||
case Format::RGB: return 3;
|
||||
case Format::BGR: return 3;
|
||||
case Format::A: return 1;
|
||||
}
|
||||
ssassert(false, "Unexpected pixmap format");
|
||||
|
@ -81,12 +83,52 @@ RgbaColor Pixmap::GetPixel(size_t x, size_t y) const {
|
|||
case Format::RGB:
|
||||
return RgbaColor::From(pixel[0], pixel[1], pixel[2], 255);
|
||||
|
||||
case Format::BGRA:
|
||||
return RgbaColor::From(pixel[2], pixel[1], pixel[0], pixel[3]);
|
||||
|
||||
case Format::BGR:
|
||||
return RgbaColor::From(pixel[2], pixel[1], pixel[0], 255);
|
||||
|
||||
case Format::A:
|
||||
return RgbaColor::From( 255, 255, 255, pixel[0]);
|
||||
}
|
||||
ssassert(false, "Unexpected resource format");
|
||||
}
|
||||
|
||||
void Pixmap::ConvertTo(Format newFormat) {
|
||||
switch(format) {
|
||||
case Format::RGBA:
|
||||
ssassert(newFormat == Format::BGRA, "Unexpected target format");
|
||||
break;
|
||||
|
||||
case Format::BGRA:
|
||||
ssassert(newFormat == Format::RGBA, "Unexpected target format");
|
||||
break;
|
||||
|
||||
case Format::RGB:
|
||||
ssassert(newFormat == Format::BGR, "Unexpected target format");
|
||||
break;
|
||||
|
||||
case Format::BGR:
|
||||
ssassert(newFormat == Format::RGB, "Unexpected target format");
|
||||
break;
|
||||
|
||||
case Format::A:
|
||||
ssassert(false, "Unexpected target format");
|
||||
}
|
||||
|
||||
size_t bpp = GetBytesPerPixel();
|
||||
for(size_t j = 0; j != height; j++) {
|
||||
uint8_t *row = &data[j * stride];
|
||||
for(size_t i = 0; i != width * bpp; i += bpp) {
|
||||
// This handles both RGB<>BGR and RGBA<>BGRA.
|
||||
std::swap(row[i], row[i + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
format = newFormat;
|
||||
}
|
||||
|
||||
static std::shared_ptr<Pixmap> ReadPngIntoPixmap(png_struct *png_ptr, png_info *info_ptr,
|
||||
bool flip) {
|
||||
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB, NULL);
|
||||
|
@ -175,10 +217,13 @@ exit:
|
|||
|
||||
bool Pixmap::WritePng(FILE *f, bool flip) {
|
||||
int colorType;
|
||||
bool bgr;
|
||||
switch(format) {
|
||||
case Format::RGBA: colorType = PNG_COLOR_TYPE_RGBA; break;
|
||||
case Format::RGB: colorType = PNG_COLOR_TYPE_RGB; break;
|
||||
case Format::A: ssassert(false, "Unexpected pixmap format");
|
||||
case Format::RGBA: colorType = PNG_COLOR_TYPE_RGBA; bgr = false; break;
|
||||
case Format::BGRA: colorType = PNG_COLOR_TYPE_RGBA; bgr = true; break;
|
||||
case Format::RGB: colorType = PNG_COLOR_TYPE_RGB; bgr = false; break;
|
||||
case Format::BGR: colorType = PNG_COLOR_TYPE_RGB; bgr = true; break;
|
||||
case Format::A: colorType = PNG_COLOR_TYPE_GRAY; bgr = false; break;
|
||||
}
|
||||
|
||||
std::vector<uint8_t *> rows;
|
||||
|
@ -204,6 +249,7 @@ bool Pixmap::WritePng(FILE *f, bool flip) {
|
|||
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
|
||||
colorType, PNG_INTERLACE_NONE,
|
||||
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
if(bgr) png_set_bgr(png_ptr);
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
png_write_image(png_ptr, &rows[0]);
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
|
|
|
@ -24,7 +24,7 @@ std::shared_ptr<Pixmap> LoadPng(const std::string &name);
|
|||
|
||||
class Pixmap {
|
||||
public:
|
||||
enum class Format { RGBA, RGB, A };
|
||||
enum class Format { BGRA, RGBA, BGR, RGB, A };
|
||||
|
||||
Format format;
|
||||
size_t width;
|
||||
|
@ -40,6 +40,8 @@ public:
|
|||
|
||||
size_t GetBytesPerPixel() const;
|
||||
RgbaColor GetPixel(size_t x, size_t y) const;
|
||||
|
||||
void ConvertTo(Format newFormat);
|
||||
};
|
||||
|
||||
class BitmapFont {
|
||||
|
|
Loading…
Reference in New Issue