Skip to content

Commit

Permalink
MMMLoadableImage: whitelist WebP and support animation for them
Browse files Browse the repository at this point in the history
  • Loading branch information
aleh committed Nov 17, 2023
1 parent cd123df commit 6fafe6b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 20 deletions.
2 changes: 1 addition & 1 deletion MMMLoadable.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
Pod::Spec.new do |s|

s.name = "MMMLoadable"
s.version = "1.11.0"
s.version = "1.12.0"
s.summary = "A simple model for async calculations"
s.description = "#{s.summary}."
s.homepage = "https://github.com/mediamonks/#{s.name}"
Expand Down
52 changes: 33 additions & 19 deletions Sources/MMMLoadableObjC/MMMLoadableImage.m
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,24 @@ - (void)didFailWithError:(NSError *)error {
}];
}

/// [UIImage imageWithData:] does not decode GIFs as an animated image, this is to fix that.
- (NSNumber *)imageAnimationDelayTime:(CGImageSourceRef)source {
CFDictionaryRef props = CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
if (!props) {
return nil;
}
NSDictionary *gifProps = (__bridge NSDictionary *)(CFDictionaryRef)CFDictionaryGetValue(props, kCGImagePropertyGIFDictionary);
NSDictionary *webpProps = (__bridge NSDictionary *)(CFDictionaryRef)CFDictionaryGetValue(props, kCGImagePropertyWebPDictionary);
CFRelease(props);
if (gifProps) {
return (NSNumber *)gifProps[(NSString *)kCGImagePropertyGIFDelayTime];
} else if (webpProps) {
return (NSNumber *)webpProps[(NSString *)kCGImagePropertyWebPDelayTime];
} else {
return nil;
}
}

/// [UIImage imageWithData:] does not decode GIFs as animated images, this is to correct that.
- (UIImage *)imageWithData:(NSData *)data {

CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)data, NULL);
Expand All @@ -230,14 +247,8 @@ - (UIImage *)imageWithData:(NSData *)data {
CFRelease(source);
return nil;
}
CFDictionaryRef props = CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
if (!props) {
CFRelease(source);
return nil;
}
NSDictionary *gifProps = (__bridge NSDictionary *)(CFDictionaryRef)CFDictionaryGetValue(props, kCGImagePropertyGIFDictionary);
CFRelease(props);
if (count == 1 || !gifProps) {
NSNumber *delayTimeNum = [self imageAnimationDelayTime:source];
if (count == 1 || !delayTimeNum) {
CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, NULL);
CFRelease(source);
return cgImage ? [UIImage imageWithCGImage:cgImage] : nil;
Expand All @@ -259,7 +270,6 @@ - (UIImage *)imageWithData:(NSData *)data {
[images addObject:image];
}

NSNumber *delayTimeNum = (NSNumber *)gifProps[(NSString *)kCGImagePropertyGIFDelayTime];
NSTimeInterval delayTime = MAX([delayTimeNum doubleValue], 0.1);

return [UIImage animatedImageWithImages:images duration:delayTime * count];
Expand All @@ -279,16 +289,20 @@ - (void)didFinishSuccessfullyWithResponse:(NSURLResponse *)response data:(NSData
return;
}

if (![[response MIMEType] isEqual:@"image/jpeg"] && ![[response MIMEType] isEqual:@"image/jp2"] &&
![[response MIMEType] isEqual:@"image/png"] && ![[response MIMEType] isEqual:@"image/gif"] &&
// Some backends just cannot configure themselves properly, so let's accept generic byte streams as well.
![[response MIMEType] isEqual:@"application/octet-stream"]
) {

[self didFailWithError:[self errorWithMessage:[NSString
stringWithFormat:@"Unsupported MIME type: '%@'", [response MIMEType]
]]];
static NSSet<NSString *> *supportedMIMETypes = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
supportedMIMETypes = [[NSSet alloc] initWithObjects:
@"image/jpeg", @"image/jp2", @"image/png", @"image/gif", @"image/webp",
// Some backends just cannot configure themselves properly, so let's accept generic byte streams as well.
@"application/octet-stream",
nil
];
});

NSString *mimeType = [[response MIMEType] lowercaseString];
if (![supportedMIMETypes containsObject:mimeType]) {
[self didFailWithError:[self errorWithMessage:[NSString stringWithFormat:@"Unsupported MIME type: '%@'", mimeType]]];
return;
}

Expand Down

0 comments on commit 6fafe6b

Please sign in to comment.