Resize link preview images if necessary.

This commit is contained in:
Matthew Chen 2019-01-24 13:28:54 -05:00
parent 9b33d70d7b
commit 9149282e94
9 changed files with 66 additions and 31 deletions

View File

@ -60,7 +60,6 @@
343A65981FC4CFE7000477A1 /* ConversationScrollButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 343A65961FC4CFE6000477A1 /* ConversationScrollButton.m */; };
3441FD9F21A3604F00BB9542 /* BackupRestoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3441FD9E21A3604F00BB9542 /* BackupRestoreViewController.swift */; };
34480B361FD0929200BC14EF /* ShareAppExtensionContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 34480B351FD0929200BC14EF /* ShareAppExtensionContext.m */; };
34480B491FD0A60200BC14EF /* OWSMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 34480B481FD0A60200BC14EF /* OWSMath.h */; settings = {ATTRIBUTES = (Public, ); }; };
34480B551FD0A7A400BC14EF /* DebugLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 34480B4D1FD0A7A300BC14EF /* DebugLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
34480B561FD0A7A400BC14EF /* DebugLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 34480B4E1FD0A7A300BC14EF /* DebugLogger.m */; };
34480B571FD0A7A400BC14EF /* OWSScrubbingLogFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 34480B4F1FD0A7A300BC14EF /* OWSScrubbingLogFormatter.h */; };
@ -710,7 +709,6 @@
34480B351FD0929200BC14EF /* ShareAppExtensionContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShareAppExtensionContext.m; sourceTree = "<group>"; };
34480B371FD092A900BC14EF /* SignalShareExtension-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SignalShareExtension-Bridging-Header.h"; sourceTree = "<group>"; };
34480B381FD092E300BC14EF /* SignalShareExtension-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SignalShareExtension-Prefix.pch"; sourceTree = "<group>"; };
34480B481FD0A60200BC14EF /* OWSMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMath.h; sourceTree = "<group>"; };
34480B4D1FD0A7A300BC14EF /* DebugLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugLogger.h; sourceTree = "<group>"; };
34480B4E1FD0A7A300BC14EF /* DebugLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugLogger.m; sourceTree = "<group>"; };
34480B4F1FD0A7A300BC14EF /* OWSScrubbingLogFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSScrubbingLogFormatter.h; sourceTree = "<group>"; };
@ -1564,7 +1562,6 @@
346129AA1FD1F0EE00532771 /* OWSFormat.m */,
45666EC71D994C0D008FE134 /* OWSGroupAvatarBuilder.h */,
45666EC81D994C0D008FE134 /* OWSGroupAvatarBuilder.m */,
34480B481FD0A60200BC14EF /* OWSMath.h */,
346129371FD1B47200532771 /* OWSPreferences.h */,
346129381FD1B47200532771 /* OWSPreferences.m */,
34641E172088D7E900E2EDE5 /* OWSScreenLock.swift */,
@ -2606,7 +2603,6 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
34480B491FD0A60200BC14EF /* OWSMath.h in Headers */,
346129E71FD5C0C600532771 /* OWSDatabaseMigrationRunner.h in Headers */,
34AC09F9211B39B100997B47 /* CountryCodeViewController.h in Headers */,
34ABB2C52090C59700C727A6 /* OWSResaveCollectionDBMigration.h in Headers */,

View File

@ -24,7 +24,6 @@
#import <SignalMessaging/AppSetup.h>
#import <SignalMessaging/Environment.h>
#import <SignalMessaging/OWSContactsManager.h>
#import <SignalMessaging/OWSMath.h>
#import <SignalMessaging/OWSNavigationController.h>
#import <SignalMessaging/OWSPreferences.h>
#import <SignalMessaging/OWSProfileManager.h>
@ -38,6 +37,7 @@
#import <SignalServiceKit/OWSFailedAttachmentDownloadsJob.h>
#import <SignalServiceKit/OWSFailedMessagesJob.h>
#import <SignalServiceKit/OWSIncompleteCallsJob.h>
#import <SignalServiceKit/OWSMath.h>
#import <SignalServiceKit/OWSMessageManager.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSPrimaryStorage+Calling.h>

View File

@ -6,9 +6,9 @@
#import "OWSAvatarBuilder.h"
#import "Signal-Swift.h"
#import <SignalMessaging/OWSFormat.h>
#import <SignalMessaging/OWSMath.h>
#import <SignalMessaging/OWSUserProfile.h>
#import <SignalMessaging/SignalMessaging-Swift.h>
#import <SignalServiceKit/OWSMath.h>
#import <SignalServiceKit/OWSMessageManager.h>
#import <SignalServiceKit/TSContactThread.h>
#import <SignalServiceKit/TSGroupThread.h>

View File

@ -1,10 +1,10 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "OWSProgressView.h"
#import <SignalMessaging/OWSMath.h>
#import <SignalMessaging/UIView+OWS.h>
#import <SignalServiceKit/OWSMath.h>
NS_ASSUME_NONNULL_BEGIN

View File

@ -31,7 +31,6 @@ FOUNDATION_EXPORT const unsigned char SignalMessagingVersionString[];
#import <SignalMessaging/OWSDatabaseMigration.h>
#import <SignalMessaging/OWSFormat.h>
#import <SignalMessaging/OWSGroupAvatarBuilder.h>
#import <SignalMessaging/OWSMath.h>
#import <SignalMessaging/OWSNavigationController.h>
#import <SignalMessaging/OWSPreferences.h>
#import <SignalMessaging/OWSProfileManager.h>

View File

