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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Example/SDWebImageWebPCoderExample/ViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

[SDImageCache.sharedImageCache clearDiskOnCompletion:nil];

[[SDImageCodersManager sharedManager] addCoder:[SDImageWebPCoder sharedCoder]];

self.imageView1 = [UIImageView new];
Expand All @@ -46,7 +48,7 @@ - (void)viewDidLoad {
}
});
}];
[self.imageView2 sd_setImageWithURL:animatedWebPURL completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
[self.imageView2 sd_setImageWithURL:animatedWebPURL placeholderImage:nil options:SDWebImageProgressiveLoad completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
if (image) {
NSLog(@"%@", @"Animated WebP load success");
}
Expand Down
57 changes: 53 additions & 4 deletions SDWebImageWebPCoder/Classes/SDImageWebPCoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ @implementation SDWebPCoderFrame
@implementation SDImageWebPCoder {
WebPIDecoder *_idec;
WebPDemuxer *_demux;
WebPData *_webpdata; // Copied for progressive animation demuxer
NSData *_imageData;
CGFloat _scale;
NSUInteger _loopCount;
Expand Down Expand Up @@ -113,6 +114,10 @@ - (void)dealloc {
WebPDemuxDelete(_demux);
_demux = NULL;
}
if (_webpdata) {
WebPDataClear(_webpdata);
_webpdata = NULL;
}
if (_canvas) {
CGContextRelease(_canvas);
_canvas = NULL;
Expand Down Expand Up @@ -290,6 +295,8 @@ - (instancetype)initIncrementalWithOptions:(nullable SDImageCoderOptions *)optio
preserveAspectRatio = preserveAspectRatioValue.boolValue;
}
_preserveAspectRatio = preserveAspectRatio;
_currentBlendIndex = NSNotFound;
_lock = dispatch_semaphore_create(1);
}
return self;
}
Expand All @@ -300,16 +307,54 @@ - (void)updateIncrementalData:(NSData *)data finished:(BOOL)finished {
}
_imageData = data;
_finished = finished;
VP8StatusCode status = WebPIUpdate(_idec, data.bytes, data.length);
if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) {
return;
if (!_demux) {
VP8StatusCode status = WebPIUpdate(_idec, data.bytes, data.length);
if (status == VP8_STATUS_OK || status == VP8_STATUS_SUSPENDED) {
return;
}
// This case may be Animated WebP progressive decode
if (status == VP8_STATUS_UNSUPPORTED_FEATURE) {
WebPDemuxState state;
WebPData tmpData;
WebPDataInit(&tmpData);
tmpData.bytes = data.bytes;
tmpData.size = data.length;
// Copy to avoid the NSData dealloc and VP8 internal retain the pointer
_webpdata = malloc(sizeof(WebPData));
WebPDataCopy(&tmpData, _webpdata);
_demux = WebPDemuxPartial(_webpdata, &state);
}
} else {
// libwebp current have no API to update demuxer, so we always delete and recreate demuxer
WebPDemuxDelete(_demux);
_demux = NULL;
WebPDemuxState state;
WebPData tmpData;
WebPDataInit(&tmpData);
tmpData.bytes = data.bytes;
tmpData.size = data.length;
// Copy to avoid the NSData dealloc and VP8 internal retain the pointer
WebPDataClear(_webpdata);
WebPDataCopy(&tmpData, _webpdata);
_demux = WebPDemuxPartial(_webpdata, &state);
}

if (_demux) {
[self scanAndCheckFramesValidWithDemuxer:_demux];
}
// libwebp current does not support progressive decoding for animated image, so no need to scan and update the frame information
}

- (UIImage *)incrementalDecodedImageWithOptions:(SDImageCoderOptions *)options {
UIImage *image;

// For Animated WebP Images, progressive decoding only return the first frame.
// If you want progressive animation, use the SDAniamtedCoder protocol method instead.
if (_demux) {
SD_LOCK(_lock);
image = [self safeStaticImageFrame];
SD_UNLOCK(_lock);
}
// For Static WebP images
int width = 0;
int height = 0;
int last_y = 0;
Expand Down Expand Up @@ -832,6 +877,10 @@ - (BOOL)scanAndCheckFramesValidWithDemuxer:(WebPDemuxer *)demuxer {

// We should loop all the frames and scan each frames' blendFromIndex for later decoding, this can also ensure all frames is valid
do {
if (!iter.complete) {
// Skip partial frame
continue;
}
SDWebPCoderFrame *frame = [[SDWebPCoderFrame alloc] init];
frame.index = iterIndex;
frame.duration = [self sd_frameDurationWithIterator:iter];
Expand Down