Skip to content

Commit

Permalink
Correct CairoImage::loadFromMemory
Browse files Browse the repository at this point in the history
Signed-off-by: falkTX <[email protected]>
  • Loading branch information
falkTX committed Oct 15, 2023
1 parent a58498f commit 49cb3e8
Showing 1 changed file with 36 additions and 21 deletions.
57 changes: 36 additions & 21 deletions dgl/src/Cairo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,13 @@ CairoImage::~CairoImage()
void CairoImage::loadFromMemory(const char* const rdata, const Size<uint>& s, const ImageFormat fmt) noexcept
{
const cairo_format_t cairoformat = asCairoImageFormat(fmt);
DISTRHO_SAFE_ASSERT_RETURN(cairoformat != CAIRO_FORMAT_INVALID,);

const int width = static_cast<int>(s.getWidth());
const int height = static_cast<int>(s.getHeight());
const int stride = cairo_format_stride_for_width(cairoformat, width);

uchar* const newdata = (uchar*)std::malloc(static_cast<size_t>(width * height * stride * 4));
uchar* const newdata = static_cast<uchar*>(std::malloc(static_cast<size_t>(width * height * stride * 4)));
DISTRHO_SAFE_ASSERT_RETURN(newdata != nullptr,);

cairo_surface_t* const newsurface = cairo_image_surface_create_for_data(newdata, cairoformat, width, height, stride);
Expand All @@ -392,12 +394,14 @@ void CairoImage::loadFromMemory(const char* const rdata, const Size<uint>& s, co
if (datarefcount != nullptr && --(*datarefcount) == 0)
std::free(surfacedata);
else
datarefcount = (int*)malloc(sizeof(*datarefcount));
datarefcount = static_cast<int*>(std::malloc(sizeof(int)));

surface = newsurface;
surfacedata = newdata;
*datarefcount = 1;

const uchar* const urdata = reinterpret_cast<const uchar*>(rdata);

switch (fmt)
{
case kImageFormatNull:
Expand All @@ -412,42 +416,53 @@ void CairoImage::loadFromMemory(const char* const rdata, const Size<uint>& s, co
{
for (int w = 0; w < width; ++w)
{
newdata[h*width*4+w*4+0] = static_cast<uchar>(rdata[h*width*3+w*3+0]);
newdata[h*width*4+w*4+1] = static_cast<uchar>(rdata[h*width*3+w*3+1]);
newdata[h*width*4+w*4+2] = static_cast<uchar>(rdata[h*width*3+w*3+2]);
newdata[h*width*4+w*4+0] = urdata[h*width*3+w*3+0];
newdata[h*width*4+w*4+1] = urdata[h*width*3+w*3+1];
newdata[h*width*4+w*4+2] = urdata[h*width*3+w*3+2];
newdata[h*width*4+w*4+3] = 0;
}
}
break;
case kImageFormatBGRA:
// BGRA8 to CAIRO_FORMAT_ARGB32
// FIXME something is wrong here...
for (int h = 0, t; h < height; ++h)
for (int h = 0; h < height; ++h)
{
for (int w = 0; w < width; ++w)
{
if ((t = rdata[h*width*4+w*4+3]) != 0)
{
newdata[h*width*4+w*4+0] = static_cast<uchar>(rdata[h*width*4+w*4+0]);
newdata[h*width*4+w*4+1] = static_cast<uchar>(rdata[h*width*4+w*4+1]);
newdata[h*width*4+w*4+2] = static_cast<uchar>(rdata[h*width*4+w*4+2]);
newdata[h*width*4+w*4+3] = static_cast<uchar>(t);
}
else
{
// make all pixels zero, cairo does not render full transparency otherwise
memset(&newdata[h*width*4+w*4], 0, 4);
}
const uchar a = urdata[h*width*4+w*4+3];
newdata[h*width*4+w*4+0] = (urdata[h*width*4+w*4+0] * a) >> 8;
newdata[h*width*4+w*4+1] = (urdata[h*width*4+w*4+1] * a) >> 8;
newdata[h*width*4+w*4+2] = (urdata[h*width*4+w*4+2] * a) >> 8;
newdata[h*width*4+w*4+3] = a;
}
}
break;
case kImageFormatRGB:
// RGB8 to CAIRO_FORMAT_RGB24
// TODO
for (int h = 0; h < height; ++h)
{
for (int w = 0; w < width; ++w)
{
newdata[h*width*4+w*4+0] = urdata[h*width*3+w*3+2];
newdata[h*width*4+w*4+1] = urdata[h*width*3+w*3+1];
newdata[h*width*4+w*4+2] = urdata[h*width*3+w*3+0];
newdata[h*width*4+w*4+3] = 0;
}
}
break;
case kImageFormatRGBA:
// RGBA8 to CAIRO_FORMAT_ARGB32
// TODO
for (int h = 0; h < height; ++h)
{
for (int w = 0; w < width; ++w)
{
const uchar a = urdata[h*width*4+w*4+3];
newdata[h*width*4+w*4+0] = (urdata[h*width*4+w*4+2] * a) >> 8;
newdata[h*width*4+w*4+1] = (urdata[h*width*4+w*4+1] * a) >> 8;
newdata[h*width*4+w*4+2] = (urdata[h*width*4+w*4+0] * a) >> 8;
newdata[h*width*4+w*4+3] = a;
}
}
break;
}

Expand Down

0 comments on commit 49cb3e8

Please sign in to comment.