From fac703140c73a7769305fafdbafb3a5b62f6629d Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Sat, 19 Jan 2019 17:59:59 +0800 Subject: [PATCH 1/4] Fix potential memory leaks for ICCP && optimize ICCP handler --- SDWebImage/SDWebImageWebPCoder.m | 56 +++++++++++++++++++------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/SDWebImage/SDWebImageWebPCoder.m b/SDWebImage/SDWebImageWebPCoder.m index bb39adf5..ab54df98 100644 --- a/SDWebImage/SDWebImageWebPCoder.m +++ b/SDWebImage/SDWebImageWebPCoder.m @@ -25,6 +25,30 @@ #endif #import +// Create and return the correct colorspace by checking the ICC Profile +static CGColorSpaceRef SDColorSpaceCreateWithDemuxer(WebPDemuxer *demuxer) { + // WebP contains ICC Profile should use the desired colorspace, instead of default device colorspace + // See: https://developers.google.com/speed/webp/docs/riff_container#color_profile + + WebPChunkIterator chunk_iter; + CGColorSpaceRef colorSpaceRef = NULL; + + int result = WebPDemuxGetChunk(demuxer, "ICCP", 1, &chunk_iter); + if (result) { + NSData *profileData = [NSData dataWithBytesNoCopy:(void *)chunk_iter.chunk.bytes length:chunk_iter.chunk.size freeWhenDone:NO]; + colorSpaceRef = CGColorSpaceCreateWithICCProfile((__bridge CFDataRef)profileData); + } + + WebPDemuxReleaseChunkIterator(&chunk_iter); + + if (!colorSpaceRef) { + colorSpaceRef = SDCGColorSpaceGetDeviceRGB(); + CGColorSpaceRetain(colorSpaceRef); + } + + return colorSpaceRef; +} + @implementation SDWebImageWebPCoder { WebPIDecoder *_idec; } @@ -87,7 +111,15 @@ WebPDemuxDelete(demuxer); return nil; } - CGColorSpaceRef colorSpace = [self sd_colorSpaceWithDemuxer:demuxer]; + + CGColorSpaceRef colorSpace = NULL; + // ICC profile + if (flags & ICCP_FLAG) { + colorSpace = SDColorSpaceCreateWithDemuxer(demuxer); + } else { + colorSpace = SDCGColorSpaceGetDeviceRGB(); + CGColorSpaceRetain(colorSpace); + } if (!(flags & ANIMATION_FLAG)) { // for static single webp image @@ -333,28 +365,6 @@ return image; } -// Create and return the correct colorspace by checking the ICC Profile -- (nonnull CGColorSpaceRef)sd_colorSpaceWithDemuxer:(nonnull WebPDemuxer *)demuxer CF_RETURNS_RETAINED { - // WebP contains ICC Profile should use the desired colorspace, instead of default device colorspace - // See: https://developers.google.com/speed/webp/docs/riff_container#color_profile - - WebPChunkIterator chunk_iter; - CGColorSpaceRef colorSpaceRef = NULL; - - int result = WebPDemuxGetChunk(demuxer, "ICCP", 1, &chunk_iter); - if (result) { - NSData *profileData = [NSData dataWithBytes:chunk_iter.chunk.bytes length:chunk_iter.chunk.size]; - colorSpaceRef = CGColorSpaceCreateWithICCProfile((__bridge CFDataRef)profileData); - } - - if (!colorSpaceRef) { - colorSpaceRef = SDCGColorSpaceGetDeviceRGB(); - CGColorSpaceRetain(colorSpaceRef); - } - - return colorSpaceRef; -} - #pragma mark - Encode - (BOOL)canEncodeToFormat:(SDImageFormat)format { return (format == SDImageFormatWebP); From 4c006ad573cd700c2a37f2ed0961e9536b1a0933 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Sat, 19 Jan 2019 20:46:05 +0800 Subject: [PATCH 2/4] Adjust indention, seems come from buggy Xcode --- SDWebImage/SDWebImageWebPCoder.m | 58 ++++++++++++++++---------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/SDWebImage/SDWebImageWebPCoder.m b/SDWebImage/SDWebImageWebPCoder.m index ab54df98..b48d27a4 100644 --- a/SDWebImage/SDWebImageWebPCoder.m +++ b/SDWebImage/SDWebImageWebPCoder.m @@ -27,26 +27,26 @@ // Create and return the correct colorspace by checking the ICC Profile static CGColorSpaceRef SDColorSpaceCreateWithDemuxer(WebPDemuxer *demuxer) { - // WebP contains ICC Profile should use the desired colorspace, instead of default device colorspace - // See: https://developers.google.com/speed/webp/docs/riff_container#color_profile - - WebPChunkIterator chunk_iter; - CGColorSpaceRef colorSpaceRef = NULL; - - int result = WebPDemuxGetChunk(demuxer, "ICCP", 1, &chunk_iter); - if (result) { - NSData *profileData = [NSData dataWithBytesNoCopy:(void *)chunk_iter.chunk.bytes length:chunk_iter.chunk.size freeWhenDone:NO]; - colorSpaceRef = CGColorSpaceCreateWithICCProfile((__bridge CFDataRef)profileData); - } - - WebPDemuxReleaseChunkIterator(&chunk_iter); - - if (!colorSpaceRef) { - colorSpaceRef = SDCGColorSpaceGetDeviceRGB(); - CGColorSpaceRetain(colorSpaceRef); - } - - return colorSpaceRef; + // WebP contains ICC Profile should use the desired colorspace, instead of default device colorspace + // See: https://developers.google.com/speed/webp/docs/riff_container#color_profile + + WebPChunkIterator chunk_iter; + CGColorSpaceRef colorSpaceRef = NULL; + + int result = WebPDemuxGetChunk(demuxer, "ICCP", 1, &chunk_iter); + if (result) { + NSData *profileData = [NSData dataWithBytesNoCopy:(void *)chunk_iter.chunk.bytes length:chunk_iter.chunk.size freeWhenDone:NO]; + colorSpaceRef = CGColorSpaceCreateWithICCProfile((__bridge CFDataRef)profileData); + } + + WebPDemuxReleaseChunkIterator(&chunk_iter); + + if (!colorSpaceRef) { + colorSpaceRef = SDCGColorSpaceGetDeviceRGB(); + CGColorSpaceRetain(colorSpaceRef); + } + + return colorSpaceRef; } @implementation SDWebImageWebPCoder { @@ -111,15 +111,15 @@ static CGColorSpaceRef SDColorSpaceCreateWithDemuxer(WebPDemuxer *demuxer) { WebPDemuxDelete(demuxer); return nil; } - - CGColorSpaceRef colorSpace = NULL; - // ICC profile - if (flags & ICCP_FLAG) { - colorSpace = SDColorSpaceCreateWithDemuxer(demuxer); - } else { - colorSpace = SDCGColorSpaceGetDeviceRGB(); - CGColorSpaceRetain(colorSpace); - } + + CGColorSpaceRef colorSpace = NULL; + // ICC profile + if (flags & ICCP_FLAG) { + colorSpace = SDColorSpaceCreateWithDemuxer(demuxer); + } else { + colorSpace = SDCGColorSpaceGetDeviceRGB(); + CGColorSpaceRetain(colorSpace); + } if (!(flags & ANIMATION_FLAG)) { // for static single webp image From 5b1ad458893b0eb2b174f0f27bf94f7a9be1b540 Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Tue, 22 Jan 2019 12:54:57 +0800 Subject: [PATCH 3/4] Revert the colorSpace naming --- SDWebImage/SDWebImageWebPCoder.m | 49 ++++++++++++++++---------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/SDWebImage/SDWebImageWebPCoder.m b/SDWebImage/SDWebImageWebPCoder.m index b48d27a4..de3a9acd 100644 --- a/SDWebImage/SDWebImageWebPCoder.m +++ b/SDWebImage/SDWebImageWebPCoder.m @@ -25,29 +25,6 @@ #endif #import -// Create and return the correct colorspace by checking the ICC Profile -static CGColorSpaceRef SDColorSpaceCreateWithDemuxer(WebPDemuxer *demuxer) { - // WebP contains ICC Profile should use the desired colorspace, instead of default device colorspace - // See: https://developers.google.com/speed/webp/docs/riff_container#color_profile - - WebPChunkIterator chunk_iter; - CGColorSpaceRef colorSpaceRef = NULL; - - int result = WebPDemuxGetChunk(demuxer, "ICCP", 1, &chunk_iter); - if (result) { - NSData *profileData = [NSData dataWithBytesNoCopy:(void *)chunk_iter.chunk.bytes length:chunk_iter.chunk.size freeWhenDone:NO]; - colorSpaceRef = CGColorSpaceCreateWithICCProfile((__bridge CFDataRef)profileData); - } - - WebPDemuxReleaseChunkIterator(&chunk_iter); - - if (!colorSpaceRef) { - colorSpaceRef = SDCGColorSpaceGetDeviceRGB(); - CGColorSpaceRetain(colorSpaceRef); - } - - return colorSpaceRef; -} @implementation SDWebImageWebPCoder { WebPIDecoder *_idec; @@ -115,7 +92,7 @@ static CGColorSpaceRef SDColorSpaceCreateWithDemuxer(WebPDemuxer *demuxer) { CGColorSpaceRef colorSpace = NULL; // ICC profile if (flags & ICCP_FLAG) { - colorSpace = SDColorSpaceCreateWithDemuxer(demuxer); + colorSpace = [self sd_colorSpaceWithDemuxer:demuxer]; } else { colorSpace = SDCGColorSpaceGetDeviceRGB(); CGColorSpaceRetain(colorSpace); @@ -365,6 +342,30 @@ static CGColorSpaceRef SDColorSpaceCreateWithDemuxer(WebPDemuxer *demuxer) { return image; } +// Create and return the correct colorspace by checking the ICC Profile +- (nonnull CGColorSpaceRef)sd_colorSpaceWithDemuxer:(nonnull WebPDemuxer *)demuxer CF_RETURNS_RETAINED { + // WebP contains ICC Profile should use the desired colorspace, instead of default device colorspace + // See: https://developers.google.com/speed/webp/docs/riff_container#color_profile + + WebPChunkIterator chunk_iter; + CGColorSpaceRef colorSpaceRef = NULL; + + int result = WebPDemuxGetChunk(demuxer, "ICCP", 1, &chunk_iter); + if (result) { + NSData *profileData = [NSData dataWithBytesNoCopy:(void *)chunk_iter.chunk.bytes length:chunk_iter.chunk.size freeWhenDone:NO]; + colorSpaceRef = CGColorSpaceCreateWithICCProfile((__bridge CFDataRef)profileData); + } + + WebPDemuxReleaseChunkIterator(&chunk_iter); + + if (!colorSpaceRef) { + colorSpaceRef = SDCGColorSpaceGetDeviceRGB(); + CGColorSpaceRetain(colorSpaceRef); + } + + return colorSpaceRef; +} + #pragma mark - Encode - (BOOL)canEncodeToFormat:(SDImageFormat)format { return (format == SDImageFormatWebP); From c3b0f64017e7ad19cdb835edb4a831e4efe777dd Mon Sep 17 00:00:00 2001 From: zhongwuzw Date: Tue, 22 Jan 2019 16:04:12 +0800 Subject: [PATCH 4/4] update --- SDWebImage/SDWebImageWebPCoder.m | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/SDWebImage/SDWebImageWebPCoder.m b/SDWebImage/SDWebImageWebPCoder.m index de3a9acd..d3d53193 100644 --- a/SDWebImage/SDWebImageWebPCoder.m +++ b/SDWebImage/SDWebImageWebPCoder.m @@ -89,14 +89,7 @@ return nil; } - CGColorSpaceRef colorSpace = NULL; - // ICC profile - if (flags & ICCP_FLAG) { - colorSpace = [self sd_colorSpaceWithDemuxer:demuxer]; - } else { - colorSpace = SDCGColorSpaceGetDeviceRGB(); - CGColorSpaceRetain(colorSpace); - } + CGColorSpaceRef colorSpace = [self sd_colorSpaceWithDemuxer:demuxer]; if (!(flags & ANIMATION_FLAG)) { // for static single webp image @@ -347,17 +340,19 @@ // WebP contains ICC Profile should use the desired colorspace, instead of default device colorspace // See: https://developers.google.com/speed/webp/docs/riff_container#color_profile - WebPChunkIterator chunk_iter; CGColorSpaceRef colorSpaceRef = NULL; + uint32_t flags = WebPDemuxGetI(demuxer, WEBP_FF_FORMAT_FLAGS); - int result = WebPDemuxGetChunk(demuxer, "ICCP", 1, &chunk_iter); - if (result) { - NSData *profileData = [NSData dataWithBytesNoCopy:(void *)chunk_iter.chunk.bytes length:chunk_iter.chunk.size freeWhenDone:NO]; - colorSpaceRef = CGColorSpaceCreateWithICCProfile((__bridge CFDataRef)profileData); + if (flags & ICCP_FLAG) { + WebPChunkIterator chunk_iter; + int result = WebPDemuxGetChunk(demuxer, "ICCP", 1, &chunk_iter); + if (result) { + NSData *profileData = [NSData dataWithBytesNoCopy:(void *)chunk_iter.chunk.bytes length:chunk_iter.chunk.size freeWhenDone:NO]; + colorSpaceRef = CGColorSpaceCreateWithICCProfile((__bridge CFDataRef)profileData); + WebPDemuxReleaseChunkIterator(&chunk_iter); + } } - WebPDemuxReleaseChunkIterator(&chunk_iter); - if (!colorSpaceRef) { colorSpaceRef = SDCGColorSpaceGetDeviceRGB(); CGColorSpaceRetain(colorSpaceRef);