Przeglądaj źródła

Merge branch 'master' of https://github.com/rs/SDWebImage into 5.x

# Conflicts:
#	SDWebImage/NSData+ImageContentType.h
#	SDWebImage/SDWebImageDownloader.m
#	SDWebImage/SDWebImageImageIOCoder.m
DreamPiggy 7 lat temu
rodzic
commit
3cd71e09ce

+ 1 - 0
Examples/SDWebImage Demo/MasterViewController.m

@@ -70,6 +70,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];

+ 0 - 2
README.md

@@ -7,8 +7,6 @@
 [![Pod Version](http://img.shields.io/cocoapods/v/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/)
 [![Pod Platform](http://img.shields.io/cocoapods/p/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/)
 [![Pod License](http://img.shields.io/cocoapods/l/SDWebImage.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html)
-[![Dependency Status](https://www.versioneye.com/objective-c/sdwebimage/badge.svg?style=flat)](https://www.versioneye.com/objective-c/sdwebimage)
-[![Reference Status](https://www.versioneye.com/objective-c/sdwebimage/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/sdwebimage/references)
 [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/rs/SDWebImage)
 [![codecov](https://codecov.io/gh/rs/SDWebImage/branch/master/graph/badge.svg)](https://codecov.io/gh/rs/SDWebImage)
 

+ 1 - 0
SDWebImage/NSData+ImageContentType.h

@@ -22,6 +22,7 @@ static const SDImageFormat SDImageFormatGIF       = 2;
 static const SDImageFormat SDImageFormatTIFF      = 3;
 static const SDImageFormat SDImageFormatWebP      = 4;
 static const SDImageFormat SDImageFormatHEIC      = 5;
+static const SDImageFormat SDImageFormatHEIF      = 6;
 
 @interface NSData (ImageContentType)
 

+ 11 - 1
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,10 @@
                     || [testString isEqualToString:@"ftyphevx"]) {
                     return SDImageFormatHEIC;
                 }
+                //....ftypmif1 ....ftypmsf1
+                if ([testString isEqualToString:@"ftypmif1"] || [testString isEqualToString:@"ftypmsf1"]) {
+                    return SDImageFormatHEIF;
+                }
             }
             break;
         }
@@ -87,6 +92,9 @@
         case SDImageFormatHEIC:
             UTType = kSDUTTypeHEIC;
             break;
+        case SDImageFormatHEIF:
+            UTType = kSDUTTypeHEIF;
+            break;
         default:
             // default is kUTTypePNG
             UTType = kUTTypePNG;
@@ -112,6 +120,8 @@
         imageFormat = SDImageFormatWebP;
     } else if (CFStringCompare(uttype, kSDUTTypeHEIC, 0) == kCFCompareEqualTo) {
         imageFormat = SDImageFormatHEIC;
+    } else if (CFStringCompare(uttype, kSDUTTypeHEIF, 0) == kCFCompareEqualTo) {
+        imageFormat = SDImageFormatHEIF;
     } else {
         imageFormat = SDImageFormatUndefined;
     }

+ 46 - 7
SDWebImage/SDImageIOCoder.m

@@ -55,6 +55,9 @@
         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 @@
         case SDImageFormatHEIC:
             // Check HEIC decoding compatibility
             return [[self class] canDecodeFromHEICFormat];
+        case SDImageFormatHEIF:
+            // Check HEIF decoding compatibility
+            return [[self class] canDecodeFromHEIFFormat];
         default:
             return YES;
     }
@@ -183,6 +189,9 @@
         case SDImageFormatHEIC:
             // Check HEIC encoding compatibility
             return [[self class] canEncodeToHEICFormat];
+        case SDImageFormatHEIF:
+            // Check HEIF encoding compatibility
+            return [[self class] canEncodeToHEIFFormat];
         default:
             return YES;
     }
@@ -243,15 +252,24 @@
     static BOOL canDecode = NO;
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
-#if TARGET_OS_SIMULATOR || SD_WATCH
-        canDecode = NO;
-#else
-        if (@available(iOS 11.0, tvOS 11.0, macOS 10.13, *)) {
+        CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:SDImageFormatHEIC];
+        NSArray *imageUTTypes = (__bridge_transfer NSArray *)CGImageSourceCopyTypeIdentifiers();
+        if ([imageUTTypes containsObject:(__bridge NSString *)(imageUTType)]) {
+            canDecode = YES;
+        }
+    });
+    return canDecode;
+}
+
++ (BOOL)canDecodeFromHEIFFormat {
+    static BOOL canDecode = NO;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat:SDImageFormatHEIF];
+        NSArray *imageUTTypes = (__bridge_transfer NSArray *)CGImageSourceCopyTypeIdentifiers();
+        if ([imageUTTypes containsObject:(__bridge NSString *)(imageUTType)]) {
             canDecode = YES;
-        } else {
-            canDecode = NO;
         }
-#endif
     });
     return canDecode;
 }
@@ -277,4 +295,25 @@
     return canEncode;
 }
 
++ (BOOL)canEncodeToHEIFFormat {
+    static BOOL canEncode = NO;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        NSMutableData *imageData = [NSMutableData data];
+        CFStringRef imageUTType = [NSData sd_UTTypeFromImageFormat: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;
+}
+
 @end

+ 23 - 2
SDWebImage/SDWebImageDownloader.m

@@ -92,11 +92,32 @@ static void * SDWebImageDownloaderContext = &SDWebImageDownloaderContext;
         _downloadQueue.maxConcurrentOperationCount = _config.maxConcurrentDownloads;
         _downloadQueue.name = @"com.hackemist.SDWebImageDownloader";
         _URLOperations = [NSMutableDictionary new];
+        NSMutableDictionary<NSString *, NSString *> *headerDictionary = [NSMutableDictionary dictionary];
+        NSString *userAgent = nil;
+#if SD_UIKIT
+        // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43
+        userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]];
+#elif SD_WATCH
+        // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43
+        userAgent = [NSString stringWithFormat:@"%@/%@ (%@; watchOS %@; Scale/%0.2f)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[WKInterfaceDevice currentDevice] model], [[WKInterfaceDevice currentDevice] systemVersion], [[WKInterfaceDevice currentDevice] screenScale]];
+#elif SD_MAC
+        userAgent = [NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleExecutableKey] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleIdentifierKey], [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] ?: [[NSBundle mainBundle] infoDictionary][(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]];
+#endif
+        if (userAgent) {
+            if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) {
+                NSMutableString *mutableUserAgent = [userAgent mutableCopy];
+                if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) {
+                    userAgent = mutableUserAgent;
+                }
+            }
+            headerDictionary[@"User-Agent"] = userAgent;
+        }
 #ifdef SD_WEBP
-        _HTTPHeaders = @{@"Accept": @"image/webp,image/*;q=0.8"};
+        headerDictionary[@"Accept"] = @"image/webp,image/*;q=0.8";
 #else
-        _HTTPHeaders = @{@"Accept": @"image/*;q=0.8"};
+        headerDictionary[@"Accept"] = @"image/*;q=0.8";
 #endif
+        _HTTPHeaders = [headerDictionary copy];
         _operationsLock = dispatch_semaphore_create(1);
         NSURLSessionConfiguration *sessionConfiguration = _config.sessionConfiguration;
         if (!sessionConfiguration) {