Kaynağa Gözat

feat: support backport to Xcode 15 SDK

DreamPiggy 1 yıl önce
ebeveyn
işleme
ba8b93feb0

+ 1 - 1
README.md

@@ -122,7 +122,7 @@ You can use those directly, or create similar components of your own, by using t
 - watchOS 2.0 or later
 - macOS 10.11 or later (10.15 for Catalyst)
 - visionOS 1.0 or later
-- Xcode 14.0 or later (visionOS requires Xcode 15.0)
+- Xcode 15.0 or later
 
 #### Backwards compatibility
 

+ 1 - 1
SDWebImage/Core/SDImageCoder.h

@@ -99,7 +99,7 @@ FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodeToHDR;
 #pragma mark - Image Encoding Options
 /**
  A NSUInteger value (NSNumber) to provide converting to HDR during encoding. Read the below carefully to choose the value.
- @note 0 means SDR; 1 means ISO HDR (at least using 10 bits per components or above, supported by AVIF/HEIF/JPEG-XL); 2 means ISO Gain Map Image (may use 8 bits per components, supported AVIF/HEIF/JPEG-XL, as well as traditional JPEG)
+ @note 0 means SDR; 1 means ISO HDR (at least using 10 bits per components or above, supported by AVIF/HEIF/JPEG-XL); 2 means ISO Gain Map HDR (may use 8 bits per components, supported by AVIF/HEIF/JPEG-XL, as well as traditional JPEG)
  @note Gain Map like a mask image with metadata, which contains the depth/bright information for each pixel (or smaller, 1/4 resolution), which used to convert between HDR and SDR.
  @note If you use CIImage as HDR pipeline, you can export as CGImage for encoding. (But it's also recommanded to use CIImage's `JPEGRepresentationOfImage` or `HEIFRepresentationOfImage`)
  @note Supported by iOS 18 and above when using ImageIO coder (third-party coder can support lower firmware)

+ 21 - 3
SDWebImage/Core/SDImageIOAnimatedCoder.m

@@ -28,6 +28,12 @@ static CGImageSourceRef (*SDCGImageGetImageSource)(CGImageRef);
 
 // Specify File Size for lossy format encoding, like JPEG
 static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestinationRequestedFileSize";
+// Support Xcode 15 SDK, use raw value instead of symbol
+static NSString * kSDCGImageDestinationEncodeRequest = @"kCGImageDestinationEncodeRequest";
+static NSString * kSDCGImageDestinationEncodeToSDR = @"kCGImageDestinationEncodeToSDR";
+static NSString * kSDCGImageDestinationEncodeToISOHDR = @"kCGImageDestinationEncodeToISOHDR";
+static NSString * kSDCGImageDestinationEncodeToISOGainmap = @"kCGImageDestinationEncodeToISOGainmap";
+
 
 // This strip the un-wanted CGImageProperty, like the internal CGImageSourceRef in iOS 15+
 // However, CGImageCreateCopy still keep those CGImageProperty, not suit for our use case
@@ -282,6 +288,18 @@ static BOOL SDImageIOPNGPluginBuggyNeedWorkaround(void) {
     BOOL _decodeToHDR;
 }
 
+#if SD_IMAGEIO_HDR_ENCODING
++ (void)initialize {
+    if (@available(macOS 15, iOS 18, tvOS 18, watchOS 11, *)) {
+        // Use SDK instead of raw value
+        kSDCGImageDestinationEncodeRequest = (__bridge NSString *)kCGImageDestinationEncodeRequest;
+        kSDCGImageDestinationEncodeToSDR = (__bridge NSString *)kCGImageDestinationEncodeToSDR;
+        kSDCGImageDestinationEncodeToISOHDR = (__bridge NSString *)kCGImageDestinationEncodeToISOHDR;
+        kSDCGImageDestinationEncodeToISOGainmap = (__bridge NSString *)kCGImageDestinationEncodeToISOGainmap;
+    }
+}
+#endif
+
 - (void)dealloc
 {
     if (_imageSource) {
@@ -902,11 +920,11 @@ static BOOL SDImageIOPNGPluginBuggyNeedWorkaround(void) {
     }
     if (@available(macOS 15, iOS 18, tvOS 18, watchOS 11, *)) {
         if (encodeToHDR == 1) {
-            properties[(__bridge NSString *)kCGImageDestinationEncodeRequest] = (__bridge NSString *)kCGImageDestinationEncodeToISOHDR;
+            properties[kSDCGImageDestinationEncodeRequest] = kSDCGImageDestinationEncodeToISOHDR;
         } else if (encodeToHDR == 2) {
-            properties[(__bridge NSString *)kCGImageDestinationEncodeRequest] = (__bridge NSString *)kCGImageDestinationEncodeToISOGainmap;
+            properties[kSDCGImageDestinationEncodeRequest] = kSDCGImageDestinationEncodeToISOGainmap;
         } else {
-            properties[(__bridge NSString *)kCGImageDestinationEncodeRequest] = (__bridge NSString *)kCGImageDestinationEncodeToSDR;
+            properties[kSDCGImageDestinationEncodeRequest] = kSDCGImageDestinationEncodeToSDR;
         }
     }
     

+ 21 - 3
SDWebImage/Core/SDImageIOCoder.m

@@ -18,6 +18,12 @@
 
 // Specify File Size for lossy format encoding, like JPEG
 static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestinationRequestedFileSize";
+// Support Xcode 15 SDK, use raw value instead of symbol
+static NSString * kSDCGImageDestinationEncodeRequest = @"kCGImageDestinationEncodeRequest";
+static NSString * kSDCGImageDestinationEncodeToSDR = @"kCGImageDestinationEncodeToSDR";
+static NSString * kSDCGImageDestinationEncodeToISOHDR = @"kCGImageDestinationEncodeToISOHDR";
+static NSString * kSDCGImageDestinationEncodeToISOGainmap = @"kCGImageDestinationEncodeToISOGainmap";
+
 
 @implementation SDImageIOCoder {
     size_t _width, _height;
@@ -31,6 +37,18 @@ static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestination
     BOOL _decodeToHDR;
 }
 
+#if SD_IMAGEIO_HDR_ENCODING
++ (void)initialize {
+    if (@available(macOS 15, iOS 18, tvOS 18, watchOS 11, *)) {
+        // Use SDK instead of raw value
+        kSDCGImageDestinationEncodeRequest = (__bridge NSString *)kCGImageDestinationEncodeRequest;
+        kSDCGImageDestinationEncodeToSDR = (__bridge NSString *)kCGImageDestinationEncodeToSDR;
+        kSDCGImageDestinationEncodeToISOHDR = (__bridge NSString *)kCGImageDestinationEncodeToISOHDR;
+        kSDCGImageDestinationEncodeToISOGainmap = (__bridge NSString *)kCGImageDestinationEncodeToISOGainmap;
+    }
+}
+#endif
+
 - (void)dealloc {
     if (_imageSource) {
         CFRelease(_imageSource);
@@ -388,11 +406,11 @@ static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestination
     }
     if (@available(macOS 15, iOS 18, tvOS 18, watchOS 11, *)) {
         if (encodeToHDR == 1) {
-            properties[(__bridge NSString *)kCGImageDestinationEncodeRequest] = (__bridge NSString *)kCGImageDestinationEncodeToISOHDR;
+            properties[kSDCGImageDestinationEncodeRequest] = kSDCGImageDestinationEncodeToISOHDR;
         } else if (encodeToHDR == 2) {
-            properties[(__bridge NSString *)kCGImageDestinationEncodeRequest] = (__bridge NSString *)kCGImageDestinationEncodeToISOGainmap;
+            properties[kSDCGImageDestinationEncodeRequest] = kSDCGImageDestinationEncodeToISOGainmap;
         } else {
-            properties[(__bridge NSString *)kCGImageDestinationEncodeRequest] = (__bridge NSString *)kCGImageDestinationEncodeToSDR;
+            properties[kSDCGImageDestinationEncodeRequest] = kSDCGImageDestinationEncodeToSDR;
         }
     }
     

+ 3 - 0
SDWebImage/Private/SDImageIOAnimatedCoderInternal.h

@@ -10,6 +10,9 @@
 #import <ImageIO/ImageIO.h>
 #import "SDImageIOAnimatedCoder.h"
 
+// Xcode 16 SDK contains HDR encoding API, but we still support Xcode 15
+#define SD_IMAGEIO_HDR_ENCODING (__IPHONE_OS_VERSION_MAX_ALLOWED >= 180000)
+
 // 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")

+ 3 - 1
Tests/Tests/SDImageCoderTests.m

@@ -891,9 +891,11 @@ withLocalImageURL:(NSURL *)imageUrl
 
 - (NSDictionary *)gainMapFromImageSource:(CGImageSourceRef)source {
     if (@available(macOS 15, iOS 18, tvOS 18, watchOS 11, *)) {
-        CFDictionaryRef HDRGainMap = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeHDRGainMap);
         CFDictionaryRef ISOGainMap = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeISOGainMap);
+        CFDictionaryRef HDRGainMap = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeHDRGainMap);
         NSDictionary *result = ISOGainMap ? (__bridge_transfer NSDictionary *)ISOGainMap : (__bridge_transfer NSDictionary *)HDRGainMap;
+        if (HDRGainMap) CFRelease(HDRGainMap);
+        if (ISOGainMap) CFRelease(ISOGainMap);
         return result;
     } else {
         return nil;