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
24 changes: 20 additions & 4 deletions SDWebImageWebPCoder.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
0EF5B6264833B7BC20894578 /* Pods_SDWebImageWebPCoderTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 46F21AD7D1692EBAC4D0FF33 /* Pods_SDWebImageWebPCoderTests.framework */; };
3219F3B2228B0453003822A6 /* TestImageBlendAnimated.webp in Resources */ = {isa = PBXBuildFile; fileRef = 3219F3B1228B0453003822A6 /* TestImageBlendAnimated.webp */; };
806E77B32136A2E900A316D2 /* UIImage+WebP.m in Sources */ = {isa = PBXBuildFile; fileRef = 806E77AA2136A2E900A316D2 /* UIImage+WebP.m */; };
806E77B42136A2E900A316D2 /* SDImageWebPCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AB2136A2E900A316D2 /* SDImageWebPCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
806E77B62136A2E900A316D2 /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 806E77AD2136A2E900A316D2 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -44,6 +45,7 @@
/* Begin PBXFileReference section */
28D8AA3D3015E075692FD3E3 /* Pods-SDWebImageWebPCoderTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SDWebImageWebPCoderTests.debug.xcconfig"; path = "SDWebImageWebPCoderTests/Pods/Target Support Files/Pods-SDWebImageWebPCoderTests/Pods-SDWebImageWebPCoderTests.debug.xcconfig"; sourceTree = "<group>"; };
3217BE7B220547EB003D0310 /* SDWebImageWebPCoder.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = SDWebImageWebPCoder.modulemap; sourceTree = "<group>"; };
3219F3B1228B0453003822A6 /* TestImageBlendAnimated.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageBlendAnimated.webp; sourceTree = "<group>"; };
46F21AD7D1692EBAC4D0FF33 /* Pods_SDWebImageWebPCoderTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SDWebImageWebPCoderTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
806E779D2136A1C000A316D2 /* SDWebImageWebPCoder.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImageWebPCoder.framework; sourceTree = BUILT_PRODUCTS_DIR; };
806E77AA2136A2E900A316D2 /* UIImage+WebP.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+WebP.m"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -205,6 +207,7 @@
children = (
808C919A213FD2B2004B0F7C /* TestImageStatic.webp */,
808C919B213FD2B2004B0F7C /* TestImageAnimated.webp */,
3219F3B1228B0453003822A6 /* TestImageBlendAnimated.webp */,
);
path = Images;
sourceTree = "<group>";
Expand Down Expand Up @@ -453,6 +456,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3219F3B2228B0453003822A6 /* TestImageBlendAnimated.webp in Resources */,
808C919D213FD2B2004B0F7C /* TestImageAnimated.webp in Resources */,
808C919C213FD2B2004B0F7C /* TestImageStatic.webp in Resources */,
);
Expand Down Expand Up @@ -620,8 +624,14 @@
"DEBUG=1",
"$(inherited)",
);
"GCC_PREPROCESSOR_DEFINITIONS[sdk=watchos*]" = "WEBP_USE_INTRINSICS=1 $(inherited)";
"GCC_PREPROCESSOR_DEFINITIONS[sdk=watchsimulator*]" = "WEBP_USE_INTRINSICS=1 $(inherited)";
"GCC_PREPROCESSOR_DEFINITIONS[sdk=watchos*]" = (
"WEBP_USE_INTRINSICS=1",
"$(inherited)",
);
"GCC_PREPROCESSOR_DEFINITIONS[sdk=watchsimulator*]" = (
"WEBP_USE_INTRINSICS=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
Expand Down Expand Up @@ -689,8 +699,14 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
"GCC_PREPROCESSOR_DEFINITIONS[sdk=watchos*]" = "WEBP_USE_INTRINSICS=1 $(inherited)";
"GCC_PREPROCESSOR_DEFINITIONS[sdk=watchsimulator*]" = "WEBP_USE_INTRINSICS=1 $(inherited)";
"GCC_PREPROCESSOR_DEFINITIONS[sdk=watchos*]" = (
"WEBP_USE_INTRINSICS=1",
"$(inherited)",
);
"GCC_PREPROCESSOR_DEFINITIONS[sdk=watchsimulator*]" = (
"WEBP_USE_INTRINSICS=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
Expand Down
12 changes: 6 additions & 6 deletions SDWebImageWebPCoder/Classes/SDImageWebPCoder.m
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ @interface SDWebPCoderFrame : NSObject
@property (nonatomic, assign) NSUInteger offsetY; // Frame origin.y in canvas (left-bottom based)
@property (nonatomic, assign) BOOL hasAlpha; // Whether frame contains alpha
@property (nonatomic, assign) BOOL isFullSize; // Whether frame size is equal to canvas size
@property (nonatomic, assign) WebPMuxAnimBlend blend; // Frame dispose method
@property (nonatomic, assign) WebPMuxAnimDispose dispose; // Frame blend operation
@property (nonatomic, assign) BOOL shouldBlend; // Frame dispose method
@property (nonatomic, assign) BOOL shouldDispose; // Frame blend operation
@property (nonatomic, assign) NSUInteger blendFromIndex; // The nearest previous frame index which blend mode is WEBP_MUX_BLEND

@end
Expand Down Expand Up @@ -719,20 +719,20 @@ - (BOOL)scanAndCheckFramesValidWithDemuxer:(WebPDemuxer *)demuxer {
frame.width = iter.width;
frame.height = iter.height;
frame.hasAlpha = iter.has_alpha;
frame.dispose = iter.dispose_method;
frame.blend = iter.blend_method;
frame.shouldDispose = iter.dispose_method == WEBP_MUX_DISPOSE_BACKGROUND;
frame.shouldBlend = iter.blend_method == WEBP_MUX_BLEND;
frame.offsetX = iter.x_offset;
frame.offsetY = canvasHeight - iter.y_offset - iter.height;

BOOL sizeEqualsToCanvas = (iter.width == canvasWidth && iter.height == canvasHeight);
BOOL offsetIsZero = (iter.x_offset == 0 && iter.y_offset == 0);
frame.isFullSize = (sizeEqualsToCanvas && offsetIsZero);

if ((!frame.blend || !frame.hasAlpha) && frame.isFullSize) {
if ((!frame.shouldBlend || !frame.hasAlpha) && frame.isFullSize) {
lastBlendIndex = iterIndex;
frame.blendFromIndex = iterIndex;
} else {
if (frame.dispose && frame.isFullSize) {
if (frame.shouldDispose && frame.isFullSize) {
frame.blendFromIndex = lastBlendIndex;
lastBlendIndex = iterIndex + 1;
} else {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions SDWebImageWebPCoderTests/SDWebImageWebPCoderTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ @interface SDAnimatedImageView ()
@property (nonatomic, assign) BOOL isProgressive;
@end

@interface SDWebPCoderFrame : NSObject
@property (nonatomic, assign) NSUInteger index; // Frame index (zero based)
@property (nonatomic, assign) NSUInteger blendFromIndex; // The nearest previous frame index which blend mode is WEBP_MUX_BLEND
@end

@implementation SDWebImageWebPCoderTests

+ (void)setUp {
Expand Down Expand Up @@ -126,6 +131,47 @@ - (void)test32AnimatedImageViewCategoryProgressive {
[self waitForExpectationsWithTimeout:kAsyncTestTimeout handler:nil];
}

- (void)test33AnimatedImageBlendMethod {
// Test the optimization for blend and disposal method works without problem
NSURL *animatedWebPURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestImageBlendAnimated" withExtension:@"webp"];
NSData *data = [NSData dataWithContentsOfURL:animatedWebPURL];
SDImageWebPCoder *coder = [[SDImageWebPCoder alloc] initWithAnimatedImageData:data options:nil];
XCTAssertNotNil(coder);
/**
This WebP image frames info is below:
Canvas size: 400 x 400
Features present: animation transparency
Background color : 0xFF000000 Loop Count : 0
Number of frames: 12
No.: width height alpha x_offset y_offset duration dispose blend image_size compression
1: 400 400 no 0 0 70 none no 5178 lossless
2: 400 400 yes 0 0 70 none yes 1386 lossless
3: 400 400 yes 0 0 70 none yes 1472 lossless
4: 400 394 yes 0 6 70 none yes 3212 lossless
5: 371 394 yes 0 6 70 none yes 1888 lossless
6: 394 382 yes 6 6 70 none yes 3346 lossless
7: 400 388 yes 0 0 70 none yes 3786 lossless
8: 394 383 yes 0 0 70 none yes 1858 lossless
9: 394 394 yes 0 6 70 none yes 3794 lossless
10: 372 394 yes 22 6 70 none yes 3458 lossless
11: 400 400 no 0 0 70 none no 5270 lossless
12: 320 382 yes 0 6 70 none yes 2506 lossless
*/
NSArray<SDWebPCoderFrame *> *frames = [coder valueForKey:@"_frames"];
XCTAssertEqual(frames.count, 12);
for (SDWebPCoderFrame *frame in frames) {
switch (frame.index) {
// frame: 11 blend == no, means clear the canvas
case 10:
case 11:
XCTAssertEqual(frame.blendFromIndex, 10);
break;
default:
XCTAssertEqual(frame.blendFromIndex, 0);
break;
}
}
}

@end

Expand Down