mirror of https://github.com/aseprite/aseprite.git
72 lines
1.9 KiB
C++
72 lines
1.9 KiB
C++
// Aseprite
|
|
// Copyright (c) 2024-2025 Igara Studio S.A.
|
|
//
|
|
// This program is distributed under the terms of
|
|
// the End-User License Agreement for Aseprite.
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "app/util/conversion_to_image.h"
|
|
|
|
#include "doc/pixel_format.h"
|
|
#include "os/surface.h"
|
|
|
|
#include <memory>
|
|
|
|
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 (a > 0 && 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.
|
|
void convert_surface_to_image(const os::Surface* surface,
|
|
int src_x,
|
|
int src_y,
|
|
int w,
|
|
int h,
|
|
ImageRef& image)
|
|
{
|
|
gfx::Rect srcBounds(src_x, src_y, w, h);
|
|
srcBounds = srcBounds.createIntersection(surface->getClipBounds());
|
|
if (srcBounds.isEmpty())
|
|
return;
|
|
|
|
src_x = srcBounds.x;
|
|
src_y = srcBounds.y;
|
|
w = srcBounds.w;
|
|
h = srcBounds.h;
|
|
|
|
image.reset(Image::create(PixelFormat::IMAGE_RGB, w, h));
|
|
|
|
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));
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace app
|