We need to change file extensions when converting data

// FREEBIE
This commit is contained in:
Michael Kirk 2017-11-29 12:29:19 -08:00
parent b242f6491a
commit 9d1e3dc223
2 changed files with 47 additions and 2 deletions

View File

@ -14,6 +14,24 @@ enum SignalAttachmentError: Error {
case invalidFileFormat
}
extension String {
var filenameWithoutExtension: String {
return (self as NSString).deletingPathExtension
}
var fileExtension: String? {
return (self as NSString).pathExtension
}
func appendingFileExtension(_ fileExtension: String) -> String {
guard let result = (self as NSString).appendingPathExtension(fileExtension) else {
owsFail("Failed to append file extension: \(fileExtension) to string: \(self)")
return self
}
return result
}
}
extension SignalAttachmentError: LocalizedError {
public var errorDescription: String {
switch self {
@ -484,6 +502,7 @@ class SignalAttachment: NSObject {
attachment.error = .fileSizeTooLarge
return attachment
}
// Never re-encode animated images (i.e. GIFs) as JPEGs.
Logger.verbose("\(TAG) Sending raw \(attachment.mimeType) to retain any animation")
return attachment
@ -495,6 +514,25 @@ class SignalAttachment: NSObject {
attachment.cachedImage = image
if isInputImageValidOutputImage(image: image, dataSource: dataSource, dataUTI: dataUTI) {
if let sourceFilename = dataSource.sourceFilename,
let sourceFileExtension = sourceFilename.fileExtension,
["heic", "heif"].contains(sourceFileExtension.lowercased()) {
// If a .heic file actually contains jpeg data, update the extension to match.
//
// Here's how that can happen:
// In iOS11, the Photos.app records photos with HEIC UTIType, with the .HEIC extension.
// Since HEIC isn't a valid output format for Signal, we'll detect that and convert to JPEG,
// updating the extension as well. No problem.
// However the problem comes in when you edit an HEIC image in Photos.app - the image is saved
// in the Photos.app as a JPEG, but retains the (now incongruous) HEIC extension in the filename.
assert(dataUTI == kUTTypeJPEG as String)
Logger.verbose("\(self.TAG) changing extension: \(sourceFileExtension) to match jpg uti type")
let baseFilename = sourceFilename.filenameWithoutExtension
dataSource.sourceFilename = baseFilename.appendingFileExtension("jpg")
}
Logger.verbose("\(TAG) Sending raw \(attachment.mimeType)")
return attachment
}
@ -579,7 +617,10 @@ class SignalAttachment: NSObject {
attachment.error = .couldNotConvertToJpeg
return attachment
}
dataSource.sourceFilename = filename
let baseFilename = filename?.filenameWithoutExtension
let jpgFilename = baseFilename?.appendingFileExtension("jpg")
dataSource.sourceFilename = jpgFilename
if UInt(jpgImageData.count) <= kMaxFileSizeImage {
let recompressedAttachment = SignalAttachment(dataSource : dataSource, dataUTI: kUTTypeJPEG as String)

View File

@ -2734,9 +2734,13 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
}
[modalActivityIndicator dismissWithCompletion:^{
NSString *baseFilename = filename.stringByDeletingPathExtension;
NSString *mp4Filename = [baseFilename stringByAppendingPathExtension:@"mp4"];
DataSource *_Nullable dataSource =
[DataSourcePath dataSourceWithURL:compressedVideoUrl];
[dataSource setSourceFilename:filename];
[dataSource setSourceFilename:mp4Filename];
// Remove temporary file when complete.
[dataSource setShouldDeleteOnDeallocation];
SignalAttachment *attachment =