Authored by DreamPiggy

Provide a way to detect HEIC encoding compatibility. So that we can avoid encoding to this format.

@@ -14,6 +14,11 @@ @@ -14,6 +14,11 @@
14 #import <MobileCoreServices/MobileCoreServices.h> 14 #import <MobileCoreServices/MobileCoreServices.h>
15 #endif 15 #endif
16 16
  17 +// Currently Image/IO does not support WebP
  18 +#define kSDUTTypeWebP ((__bridge CFStringRef)@"public.webp")
  19 +// AVFileTypeHEIC is defined in AVFoundation via iOS 11, we use this without import AVFoundation
  20 +#define kSDUTTypeHEIC ((__bridge CFStringRef)@"public.heic")
  21 +
17 @implementation NSData (ImageContentType) 22 @implementation NSData (ImageContentType)
18 23
19 + (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data { 24 + (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data {
@@ -48,7 +53,7 @@ @@ -48,7 +53,7 @@
48 if (data.length >= 12) { 53 if (data.length >= 12) {
49 //....ftypheic 54 //....ftypheic
50 NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding]; 55 NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(4, 8)] encoding:NSASCIIStringEncoding];
51 - if ([testString hasPrefix:@"ftyp"] && [testString hasSuffix:@"heic"]) { 56 + if ([testString isEqualToString:@"ftypheic"]) {
52 return SDImageFormatHEIC; 57 return SDImageFormatHEIC;
53 } 58 }
54 } 59 }
@@ -73,6 +78,12 @@ @@ -73,6 +78,12 @@
73 case SDImageFormatTIFF: 78 case SDImageFormatTIFF:
74 UTType = kUTTypeTIFF; 79 UTType = kUTTypeTIFF;
75 break; 80 break;
  81 + case SDImageFormatWebP:
  82 + UTType = kSDUTTypeWebP;
  83 + break;
  84 + case SDImageFormatHEIC:
  85 + UTType = kSDUTTypeHEIC;
  86 + break;
76 default: 87 default:
77 // default is kUTTypePNG 88 // default is kUTTypePNG
78 UTType = kUTTypePNG; 89 UTType = kUTTypePNG;
@@ -397,6 +397,8 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over @@ -397,6 +397,8 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
397 // Do not support WebP encoding 397 // Do not support WebP encoding
398 case SDImageFormatWebP: 398 case SDImageFormatWebP:
399 return NO; 399 return NO;
  400 + case SDImageFormatHEIC:
  401 + return [[self class] canEncodeToHEICFormat];
400 default: 402 default:
401 return YES; 403 return YES;
402 } 404 }
@@ -469,6 +471,28 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over @@ -469,6 +471,28 @@ static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to over
469 return YES; 471 return YES;
470 } 472 }
471 473
  474 ++ (BOOL)canEncodeToHEICFormat
  475 +{
  476 + static BOOL canEncode = NO;
  477 + static dispatch_once_t onceToken;
  478 + dispatch_once(&onceToken, ^{
  479 + NSMutableData *imageData = [NSMutableData data];
  480 + CFStringRef imageUTType = [NSData sd_UTTypeFromSDImageFormat:SDImageFormatHEIC];
  481 +
  482 + // Create an image destination.
  483 + CGImageDestinationRef imageDestination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageData, imageUTType, 1, NULL);
  484 + if (!imageDestination) {
  485 + // Can encode to HEIC
  486 + canEncode = NO;
  487 + } else {
  488 + // Can't encode to HEIF
  489 + CFRelease(imageDestination);
  490 + canEncode = YES;
  491 + }
  492 + });
  493 + return canEncode;
  494 +}
  495 +
472 #if SD_UIKIT || SD_WATCH 496 #if SD_UIKIT || SD_WATCH
473 #pragma mark EXIF orientation tag converter 497 #pragma mark EXIF orientation tag converter
474 + (UIImageOrientation)sd_imageOrientationFromImageData:(nonnull NSData *)imageData { 498 + (UIImageOrientation)sd_imageOrientationFromImageData:(nonnull NSData *)imageData {