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::RGBA: format = GL_RGBA; break;
|
||||||
case Pixmap::Format::RGB: format = GL_RGB; break;
|
case Pixmap::Format::RGB: format = GL_RGB; break;
|
||||||
case Pixmap::Format::A: format = GL_ALPHA; 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,
|
glTexImage2D(GL_TEXTURE_2D, 0, format, pm->width, pm->height, 0,
|
||||||
format, GL_UNSIGNED_BYTE, &pm->data[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 {
|
size_t Pixmap::GetBytesPerPixel() const {
|
||||||
switch(format) {
|
switch(format) {
|
||||||
case Format::RGBA: return 4;
|
case Format::RGBA: return 4;
|
||||||
|
case Format::BGRA: return 4;
|
||||||
case Format::RGB: return 3;
|
case Format::RGB: return 3;
|
||||||
|
case Format::BGR: return 3;
|
||||||
case Format::A: return 1;
|
case Format::A: return 1;
|
||||||
}
|
}
|
||||||
ssassert(false, "Unexpected pixmap format");
|
ssassert(false, "Unexpected pixmap format");
|
||||||
|
@ -81,12 +83,52 @@ RgbaColor Pixmap::GetPixel(size_t x, size_t y) const {
|
||||||
case Format::RGB:
|
case Format::RGB:
|
||||||
return RgbaColor::From(pixel[0], pixel[1], pixel[2], 255);
|
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:
|
case Format::A:
|
||||||
return RgbaColor::From( 255, 255, 255, pixel[0]);
|
return RgbaColor::From( 255, 255, 255, pixel[0]);
|
||||||
}
|
}
|
||||||
ssassert(false, "Unexpected resource format");
|
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,
|
static std::shared_ptr<Pixmap> ReadPngIntoPixmap(png_struct *png_ptr, png_info *info_ptr,
|
||||||
bool flip) {
|
bool flip) {
|
||||||
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB, NULL);
|
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) {
|
bool Pixmap::WritePng(FILE *f, bool flip) {
|
||||||
int colorType;
|
int colorType;
|
||||||
|
bool bgr;
|
||||||
switch(format) {
|
switch(format) {
|
||||||
case Format::RGBA: colorType = PNG_COLOR_TYPE_RGBA; break;
|
case Format::RGBA: colorType = PNG_COLOR_TYPE_RGBA; bgr = false; break;
|
||||||
case Format::RGB: colorType = PNG_COLOR_TYPE_RGB; break;
|
case Format::BGRA: colorType = PNG_COLOR_TYPE_RGBA; bgr = true; break;
|
||||||
case Format::A: ssassert(false, "Unexpected pixmap format");
|
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;
|
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,
|
png_set_IHDR(png_ptr, info_ptr, width, height, 8,
|
||||||
colorType, PNG_INTERLACE_NONE,
|
colorType, PNG_INTERLACE_NONE,
|
||||||
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||||
|
if(bgr) png_set_bgr(png_ptr);
|
||||||
png_write_info(png_ptr, info_ptr);
|
png_write_info(png_ptr, info_ptr);
|
||||||
png_write_image(png_ptr, &rows[0]);
|
png_write_image(png_ptr, &rows[0]);
|
||||||
png_write_end(png_ptr, info_ptr);
|
png_write_end(png_ptr, info_ptr);
|
||||||
|
|
|
@ -24,7 +24,7 @@ std::shared_ptr<Pixmap> LoadPng(const std::string &name);
|
||||||
|
|
||||||
class Pixmap {
|
class Pixmap {
|
||||||
public:
|
public:
|
||||||
enum class Format { RGBA, RGB, A };
|
enum class Format { BGRA, RGBA, BGR, RGB, A };
|
||||||
|
|
||||||
Format format;
|
Format format;
|
||||||
size_t width;
|
size_t width;
|
||||||
|
@ -40,6 +40,8 @@ public:
|
||||||
|
|
||||||
size_t GetBytesPerPixel() const;
|
size_t GetBytesPerPixel() const;
|
||||||
RgbaColor GetPixel(size_t x, size_t y) const;
|
RgbaColor GetPixel(size_t x, size_t y) const;
|
||||||
|
|
||||||
|
void ConvertTo(Format newFormat);
|
||||||
};
|
};
|
||||||
|
|
||||||
class BitmapFont {
|
class BitmapFont {
|
||||||
|
|
Loading…
Reference in New Issue