MCPcopy Create free account
hub / github.com/SFML/SFML / copy

Method copy

src/SFML/Graphics/Image.cpp:588–672  ·  view source on GitHub ↗

///////////////////////////////////////////////////////

Source from the content-addressed store, hash-verified

586
587////////////////////////////////////////////////////////////
588bool Image::copy(const Image& source, Vector2u dest, const IntRect& sourceRect, bool applyAlpha)
589{
590 // Make sure that both images are valid
591 if (source.m_size.x == 0 || source.m_size.y == 0 || m_size.x == 0 || m_size.y == 0)
592 return false;
593
594 // Make sure the sourceRect components are non-negative before casting them to unsigned values
595 if (sourceRect.position.x < 0 || sourceRect.position.y < 0 || sourceRect.size.x < 0 || sourceRect.size.y < 0)
596 return false;
597
598 Rect<unsigned int> srcRect(sourceRect);
599
600 // Use the whole source image as srcRect if the provided source rectangle is empty
601 if (srcRect.size.x == 0 || srcRect.size.y == 0)
602 {
603 srcRect = Rect<unsigned int>({0, 0}, source.m_size);
604 }
605 // Otherwise make sure the provided source rectangle fits into the source image
606 else
607 {
608 // Checking the bottom right corner is enough because
609 // left and top are non-negative and width and height are positive.
610 if (source.m_size.x < srcRect.position.x + srcRect.size.x || source.m_size.y < srcRect.position.y + srcRect.size.y)
611 return false;
612 }
613
614 // Make sure the destination position is within this image bounds
615 if (m_size.x <= dest.x || m_size.y <= dest.y)
616 return false;
617
618 // Then find the valid size of the destination rectangle
619 const Vector2u dstSize(std::min(m_size.x - dest.x, srcRect.size.x), std::min(m_size.y - dest.y, srcRect.size.y));
620
621 // Precompute as much as possible
622 const std::size_t pitch = static_cast<std::size_t>(dstSize.x) * 4;
623 const unsigned int srcStride = source.m_size.x * 4;
624 const unsigned int dstStride = m_size.x * 4;
625
626 const std::uint8_t* srcPixels = source.m_pixels.data() + (srcRect.position.x + srcRect.position.y * source.m_size.x) * 4;
627 std::uint8_t* dstPixels = m_pixels.data() + (dest.x + dest.y * m_size.x) * 4;
628
629 // Copy the pixels
630 if (applyAlpha)
631 {
632 // Interpolation using alpha values, pixel by pixel (slower)
633 for (unsigned int i = 0; i < dstSize.y; ++i)
634 {
635 for (unsigned int j = 0; j < dstSize.x; ++j)
636 {
637 // Get a direct pointer to the components of the current pixel
638 const std::uint8_t* src = srcPixels + j * 4;
639 std::uint8_t* dst = dstPixels + j * 4;
640
641 // Interpolate RGBA components using the alpha values of the destination and source pixels
642 const std::uint8_t srcAlpha = src[3];
643 const std::uint8_t dstAlpha = dst[3];
644 const auto outAlpha = static_cast<std::uint8_t>(srcAlpha + dstAlpha - srcAlpha * dstAlpha / 255);
645

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected