Merge pull request #3743 from dreampiggy/bugfix/fix_jfif_orientation_new_solution

Fix the thumbnail decoding on JPEG which contains EXIF orientation, use the new way to workaround JFIF bug
This commit is contained in:
DreamPiggy 2024-08-22 15:28:01 +08:00 committed by GitHub
commit 0a4f92c59a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 16 additions and 9 deletions

View File

@ -27,8 +27,6 @@ static CGImageSourceRef (*SDCGImageGetImageSource)(CGImageRef);
// Specify File Size for lossy format encoding, like JPEG
static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestinationRequestedFileSize";
// Avoid ImageIO translate JFIF orientation to EXIF orientation which cause bug because returned CGImage already apply the orientation transform
static NSString * kSDCGImageSourceSkipMetadata = @"kCGImageSourceSkipMetadata";
// 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
@ -440,12 +438,13 @@ static BOOL SDImageIOPNGPluginBuggyNeedWorkaround(void) {
}
}
// Parse the image properties
NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, index, (__bridge CFDictionaryRef)@{kSDCGImageSourceSkipMetadata : @(YES)});
NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, index, NULL);
CGFloat pixelWidth = [properties[(__bridge NSString *)kCGImagePropertyPixelWidth] doubleValue];
CGFloat pixelHeight = [properties[(__bridge NSString *)kCGImagePropertyPixelHeight] doubleValue];
CGImagePropertyOrientation exifOrientation = (CGImagePropertyOrientation)[properties[(__bridge NSString *)kCGImagePropertyOrientation] unsignedIntegerValue];
if (!exifOrientation) {
exifOrientation = kCGImagePropertyOrientationUp;
CGImagePropertyOrientation exifOrientation = kCGImagePropertyOrientationUp;
NSNumber *exifOrientationValue = properties[(__bridge NSString *)kCGImagePropertyOrientation];
if (exifOrientationValue != NULL) {
exifOrientation = [exifOrientationValue unsignedIntValue];
}
NSMutableDictionary *decodingOptions;

View File

@ -547,15 +547,23 @@
}
- (void)test29ThatJFIFDecodeOrientationShouldNotApplyTwice {
// I don't think this is SDWebImage's issue, it's Apple's ImgeIO Bug, but user complain about this: #3594
// In W3C standard, JFIF should always be orientation up, and should not contains EXIF orientation
// But some bad image editing tool will generate this kind of image :(
NSURL *url = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestJFIF" withExtension:@"jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [SDImageIOCoder.sharedCoder decodedImageWithData:data options:nil];
expect(image.sd_imageFormat).equal(SDImageFormatJPEG);
#if SD_UIKIT
UIImageOrientation orientation = image.imageOrientation;
expect(orientation).equal(UIImageOrientationUp);
#else
expect(image.sd_imageFormat).equal(SDImageFormatJPEG);
expect(orientation).equal(UIImageOrientationDown);
#endif
UIImage *systemImage = [[UIImage alloc] initWithData:data];
#if SD_UIKIT
orientation = image.imageOrientation;
expect(orientation).equal(UIImageOrientationDown);
#endif
// Manual test again for Apple's API