diff --git a/Tusker/Models/CompositionAttachmentData.swift b/Tusker/Models/CompositionAttachmentData.swift index 96cdaa85..0eb6e2e2 100644 --- a/Tusker/Models/CompositionAttachmentData.swift +++ b/Tusker/Models/CompositionAttachmentData.swift @@ -67,15 +67,24 @@ enum CompositionAttachmentData { completion(.failure(.missingData)) return } - + let utType: UTType - if dataUTI == "public.heic" { - // neither Mastodon nor Pleroma handles HEIC well, so convert to JPEG - let image = CIImage(data: data)! + let image = CIImage(data: data)! + let needsColorSpaceConversion = image.colorSpace?.name != CGColorSpace.sRGB + + // neither Mastodon nor Pleroma handles HEIC well, so convert to JPEG + // they also do a bad job converting wide color gamut images (they seem to just drop the profile, letting the wide-gamut values be reinterprete as sRGB) + // if that changes in the future, we'll need to pass the InstanceFeatures in here somehow and gate the conversion + if needsColorSpaceConversion || dataUTI == "public.heic" { let context = CIContext() - let colorSpace = image.colorSpace ?? CGColorSpace(name: CGColorSpace.sRGB)! - data = context.jpegRepresentation(of: image, colorSpace: colorSpace, options: [:])! - utType = .jpeg + let sRGB = CGColorSpace(name: CGColorSpace.sRGB)! + if dataUTI == "public.png" { + data = context.pngRepresentation(of: image, format: .ARGB8, colorSpace: sRGB)! + utType = .png + } else { + data = context.jpegRepresentation(of: image, colorSpace: sRGB)! + utType = .jpeg + } } else { utType = UTType(dataUTI)! }