From cab8cd977c4b4a5df88a4d513c6f817fcdcb8946 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Mon, 1 Feb 2021 20:27:13 +0800 Subject: [PATCH] Fix the issue when WebP Encoding grayscale image with only 1 channel, which cause the wrong encoded WebP image (each column repeats 3 times) --- SDWebImageWebPCoder/Classes/SDImageWebPCoder.m | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m index 5675170..76d56e5 100644 --- a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m +++ b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m @@ -736,6 +736,9 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio } size_t bytesPerRow = CGImageGetBytesPerRow(imageRef); + size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef); + size_t bitsPerPixel = CGImageGetBitsPerPixel(imageRef); + size_t components = bitsPerPixel / bitsPerComponent; CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask; CGBitmapInfo byteOrderInfo = bitmapInfo & kCGBitmapByteOrderMask; @@ -766,7 +769,9 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio uint8_t *rgba = NULL; // RGBA Buffer managed by CFData, don't call `free` on it, instead call `CFRelease` on `dataRef` // We could not assume that input CGImage's color mode is always RGB888/RGBA8888. Convert all other cases to target color mode using vImage - if (byteOrderNormal && ((alphaInfo == kCGImageAlphaNone) || (alphaInfo == kCGImageAlphaLast))) { + BOOL isRGB888 = byteOrderNormal && alphaInfo == kCGImageAlphaNone && components == 3; + BOOL isRGBA8888 = byteOrderNormal && alphaInfo == kCGImageAlphaLast && components == 4; + if (isRGB888 || isRGBA8888) { // If the input CGImage is already RGB888/RGBA8888 rgba = (uint8_t *)CFDataGetBytePtr(dataRef); } else { @@ -775,8 +780,8 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio vImage_Error error = kvImageNoError; vImage_CGImageFormat srcFormat = { - .bitsPerComponent = (uint32_t)CGImageGetBitsPerComponent(imageRef), - .bitsPerPixel = (uint32_t)CGImageGetBitsPerPixel(imageRef), + .bitsPerComponent = (uint32_t)bitsPerComponent, + .bitsPerPixel = (uint32_t)bitsPerPixel, .colorSpace = CGImageGetColorSpace(imageRef), .bitmapInfo = bitmapInfo };