diff --git a/src/Util/MIMETypeUtil.h b/src/Util/MIMETypeUtil.h index dcfa982a4..5f34a2969 100644 --- a/src/Util/MIMETypeUtil.h +++ b/src/Util/MIMETypeUtil.h @@ -1,4 +1,6 @@ -// Copyright © 2016 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// extern NSString *const OWSMimeTypeApplicationOctetStream; extern NSString *const OWSMimeTypeImagePng; @@ -44,4 +46,9 @@ extern NSString *const OWSMimeTypeImagePng; + (BOOL)getIsSupportedTypeFromImage:(UIImage *)image; #endif ++ (NSSet *)supportedVideoUTITypes; ++ (NSSet *)supportedAudioUTITypes; ++ (NSSet *)supportedImageUTITypes; ++ (NSSet *)supportedAnimatedImageUTITypes; + @end diff --git a/src/Util/MIMETypeUtil.m b/src/Util/MIMETypeUtil.m index 420abece4..bd1650203 100644 --- a/src/Util/MIMETypeUtil.m +++ b/src/Util/MIMETypeUtil.m @@ -1,6 +1,13 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + #import "MIMETypeUtil.h" #if TARGET_OS_IPHONE #import "UIImage+contentTypes.h" +#import +#else +#import #endif NSString *const OWSMimeTypeApplicationOctetStream = @"application/octet-stream"; @@ -9,119 +16,165 @@ NSString *const OWSMimeTypeImagePng = @"image/png"; @implementation MIMETypeUtil + (NSDictionary *)supportedVideoMIMETypesToExtensionTypes { - return @{ - @"video/3gpp" : @"3gp", - @"video/3gpp2" : @"3g2", - @"video/mp4" : @"mp4", - @"video/quicktime" : @"mov", - @"video/x-m4v" : @"m4v" - }; + static NSDictionary *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = @{ + @"video/3gpp" : @"3gp", + @"video/3gpp2" : @"3g2", + @"video/mp4" : @"mp4", + @"video/quicktime" : @"mov", + @"video/x-m4v" : @"m4v" + }; + }); + return result; } + (NSDictionary *)supportedAudioMIMETypesToExtensionTypes { - return @{ - @"audio/aac" : @"m4a", - @"audio/x-m4p" : @"m4p", - @"audio/x-m4b" : @"m4b", - @"audio/x-m4a" : @"m4a", - @"audio/wav" : @"wav", - @"audio/x-wav" : @"wav", - @"audio/x-mpeg" : @"mp3", - @"audio/mpeg" : @"mp3", - @"audio/mp4" : @"mp4", - @"audio/mp3" : @"mp3", - @"audio/mpeg3" : @"mp3", - @"audio/x-mp3" : @"mp3", - @"audio/x-mpeg3" : @"mp3", - @"audio/amr" : @"amr", - @"audio/aiff" : @"aiff", - @"audio/x-aiff" : @"aiff", - @"audio/3gpp2" : @"3g2", - @"audio/3gpp" : @"3gp" - }; + static NSDictionary *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = @{ + @"audio/aac" : @"m4a", + @"audio/x-m4p" : @"m4p", + @"audio/x-m4b" : @"m4b", + @"audio/x-m4a" : @"m4a", + @"audio/wav" : @"wav", + @"audio/x-wav" : @"wav", + @"audio/x-mpeg" : @"mp3", + @"audio/mpeg" : @"mp3", + @"audio/mp4" : @"mp4", + @"audio/mp3" : @"mp3", + @"audio/mpeg3" : @"mp3", + @"audio/x-mp3" : @"mp3", + @"audio/x-mpeg3" : @"mp3", + @"audio/amr" : @"amr", + @"audio/aiff" : @"aiff", + @"audio/x-aiff" : @"aiff", + @"audio/3gpp2" : @"3g2", + @"audio/3gpp" : @"3gp" + }; + }); + return result; } + (NSDictionary *)supportedImageMIMETypesToExtensionTypes { - return @{ - @"image/jpeg" : @"jpeg", - @"image/pjpeg" : @"jpeg", - OWSMimeTypeImagePng : @"png", - @"image/tiff" : @"tif", - @"image/x-tiff" : @"tif", - @"image/bmp" : @"bmp", - @"image/x-windows-bmp" : @"bmp" - }; + static NSDictionary *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = @{ + @"image/jpeg" : @"jpeg", + @"image/pjpeg" : @"jpeg", + OWSMimeTypeImagePng : @"png", + @"image/tiff" : @"tif", + @"image/x-tiff" : @"tif", + @"image/bmp" : @"bmp", + @"image/x-windows-bmp" : @"bmp" + }; + }); + return result; } + (NSDictionary *)supportedAnimatedMIMETypesToExtensionTypes { - return @{ - @"image/gif" : @"gif", - }; + static NSDictionary *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = @{ + @"image/gif" : @"gif", + }; + }); + return result; } + (NSDictionary *)supportedBinaryDataMIMETypesToExtensionTypes { - return @{ - OWSMimeTypeApplicationOctetStream : @"dat", - }; + static NSDictionary *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = @{ + OWSMimeTypeApplicationOctetStream : @"dat", + }; + }); + return result; } + (NSDictionary *)supportedVideoExtensionTypesToMIMETypes { - return @{ - @"3gp" : @"video/3gpp", - @"3gpp" : @"video/3gpp", - @"3gp2" : @"video/3gpp2", - @"3gpp2" : @"video/3gpp2", - @"mp4" : @"video/mp4", - @"mov" : @"video/quicktime", - @"mqv" : @"video/quicktime", - @"m4v" : @"video/x-m4v" - }; + static NSDictionary *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = @{ + @"3gp" : @"video/3gpp", + @"3gpp" : @"video/3gpp", + @"3gp2" : @"video/3gpp2", + @"3gpp2" : @"video/3gpp2", + @"mp4" : @"video/mp4", + @"mov" : @"video/quicktime", + @"mqv" : @"video/quicktime", + @"m4v" : @"video/x-m4v" + }; + }); + return result; } + + (NSDictionary *)supportedAudioExtensionTypesToMIMETypes { - return @{ - @"3gp" : @"audio/3gpp", - @"3gpp" : @"@audio/3gpp", - @"3g2" : @"audio/3gpp2", - @"3gp2" : @"audio/3gpp2", - @"aiff" : @"audio/aiff", - @"aif" : @"audio/aiff", - @"aifc" : @"audio/aiff", - @"cdda" : @"audio/aiff", - @"amr" : @"audio/amr", - @"mp3" : @"audio/mp3", - @"swa" : @"audio/mp3", - @"mp4" : @"audio/mp4", - @"mpeg" : @"audio/mpeg", - @"mpg" : @"audio/mpeg", - @"wav" : @"audio/wav", - @"bwf" : @"audio/wav", - @"m4a" : @"audio/x-m4a", - @"m4b" : @"audio/x-m4b", - @"m4p" : @"audio/x-m4p" - }; + static NSDictionary *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = @{ + @"3gp" : @"audio/3gpp", + @"3gpp" : @"@audio/3gpp", + @"3g2" : @"audio/3gpp2", + @"3gp2" : @"audio/3gpp2", + @"aiff" : @"audio/aiff", + @"aif" : @"audio/aiff", + @"aifc" : @"audio/aiff", + @"cdda" : @"audio/aiff", + @"amr" : @"audio/amr", + @"mp3" : @"audio/mp3", + @"swa" : @"audio/mp3", + @"mp4" : @"audio/mp4", + @"mpeg" : @"audio/mpeg", + @"mpg" : @"audio/mpeg", + @"wav" : @"audio/wav", + @"bwf" : @"audio/wav", + @"m4a" : @"audio/x-m4a", + @"m4b" : @"audio/x-m4b", + @"m4p" : @"audio/x-m4p" + }; + }); + return result; } + (NSDictionary *)supportedImageExtensionTypesToMIMETypes { - return @{ - @"png" : OWSMimeTypeImagePng, - @"x-png" : OWSMimeTypeImagePng, - @"jfif" : @"image/jpeg", - @"jfif" : @"image/pjpeg", - @"jfif-tbnl" : @"image/jpeg", - @"jpe" : @"image/jpeg", - @"jpe" : @"image/pjpeg", - @"jpeg" : @"image/jpeg", - @"jpg" : @"image/jpeg", - @"tif" : @"image/tiff", - @"tiff" : @"image/tiff" - }; + static NSDictionary *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = @{ + @"png" : OWSMimeTypeImagePng, + @"x-png" : OWSMimeTypeImagePng, + @"jfif" : @"image/jpeg", + @"jfif" : @"image/pjpeg", + @"jfif-tbnl" : @"image/jpeg", + @"jpe" : @"image/jpeg", + @"jpe" : @"image/pjpeg", + @"jpeg" : @"image/jpeg", + @"jpg" : @"image/jpeg", + @"tif" : @"image/tiff", + @"tiff" : @"image/tiff" + }; + }); + return result; } + (NSDictionary *)supportedAnimatedExtensionTypesToMIMETypes { - return @{ - @"gif" : @"image/gif", - }; + static NSDictionary *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = @{ + @"gif" : @"image/gif", + }; + }); + return result; } + (BOOL)isSupportedVideoMIMEType:(NSString *)contentType { @@ -303,4 +356,64 @@ NSString *const OWSMimeTypeImagePng = @"image/png"; #endif ++ (NSString *)utiTypeForMIMEType:(NSString *)mimeType +{ + CFStringRef utiType + = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, (__bridge CFStringRef)mimeType, NULL); + return (__bridge_transfer NSString *)utiType; +} + ++ (NSSet *)utiTypesForMIMETypes:(NSArray *)mimeTypes +{ + NSMutableSet *result = [NSMutableSet new]; + for (NSString *mimeType in mimeTypes) { + [result addObject:[self utiTypeForMIMEType:mimeType]]; + } + return result; +} + ++ (NSSet *)supportedVideoUTITypes +{ + OWSAssert([NSThread isMainThread]); + static NSSet *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = [self utiTypesForMIMETypes:[self supportedVideoMIMETypesToExtensionTypes].allKeys]; + }); + return result; +} + ++ (NSSet *)supportedAudioUTITypes +{ + OWSAssert([NSThread isMainThread]); + static NSSet *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = [self utiTypesForMIMETypes:[self supportedAudioMIMETypesToExtensionTypes].allKeys]; + }); + return result; +} + ++ (NSSet *)supportedImageUTITypes +{ + OWSAssert([NSThread isMainThread]); + static NSSet *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = [self utiTypesForMIMETypes:[self supportedImageMIMETypesToExtensionTypes].allKeys]; + }); + return result; +} + ++ (NSSet *)supportedAnimatedImageUTITypes +{ + OWSAssert([NSThread isMainThread]); + static NSSet *result = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + result = [self utiTypesForMIMETypes:[self supportedAnimatedMIMETypesToExtensionTypes].allKeys]; + }); + return result; +} + @end