From 7ddb75710cb67caaf5a3db60ef42ee786e3628b7 Mon Sep 17 00:00:00 2001 From: DreamPiggy Date: Mon, 6 Aug 2018 17:53:24 +0800 Subject: [PATCH] Add SDImageFormatHEIF represent mif1 && msf1 brands Fix the current hard-coded system version checking with Image/IO source uttypes checking --- .../SDWebImage Demo/MasterViewController.m | 1 + SDWebImage/NSData+ImageContentType.h | 3 +- SDWebImage/NSData+ImageContentType.m | 11 +++- SDWebImage/SDWebImageImageIOCoder.m | 66 +++++++++++++------ 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/Examples/SDWebImage Demo/MasterViewController.m b/Examples/SDWebImage Demo/MasterViewController.m index 5e2b37bb..2328ed38 100644 --- a/Examples/SDWebImage Demo/MasterViewController.m +++ b/Examples/SDWebImage Demo/MasterViewController.m @@ -68,6 +68,7 @@ @"http://littlesvr.ca/apng/images/SteamEngine.webp", @"http://littlesvr.ca/apng/images/world-cup-2014-42.webp", @"https://isparta.github.io/compare-webp/image/gif_webp/webp/2.webp", + @"https://nokiatech.github.io/heif/content/images/ski_jump_1440x960.heic", @"https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png", @"http://via.placeholder.com/200x200.jpg", nil]; diff --git a/SDWebImage/NSData+ImageContentType.h b/SDWebImage/NSData+ImageContentType.h index d7e21428..d29bbad3 100644 --- a/SDWebImage/NSData+ImageContentType.h +++ b/SDWebImage/NSData+ImageContentType.h @@ -17,7 +17,8 @@ typedef NS_ENUM(NSInteger, SDImageFormat) { SDImageFormatGIF, SDImageFormatTIFF, SDImageFormatWebP, - SDImageFormatHEIC + SDImageFormatHEIC, + SDImageFormatHEIF }; @interface NSData (ImageContentType) diff --git a/SDWebImage/NSData+ImageContentType.m b/SDWebImage/NSData+ImageContentType.m index 64ea0a30..927330cd 100644 --- a/SDWebImage/NSData+ImageContentType.m +++ b/SDWebImage/NSData+ImageContentType.m @@ -16,8 +16,9 @@ // Currently Image/IO does not support WebP #define kSDUTTypeWebP ((__bridge CFStringRef)@"public.webp") -// AVFileTypeHEIC is defined in AVFoundation via iOS 11, we use this without import AVFoundation +// AVFileTypeHEIC/AVFileTypeHEIF is defined in AVFoundation via iOS 11, we use this without import AVFoundation #define kSDUTTypeHEIC ((__bridge CFStringRef)@"public.heic") +#define kSDUTTypeHEIF ((__bridge CFStringRef)@"public.heif") @implementation NSData (ImageContentType) @@ -59,6 +60,9 @@ || [testString isEqualToString:@"ftyphevx"]) { return SDImageFormatHEIC; } + if ([testString isEqualToString:@"ftypmif1"] || [testString isEqualToString:@"ftypmsf1"]) { + return SDImageFormatHEIF; + } } break; } @@ -87,6 +91,9 @@ case SDImageFormatHEIC: UTType = kSDUTTypeHEIC; break; + case SDImageFormatHEIF: + UTType = kSDUTTypeHEIF; + break; default: // default is kUTTypePNG UTType = kUTTypePNG; @@ -112,6 +119,8 @@ imageFormat = SDImageFormatWebP; } else if (CFStringCompare(uttype, kSDUTTypeHEIC, 0) == kCFCompareEqualTo) { imageFormat = SDImageFormatHEIC; + } else if (CFStringCompare(uttype, kSDUTTypeHEIF, 0) == kCFCompareEqualTo) { + imageFormat = SDImageFormatHEIF; } else { imageFormat = SDImageFormatUndefined; } diff --git a/SDWebImage/SDWebImageImageIOCoder.m b/SDWebImage/SDWebImageImageIOCoder.m index 1d0238ea..95b25b08 100644 --- a/SDWebImage/SDWebImageImageIOCoder.m +++ b/SDWebImage/SDWebImageImageIOCoder.m @@ -74,6 +74,9 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over case SDImageFormatHEIC: // Check HEIC decoding compatibility return [[self class] canDecodeFromHEICFormat]; + case SDImageFormatHEIF: + // Check HEIF decoding compatibility + return [[self class] canDecodeFromHEIFFormat]; default: return YES; } @@ -87,6 +90,9 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over case SDImageFormatHEIC: // Check HEIC decoding compatibility return [[self class] canDecodeFromHEICFormat]; + case SDImageFormatHEIF: + // Check HEIF decoding compatibility + return [[self class] canDecodeFromHEIFFormat]; default: return YES; } @@ -372,6 +378,9 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over case SDImageFormatHEIC: // Check HEIC encoding compatibility return [[self class] canEncodeToHEICFormat]; + case SDImageFormatHEIF: + // Check HEIF encoding compatibility + return [[self class] canEncodeToHEIFFormat]; default: return YES; } @@ -440,28 +449,24 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over static BOOL canDecode = NO; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability" -#if TARGET_OS_SIMULATOR || SD_WATCH - canDecode = NO; -#elif SD_MAC - NSProcessInfo *processInfo = [NSProcessInfo processInfo]; - if ([processInfo respondsToSelector:@selector(operatingSystemVersion)]) { - // macOS 10.13+ - canDecode = processInfo.operatingSystemVersion.minorVersion >= 13; - } else { - canDecode = NO; + CFStringRef imageUTType = [NSData sd_UTTypeFromSDImageFormat:SDImageFormatHEIC]; + NSArray *imageUTTypes = (__bridge_transfer NSArray *)CGImageSourceCopyTypeIdentifiers(); + if ([imageUTTypes containsObject:(__bridge NSString *)(imageUTType)]) { + canDecode = YES; } -#elif SD_UIKIT - NSProcessInfo *processInfo = [NSProcessInfo processInfo]; - if ([processInfo respondsToSelector:@selector(operatingSystemVersion)]) { - // iOS 11+ && tvOS 11+ - canDecode = processInfo.operatingSystemVersion.majorVersion >= 11; - } else { - canDecode = NO; + }); + return canDecode; +} + ++ (BOOL)canDecodeFromHEIFFormat { + static BOOL canDecode = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + CFStringRef imageUTType = [NSData sd_UTTypeFromSDImageFormat:SDImageFormatHEIF]; + NSArray *imageUTTypes = (__bridge_transfer NSArray *)CGImageSourceCopyTypeIdentifiers(); + if ([imageUTTypes containsObject:(__bridge NSString *)(imageUTType)]) { + canDecode = YES; } -#endif -#pragma clang diagnostic pop }); return canDecode; } @@ -487,6 +492,27 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over return canEncode; } ++ (BOOL)canEncodeToHEIFFormat { + static BOOL canEncode = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSMutableData *imageData = [NSMutableData data]; + CFStringRef imageUTType = [NSData sd_UTTypeFromSDImageFormat:SDImageFormatHEIF]; + + // Create an image destination. + CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, 1, NULL); + if (!imageDestination) { + // Can't encode to HEIF + canEncode = NO; + } else { + // Can encode to HEIF + CFRelease(imageDestination); + canEncode = YES; + } + }); + return canEncode; +} + #if SD_UIKIT || SD_WATCH + (BOOL)shouldScaleDownImage:(nonnull UIImage *)image { BOOL shouldScaleDown = YES;