Merge pull request #23 from SDWebImage/fix_animated_webp_frame_blend_issue

Recheck the animated canvas calculation logic, fix the issue of that calculation
This commit is contained in:
DreamPiggy 2019-09-12 17:50:56 +08:00 committed by GitHub
commit b4e72dd678
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 8 additions and 5 deletions

View File

@ -810,12 +810,10 @@ static void FreeImageData(void *info, const void *data, size_t size) {
// But when one frame's dispose method is `WEBP_MUX_DISPOSE_BACKGROUND`, the canvas is cleared after the frame decoded. And subsequent frames are not effected by that frame. // But when one frame's dispose method is `WEBP_MUX_DISPOSE_BACKGROUND`, the canvas is cleared after the frame decoded. And subsequent frames are not effected by that frame.
// So, we calculate each frame's `blendFromIndex`. Then directly draw canvas from that index, instead of always from 0 index. // So, we calculate each frame's `blendFromIndex`. Then directly draw canvas from that index, instead of always from 0 index.
if (_currentBlendIndex + 1 == index) { if (_currentBlendIndex != NSNotFound && _currentBlendIndex + 1 == index) {
// If the request index is subsequence of current blend index, it does not matter what dispose method is. The canvas is always ready. // If the request index is subsequence of current blend index, it does not matter what dispose method is. The canvas is always ready.
_currentBlendIndex = index;
NSUInteger startIndex = index;
// libwebp's index start with 1 // libwebp's index start with 1
if (!WebPDemuxGetFrame(_demux, (int)(startIndex + 1), &iter)) { if (!WebPDemuxGetFrame(_demux, (int)(index + 1), &iter)) {
WebPDemuxReleaseIterator(&iter); WebPDemuxReleaseIterator(&iter);
return nil; return nil;
} }
@ -824,7 +822,6 @@ static void FreeImageData(void *info, const void *data, size_t size) {
if (_currentBlendIndex != NSNotFound) { if (_currentBlendIndex != NSNotFound) {
CGContextClearRect(_canvas, CGRectMake(0, 0, _canvasWidth, _canvasHeight)); CGContextClearRect(_canvas, CGRectMake(0, 0, _canvasWidth, _canvasHeight));
} }
_currentBlendIndex = index;
// Then, loop from the blend from index, draw each of previous frames on the canvas. // Then, loop from the blend from index, draw each of previous frames on the canvas.
// We use do while loop to call `WebPDemuxNextFrame`(fast), until the endIndex meet. // We use do while loop to call `WebPDemuxNextFrame`(fast), until the endIndex meet.
@ -843,7 +840,13 @@ static void FreeImageData(void *info, const void *data, size_t size) {
} }
} while ((size_t)iter.frame_num < endIndex && WebPDemuxNextFrame(&iter)); } while ((size_t)iter.frame_num < endIndex && WebPDemuxNextFrame(&iter));
} }
// libwebp's index start with 1
if (!WebPDemuxGetFrame(_demux, (int)(index + 1), &iter)) {
WebPDemuxReleaseIterator(&iter);
return nil;
}
} }
_currentBlendIndex = index;
// Now the canvas is ready, which respects of dispose method behavior. Just do normal decoding and produce image. // Now the canvas is ready, which respects of dispose method behavior. Just do normal decoding and produce image.
CGImageRef imageRef = [self sd_drawnWebpImageWithCanvas:_canvas iterator:iter colorSpace:_colorSpace]; CGImageRef imageRef = [self sd_drawnWebpImageWithCanvas:_canvas iterator:iter colorSpace:_colorSpace];