Fix the issue that iOS 17 indexed PNG workaround breaks the 16bit RGBA PNG

This commit is contained in:
DreamPiggy 2024-02-23 16:05:18 +08:00
parent b11493f764
commit a822ef6e3a
1 changed files with 6 additions and 1 deletions

View File

@ -48,6 +48,10 @@ static CGImageRef __nullable SDCGImageCreateMutableCopy(CGImageRef cg_nullable i
return newImage; return newImage;
} }
static inline BOOL SDCGImageIs8Bit(CGImageRef cg_nullable image) {
return CGImageGetBitsPerComponent(image) == 8;
}
static inline CGImageRef __nullable SDCGImageCreateCopy(CGImageRef cg_nullable image) { static inline CGImageRef __nullable SDCGImageCreateCopy(CGImageRef cg_nullable image) {
if (!image) return nil; if (!image) return nil;
return SDCGImageCreateMutableCopy(image, CGImageGetBitmapInfo(image)); return SDCGImageCreateMutableCopy(image, CGImageGetBitmapInfo(image));
@ -209,6 +213,7 @@ static BOOL SDImageIOPNGPluginBuggyNeedWorkaround(void) {
// See: #3605 FB13322459 // 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 // 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 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: // So, we do a hack workaround:
// 1. Decode a indexed color PNG in runtime // 1. Decode a indexed color PNG in runtime
// 2. If the bitmap is premultiplied alpha, then assume it's buggy // 2. If the bitmap is premultiplied alpha, then assume it's buggy
@ -527,7 +532,7 @@ static BOOL SDImageIOPNGPluginBuggyNeedWorkaround(void) {
// :) // :)
CFStringRef uttype = CGImageSourceGetType(source); CFStringRef uttype = CGImageSourceGetType(source);
SDImageFormat imageFormat = [NSData sd_imageFormatFromUTType:uttype]; SDImageFormat imageFormat = [NSData sd_imageFormatFromUTType:uttype];
if (imageFormat == SDImageFormatPNG && SDImageIOPNGPluginBuggyNeedWorkaround()) { if (imageFormat == SDImageFormatPNG && SDCGImageIs8Bit(imageRef) && SDImageIOPNGPluginBuggyNeedWorkaround()) {
CGImageRef newImageRef = SDImageIOPNGPluginBuggyCreateWorkaround(imageRef); CGImageRef newImageRef = SDImageIOPNGPluginBuggyCreateWorkaround(imageRef);
CGImageRelease(imageRef); CGImageRelease(imageRef);
imageRef = newImageRef; imageRef = newImageRef;