Skip to content

Commit 92a7ab9

Browse files
committed
Support decoding ISO HDR (avif/heic/jpeg-xl, etc) (SDWebImage#3778)
* Support HDR * Support HDR * When using SDWebImageProgressiveLoad and setting it to SDWebImageContextImageDecodeToHDR, it will be decoded to HDR only when loading is complete. * When SDImageIOAnimatedCoder turns on incremental, it does not need to be decoded to HDR when it is not completed * Sample image to remove sensitive information * 1、use remote resources for HDR testing 2、add simulator log for HDR * Support HDR encode * Support HDR encode * imageRef release error * HDR Decoded is not required for decoding, otherwise the type will be lost * HDR encode format * hdrImageRef not released correctly * HDR image must be lazy decode * HDR image must be lazy decode * JEPG HDR image must be lazy decode, otherwise it will crash * HDR, encoding properties add kCGImageDestinationEncodeToISOGainmap, compatible with SDR displays while preserving HDR * 支持 decode to HDR * HDR encoding is not currently supported * add UIImage.sd_isHighDynamicRange, use check UIImage is HDR * refactor: Do not hack on HEICS and distinguish static/aniamted image encoding UTI * refactor: Move cross-platform screen info into SDDeviceHelper * change: Do not disable force decode when turn on decodeToHDR Need actually check the HDR info of CGImage, or better, we can pre-decode to drop lazy HDR image * change: use UIImage.imageRendererFormat when force decode using graphics renderer This can inherit the possible info like dynamic range * fix: When decode HDR image to SDR, need specify the decode request Tested on macOS 14.5 and iOS 18.0 behavior * test: Added unit test for HDR decoding * demo: Update the macOS demo to show the HDR image * test: workaround the SDR decode on Simulator environment * change: The `sd_isHighDynamicRange` should check CGImage as fallback as well * test: temp disable a unused test case --------- Co-authored-by: DreamPiggy <[email protected]>
1 parent e7d3256 commit 92a7ab9

29 files changed

+365
-117
lines changed

Examples/SDWebImage Demo/DetailViewController.m

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,21 @@ - (void)configureView {
2222
if (!self.imageView.sd_imageIndicator) {
2323
self.imageView.sd_imageIndicator = SDWebImageProgressIndicator.defaultIndicator;
2424
}
25+
BOOL isHDR = [self.imageURL.absoluteString containsString:@"HDR"];
26+
if (@available(iOS 17.0, *)) {
27+
self.imageView.preferredImageDynamicRange = isHDR ? UIImageDynamicRangeHigh : UIImageDynamicRangeUnspecified;
28+
}
29+
SDWebImageContext *context = @{
30+
SDWebImageContextImageDecodeToHDR: @(isHDR)
31+
};
2532
[self.imageView sd_setImageWithURL:self.imageURL
2633
placeholderImage:nil
27-
options:SDWebImageProgressiveLoad | SDWebImageScaleDownLargeImages
28-
context:@{SDWebImageContextImageForceDecodePolicy: @(SDImageForceDecodePolicyNever)}
29-
];
34+
options:SDWebImageFromLoaderOnly | SDWebImageScaleDownLargeImages
35+
context:context
36+
progress:nil
37+
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
38+
NSLog(@"isHighDynamicRange %@", @(image.sd_isHighDynamicRange));
39+
}];
3040
self.imageView.shouldCustomLoopCount = YES;
3141
self.imageView.animationRepeatCount = 0;
3242
}

Examples/SDWebImage Demo/MasterViewController.m

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibB
5959
[SDWebImageDownloader sharedDownloader].config.executionOrder = SDWebImageDownloaderLIFOExecutionOrder;
6060

