Signal-iOS/SignalServiceKit/Util/ImageMetadata/ImageMetadata.swift
2026-01-15 16:13:09 -06:00

86 lines
2.3 KiB
Swift

//
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public enum ImageFormat: CustomStringConvertible {
case png
case gif
case tiff
case jpeg
case bmp
case webp
case heic
case heif
public var description: String {
switch self {
case .png:
"ImageFormat_Png"
case .gif:
"ImageFormat_Gif"
case .tiff:
"ImageFormat_Tiff"
case .jpeg:
"ImageFormat_Jpeg"
case .bmp:
"ImageFormat_Bmp"
case .webp:
"ImageFormat_Webp"
case .heic:
"ImageFormat_Heic"
case .heif:
"ImageFormat_Heif"
}
}
public var mimeType: MimeType {
return self.mimeTypes.preferredMimeType
}
private var mimeTypes: (preferredMimeType: MimeType, alternativeMimeTypes: [MimeType]) {
switch self {
case .png: (.imagePng, [.imageApng, .imageVndMozillaApng])
case .gif: (.imageGif, [])
case .tiff: (.imageTiff, [.imageXTiff])
case .jpeg: (.imageJpeg, [])
case .bmp: (.imageBmp, [.imageXWindowsBmp])
case .webp: (.imageWebp, [])
case .heic: (.imageHeic, [])
case .heif: (.imageHeif, [])
}
}
public var fileExtension: String {
// All known ImageFormats must have a corresponding extension.
return MimeTypeUtil.fileExtensionForMimeType(mimeType.rawValue)!
}
func isValid(mimeType: String) -> Bool {
owsAssertDebug(!mimeType.isEmpty)
let mimeTypes = self.mimeTypes
return ([mimeTypes.preferredMimeType] + mimeTypes.alternativeMimeTypes).contains(where: {
return mimeType.caseInsensitiveCompare($0.rawValue) == .orderedSame
})
}
}
public struct ImageMetadata {
public let imageFormat: ImageFormat
public let pixelSize: CGSize
public let hasAlpha: Bool
public let isAnimated: Bool
public var hasStickerLikeProperties: Bool {
let maxStickerHeight = CGFloat(512)
return
pixelSize.width <= maxStickerHeight
&& pixelSize.height <= maxStickerHeight
&& pixelSize != CGSize(width: 1, height: 1)
&& hasAlpha
}
}