Skip to content

Commit

Permalink
Merge pull request #40 from SDWebImage/fix_copy_data_buffer_threads
Browse files Browse the repository at this point in the history
Fix ICC profile, buffer and AVIF encoding memory leak
  • Loading branch information
dreampiggy authored Aug 11, 2022
2 parents 99e6c22 + d5b9708 commit 27385c6
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 16 deletions.
4 changes: 2 additions & 2 deletions SDWebImageAVIFCoder/Classes/ColorSpace.m
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ void SDAVIFCalcColorSpaceMono(avifImage * avif, CGColorSpaceRef* ref, BOOL* shou
}
if(avif->icc.data && avif->icc.size) {
if(@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
CFDataRef iccData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, avif->icc.data, avif->icc.size,kCFAllocatorNull);
CFDataRef iccData = CFDataCreate(kCFAllocatorDefault, avif->icc.data, avif->icc.size);
*ref = CGColorSpaceCreateWithICCData(iccData);
CFRelease(iccData);
*shouldRelease = TRUE;
Expand Down Expand Up @@ -313,7 +313,7 @@ void SDAVIFCalcColorSpaceRGB(avifImage * avif, CGColorSpaceRef* ref, BOOL* shoul
}
if(avif->icc.data && avif->icc.size) {
if(@available(macOS 10.12, iOS 10.0, tvOS 10.0, *)) {
CFDataRef iccData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, avif->icc.data, avif->icc.size,kCFAllocatorNull);
CFDataRef iccData = CFDataCreate(kCFAllocatorDefault, avif->icc.data, avif->icc.size);
*ref = CGColorSpaceCreateWithICCData(iccData);
CFRelease(iccData);
*shouldRelease = TRUE;
Expand Down
10 changes: 5 additions & 5 deletions SDWebImageAVIFCoder/Classes/Conversion.m
Original file line number Diff line number Diff line change
Expand Up @@ -704,11 +704,11 @@ static CGImageRef CreateCGImage8(avifImage * avif) {
}

end_all:
free(resultBufferData);
free(argbBufferData);
free(dummyCbData);
free(dummyCrData);
free(scaledAlphaBufferData);
if (resultBufferData) free(resultBufferData);
if (argbBufferData) free(argbBufferData);
if (dummyCbData) free(dummyCbData);
if (dummyCrData) free(dummyCrData);
if (scaledAlphaBufferData) free(scaledAlphaBufferData);
return result;
}

Expand Down
20 changes: 11 additions & 9 deletions SDWebImageAVIFCoder/Classes/SDImageAVIFCoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,14 @@ - (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image format:(SDIm
vImage_Buffer src;
v_error = vImageBuffer_InitWithCGImage(&src, &srcFormat, NULL, imageRef, kvImageNoFlags);
if (v_error != kvImageNoError) {
vImageConverter_Release(convertor);
return nil;
}
vImage_Buffer dest;
vImageBuffer_Init(&dest, height, width, hasAlpha ? 32 : 24, kvImageNoFlags);
if (!dest.data) {
free(src.data);
v_error = vImageBuffer_Init(&dest, height, width, hasAlpha ? 32 : 24, kvImageNoFlags);
if (v_error != kvImageNoError) {
if (src.data) free(src.data);
vImageConverter_Release(convertor);
return nil;
}

Expand All @@ -224,15 +226,15 @@ - (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image format:(SDIm
free(src.data);
vImageConverter_Release(convertor);
if (v_error != kvImageNoError) {
free(dest.data);
if(dest.data) free(dest.data);
return nil;
}

avifPixelFormat avifFormat = AVIF_PIXEL_FORMAT_YUV444;

avifImage *avif = avifImageCreate((int)width, (int)height, 8, avifFormat);
if (!avif) {
free(dest.data);
if (dest.data) free(dest.data);
return nil;
}
avifRGBImage rgb = {
Expand All @@ -245,7 +247,6 @@ - (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image format:(SDIm
};
avifImageRGBToYUV(avif, &rgb);
free(dest.data);
dest.data = NULL;

NSData *iccProfile = (__bridge_transfer NSData *)CGColorSpaceCopyICCProfile([SDImageCoderHelper colorSpaceGetDeviceRGB]);

Expand All @@ -264,14 +265,15 @@ - (nullable NSData *)encodedDataWithImage:(nullable UIImage *)image format:(SDIm
encoder->maxThreads = 2;
avifResult result = avifEncoderWrite(encoder, avif, &raw);

avifImageDestroy(avif);
avifEncoderDestroy(encoder);
if (result != AVIF_RESULT_OK) {
avifEncoderDestroy(encoder);
if (raw.data) avifRWDataFree(&raw);
return nil;
}

NSData *imageData = [NSData dataWithBytes:raw.data length:raw.size];
free(raw.data);
avifEncoderDestroy(encoder);
avifRWDataFree(&raw);

return imageData;
}
Expand Down

0 comments on commit 27385c6

Please sign in to comment.