|
|
@@ -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); |
|
|
@@ -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: |
|
|
@@ -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; |
|
|
|
} |
|
|
|
|
|
|
|