Skip to content

Commit 9f766bc

Browse files
committed
test: added test case about Apple ImageIO HDR encoding
this need iOS 18 and macOS 15 device (not simulator)
1 parent 0d028c6 commit 9f766bc

File tree

1 file changed

+68
-3
lines changed

1 file changed

+68
-3
lines changed

Tests/Tests/SDImageCoderTests.m

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -666,9 +666,6 @@ - (void)test32ThatISOHDRDecodeWorks {
666666
expect(SDRBPC).beLessThanOrEqualTo(8);
667667
expect([SDRImage sd_colorAtPoint:CGPointMake(1, 1)]).notTo.beNil();
668668
#endif
669-
670-
// FIXME: Encoding need iOS 18+/macOS 15+
671-
// And need test both GainMap HDR or ISO HDR, TODO
672669
}
673670
}
674671
#endif
@@ -706,6 +703,63 @@ - (void)test33ThatGainMapHDRDecodeWorks {
706703
#endif
707704
}
708705

706+
- (void)test34ThatHDREncodeWorks {
707+
// FIXME: Encoding need iOS 18+/macOS 15+
708+
// GitHub Action virtualization framework contains issue for Gain Map HDR convert:
709+
if (SDTestCase.isCI) {
710+
return;
711+
}
712+
// Actually we test 4 cases, because decoded CGImage can contains gain map or not
713+
// heic -> heic / heic -> jpeg / jpeg(gain map) -> heic / jpeg(gain map) -> jpeg
714+
if (@available(macOS 15, iOS 18, tvOS 18, watchOS 11, *)) {
715+
NSArray *decodeFormats = @[@"heic", @"jpeg"];
716+
for (NSString *decodeFormat in decodeFormats) {
717+
NSURL *url = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestHDR" withExtension:decodeFormat];
718+
NSData *data = [NSData dataWithContentsOfURL:url];
719+
// Decoding
720+
UIImage *HDRImage = [SDImageIOCoder.sharedCoder decodedImageWithData:data options:@{SDImageCoderDecodeToHDR : @(YES)}];
721+
float headroom = CGImageGetContentHeadroom(HDRImage.CGImage);
722+
expect(headroom).beGreaterThan(1);
723+
724+
NSArray *encodeFormats = @[@"heic", @"jpeg"];
725+
for (NSString *encodeFormat in encodeFormats) {
726+
NSLog(@"Testing HDR encodde from original : %@ to %@", decodeFormat, encodeFormat);
727+
// HEIC with ISO Gain Map
728+
SDImageFormat format = SDImageFormatHEIC;
729+
if ([encodeFormat isEqualToString:@"jpeg"]) {
730+
// JPEG with XMP Gain Map
731+
format = SDImageFormatJPEG;
732+
}
733+
NSData *SDRData = [SDImageIOCoder.sharedCoder encodedDataWithImage:HDRImage format:format options:@{SDImageCoderEncodeToHDR : @(0)}];
734+
NSData *HDRData = [SDImageIOCoder.sharedCoder encodedDataWithImage:HDRImage format:format options:@{SDImageCoderEncodeToHDR : @(1)}];
735+
NSData *HDRGainMapData = [SDImageIOCoder.sharedCoder encodedDataWithImage:HDRImage format:format options:@{SDImageCoderEncodeToHDR : @(2)}];
736+
expect(SDRData).notTo.beNil();
737+
expect(HDRData).notTo.beNil();
738+
expect(HDRGainMapData).notTo.beNil();
739+
// JPEG has no built-in support Gain Map, so it stored in XMP and be larger
740+
if ([encodeFormat isEqualToString:@"jpeg"]) {
741+
expect(HDRGainMapData.length).beGreaterThan(HDRData.length);
742+
}
743+
744+
// Check gain map information
745+
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)HDRGainMapData, NULL);
746+
NSDictionary *gainMap = [self gainMapFromImageSource:source];
747+
expect(gainMap.count).beGreaterThan(0);
748+
// At least gain map contains `kCGImageAuxiliaryDataInfoMetadata`
749+
CGImageMetadataRef meta = (__bridge CGImageMetadataRef)(gainMap[(__bridge NSString *)kCGImageAuxiliaryDataInfoMetadata]);
750+
expect(meta).notTo.beNil();
751+
752+
// A check for redecoded CGImage
753+
CGImageRef redecodeSDRImage = CGImageSourceCreateImageAtIndex(source, 0, nil);
754+
expect(redecodeSDRImage).notTo.beNil();
755+
headroom = CGImageGetContentHeadroom(redecodeSDRImage);
756+
expect(headroom).equal(1);
757+
CFRelease(source);
758+
}
759+
}
760+
}
761+
}
762+
709763
#pragma mark - Utils
710764

711765
- (void)verifyCoder:(id<SDImageCoder>)coder
@@ -835,6 +889,17 @@ - (NSArray *)thumbnailImagesFromImageSource:(CGImageSourceRef)source API_AVAILAB
835889
return thumbnailImages;
836890
}
837891

892+
- (NSDictionary *)gainMapFromImageSource:(CGImageSourceRef)source {
893+
if (@available(macOS 15, iOS 18, tvOS 18, watchOS 11, *)) {
894+
CFDictionaryRef HDRGainMap = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeHDRGainMap);
895+
CFDictionaryRef ISOGainMap = CGImageSourceCopyAuxiliaryDataInfoAtIndex(source, 0, kCGImageAuxiliaryDataTypeISOGainMap);
896+
NSDictionary *result = ISOGainMap ? (__bridge_transfer NSDictionary *)ISOGainMap : (__bridge_transfer NSDictionary *)HDRGainMap;
897+
return result;
898+
} else {
899+
return nil;
900+
}
901+
}
902+
838903
#pragma mark - Utils
839904
- (CGRect)boxRectFromPDFData:(nonnull NSData *)data {
840905
CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);

0 commit comments

Comments
 (0)