Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 45 additions & 7 deletions SDWebImageWebPCoder/Classes/SDImageWebPCoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,18 @@ - (BOOL)scanAndCheckFramesValidWithDemuxer:(WebPDemuxer *)demuxer {
uint32_t loopCount = WebPDemuxGetI(demuxer, WEBP_FF_LOOP_COUNT);
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
do {
SDWebPCoderFrame *frame = [[SDWebPCoderFrame alloc] init];
Expand Down Expand Up @@ -748,12 +760,6 @@ - (BOOL)scanAndCheckFramesValidWithDemuxer:(WebPDemuxer *)demuxer {
return NO;
}
_frames = [frames copy];
_hasAnimation = hasAnimation;
_hasAlpha = hasAlpha;
_canvasWidth = canvasWidth;
_canvasHeight = canvasHeight;
_frameCount = frameCount;
_loopCount = loopCount;

return YES;
}
Expand All @@ -774,6 +780,9 @@ - (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index {
if (index >= _frameCount) {
return 0;
}
if (_frameCount <= 1) {
return 0;
}
return _frames[index].duration;
}

Expand All @@ -783,11 +792,40 @@ - (UIImage *)animatedImageFrameAtIndex:(NSUInteger)index {
return nil;
}
SD_LOCK(_lock);
image = [self safeAnimatedImageFrameAtIndex:index];
if (_frameCount <= 1) {
image = [self safeStaticImageFrame];
} else {
image = [self safeAnimatedImageFrameAtIndex:index];
}
SD_UNLOCK(_lock);
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 {
if (!_canvas) {
CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Host;
Expand Down
13 changes: 13 additions & 0 deletions SDWebImageWebPCoderTests/SDWebImageWebPCoderTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
@import XCTest;
#import <SDWebImage/SDWebImage.h>
#import <SDWebImageWebPCoder/SDWebImageWebPCoder.h>
#import <objc/runtime.h>

const int64_t kAsyncTestTimeout = 5;

Expand Down Expand Up @@ -172,6 +173,18 @@ - (void)test33AnimatedImageBlendMethod {
}
}

- (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

@implementation SDWebImageWebPCoderTests (Helpers)
Expand Down