Merge pull request #54 from SDWebImage/bugfix_encoding_leak
Fix the encoding leak when input CGImage is not RGBA8888 or RGB888
This commit is contained in:
commit
9d3c8fdc20
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue