| 443 | } |
| 444 | |
| 445 | CesiumUtility::IntrusivePointer<CesiumImage::ImageAsset> |
| 446 | VectorRasterizer::finalize() { |
| 447 | if (_finalized) { |
| 448 | return this->_imageAsset; |
| 449 | } |
| 450 | |
| 451 | this->_context.end(); |
| 452 | |
| 453 | // Blend2D writes in BGRA whereas ImageAsset is RGBA. |
| 454 | // We need to swap the channels to fix the values. |
| 455 | // Blend2D provides BLPixelConverter for these sorts of operations, which |
| 456 | // should be faster because it has SIMD support. But the current |
| 457 | // implementation seems to perform well as-is, likely thanks to the |
| 458 | // compiler's vectorization. |
| 459 | std::byte* pData = |
| 460 | this->_mipLevel == 0 |
| 461 | ? this->_imageAsset->pixelData.data() |
| 462 | : this->_imageAsset->pixelData.data() + |
| 463 | this->_imageAsset->mipPositions[this->_mipLevel].byteOffset; |
| 464 | const size_t size = |
| 465 | this->_mipLevel == 0 |
| 466 | ? this->_imageAsset->pixelData.size() |
| 467 | : this->_imageAsset->mipPositions[this->_mipLevel].byteSize; |
| 468 | for (size_t i = 0; i < size; i += 4) { |
| 469 | // We need to turn BGRA to RGBA, but this is little endian so it's really |
| 470 | // ARGB to ABGR. |
| 471 | uint32_t* pPixel = reinterpret_cast<uint32_t*>(pData + i); |
| 472 | const uint32_t pixel = *pPixel; |
| 473 | const uint32_t newPixel = |
| 474 | (pixel & 0xff000000) | ((pixel & 0x00ff0000) >> 16) | |
| 475 | (pixel & 0x0000ff00) | ((pixel & 0x000000ff) << 16); |
| 476 | *pPixel = newPixel; |
| 477 | } |
| 478 | |
| 479 | this->_finalized = true; |
| 480 | return this->_imageAsset; |
| 481 | } |
| 482 | |
| 483 | } // namespace CesiumVectorData |
no test coverage detected