Merge pull request #30 from SDWebImage/fix_static_webp_cgcontext_RAM
Fix the issue when WebP is static webp, the `SDAnimatedImageCoder` protocol implementation still create CGContext, this can reduce RAM usage
This commit is contained in:
commit
3e2d252aa9
|
@ -711,6 +711,18 @@ static void FreeImageData(void *info, const void *data, size_t size) {
|
||||||
uint32_t loopCount = WebPDemuxGetI(demuxer, WEBP_FF_LOOP_COUNT);
|
uint32_t loopCount = WebPDemuxGetI(demuxer, WEBP_FF_LOOP_COUNT);
|
||||||
NSMutableArray<SDWebPCoderFrame *> *frames = [NSMutableArray array];
|
NSMutableArray<SDWebPCoderFrame *> *frames = [NSMutableArray array];
|
||||||
|
|
||||||
|
_hasAnimation = hasAnimation;
|
||||||
|
_hasAlpha = hasAlpha;
|
||||||
|
_canvasWidth = canvasWidth;
|
||||||
|
_canvasHeight = canvasHeight;
|
||||||
|
_frameCount = frameCount;
|
||||||
|
_loopCount = loopCount;
|
||||||
|
|
||||||
|
// If static WebP, does not need to parse the frame blend index
|
||||||
|
if (frameCount <= 1) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
// We should loop all the frames and scan each frames' blendFromIndex for later decoding, this can also ensure all frames is valid
|
// We should loop all the frames and scan each frames' blendFromIndex for later decoding, this can also ensure all frames is valid
|
||||||
do {
|
do {
|
||||||
SDWebPCoderFrame *frame = [[SDWebPCoderFrame alloc] init];
|
SDWebPCoderFrame *frame = [[SDWebPCoderFrame alloc] init];
|
||||||
|
@ -748,12 +760,6 @@ static void FreeImageData(void *info, const void *data, size_t size) {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
_frames = [frames copy];
|
_frames = [frames copy];
|
||||||
_hasAnimation = hasAnimation;
|
|
||||||
_hasAlpha = hasAlpha;
|
|
||||||
_canvasWidth = canvasWidth;
|
|
||||||
_canvasHeight = canvasHeight;
|
|
||||||
_frameCount = frameCount;
|
|
||||||
_loopCount = loopCount;
|
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
@ -774,6 +780,9 @@ static void FreeImageData(void *info, const void *data, size_t size) {
|
||||||
if (index >= _frameCount) {
|
if (index >= _frameCount) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (_frameCount <= 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return _frames[index].duration;
|
return _frames[index].duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,11 +792,40 @@ static void FreeImageData(void *info, const void *data, size_t size) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
SD_LOCK(_lock);
|
SD_LOCK(_lock);
|
||||||
image = [self safeAnimatedImageFrameAtIndex:index];
|
if (_frameCount <= 1) {
|
||||||
|
image = [self safeStaticImageFrame];
|
||||||
|
} else {
|
||||||
|
image = [self safeAnimatedImageFrameAtIndex:index];
|
||||||
|
}
|
||||||
SD_UNLOCK(_lock);
|
SD_UNLOCK(_lock);
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIImage *)safeStaticImageFrame {
|
||||||
|
UIImage *image;
|
||||||
|
if (!_colorSpace) {
|
||||||
|
_colorSpace = [self sd_colorSpaceWithDemuxer:_demux];
|
||||||
|
}
|
||||||
|
// Static WebP image
|
||||||
|
WebPIterator iter;
|
||||||
|
if (!WebPDemuxGetFrame(_demux, 1, &iter)) {
|
||||||
|
WebPDemuxReleaseIterator(&iter);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
CGImageRef imageRef = [self sd_createWebpImageWithData:iter.fragment colorSpace:_colorSpace];
|
||||||
|
if (!imageRef) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
#if SD_UIKIT || SD_WATCH
|
||||||
|
image = [[UIImage alloc] initWithCGImage:imageRef scale:_scale orientation:UIImageOrientationUp];
|
||||||
|
#else
|
||||||
|
image = [[UIImage alloc] initWithCGImage:imageRef scale:_scale orientation:kCGImagePropertyOrientationUp];
|
||||||
|
#endif
|
||||||
|
CGImageRelease(imageRef);
|
||||||
|
WebPDemuxReleaseIterator(&iter);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
- (UIImage *)safeAnimatedImageFrameAtIndex:(NSUInteger)index {
|
- (UIImage *)safeAnimatedImageFrameAtIndex:(NSUInteger)index {
|
||||||
if (!_canvas) {
|
if (!_canvas) {
|
||||||
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host;
|
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
@import XCTest;
|
@import XCTest;
|
||||||
#import <SDWebImage/SDWebImage.h>
|
#import <SDWebImage/SDWebImage.h>
|
||||||
#import <SDWebImageWebPCoder/SDWebImageWebPCoder.h>
|
#import <SDWebImageWebPCoder/SDWebImageWebPCoder.h>
|
||||||
|
#import <objc/runtime.h>
|
||||||
|
|
||||||
const int64_t kAsyncTestTimeout = 5;
|
const int64_t kAsyncTestTimeout = 5;
|
||||||
|
|
||||||
|
@ -172,6 +173,18 @@ const int64_t kAsyncTestTimeout = 5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)test34StaticImageNotCreateCGContext {
|
||||||
|
NSURL *staticWebPURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImageStatic" withExtension:@"webp"];
|
||||||
|
NSData *data = [NSData dataWithContentsOfURL:staticWebPURL];
|
||||||
|
SDImageWebPCoder *coder = [[SDImageWebPCoder alloc] initWithAnimatedImageData:data options:nil];
|
||||||
|
XCTAssertTrue(coder.animatedImageFrameCount == 1);
|
||||||
|
UIImage *image = [coder animatedImageFrameAtIndex:0];
|
||||||
|
XCTAssertNotNil(image);
|
||||||
|
Ivar ivar = class_getInstanceVariable(coder.class, "_canvas");
|
||||||
|
CGContextRef canvas = ((CGContextRef (*)(id, Ivar))object_getIvar)(coder, ivar);
|
||||||
|
XCTAssert(canvas == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation SDWebImageWebPCoderTests (Helpers)
|
@implementation SDWebImageWebPCoderTests (Helpers)
|
||||||
|
|
Loading…
Reference in New Issue