From dcca72484f068e2775b2a051457f528ee11c9741 Mon Sep 17 00:00:00 2001 From: reuk Date: Tue, 3 Dec 2024 19:41:43 +0000 Subject: [PATCH] Image: Update return type of getPixelData to avoid dangling pointers --- modules/juce_graphics/images/juce_Image.cpp | 11 +++++------ modules/juce_graphics/images/juce_Image.h | 2 +- .../native/juce_CoreGraphicsContext_mac.mm | 8 ++++---- .../native/juce_Direct2DGraphicsContext_windows.cpp | 8 ++++---- .../native/juce_Direct2DImage_windows.cpp | 6 +++--- .../juce_gui_basics/native/juce_Windowing_windows.cpp | 2 +- .../native/juce_XWindowSystem_linux.cpp | 2 +- .../juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp | 4 ++-- modules/juce_opengl/opengl/juce_OpenGLImage.cpp | 2 +- 9 files changed, 22 insertions(+), 23 deletions(-) diff --git a/modules/juce_graphics/images/juce_Image.cpp b/modules/juce_graphics/images/juce_Image.cpp index 277ebd6bf0..fa4c38d42f 100644 --- a/modules/juce_graphics/images/juce_Image.cpp +++ b/modules/juce_graphics/images/juce_Image.cpp @@ -103,15 +103,14 @@ public: { jassert (getReferenceCount() > 0); // (This method can't be used on an unowned pointer, as it will end up self-deleting) auto type = createType(); - - Image newImage (type->create (pixelFormat, area.getWidth(), area.getHeight(), pixelFormat != Image::RGB)); + auto result = type->create (pixelFormat, area.getWidth(), area.getHeight(), pixelFormat != Image::RGB); { - Graphics g (newImage); + Graphics g { Image { result } }; g.drawImageAt (Image (*this), 0, 0); } - return *newImage.getPixelData(); + return result; } std::unique_ptr createType() const override { return sourceImage->createType(); } @@ -735,7 +734,7 @@ void Image::moveImageSection (int dx, int dy, void ImageEffects::applyGaussianBlurEffect (float radius, const Image& input, Image& result) { - auto* image = input.getPixelData(); + auto image = input.getPixelData(); if (image == nullptr) { @@ -806,7 +805,7 @@ static void blurSingleChannelImage (Image& image, int radius) void ImageEffects::applySingleChannelBoxBlurEffect (int radius, const Image& input, Image& result) { - auto* image = input.getPixelData(); + auto image = input.getPixelData(); if (image == nullptr) { diff --git a/modules/juce_graphics/images/juce_Image.h b/modules/juce_graphics/images/juce_Image.h index b0d322a558..7875504664 100644 --- a/modules/juce_graphics/images/juce_Image.h +++ b/modules/juce_graphics/images/juce_Image.h @@ -418,7 +418,7 @@ public: //============================================================================== /** @internal */ - ImagePixelData* getPixelData() const noexcept { return image.get(); } + ReferenceCountedObjectPtr getPixelData() const noexcept { return image; } /** @internal */ explicit Image (ReferenceCountedObjectPtr) noexcept; diff --git a/modules/juce_graphics/native/juce_CoreGraphicsContext_mac.mm b/modules/juce_graphics/native/juce_CoreGraphicsContext_mac.mm index aa18f90ac1..6c7022c349 100644 --- a/modules/juce_graphics/native/juce_CoreGraphicsContext_mac.mm +++ b/modules/juce_graphics/native/juce_CoreGraphicsContext_mac.mm @@ -104,7 +104,7 @@ public: //============================================================================== static CGImageRef getCachedImageRef (const Image& juceImage, CGColorSpaceRef colourSpace) { - auto cgim = dynamic_cast (juceImage.getPixelData()); + auto cgim = dynamic_cast (juceImage.getPixelData().get()); if (cgim != nullptr && cgim->cachedImageRef != nullptr) return CGImageRetain (cgim->cachedImageRef.get()); @@ -123,7 +123,7 @@ public: const auto provider = [&] { - if (auto* cgim = dynamic_cast (juceImage.getPixelData())) + if (auto* cgim = dynamic_cast (juceImage.getPixelData().get())) { return detail::DataProviderPtr { CGDataProviderCreateWithData (new ImageDataContainer::Ptr (cgim->imageData), srcData.data, @@ -1033,7 +1033,7 @@ Image juce_loadWithCoreImage (InputStream& input) (int) CGImageGetHeight (loadedImage), hasAlphaChan)); - auto cgImage = dynamic_cast (image.getPixelData()); + auto cgImage = dynamic_cast (image.getPixelData().get()); jassert (cgImage != nullptr); // if USE_COREGRAPHICS_RENDERING is set, the CoreGraphicsPixelData class should have been used. CGContextDrawImage (cgImage->context.get(), convertToCGRect (image.getBounds()), loadedImage); @@ -1070,7 +1070,7 @@ CGImageRef juce_createCoreGraphicsImage (const Image& juceImage, CGColorSpaceRef CGContextRef juce_getImageContext (const Image& image) { - if (auto cgi = dynamic_cast (image.getPixelData())) + if (auto cgi = dynamic_cast (image.getPixelData().get())) return cgi->context.get(); jassertfalse; diff --git a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp index 65e007546a..ec5dadb0a9 100644 --- a/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DGraphicsContext_windows.cpp @@ -340,7 +340,7 @@ public: const auto d2d1Bitmap = [&] { - if (auto direct2DPixelData = dynamic_cast (fillType.image.getPixelData())) + if (auto direct2DPixelData = dynamic_cast (fillType.image.getPixelData().get())) if (const auto page = direct2DPixelData->getFirstPageForContext (context)) if (page->GetPixelFormat().format == DXGI_FORMAT_B8G8R8A8_UNORM) return page; @@ -1170,7 +1170,7 @@ void Direct2DGraphicsContext::clipToImageAlpha (const Image& sourceImage, const // Is this a Direct2D image already? ComSmartPtr d2d1Bitmap; - if (auto direct2DPixelData = dynamic_cast (sourceImage.getPixelData())) + if (auto direct2DPixelData = dynamic_cast (sourceImage.getPixelData().get())) d2d1Bitmap = direct2DPixelData->getFirstPageForContext (deviceContext); if (! d2d1Bitmap) @@ -1454,7 +1454,7 @@ void Direct2DGraphicsContext::drawImage (const Image& imageIn, const AffineTrans const auto imageTransform = currentState->currentTransform.getTransformWith (transform); - if (auto* subsectionPixelData = dynamic_cast (image.getPixelData())) + if (auto* subsectionPixelData = dynamic_cast (image.getPixelData().get())) { if (auto direct2DPixelData = dynamic_cast (subsectionPixelData->getSourcePixelData().get())) { @@ -1462,7 +1462,7 @@ void Direct2DGraphicsContext::drawImage (const Image& imageIn, const AffineTrans imageClipArea = subsectionPixelData->getSubsection(); } } - else if (auto direct2DPixelData = dynamic_cast (image.getPixelData())) + else if (auto direct2DPixelData = dynamic_cast (image.getPixelData().get())) { nativeBitmap = direct2DPixelData; imageClipArea = { direct2DPixelData->width, direct2DPixelData->height }; diff --git a/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp b/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp index 19e9326191..878862e4da 100644 --- a/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp +++ b/modules/juce_graphics/native/juce_Direct2DImage_windows.cpp @@ -524,7 +524,7 @@ void Direct2DPixelData::initialiseBitmapData (Image::BitmapData& bitmap, void Direct2DPixelData::applyGaussianBlurEffect (float radius, Image& result) { // The result must be a separate image! - jassert (result.getPixelData() != this); + jassert (result.getPixelData().get() != this); const auto adapter = directX->adapters.getDefaultAdapter(); @@ -571,7 +571,7 @@ void Direct2DPixelData::applyGaussianBlurEffect (float radius, Image& result) void Direct2DPixelData::applySingleChannelBoxBlurEffect (int radius, Image& result) { // The result must be a separate image! - jassert (result.getPixelData() != this); + jassert (result.getPixelData().get() != this); const auto adapter = directX->adapters.getDefaultAdapter(); @@ -778,7 +778,7 @@ public: const auto maxPageBounds = [&] { - if (auto* data = dynamic_cast (d2dImage.getPixelData())) + if (auto* data = dynamic_cast (d2dImage.getPixelData().get())) if (auto pages = data->getPagesForContext (contextToUse); ! pages.empty()) return pages.front().getBounds(); diff --git a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp index bad69a372b..a9f6ab7f86 100644 --- a/modules/juce_gui_basics/native/juce_Windowing_windows.cpp +++ b/modules/juce_gui_basics/native/juce_Windowing_windows.cpp @@ -4977,7 +4977,7 @@ private: peer.handlePaint (*context); } - auto* image = static_cast (offscreenImage.getPixelData()); + auto* image = static_cast (offscreenImage.getPixelData().get()); if (perPixelTransparent) { diff --git a/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp b/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp index 8e89116f87..6d7ed6e783 100644 --- a/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp +++ b/modules/juce_gui_basics/native/juce_XWindowSystem_linux.cpp @@ -2207,7 +2207,7 @@ void XWindowSystem::blitToWindow (::Window windowH, Image image, Rectangle { jassert (windowH != 0); - auto* xbitmap = static_cast (image.getPixelData()); + auto* xbitmap = static_cast (image.getPixelData().get()); xbitmap->blitToWindow (windowH, destinationRect.getX(), destinationRect.getY(), diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index a55bdd592f..e767a2d991 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -73,7 +73,7 @@ struct CachedImageList final : public ReferenceCountedObject, TextureInfo getTextureFor (const Image& image) { auto pixelData = image.getPixelData(); - auto* c = findCachedImage (pixelData); + auto* c = findCachedImage (pixelData.get()); if (c == nullptr) { @@ -89,7 +89,7 @@ struct CachedImageList final : public ReferenceCountedObject, return t; } - c = images.add (new CachedImage (*this, pixelData)); + c = images.add (new CachedImage (*this, pixelData.get())); totalSize += c->imageSize; while (totalSize > maxCacheSize && images.size() > 1 && totalSize > 0) diff --git a/modules/juce_opengl/opengl/juce_OpenGLImage.cpp b/modules/juce_opengl/opengl/juce_OpenGLImage.cpp index 5bdc788a2f..82cccd38e9 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLImage.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLImage.cpp @@ -217,7 +217,7 @@ ImagePixelData::Ptr OpenGLImageType::create (Image::PixelFormat, int width, int OpenGLFrameBuffer* OpenGLImageType::getFrameBufferFrom (const Image& image) { - if (OpenGLFrameBufferImage* const glImage = dynamic_cast (image.getPixelData())) + if (OpenGLFrameBufferImage* const glImage = dynamic_cast (image.getPixelData().get())) return &(glImage->frameBuffer); return nullptr;