diff --git a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m index 9aec9ff..863bf60 100644 --- a/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m +++ b/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m @@ -762,20 +762,21 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio if (!dataProvider) { return nil; } - CFDataRef dataRef = CGDataProviderCopyData(dataProvider); - if (!dataRef) { - return nil; - } // Check colorSpace is RGB/RGBA CGColorSpaceRef colorSpace = CGImageGetColorSpace(imageRef); BOOL isRGB = CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelRGB; + CFDataRef dataRef; 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 BOOL isRGB888 = isRGB && byteOrderNormal && alphaInfo == kCGImageAlphaNone && components == 3; BOOL isRGBA8888 = isRGB && byteOrderNormal && alphaInfo == kCGImageAlphaLast && components == 4; if (isRGB888 || isRGBA8888) { // If the input CGImage is already RGB888/RGBA8888 + dataRef = CGDataProviderCopyData(dataProvider); + if (!dataRef) { + return nil; + } rgba = (uint8_t *)CFDataGetBytePtr(dataRef); } else { // Convert all other cases to target color mode using vImage @@ -798,7 +799,6 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio convertor = vImageConverter_CreateWithCGImageFormat(&srcFormat, &destFormat, NULL, kvImageNoFlags, &error); if (error != kvImageNoError) { - CFRelease(dataRef); return nil; } @@ -806,7 +806,6 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio error = vImageBuffer_InitWithCGImage(&src, &srcFormat, nil, imageRef, kvImageNoFlags); if (error != kvImageNoError) { vImageConverter_Release(convertor); - CFRelease(dataRef); return nil; } @@ -814,21 +813,23 @@ static CGSize SDCalculateThumbnailSize(CGSize fullSize, BOOL preserveAspectRatio error = vImageBuffer_Init(&dest, height, width, destFormat.bitsPerPixel, kvImageNoFlags); if (error != kvImageNoError) { vImageConverter_Release(convertor); - CFRelease(dataRef); + free(src.data); return nil; } // Convert input color mode to RGB888/RGBA8888 error = vImageConvert_AnyToAny(convertor, &src, &dest, NULL, kvImageNoFlags); + + // Free the buffer + free(src.data); vImageConverter_Release(convertor); if (error != kvImageNoError) { - CFRelease(dataRef); + free(dest.data); return nil; } rgba = dest.data; // Converted buffer bytesPerRow = dest.rowBytes; // Converted bytePerRow - CFRelease(dataRef); // Use CFData to manage bytes for free, the same code path for error handling dataRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, rgba, bytesPerRow * height, kCFAllocatorDefault); }