@ -2,8 +2,8 @@
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "OWSMath.h"
#import <PureLayout/PureLayout.h>
#import <SignalServiceKit/OWSMath.h>
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN

View File

@ -12,6 +12,7 @@ public enum LinkPreviewError: Int, Error {
case assertionFailure
case couldNotDownload
case featureDisabled
case invalidContent
}
// MARK: - OWSLinkPreviewDraft
@ -540,7 +541,7 @@ public class OWSLinkPreview: MTLModel {
return promise
}
private class func downloadImage(url urlString: String) -> Promise<Data> {
private class func downloadImage(url urlString: String, imageMimeType: String) -> Promise<Data> {
Logger.verbose("url: \(urlString)")
@ -566,8 +567,32 @@ public class OWSLinkPreview: MTLModel {
}
return promise.then(on: DispatchQueue.global()) { (asset: ProxiedContentAsset) -> Promise<Data> in
do {
let imageSize = NSData.imageSize(forFilePath: asset.filePath, mimeType: imageMimeType)
guard imageSize.width > 0, imageSize.height > 0 else {
Logger.error("Link preview is invalid or has invalid size.")
return Promise(error: LinkPreviewError.invalidContent)
}
let data = try Data(contentsOf: URL(fileURLWithPath: asset.filePath))
return Promise.value(data)
let maxImageSize: CGFloat = 1024
let shouldResize = imageSize.width > maxImageSize || imageSize.height > maxImageSize
guard shouldResize else {
return Promise.value(data)
}
guard let srcImage = UIImage(data: data) else {
Logger.error("Could not parse image.")
return Promise(error: LinkPreviewError.invalidContent)
}
guard let dstImage = srcImage.resized(withMaxDimensionPoints: maxImageSize) else {
Logger.error("Could not resize image.")
return Promise(error: LinkPreviewError.invalidContent)
}
guard let dstData = UIImageJPEGRepresentation(dstImage, 0.8) else {
Logger.error("Could not write resized image.")
return Promise(error: LinkPreviewError.invalidContent)
}
return Promise.value(dstData)
} catch {
owsFailDebug("Could not load asset data: \(type(of: asset.filePath)).")
return Promise(error: LinkPreviewError.assertionFailure)
@ -617,27 +642,16 @@ public class OWSLinkPreview: MTLModel {
Logger.error("Invalid image URL.")
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
}
Logger.verbose("imageUrlString: \(imageUrlString)")
guard let imageUrl = URL(string: imageUrlString) else {
Logger.error("Could not parse image URL.")
guard let imageFileExtension = fileExtension(forImageUrl: imageUrlString) else {
Logger.error("Image URL has unknown or invalid file extension: \(imageUrlString).")
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
}
let imageFilename = imageUrl.lastPathComponent
let imageFileExtension = (imageFilename as NSString).pathExtension.lowercased()
guard let imageMimeType = MIMETypeUtil.mimeType(forFileExtension: imageFileExtension) else {
Logger.error("Image URL has unknown content type: \(imageFileExtension).")
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
}
let kValidMimeTypes = [
OWSMimeTypeImagePng,
OWSMimeTypeImageJpeg
]
guard kValidMimeTypes.contains(imageMimeType) else {
Logger.error("Image URL has invalid content type: \(imageMimeType).")
guard let imageMimeType = mimetype(forImageFileExtension: imageFileExtension) else {
Logger.error("Image URL has unknown or invalid content type: \(imageUrlString).")
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
}
return downloadImage(url: imageUrlString)
return downloadImage(url: imageUrlString, imageMimeType: imageMimeType)
.then(on: DispatchQueue.global()) { (imageData: Data) -> Promise<OWSLinkPreviewDraft> in
let imageFilePath = OWSFileSystem.temporaryFilePath(withFileExtension: imageFileExtension)
do {
@ -665,6 +679,32 @@ public class OWSLinkPreview: MTLModel {
}
}
private class func fileExtension(forImageUrl urlString: String) -> String? {
guard let imageUrl = URL(string: urlString) else {
Logger.error("Could not parse image URL.")
return nil
}
let imageFilename = imageUrl.lastPathComponent
let imageFileExtension = (imageFilename as NSString).pathExtension.lowercased()
return imageFileExtension
}
private class func mimetype(forImageFileExtension imageFileExtension: String) -> String? {
guard let imageMimeType = MIMETypeUtil.mimeType(forFileExtension: imageFileExtension) else {
Logger.error("Image URL has unknown content type: \(imageFileExtension).")
return nil
}
let kValidMimeTypes = [
OWSMimeTypeImagePng,
OWSMimeTypeImageJpeg
]
guard kValidMimeTypes.contains(imageMimeType) else {
Logger.error("Image URL has invalid content type: \(imageMimeType).")
return nil
}
return imageMimeType
}
private class func decodeHTMLEntities(inString value: String) -> String? {
guard let data = value.data(using: .utf8) else {
return nil

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN

View File

@ -1,5 +1,5 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <Foundation/Foundation.h>
@ -14,7 +14,6 @@
#import <SignalMessaging/DebugLogger.h>
#import <SignalMessaging/Environment.h>
#import <SignalMessaging/OWSContactsManager.h>
#import <SignalMessaging/OWSMath.h>
#import <SignalMessaging/OWSPreferences.h>
#import <SignalMessaging/UIColor+OWS.h>
#import <SignalMessaging/UIFont+OWS.h>
@ -23,5 +22,6 @@
#import <SignalServiceKit/AppContext.h>
#import <SignalServiceKit/AppReadiness.h>
#import <SignalServiceKit/AppVersion.h>
#import <SignalServiceKit/OWSMath.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/TSAccountManager.h>