From 9846f459936cfa660e3d6a91543d2588b0c9e915 Mon Sep 17 00:00:00 2001 From: luigi-rosso Date: Mon, 12 Aug 2024 23:49:33 +0000 Subject: [PATCH] Decode image data directly on iOS ...instead of rendering to a core graphics context and then copying the context's buffer. Seems like our alpha un-premultiply logic is no longer taking affect: https://github.com/rive-app/rive/blob/1c9233455851e5d346c4c97b01fdf74a5966017d/packages/runtime_ios/Source/Renderer/RenderContextManager.mm#L74-L82 Expected: Currently: Thread with details here: https://2dimensions.slack.com/archives/C06ER4J62BA/p1722438338690329 This fixes the issue by extracting the decoded PNG bytes directly (which are un-premultiplied). Diffs= 714b8894f Decode image data directly on iOS (#7820) Co-authored-by: Chris Dalton Co-authored-by: Luigi Rosso --- .rive_head | 2 +- Source/Renderer/PlatformCGImage.mm | 31 ++++-------------------------- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/.rive_head b/.rive_head index 27941d26..dadbd9f9 100644 --- a/.rive_head +++ b/.rive_head @@ -1 +1 @@ -55de8286c5ba680de950a3a0aac26e13bb890d6b +714b8894f37ab931a1df4b27d63c1e0991a97e3a diff --git a/Source/Renderer/PlatformCGImage.mm b/Source/Renderer/PlatformCGImage.mm index 35542590..50e6a2ee 100644 --- a/Source/Renderer/PlatformCGImage.mm +++ b/Source/Renderer/PlatformCGImage.mm @@ -49,40 +49,17 @@ bool PlatformCGImageDecode(const uint8_t* encodedBytes, break; } - // Now create a drawing context to produce RGBA pixels - - const size_t bitsPerComponent = 8; - CGBitmapInfo cgInfo = kCGBitmapByteOrder32Big; // rgba - if (isOpaque) - { - cgInfo |= kCGImageAlphaNoneSkipLast; - } - else - { - cgInfo |= kCGImageAlphaPremultipliedLast; // premul - } + CFDataRef dataRef = CGDataProviderCopyData(CGImageGetDataProvider(image)); + const UInt8* pixelData = CFDataGetBytePtr(dataRef); const size_t width = CGImageGetWidth(image); const size_t height = CGImageGetHeight(image); const size_t rowBytes = width * 4; // 4 bytes per pixel const size_t size = rowBytes * height; - std::vector pixels; - pixels.resize(size); - - AutoCF cs = CGColorSpaceCreateDeviceRGB(); - AutoCF cg = - CGBitmapContextCreate(pixels.data(), width, height, bitsPerComponent, rowBytes, cs, cgInfo); - if (!cg) - { - return false; - } - - CGContextSetBlendMode(cg, kCGBlendModeCopy); - CGContextDrawImage(cg, CGRectMake(0, 0, width, height), image); - platformImage->width = rive::castTo(width); platformImage->height = rive::castTo(height); platformImage->opaque = isOpaque; - platformImage->pixels = std::move(pixels); + platformImage->pixels = std::vector(pixelData, pixelData + size); + CFRelease(dataRef); return true; }