Merge pull request #1985 from dreampiggy/performance_webp_decoding_optimize

Performance enhancement related to single WebP and animated WebP decoding...
This commit is contained in:
DreamPiggy 2017-09-29 12:01:18 +08:00 committed by GitHub
commit 250e1fc87f
3 changed files with 73 additions and 34 deletions

View File

@ -347,6 +347,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
if (data) {
UIImage *image = [UIImage sd_imageWithData:data];
image = [self scaledImageForKey:key image:image];
#ifdef SD_WEBP
SDImageFormat imageFormat = [NSData sd_imageFormatForImageData:data];
if (imageFormat == SDImageFormatWebP) {
return image;
}
#endif
if (self.config.shouldDecompressImages) {
image = [UIImage decodedImageWithImage:image];
}

View File

@ -446,8 +446,20 @@ didReceiveResponse:(NSURLResponse *)response
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL];
image = [self scaledImageForKey:key image:image];
// Do not force decoding animated GIFs
if (!image.images) {
BOOL shouldDecode = YES;
// Do not force decoding animated GIFs and WebPs
if (image.images) {
shouldDecode = NO;
} else {
#ifdef SD_WEBP
SDImageFormat imageFormat = [NSData sd_imageFormatForImageData:self.imageData];
if (imageFormat == SDImageFormatWebP) {
shouldDecode = NO;
}
#endif
}
if (shouldDecode) {
if (self.shouldDecompressImages) {
if (self.options & SDWebImageDownloaderScaleDownLargeImages) {
#if SD_UIKIT || SD_WATCH

View File

@ -43,14 +43,6 @@ static void FreeImageData(void *info, const void *data, size_t size) {
return nil;
}
uint32_t flags = WebPDemuxGetI(demuxer, WEBP_FF_FORMAT_FLAGS);
if (!(flags & ANIMATION_FLAG)) {
// for static single webp image
UIImage *staticImage = [self sd_rawWebpImageWithData:webpData];
WebPDemuxDelete(demuxer);
return staticImage;
}
WebPIterator iter;
if (!WebPDemuxGetFrame(demuxer, 1, &iter)) {
WebPDemuxReleaseIterator(&iter);
@ -58,6 +50,8 @@ static void FreeImageData(void *info, const void *data, size_t size) {
return nil;
}
uint32_t flags = WebPDemuxGetI(demuxer, WEBP_FF_FORMAT_FLAGS);
#if SD_UIKIT || SD_WATCH
int loopCount = WebPDemuxGetI(demuxer, WEBP_FF_LOOP_COUNT);
int frameCount = WebPDemuxGetI(demuxer, WEBP_FF_FRAME_COUNT);
@ -77,6 +71,30 @@ static void FreeImageData(void *info, const void *data, size_t size) {
return nil;
}
if (!(flags & ANIMATION_FLAG)) {
// for static single webp image
UIImage *staticImage = [self sd_rawWebpImageWithData:webpData];
if (staticImage) {
// draw on CGBitmapContext can reduce memory usage
CGImageRef imageRef = staticImage.CGImage;
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
CGContextDrawImage(canvas, CGRectMake(0, 0, width, height), imageRef);
CGImageRef newImageRef = CGBitmapContextCreateImage(canvas);
#if SD_UIKIT || SD_WATCH
staticImage = [[UIImage alloc] initWithCGImage:newImageRef];
#else
staticImage = [[UIImage alloc] initWithCGImage:newImageRef size:NSZeroSize];
#endif
CGImageRelease(newImageRef);
}
WebPDemuxReleaseIterator(&iter);
WebPDemuxDelete(demuxer);
CGContextRelease(canvas);
return staticImage;
}
// for animated webp image
NSMutableArray<UIImage *> *images = [NSMutableArray array];
#if SD_UIKIT || SD_WATCH
NSTimeInterval totalDuration = 0;
@ -84,6 +102,7 @@ static void FreeImageData(void *info, const void *data, size_t size) {
#endif
do {
@autoreleasepool {
UIImage *image;
if (iter.blend_method == WEBP_MUX_BLEND) {
image = [self sd_blendWebpImageWithCanvas:canvas iterator:iter];
@ -111,6 +130,8 @@ static void FreeImageData(void *info, const void *data, size_t size) {
size_t count = images.count;
durations[count - 1] = duration;
#endif
}
} while (WebPDemuxNextFrame(&iter));
WebPDemuxReleaseIterator(&iter);