From 3e553d1efe2183cb67256c64f9142be27d9c108a Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Fri, 23 Feb 2024 16:05:18 +0800 Subject: [PATCH] Fix the issue that iOS 17 indexed PNG workaround breaks the 16bit RGBA PNG --- SDWebImage/Core/SDImageIOAnimatedCoder.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SDWebImage/Core/SDImageIOAnimatedCoder.m b/SDWebImage/Core/SDImageIOAnimatedCoder.m index dca44f18..b529efbc 100644 --- a/SDWebImage/Core/SDImageIOAnimatedCoder.m +++ b/SDWebImage/Core/SDImageIOAnimatedCoder.m @@ -48,6 +48,10 @@ static CGImageRef __nullable SDCGImageCreateMutableCopy(CGImageRef cg_nullable i return newImage; } +static inline BOOL SDCGImageIs8Bit(CGImageRef cg_nullable image) { + return CGImageGetBitsPerComponent(image) == 8; +} + static inline CGImageRef __nullable SDCGImageCreateCopy(CGImageRef cg_nullable image) { if (!image) return nil; return SDCGImageCreateMutableCopy(image, CGImageGetBitmapInfo(image)); @@ -209,6 +213,7 @@ static BOOL SDImageIOPNGPluginBuggyNeedWorkaround(void) { // See: #3605 FB13322459 // ImageIO on iOS 17 (17.0~17.2), there is one serious problem on ImageIO PNG plugin. The decode result for indexed color PNG use the wrong CGImageAlphaInfo // The returned CGImageAlphaInfo is alpha last, but the actual bitmap data is premultiplied alpha last, which cause many runtime render bug. + // The bug only exists on 8-bits indexed color, not about 16-bits // So, we do a hack workaround: // 1. Decode a indexed color PNG in runtime // 2. If the bitmap is premultiplied alpha, then assume it's buggy @@ -527,7 +532,7 @@ static BOOL SDImageIOPNGPluginBuggyNeedWorkaround(void) { // :) CFStringRef uttype = CGImageSourceGetType(source); SDImageFormat imageFormat = [NSData sd_imageFormatFromUTType:uttype]; - if (imageFormat == SDImageFormatPNG && SDImageIOPNGPluginBuggyNeedWorkaround()) { + if (imageFormat == SDImageFormatPNG && SDCGImageIs8Bit(imageRef) && SDImageIOPNGPluginBuggyNeedWorkaround()) { CGImageRef newImageRef = SDImageIOPNGPluginBuggyCreateWorkaround(imageRef); CGImageRelease(imageRef); imageRef = newImageRef;