6161
self.objects = [NSMutableArray arrayWithObjects:
62+
@"https://raw.githubusercontent.com/CloudlessMoon/SuperResources/master/Images/HEIC/TestHDR1.heic",
63+
@"https://raw.githubusercontent.com/CloudlessMoon/SuperResources/master/Images/JPG/TestHDR1.JPG",
64+
@"https://raw.githubusercontent.com/CloudlessMoon/SuperResources/master/Images/JPG/TestHDR2.JPG",
6265
@"http://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?0.35786508303135633", // requires HTTP auth, used to demo the NTLM auth
6366
@"http://assets.sbnation.com/assets/2512203/dogflops.gif",
6467
@"https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif",

Examples/SDWebImage OSX Demo/Base.lproj/Main.storyboard

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
2+
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="23094" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
33
<dependencies>
44
<deployment identifier="macosx"/>
5-
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
5+
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23094"/>
66
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
77
</dependencies>
88
<scenes>
@@ -677,35 +677,15 @@
677677
<rect key="frame" x="0.0" y="0.0" width="480" height="400"/>
678678
<autoresizingMask key="autoresizingMask"/>
679679
<subviews>
680-
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nbD-Cx-g7b">
681-
<rect key="frame" x="20" y="252" width="204" height="128"/>
682-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
683-
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="vAn-1d-apO"/>
684-
</imageView>
685-
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kv0-67-hkh">
686-
<rect key="frame" x="256" y="252" width="204" height="128"/>
687-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
688-
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="f0P-c9-GMe"/>
689-
</imageView>
690-
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JIp-Or-vBM" customClass="SDAnimatedImageView">
691-
<rect key="frame" x="20" y="116" width="204" height="128"/>
692-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
693-
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="NJq-m3-LlB"/>
694-
</imageView>
695-
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="khI-tY-l0M" customClass="SDAnimatedImageView">
696-
<rect key="frame" x="256" y="116" width="204" height="128"/>
697-
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
698-
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="WbV-Do-9qy"/>
699-
</imageView>
700680
<button translatesAutoresizingMaskIntoConstraints="NO" id="NqE-Zi-qhY">
701-
<rect key="frame" x="212" y="17" width="56" height="31"/>
702-
<constraints>
703-
<constraint firstAttribute="height" constant="26" id="WoQ-RY-bSV"/>
704-
</constraints>
681+
<rect key="frame" x="211" y="16" width="58" height="33"/>
705682
<buttonCell key="cell" type="bevel" title="Clear" bezelStyle="regularSquare" alignment="center" borderStyle="border" imageScaling="proportionallyUpOrDown" inset="2" id="OYN-fG-Plb">
706683
<behavior key="behavior" pushIn="YES" changeContents="YES" lightByContents="YES"/>
707684
<font key="font" metaFont="system"/>
708685
</buttonCell>
686+
<constraints>
687+
<constraint firstAttribute="height" constant="26" id="WoQ-RY-bSV"/>
688+
</constraints>
709689
</button>
710690
</subviews>
711691
<constraints>
@@ -715,10 +695,6 @@
715695
</view>
716696
<connections>
717697
<outlet property="clearCacheButton" destination="NqE-Zi-qhY" id="eoz-cU-wWs"/>
718-
<outlet property="imageView1" destination="nbD-Cx-g7b" id="t2R-8w-ybH"/>
719-
<outlet property="imageView2" destination="kv0-67-hkh" id="i4k-5c-bno"/>
720-
<outlet property="imageView3" destination="JIp-Or-vBM" id="Qcf-og-59T"/>
721-
<outlet property="imageView4" destination="khI-tY-l0M" id="STy-c1-ihV"/>
722698
</connections>
723699
</viewController>
724700
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>

Examples/SDWebImage OSX Demo/ViewController.m

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,15 @@
1111

1212
@interface ViewController ()
1313

14-
@property (weak) IBOutlet NSImageView *imageView1;
15-
@property (weak) IBOutlet NSImageView *imageView2;
16-
@property (weak) IBOutlet SDAnimatedImageView *imageView3;
17-
@property (weak) IBOutlet SDAnimatedImageView *imageView4;
14+
@property (strong) NSImageView *imageView1;
15+
@property (strong) SDAnimatedImageView *imageView2;
16+
17+
@property (strong) NSImageView *imageView3;
18+
@property (strong) SDAnimatedImageView *imageView4;
19+
20+
@property (strong) NSImageView *imageView5;
21+
@property (strong) NSImageView *imageView6;
22+
1823
@property (weak) IBOutlet NSButton *clearCacheButton;
1924

2025
@end
@@ -23,26 +28,39 @@ @implementation ViewController
2328

2429
- (void)viewDidLoad {
2530
[super viewDidLoad];
31+
self.imageView1 = [NSImageView new];
32+
self.imageView2 = [SDAnimatedImageView new];
33+
self.imageView3 = [NSImageView new];
34+
self.imageView4 = [SDAnimatedImageView new];
35+
self.imageView5 = [NSImageView new];
36+
self.imageView6 = [NSImageView new];
37+
38+
[self.view addSubview:self.imageView1];
39+
[self.view addSubview:self.imageView2];
40+
[self.view addSubview:self.imageView3];
41+
[self.view addSubview:self.imageView4];
42+
[self.view addSubview:self.imageView5];
43+
[self.view addSubview:self.imageView6];
2644

2745
// For animated GIF rendering, set `animates` to YES or will only show the first frame
28-
self.imageView2.animates = YES; // `SDAnimatedImageRep` can be used for built-in `NSImageView` to support better GIF & APNG rendering as well. No need `SDAnimatedImageView`
46+
self.imageView3.animates = YES; // `SDAnimatedImageRep` can be used for built-in `NSImageView` to support better GIF & APNG rendering as well. No need `SDAnimatedImageView`
2947
self.imageView4.animates = YES;
3048

49+
#pragma mark - Static Image
3150
// NSImageView + Static Image
3251
self.imageView1.sd_imageIndicator = SDWebImageProgressIndicator.defaultIndicator;
3352
[self.imageView1 sd_setImageWithURL:[NSURL URLWithString:@"https://raw.githubusercontent.com/recurser/exif-orientation-examples/master/Landscape_2.jpg"] placeholderImage:nil options:SDWebImageProgressiveLoad];
53+
// SDAnimatedImageView + Static Image
54+
[self.imageView2 sd_setImageWithURL:[NSURL URLWithString:@"https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png"]];
3455

56+
#pragma mark - Animated Image
3557
// NSImageView + Animated Image
36-
self.imageView2.sd_imageIndicator = SDWebImageActivityIndicator.largeIndicator;
37-
[self.imageView2 sd_setImageWithURL:[NSURL URLWithString:@"https://raw.githubusercontent.com/onevcat/APNGKit/2.2.0/Tests/APNGKitTests/Resources/General/APNG-cube.apng"]];
58+
self.imageView3.sd_imageIndicator = SDWebImageActivityIndicator.largeIndicator;
59+
[self.imageView3 sd_setImageWithURL:[NSURL URLWithString:@"https://raw.githubusercontent.com/onevcat/APNGKit/2.2.0/Tests/APNGKitTests/Resources/General/APNG-cube.apng"]];
3860
NSMenu *menu1 = [[NSMenu alloc] initWithTitle:@"Toggle Animation"];
3961
NSMenuItem *item1 = [menu1 addItemWithTitle:@"Toggle Animation" action:@selector(toggleAnimation:) keyEquivalent:@""];
4062
item1.tag = 1;
41-
self.imageView2.menu = menu1;
42-
43-
// SDAnimatedImageView + Static Image
44-
[self.imageView3 sd_setImageWithURL:[NSURL URLWithString:@"https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png"]];
45-
63+
self.imageView3.menu = menu1;
4664
// SDAnimatedImageView + Animated Image
4765
self.imageView4.sd_imageTransition = SDWebImageTransition.fadeTransition;
4866
self.imageView4.imageScaling = NSImageScaleProportionallyUpOrDown;
@@ -53,12 +71,36 @@ - (void)viewDidLoad {
5371
item2.tag = 2;
5472
self.imageView4.menu = menu2;
5573

74+
#pragma mark - HDR Image
75+
// HDR Image
76+
if (@available(macOS 14.0, *)) {
77+
self.imageView5.preferredImageDynamicRange = NSImageDynamicRangeHigh;
78+
self.imageView6.preferredImageDynamicRange = NSImageDynamicRangeHigh;
79+
}
80+
[self.imageView5 sd_setImageWithURL:[NSURL URLWithString:@"https://lightroom.adobe.com/v2c/spaces/113ab046f0d04b40aa7f8e10285961a7/assets/cd191116be514e1288ca6ea372303139/revisions/2749aff3294e404c9ffce3518e467d4a/renditions/99673919d096b42650b448f6516089cc.avif"] placeholderImage:nil options:0 context:@{SDWebImageContextImageDecodeToHDR : @(YES)}];
81+
// SDR Image
82+
[self.imageView6 sd_setImageWithURL:[NSURL URLWithString:@"https://lightroom.adobe.com/v2c/spaces/113ab046f0d04b40aa7f8e10285961a7/assets/cd191116be514e1288ca6ea372303139/revisions/2749aff3294e404c9ffce3518e467d4a/renditions/99673919d096b42650b448f6516089cc"] placeholderImage:nil options:0 context:@{SDWebImageContextImageDecodeToHDR : @(NO)}];
83+
5684
self.clearCacheButton.target = self;
5785
self.clearCacheButton.action = @selector(clearCacheButtonClicked:);
5886
[self.clearCacheButton sd_setImageWithURL:[NSURL URLWithString:@"https://png.icons8.com/color/100/000000/delete-sign.png"]];
5987
[self.clearCacheButton sd_setAlternateImageWithURL:[NSURL URLWithString:@"https://png.icons8.com/color/100/000000/checkmark.png"]];
6088
}
6189

90+
- (void)viewDidLayout {
91+
[super viewDidLayout];
92+
CGFloat space = 20;
93+
CGFloat imageWidth = (self.view.frame.size.width - space * 4) / 3;
94+
CGFloat imageHeight = (self.view.frame.size.height - space * 3) / 2;
95+
96+
self.imageView1.frame = CGRectMake(space * 1 + imageWidth * 0, space, imageWidth, imageHeight);
97+
self.imageView2.frame = CGRectMake(self.imageView1.frame.origin.x, self.imageView1.frame.origin.y + imageHeight + space, imageWidth, imageHeight);
98+
self.imageView3.frame = CGRectMake(space * 2 + imageWidth * 1, space, imageWidth, imageHeight);
99+
self.imageView4.frame = CGRectMake(self.imageView3.frame.origin.x, self.imageView3.frame.origin.y + imageHeight + space, imageWidth, imageHeight);
100+
self.imageView5.frame = CGRectMake(space * 3 + imageWidth * 2, space, imageWidth, imageHeight);
101+
self.imageView6.frame = CGRectMake(self.imageView5.frame.origin.x, self.imageView5.frame.origin.y + imageHeight + space, imageWidth, imageHeight);
102+
}
103+
62104
- (void)clearCacheButtonClicked:(NSResponder *)sender {
63105
NSButton *button = (NSButton *)sender;
64106
button.state = NSControlStateValueOn;
@@ -69,7 +111,7 @@ - (void)clearCacheButtonClicked:(NSResponder *)sender {
69111
}
70112

71113
- (void)toggleAnimation:(NSMenuItem *)sender {
72-
NSImageView *imageView = sender.tag == 1 ? self.imageView2 : self.imageView4;
114+
NSImageView *imageView = sender.tag == 1 ? self.imageView3 : self.imageView4;
73115
if (imageView.animates) {
74116
imageView.animates = NO;
75117
} else {

SDWebImage/Core/SDGraphicsImageRenderer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ typedef NS_ENUM(NSInteger, SDGraphicsImageRendererFormatRange) {
3434
/// A set of drawing attributes that represent the configuration of an image renderer context.
3535
@interface SDGraphicsImageRendererFormat : NSObject
3636

37+
#if SD_UIKIT
38+
/// The underlying uiformat for UIKit. This usage of this API should be careful, which may cause out of sync.
39+
@property (nonatomic, strong, nonnull) UIGraphicsImageRendererFormat *uiformat API_AVAILABLE(ios(10.0), tvos(10.0));
40+
#endif
41+
3742
/// The display scale of the image renderer context.
3843
/// The default value is equal to the scale of the main screen.
3944
@property (nonatomic) CGFloat scale;

SDWebImage/Core/SDGraphicsImageRenderer.m

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,7 @@
88

99
#import "SDGraphicsImageRenderer.h"
1010
#import "SDImageGraphics.h"
11-
12-
@interface SDGraphicsImageRendererFormat ()
13-
#if SD_UIKIT
14-
@property (nonatomic, strong) UIGraphicsImageRendererFormat *uiformat API_AVAILABLE(ios(10.0), tvos(10.0));
15-
#endif
16-
@end
11+
#import "SDDeviceHelper.h"
1712

1813
@implementation SDGraphicsImageRendererFormat
1914
@synthesize scale = _scale;
@@ -131,21 +126,7 @@ - (instancetype)init {
131126
self.uiformat = uiformat;
132127
} else {
133128
#endif
134-
#if SD_VISION
135-
CGFloat screenScale = UITraitCollection.currentTraitCollection.displayScale;
136-
#elif SD_WATCH
137-
CGFloat screenScale = [WKInterfaceDevice currentDevice].screenScale;
138-
#elif SD_UIKIT
139-
CGFloat screenScale = [UIScreen mainScreen].scale;
140-
#elif SD_MAC
141-
NSScreen *mainScreen = nil;
142-
if (@available(macOS 10.12, *)) {
143-
mainScreen = [NSScreen mainScreen];
144-
} else {
145-
mainScreen = [NSScreen screens].firstObject;
146-
}
147-
CGFloat screenScale = mainScreen.backingScaleFactor ?: 1.0f;
148-
#endif
129+
CGFloat screenScale = SDDeviceHelper.screenScale;
149130
self.scale = screenScale;
150131
self.opaque = NO;
151132
#if SD_UIKIT
@@ -172,21 +153,7 @@ - (instancetype)initForMainScreen {
172153
self.uiformat = uiformat;
173154
} else {
174155
#endif
175-
#if SD_VISION
176-
CGFloat screenScale = UITraitCollection.currentTraitCollection.displayScale;
177-
#elif SD_WATCH
178-
CGFloat screenScale = [WKInterfaceDevice currentDevice].screenScale;
179-
#elif SD_UIKIT
180-
CGFloat screenScale = [UIScreen mainScreen].scale;
181-
#elif SD_MAC
182-
NSScreen *mainScreen = nil;
183-
if (@available(macOS 10.12, *)) {
184-
mainScreen = [NSScreen mainScreen];
185-
} else {
186-
mainScreen = [NSScreen screens].firstObject;
187-
}
188-
CGFloat screenScale = mainScreen.backingScaleFactor ?: 1.0f;
189-
#endif
156+
CGFloat screenScale = SDDeviceHelper.screenScale;
190157
self.scale = screenScale;
191158
self.opaque = NO;
192159
#if SD_UIKIT

SDWebImage/Core/SDImageCacheDefine.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#import "SDAnimatedImage.h"
1313
#import "UIImage+Metadata.h"
1414
#import "SDInternalMacros.h"
15+
#import "SDDeviceHelper.h"
1516

1617
#import <CoreServices/CoreServices.h>
1718

@@ -49,6 +50,12 @@
4950
mutableCoderOptions = [NSMutableDictionary dictionaryWithCapacity:6];
5051
}
5152

53+
// Some options need preserve the custom decode options
54+
NSNumber *decodeToHDR = context[SDWebImageContextImageDecodeToHDR];
55+
if (decodeToHDR == nil) {
56+
decodeToHDR = mutableCoderOptions[SDImageCoderDecodeToHDR];
57+
}
58+
5259
// Override individual options
5360
mutableCoderOptions[SDImageCoderDecodeFirstFrameOnly] = @(decodeFirstFrame);
5461
mutableCoderOptions[SDImageCoderDecodeScaleFactor] = @(scale);
@@ -57,6 +64,7 @@
5764
mutableCoderOptions[SDImageCoderDecodeTypeIdentifierHint] = typeIdentifierHint;
5865
mutableCoderOptions[SDImageCoderDecodeFileExtensionHint] = fileExtensionHint;
5966
mutableCoderOptions[SDImageCoderDecodeScaleDownLimitBytes] = scaleDownLimitBytesValue;
67+
mutableCoderOptions[SDImageCoderDecodeToHDR] = decodeToHDR;
6068

6169
return [mutableCoderOptions copy];
6270
}
@@ -72,6 +80,7 @@ void SDSetDecodeOptionsToContext(SDWebImageMutableContext * _Nonnull mutableCont
7280
mutableContext[SDWebImageContextImagePreserveAspectRatio] = decodeOptions[SDImageCoderDecodePreserveAspectRatio];
7381
mutableContext[SDWebImageContextImageThumbnailPixelSize] = decodeOptions[SDImageCoderDecodeThumbnailPixelSize];
7482
mutableContext[SDWebImageContextImageScaleDownLimitBytes] = decodeOptions[SDImageCoderDecodeScaleDownLimitBytes];
83+
mutableContext[SDWebImageContextImageDecodeToHDR] = decodeOptions[SDImageCoderDecodeToHDR];
7584

7685
NSString *typeIdentifierHint = decodeOptions[SDImageCoderDecodeTypeIdentifierHint];
7786
if (!typeIdentifierHint) {

SDWebImage/Core/SDImageCoder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,14 @@ FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodeUseLazyDec
8888
*/
8989
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodeScaleDownLimitBytes;
9090

91+
/**
92+
A Boolean value to provide converting to HDR during decoding.
93+
@note Supported by iOS 17 and above when using ImageIO coder (third-party coder can support lower firmware)
94+
Defaults to NO, decoder will automatically convert SDR.
95+
@note works for `SDImageCoder`
96+
*/
97+
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderDecodeToHDR;
98+
9199
// These options are for image encoding
92100
/**
93101
A Boolean value indicating whether to encode the first frame only for animated image during encoding. (NSNumber). If not provide, encode animated image if need.

SDWebImage/Core/SDImageCoder.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
SDImageCoderOption const SDImageCoderDecodeTypeIdentifierHint = @"decodeTypeIdentifierHint";
1717
SDImageCoderOption const SDImageCoderDecodeUseLazyDecoding = @"decodeUseLazyDecoding";
1818
SDImageCoderOption const SDImageCoderDecodeScaleDownLimitBytes = @"decodeScaleDownLimitBytes";
19+
SDImageCoderOption const SDImageCoderDecodeToHDR = @"decodeToHDR";
1920

2021
SDImageCoderOption const SDImageCoderEncodeFirstFrameOnly = @"encodeFirstFrameOnly";
2122
SDImageCoderOption const SDImageCoderEncodeCompressionQuality = @"encodeCompressionQuality";

0 commit comments

Comments
 (0)