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.
This commit is contained in:
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
Block a user