mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 13:21:34 +00:00
Fix function to use surface format data
In Windows and macOs the underlying surfaces have different color components order without this fix images are displayed with incorrect colors
This commit is contained in:
parent
0bf62c4545
commit
da60d14b11
@ -20,6 +20,24 @@ namespace app {
|
||||
|
||||
using namespace doc;
|
||||
|
||||
uint32_t convert_color_to_image(
|
||||
gfx::Color c,
|
||||
const os::SurfaceFormatData* fd)
|
||||
{
|
||||
uint8_t r = ((c & fd->redMask) >> fd->redShift);
|
||||
uint8_t g = ((c & fd->greenMask) >> fd->greenShift);
|
||||
uint8_t b = ((c & fd->blueMask) >> fd->blueShift);
|
||||
uint8_t a = ((c & fd->alphaMask) >> fd->alphaShift);
|
||||
|
||||
if (fd->pixelAlpha == os::PixelAlpha::kPremultiplied) {
|
||||
r = r * 255 / a;
|
||||
g = g * 255 / a;
|
||||
b = b * 255 / a;
|
||||
}
|
||||
|
||||
return rgba(r, g, b, a);
|
||||
}
|
||||
|
||||
// TODO: This implementation has a lot of room for improvement, I made the bare
|
||||
// minimum to make it work. Right now it only supports converting RGBA surfaces,
|
||||
// other kind of surfaces won't be converted to an image as expected.
|
||||
@ -41,12 +59,15 @@ void convert_surface_to_image(
|
||||
|
||||
image.reset(Image::create(PixelFormat::IMAGE_RGB, w, h));
|
||||
|
||||
for (int v=0; v<h; ++v, ++src_y) {
|
||||
uint8_t* src_address = surface->getData(0, v);
|
||||
uint8_t* dst_address = image->getPixelAddress(src_x, src_y);
|
||||
std::copy(src_address,
|
||||
src_address + RgbTraits::bytes_per_pixel * w,
|
||||
dst_address);
|
||||
os::SurfaceFormatData fd;
|
||||
surface->getFormat(&fd);
|
||||
|
||||
for (int v=0; v<h; ++v) {
|
||||
for (int u=0; u<w; ++u) {
|
||||
uint32_t* c = (uint32_t*)(surface->getData(u, v));
|
||||
image->putPixel(src_x + u,
|
||||
src_y + v, convert_color_to_image(*c, &fd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,14 @@
|
||||
namespace app {
|
||||
namespace util {
|
||||
|
||||
static WEBP_CSP_MODE colorMode()
|
||||
{
|
||||
auto surface = os::instance()->makeSurface(1, 1);
|
||||
os::SurfaceFormatData fd;
|
||||
surface->getFormat(&fd);
|
||||
return (fd.redShift == 0 ? MODE_RGBA : MODE_BGRA);
|
||||
}
|
||||
|
||||
os::SurfaceRef decode_webp(const uint8_t* buf, uint32_t len)
|
||||
{
|
||||
// I've considered using the FileFormatsManager here but we don't have a file
|
||||
@ -26,7 +34,7 @@ os::SurfaceRef decode_webp(const uint8_t* buf, uint32_t len)
|
||||
|
||||
WebPAnimDecoderOptions dec_options;
|
||||
WebPAnimDecoderOptionsInit(&dec_options);
|
||||
dec_options.color_mode = MODE_RGBA;
|
||||
dec_options.color_mode = colorMode();
|
||||
|
||||
WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options);
|
||||
if (dec == nullptr) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user