| 402 | } |
| 403 | |
| 404 | void CairoImage::loadFromMemory(const char* const rdata, const Size<uint>& s, const ImageFormat fmt) noexcept |
| 405 | { |
| 406 | const cairo_format_t cairoformat = asCairoImageFormat(fmt); |
| 407 | DISTRHO_SAFE_ASSERT_RETURN(cairoformat != CAIRO_FORMAT_INVALID,); |
| 408 | |
| 409 | const int width = static_cast<int>(s.getWidth()); |
| 410 | const int height = static_cast<int>(s.getHeight()); |
| 411 | const int stride = cairo_format_stride_for_width(cairoformat, width); |
| 412 | |
| 413 | uchar* const newdata = static_cast<uchar*>(std::malloc(static_cast<size_t>(width * height * stride * 4))); |
| 414 | DISTRHO_SAFE_ASSERT_RETURN(newdata != nullptr,); |
| 415 | |
| 416 | cairo_surface_t* const newsurface = cairo_image_surface_create_for_data(newdata, cairoformat, width, height, stride); |
| 417 | DISTRHO_SAFE_ASSERT_RETURN(newsurface != nullptr,); |
| 418 | DISTRHO_SAFE_ASSERT_RETURN(static_cast<int>(s.getWidth()) == cairo_image_surface_get_width(newsurface),); |
| 419 | DISTRHO_SAFE_ASSERT_RETURN(static_cast<int>(s.getHeight()) == cairo_image_surface_get_height(newsurface),); |
| 420 | |
| 421 | cairo_surface_destroy(surface); |
| 422 | |
| 423 | if (datarefcount != nullptr && --(*datarefcount) == 0) |
| 424 | std::free(surfacedata); |
| 425 | else |
| 426 | datarefcount = static_cast<int*>(std::malloc(sizeof(int))); |
| 427 | |
| 428 | surface = newsurface; |
| 429 | surfacedata = newdata; |
| 430 | *datarefcount = 1; |
| 431 | |
| 432 | const uchar* const urdata = reinterpret_cast<const uchar*>(rdata); |
| 433 | |
| 434 | switch (fmt) |
| 435 | { |
| 436 | case kImageFormatNull: |
| 437 | break; |
| 438 | case kImageFormatGrayscale: |
| 439 | // Grayscale to CAIRO_FORMAT_RGB24 |
| 440 | for (int h = 0; h < height; ++h) |
| 441 | { |
| 442 | for (int w = 0; w < width; ++w) |
| 443 | { |
| 444 | newdata[h*width*4+w*4+0] = urdata[h*width+w]; |
| 445 | newdata[h*width*4+w*4+1] = urdata[h*width+w]; |
| 446 | newdata[h*width*4+w*4+2] = urdata[h*width+w]; |
| 447 | newdata[h*width*4+w*4+3] = 0; |
| 448 | } |
| 449 | } |
| 450 | break; |
| 451 | case kImageFormatBGR: |
| 452 | // BGR8 to CAIRO_FORMAT_RGB24 |
| 453 | for (int h = 0; h < height; ++h) |
| 454 | { |
| 455 | for (int w = 0; w < width; ++w) |
| 456 | { |
| 457 | newdata[h*width*4+w*4+0] = urdata[h*width*3+w*3+0]; |
| 458 | newdata[h*width*4+w*4+1] = urdata[h*width*3+w*3+1]; |
| 459 | newdata[h*width*4+w*4+2] = urdata[h*width*3+w*3+2]; |
| 460 | newdata[h*width*4+w*4+3] = 0; |
| 461 | } |
no test coverage detected