Merge pull request #3597 from dreampiggy/bugfix/jfif_orientation
Fix the JFIF image orientation bug (which does not use EXIF but JFIF metadata)
This commit is contained in:
commit
f62ae2adf8
|
@ -27,6 +27,8 @@ static CGImageSourceRef (*SDCGImageGetImageSource)(CGImageRef);
|
||||||
|
|
||||||
// Specify File Size for lossy format encoding, like JPEG
|
// Specify File Size for lossy format encoding, like JPEG
|
||||||
static NSString * kSDCGImageDestinationRequestedFileSize = @"kCGImageDestinationRequestedFileSize";
|
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+
|
// 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
|
// However, CGImageCreateCopy still keep those CGImageProperty, not suit for our use case
|
||||||
|
@ -232,7 +234,7 @@ static CGImageRef __nullable SDCGImageCreateCopy(CGImageRef cg_nullable image) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Parse the image properties
|
// Parse the image properties
|
||||||
NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, index, NULL);
|
NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, index, (__bridge CFDictionaryRef)@{kSDCGImageSourceSkipMetadata : @(YES)});
|
||||||
CGFloat pixelWidth = [properties[(__bridge NSString *)kCGImagePropertyPixelWidth] doubleValue];
|
CGFloat pixelWidth = [properties[(__bridge NSString *)kCGImagePropertyPixelWidth] doubleValue];
|
||||||
CGFloat pixelHeight = [properties[(__bridge NSString *)kCGImagePropertyPixelHeight] doubleValue];
|
CGFloat pixelHeight = [properties[(__bridge NSString *)kCGImagePropertyPixelHeight] doubleValue];
|
||||||
CGImagePropertyOrientation exifOrientation = (CGImagePropertyOrientation)[properties[(__bridge NSString *)kCGImagePropertyOrientation] unsignedIntegerValue];
|
CGImagePropertyOrientation exifOrientation = (CGImagePropertyOrientation)[properties[(__bridge NSString *)kCGImagePropertyOrientation] unsignedIntegerValue];
|
||||||
|
|
|
@ -38,6 +38,9 @@
|
||||||
32648067250232F7004FA0FC /* 1@2x.gif in Resources */ = {isa = PBXBuildFile; fileRef = 32648066250232F7004FA0FC /* 1@2x.gif */; };
|
32648067250232F7004FA0FC /* 1@2x.gif in Resources */ = {isa = PBXBuildFile; fileRef = 32648066250232F7004FA0FC /* 1@2x.gif */; };
|
||||||
32648068250232F7004FA0FC /* 1@2x.gif in Resources */ = {isa = PBXBuildFile; fileRef = 32648066250232F7004FA0FC /* 1@2x.gif */; };
|
32648068250232F7004FA0FC /* 1@2x.gif in Resources */ = {isa = PBXBuildFile; fileRef = 32648066250232F7004FA0FC /* 1@2x.gif */; };
|
||||||
32648069250232F7004FA0FC /* 1@2x.gif in Resources */ = {isa = PBXBuildFile; fileRef = 32648066250232F7004FA0FC /* 1@2x.gif */; };
|
32648069250232F7004FA0FC /* 1@2x.gif in Resources */ = {isa = PBXBuildFile; fileRef = 32648066250232F7004FA0FC /* 1@2x.gif */; };
|
||||||
|
3264CD172AAB1E23001E338B /* TestJFIF.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 3264CD162AAB1E23001E338B /* TestJFIF.jpg */; };
|
||||||
|
3264CD182AAB1E23001E338B /* TestJFIF.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 3264CD162AAB1E23001E338B /* TestJFIF.jpg */; };
|
||||||
|
3264CD192AAB1E23001E338B /* TestJFIF.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 3264CD162AAB1E23001E338B /* TestJFIF.jpg */; };
|
||||||
3264FF2F205D42CB00F6BD48 /* SDWebImageTestTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */; };
|
3264FF2F205D42CB00F6BD48 /* SDWebImageTestTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */; };
|
||||||
3264FF30205D42CB00F6BD48 /* SDWebImageTestTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */; };
|
3264FF30205D42CB00F6BD48 /* SDWebImageTestTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */; };
|
||||||
326E69472334C0C300B7252C /* TestLoopCount.gif in Resources */ = {isa = PBXBuildFile; fileRef = 326E69462334C0C200B7252C /* TestLoopCount.gif */; };
|
326E69472334C0C300B7252C /* TestLoopCount.gif in Resources */ = {isa = PBXBuildFile; fileRef = 326E69462334C0C200B7252C /* TestLoopCount.gif */; };
|
||||||
|
@ -141,6 +144,7 @@
|
||||||
32515F9824AF1919005E8F79 /* TestImageAnimated.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageAnimated.webp; sourceTree = "<group>"; };
|
32515F9824AF1919005E8F79 /* TestImageAnimated.webp */ = {isa = PBXFileReference; lastKnownFileType = file; path = TestImageAnimated.webp; sourceTree = "<group>"; };
|
||||||
3254C31F20641077008D1022 /* SDImageTransformerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDImageTransformerTests.m; sourceTree = "<group>"; };
|
3254C31F20641077008D1022 /* SDImageTransformerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDImageTransformerTests.m; sourceTree = "<group>"; };
|
||||||
32648066250232F7004FA0FC /* 1@2x.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "1@2x.gif"; sourceTree = "<group>"; };
|
32648066250232F7004FA0FC /* 1@2x.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "1@2x.gif"; sourceTree = "<group>"; };
|
||||||
|
3264CD162AAB1E23001E338B /* TestJFIF.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = TestJFIF.jpg; sourceTree = "<group>"; };
|
||||||
3264FF2D205D42CB00F6BD48 /* SDWebImageTestTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTestTransformer.h; sourceTree = "<group>"; };
|
3264FF2D205D42CB00F6BD48 /* SDWebImageTestTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDWebImageTestTransformer.h; sourceTree = "<group>"; };
|
||||||
3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTestTransformer.m; sourceTree = "<group>"; };
|
3264FF2E205D42CB00F6BD48 /* SDWebImageTestTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDWebImageTestTransformer.m; sourceTree = "<group>"; };
|
||||||
326E69462334C0C200B7252C /* TestLoopCount.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = TestLoopCount.gif; sourceTree = "<group>"; };
|
326E69462334C0C200B7252C /* TestLoopCount.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = TestLoopCount.gif; sourceTree = "<group>"; };
|
||||||
|
@ -264,6 +268,7 @@
|
||||||
32648066250232F7004FA0FC /* 1@2x.gif */,
|
32648066250232F7004FA0FC /* 1@2x.gif */,
|
||||||
433BBBBA1D7EFA8B0086B6E9 /* MonochromeTestImage.jpg */,
|
433BBBBA1D7EFA8B0086B6E9 /* MonochromeTestImage.jpg */,
|
||||||
324047432271956F007C53E1 /* TestEXIF.png */,
|
324047432271956F007C53E1 /* TestEXIF.png */,
|
||||||
|
3264CD162AAB1E23001E338B /* TestJFIF.jpg */,
|
||||||
321F310D27D0DC490042B274 /* TestImage.bmp */,
|
321F310D27D0DC490042B274 /* TestImage.bmp */,
|
||||||
433BBBB61D7EF8200086B6E9 /* TestImage.gif */,
|
433BBBB61D7EF8200086B6E9 /* TestImage.gif */,
|
||||||
326E69462334C0C200B7252C /* TestLoopCount.gif */,
|
326E69462334C0C200B7252C /* TestLoopCount.gif */,
|
||||||
|
@ -481,6 +486,7 @@
|
||||||
files = (
|
files = (
|
||||||
32F788A5290D252200B57A1C /* TestImage.nef in Resources */,
|
32F788A5290D252200B57A1C /* TestImage.nef in Resources */,
|
||||||
6BC1C210270F073A003FFAB1 /* TestAnimatedImageMemory.webp in Resources */,
|
6BC1C210270F073A003FFAB1 /* TestAnimatedImageMemory.webp in Resources */,
|
||||||
|
3264CD192AAB1E23001E338B /* TestJFIF.jpg in Resources */,
|
||||||
3299228D2365DC6C00EAFD97 /* TestImageAnimated.apng in Resources */,
|
3299228D2365DC6C00EAFD97 /* TestImageAnimated.apng in Resources */,
|
||||||
3299228B2365DC6C00EAFD97 /* TestImage.heic in Resources */,
|
3299228B2365DC6C00EAFD97 /* TestImage.heic in Resources */,
|
||||||
329922872365DC6C00EAFD97 /* TestLoopCount.gif in Resources */,
|
329922872365DC6C00EAFD97 /* TestLoopCount.gif in Resources */,
|
||||||
|
@ -507,6 +513,7 @@
|
||||||
files = (
|
files = (
|
||||||
32F788A4290D252200B57A1C /* TestImage.nef in Resources */,
|
32F788A4290D252200B57A1C /* TestImage.nef in Resources */,
|
||||||
6BC1C20F270F0193003FFAB1 /* TestAnimatedImageMemory.webp in Resources */,
|
6BC1C20F270F0193003FFAB1 /* TestAnimatedImageMemory.webp in Resources */,
|
||||||
|
3264CD182AAB1E23001E338B /* TestJFIF.jpg in Resources */,
|
||||||
327054E3206CEFF3006EA328 /* TestImageAnimated.apng in Resources */,
|
327054E3206CEFF3006EA328 /* TestImageAnimated.apng in Resources */,
|
||||||
32B99EA3203B31360017FD66 /* TestImage.gif in Resources */,
|
32B99EA3203B31360017FD66 /* TestImage.gif in Resources */,
|
||||||
324047452271956F007C53E1 /* TestEXIF.png in Resources */,
|
324047452271956F007C53E1 /* TestEXIF.png in Resources */,
|
||||||
|
@ -533,6 +540,7 @@
|
||||||
files = (
|
files = (
|
||||||
32F788A3290D252200B57A1C /* TestImage.nef in Resources */,
|
32F788A3290D252200B57A1C /* TestImage.nef in Resources */,
|
||||||
327A418C211D660600495442 /* TestImage.heic in Resources */,
|
327A418C211D660600495442 /* TestImage.heic in Resources */,
|
||||||
|
3264CD172AAB1E23001E338B /* TestJFIF.jpg in Resources */,
|
||||||
6B181A1B265757ED00BD06B3 /* TestAnimatedImageMemory.webp in Resources */,
|
6B181A1B265757ED00BD06B3 /* TestAnimatedImageMemory.webp in Resources */,
|
||||||
5F7F38AD1AE2A77A00B0E330 /* TestImage.jpg in Resources */,
|
5F7F38AD1AE2A77A00B0E330 /* TestImage.jpg in Resources */,
|
||||||
32905E64211D786E00460FCF /* TestImage.heif in Resources */,
|
32905E64211D786E00460FCF /* TestImage.heif in Resources */,
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 2.4 MiB |
|
@ -540,6 +540,24 @@
|
||||||
XCTAssertTrue(newResult);
|
XCTAssertTrue(newResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)test29ThatJFIFDecodeOrientationShouldNotApplyTwice {
|
||||||
|
NSURL *url = [[NSBundle bundleForClass:[self class]] URLForResource:@"TestJFIF" withExtension:@"jpg"];
|
||||||
|
NSData *data = [NSData dataWithContentsOfURL:url];
|
||||||
|
|
||||||
|
UIImage *image = [SDImageIOCoder.sharedCoder decodedImageWithData:data options:nil];
|
||||||
|
#if SD_UIKIT
|
||||||
|
UIImageOrientation orientation = image.imageOrientation;
|
||||||
|
expect(orientation).equal(UIImageOrientationUp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Manual test again for Apple's API
|
||||||
|
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, nil);
|
||||||
|
NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, 0, nil);
|
||||||
|
NSUInteger exifOrientation = [properties[(__bridge NSString *)kCGImagePropertyOrientation] unsignedIntegerValue];
|
||||||
|
CFRelease(source);
|
||||||
|
expect(exifOrientation).equal(kCGImagePropertyOrientationDown);
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Utils
|
#pragma mark - Utils
|
||||||
|
|
||||||
- (void)verifyCoder:(id<SDImageCoder>)coder
|
- (void)verifyCoder:(id<SDImageCoder>)coder
|
||||||
|
|
Loading…
Reference in New Issue