Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebP animated image played incorrectly with the SDImageAWebPCoder #3558

Open
3 tasks done
Lguanghui opened this issue Jul 5, 2023 · 13 comments
Open
3 tasks done

WebP animated image played incorrectly with the SDImageAWebPCoder #3558

Lguanghui opened this issue Jul 5, 2023 · 13 comments
Labels
apple bug apple's bug cause our framework author's pain ImageIO Anything related to Apple ImageIO codec WebP

Comments

@Lguanghui
Copy link

Lguanghui commented Jul 5, 2023

New Issue Checklist

Issue Info

Info Value
Platform Name iOS
Platform Version 16.5
SDWebImage Version 5.16.0
Integration Method cocoapods
Xcode Version Xcode 14.3.1
Repro rate all the time
Repro with our demo prj yes

Issue Description and Steps

WebP animation url for test: https://pic.rmb.bdstatic.com/2021-1/1610332479407/37d4f305c2db.webp

When using SDImageAWebPCoder, some WebP animated image will be played incorrectly.

2023-07-05.15.40.12.mov

Compare with SDImageWebPCoder:

2023-07-05.15.37.55.mov

Is this a bug from Apple's build-in WebP coder?

@dreampiggy
Copy link
Contributor

SDImageAWebPCoder is driven by ImageIO...Which means:

How many frames here ?
What's the duration of this frame index ?

Is answered by ImageIO, not libwebp

Maybe it's bug of Apple, not SD...

@dreampiggy dreampiggy added WebP apple bug apple's bug cause our framework author's pain ImageIO Anything related to Apple ImageIO codec labels Jul 5, 2023
@dreampiggy
Copy link
Contributor

Only reproduce in iOS 16.5 ? Did you test iOS 14/15 (ImageIO supports WebP from iOS 14+)

@Lguanghui
Copy link
Author

Only reproduce in iOS 16.5 ? Did you test iOS 14/15 (ImageIO supports WebP from iOS 14+)

I can also reproduce with iPhone SE 1st, which runs on iOS 14 and the test result is even worse. 😂

RPReplay_Final1688549784.MP4

@dreampiggy
Copy link
Contributor

dreampiggy commented Jul 7, 2023

For this WebP. The CGImageSourceCreateImageAtIndex returned CGImage has already been broken...

Which means, seems there are no way for us (as a framework author) level can do to solve this. I guess this is bug in Apple's ImageIO, they does not follows the correct render of the dispose method in WebP standard.

See: https://developers.google.com/speed/webp/docs/riff_container. There are pseudocode for correcting render WebP (Which I implements in https://github.com/SDWebImage/SDWebImageWebPCoder)

Disposal method (D): 1 bit
Indicates how the current frame is to be treated after it has been displayed (before rendering the next frame) on the canvas:

0: Do not dispose. Leave the canvas as is.

1: Dispose to the background color. Fill the rectangle on the canvas covered by the current frame with the background color specified in the ['ANIM' Chunk](https://developers.google.com/speed/webp/docs/riff_container#anim_chunk).

My implementation follows the standard and it's not hard at all: https://github.com/SDWebImage/SDWebImageWebPCoder/blob/0.12.0/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m#L488-L506

Maybe we need to update the limits of ImageIO's WebP here... https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#awebp-coder

@dreampiggy
Copy link
Contributor

dreampiggy commented Jul 7, 2023

I guess Apple made mistake on this render logic:

        BOOL shouldBlend = iter.blend_method == WEBP_MUX_BLEND;
        // If not blend, cover the target image rect. (firstly clear then draw)
        if (!shouldBlend) {
            CGContextClearRect(canvas, imageRect);
        }
        CGContextDrawImage(canvas, imageRect, imageRef);
        CGImageRelease(imageRef);

They seems to do like this (buggy):

        BOOL shouldBlend = iter.blend_method == WEBP_MUX_BLEND;
        if (!shouldBlend) {
            CGContextSetBlendMode(canvas, kCGBlendModeCopy); //. This is not correct actually, from real world example
        } else {
            CGContextSetBlendMode(canvas, kCGBlendModeNormal);
        }
        CGContextDrawImage(canvas, imageRect, imageRef);
        CGImageRelease(imageRef);

@ijunfly
Copy link

ijunfly commented Sep 25, 2023

今天遇到一个webp问题, CollectionView 每个cell都展示webp动画, 一屏大概六个.

iOS 17.0.1
SDWebImageWebPCoder: 0.11.0
libwebp: 1.2.4
SDWebImage: 5.15.5
Xcode 15
正常渲染, 滑动collectionView不卡. (未使用SDWebImageAWebPCoder)

升级到最新的 5.18.2 (同时 libwebp: 1.2.4 -> 1.3.2, SDWebImageWebPCoder: 0.11.0 -> 0.13.0)
webp不展示, 但是隐约能看到有亮度的变化

使用SDWebImageAWebPCoder 可以展示, 但是滑动有点卡.

在想是继续保持5.15.5还是...

@dreampiggy
Copy link
Contributor

Provide a reproducable demo ?

@joaopdcgarcia
Copy link

@dreampiggy could this relate to #3356 ?

@dreampiggy
Copy link
Contributor

@dreampiggy could this relate to #3356 ?

Guess not ? This issue is about the different render result (still a valid UIImage/AnimatedImage obejct) but not "decode failed" (means, nil/null UIImage object)

But anyway, you can try to use the external libwebp based WebPCoder (See readme) and register as a coder to test again.

https://github.com/SDWebImage/SDWebImageWebPCoder#add-coder

@joaopdcgarcia
Copy link

joaopdcgarcia commented Nov 30, 2023

Oh ok your image is valid. In my context image is not nil but not valid as it has width and/or height as 0:

                CGSize imageSize = image.size;
            if (imageSize.width == 0 || imageSize.height == 0) {
                NSString *description = image == nil ? @"Downloaded image decode failed" : @"Downloaded image has 0 pixels";
                NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorBadImageData userInfo:@{NSLocalizedDescriptionKey : description}];
                [self callCompletionBlockWithToken:token image:nil imageData:nil error:error finished:YES];
                }

@dreampiggy
Copy link
Contributor

Oh ok your image is valid. In my context image is not nil but not valid as it has width and/or height as 0:

                CGSize imageSize = image.size;
            if (imageSize.width == 0 || imageSize.height == 0) {
                NSString *description = image == nil ? @"Downloaded image decode failed" : @"Downloaded image has 0 pixels";
                NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorBadImageData userInfo:@{NSLocalizedDescriptionKey : description}];
                [self callCompletionBlockWithToken:token image:nil imageData:nil error:error finished:YES];
                }

That is just a stupid log. Even if image is nil it will still output log for "zero width or height". This is Objc code, "nil.width == 0" (any function call to nil returns 0)

@dreampiggy
Copy link
Contributor

dreampiggy commented Mar 27, 2024

Apple seems never fix this issue.

And this bug exists for Safari/WebKit as well. Community even use some tools to avoid 'dispose_method' and 'blend_mode' on iOS Webp, fallback to old school GIF workaround (each frame use a new canvas without previous status, unlike video, which is VP8 designed for), however this ugly workaround will cause the WebP size becomes larger😼

like this tool: https://bandisoft.com/honeycam/help/webp-iphone-compatible/

For now, if you care about your App's performance and bandwidth for WebP images, always choose that SDWebImageWebPCoder instead , even on iOS 17 (until Apple someday fix in their close-sourced decoder)

@ijunfly
Copy link

ijunfly commented Apr 9, 2024

今天遇到一个webp问题, CollectionView 每个cell都展示webp动画, 一屏大概六个.

iOS 17.0.1 SDWebImageWebPCoder: 0.11.0 libwebp: 1.2.4 SDWebImage: 5.15.5 Xcode 15 正常渲染, 滑动collectionView不卡.(未使用SDWebImageAWebPCoder)

升级到最新的 5.18.2 (同时 libwebp: 1.2.4 -> 1.3.2, SDWebImageWebPCoder: 0.11.0 -> 0.13.0) webp不展示, 但是隐约能看到有亮度的变化

使用SDWebImageAWebPCoder 可以展示, 但是滑动有点卡.

在想是继续保持5.15.5还是...

是因为在 options 参数中 使用了 SDWebImageScaleDownLargeImages 导致的.... 删了 此参数就可以了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
apple bug apple's bug cause our framework author's pain ImageIO Anything related to Apple ImageIO codec WebP
Projects
None yet
Development

No branches or pull requests

4 participants