Migrate from YYImage to SDWebImage

This commit is contained in:
Pete Walters
2025-09-10 21:39:41 -05:00
committed by GitHub
parent 2b763d5f26
commit 1761235f88
23 changed files with 88 additions and 103 deletions

View File

@@ -1002,7 +1002,7 @@
667DEE672BC7342900EFF32D /* AttachmentReferenceId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 667DEE662BC7342900EFF32D /* AttachmentReferenceId.swift */; };
667DEE6B2BC7603C00EFF32D /* DatedAttachmentReferenceId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 667DEE6A2BC7603C00EFF32D /* DatedAttachmentReferenceId.swift */; };
667E90D028E799D1005FE603 /* ConnectionsEducationSheetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 667E90CF28E799D1005FE603 /* ConnectionsEducationSheetViewController.swift */; };
667EDE6428F8D6B7001FB487 /* YYAnimatedImage+Duration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 667EDE6328F8D6B7001FB487 /* YYAnimatedImage+Duration.swift */; };
667EDE6428F8D6B7001FB487 /* SDAnimatedImage+Duration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 667EDE6328F8D6B7001FB487 /* SDAnimatedImage+Duration.swift */; };
667EDE6628FA0372001FB487 /* StoryBadgeCountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 667EDE6528FA0372001FB487 /* StoryBadgeCountManager.swift */; };
6681AB652B7AE53B0099D187 /* PreloadedTextAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6681AB642B7AE53B0099D187 /* PreloadedTextAttachment.swift */; };
668345502DCA9BEE00566AB3 /* BackupAttachmentUploadProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6683454F2DCA9BE700566AB3 /* BackupAttachmentUploadProgress.swift */; };
@@ -1058,7 +1058,7 @@
668B5BFA2C7E420E0018CF36 /* BackupArchiveChatStyleArchiver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 668B5BF92C7E420E0018CF36 /* BackupArchiveChatStyleArchiver.swift */; };
668B5BFC2C7E46D30018CF36 /* PaletteChatColor+Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 668B5BFB2C7E46D30018CF36 /* PaletteChatColor+Constants.swift */; };
668CAB3E289983520085A2C3 /* AudioMessagePlaybackRateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 668CAB3D289983520085A2C3 /* AudioMessagePlaybackRateView.swift */; };
668E403C2BE43752004B6730 /* YYImage+Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 668E403B2BE43752004B6730 /* YYImage+Attachment.swift */; };
668E403C2BE43752004B6730 /* SDAnimatedImage+Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 668E403B2BE43752004B6730 /* SDAnimatedImage+Attachment.swift */; };
668FE09B28B923A4008B9071 /* Bool+SSK.swift in Sources */ = {isa = PBXBuildFile; fileRef = 668FE09A28B923A4008B9071 /* Bool+SSK.swift */; };
668FE09F28B947ED008B9071 /* StoryContextMenuGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 668FE09E28B947ED008B9071 /* StoryContextMenuGenerator.swift */; };
6691E7EF2996E8FB0032A68A /* TSRequestOWSURLSessionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6691E7EE2996E8FB0032A68A /* TSRequestOWSURLSessionMock.swift */; };
@@ -4950,7 +4950,7 @@
667DEE662BC7342900EFF32D /* AttachmentReferenceId.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentReferenceId.swift; sourceTree = "<group>"; };
667DEE6A2BC7603C00EFF32D /* DatedAttachmentReferenceId.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatedAttachmentReferenceId.swift; sourceTree = "<group>"; };
667E90CF28E799D1005FE603 /* ConnectionsEducationSheetViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionsEducationSheetViewController.swift; sourceTree = "<group>"; };
667EDE6328F8D6B7001FB487 /* YYAnimatedImage+Duration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "YYAnimatedImage+Duration.swift"; sourceTree = "<group>"; };
667EDE6328F8D6B7001FB487 /* SDAnimatedImage+Duration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SDAnimatedImage+Duration.swift"; sourceTree = "<group>"; };
667EDE6528FA0372001FB487 /* StoryBadgeCountManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryBadgeCountManager.swift; sourceTree = "<group>"; };
6681AB642B7AE53B0099D187 /* PreloadedTextAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreloadedTextAttachment.swift; sourceTree = "<group>"; };
6683454F2DCA9BE700566AB3 /* BackupAttachmentUploadProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupAttachmentUploadProgress.swift; sourceTree = "<group>"; };
@@ -5007,7 +5007,7 @@
668B5BF92C7E420E0018CF36 /* BackupArchiveChatStyleArchiver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupArchiveChatStyleArchiver.swift; sourceTree = "<group>"; };
668B5BFB2C7E46D30018CF36 /* PaletteChatColor+Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PaletteChatColor+Constants.swift"; sourceTree = "<group>"; };
668CAB3D289983520085A2C3 /* AudioMessagePlaybackRateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioMessagePlaybackRateView.swift; sourceTree = "<group>"; };
668E403B2BE43752004B6730 /* YYImage+Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "YYImage+Attachment.swift"; sourceTree = "<group>"; };
668E403B2BE43752004B6730 /* SDAnimatedImage+Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SDAnimatedImage+Attachment.swift"; sourceTree = "<group>"; };
668FE09A28B923A4008B9071 /* Bool+SSK.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bool+SSK.swift"; sourceTree = "<group>"; };
668FE09E28B947ED008B9071 /* StoryContextMenuGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryContextMenuGenerator.swift; sourceTree = "<group>"; };
6691E7EE2996E8FB0032A68A /* TSRequestOWSURLSessionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSRequestOWSURLSessionMock.swift; sourceTree = "<group>"; };
@@ -9558,8 +9558,8 @@
isa = PBXGroup;
children = (
6649651B2BDC6EAD00E2DE98 /* AVAsset+Attachment.swift */,
668E403B2BE43752004B6730 /* SDAnimatedImage+Attachment.swift */,
6649651D2BDF169F00E2DE98 /* UIImage+Attachment.swift */,
668E403B2BE43752004B6730 /* YYImage+Attachment.swift */,
);
path = Playback;
sourceTree = "<group>";
@@ -10552,12 +10552,12 @@
888CC15828E3CE8100A13493 /* ProxyConnectionChecker.swift */,
66A22C0828A18D49007CD4F5 /* RingerSwitch.swift */,
7677E41229F84C2100AC6A75 /* ScreenLockUI.swift */,
667EDE6328F8D6B7001FB487 /* SDAnimatedImage+Duration.swift */,
8822558C26B9D1D7001A33C4 /* SignalDotMePhoneNumberLink.swift */,
6675F64E29261C39007A311E /* SyncPushTokensJob.swift */,
4521C3BF1F59F3BA00B4C582 /* TextHelper.swift */,
660248EF2BBCD29D009E2956 /* TSMessage+RenderableContent.swift */,
8811CF832295D8DA00FF6549 /* VolumeButtons.swift */,
667EDE6328F8D6B7001FB487 /* YYAnimatedImage+Duration.swift */,
);
path = util;
sourceTree = "<group>";
@@ -17417,6 +17417,7 @@
D9E43C2C2CC194140001536E /* RTCIceServerFetcher.swift in Sources */,
C1D9B1552B7FA28200D94595 /* SafetyTipsViewController.swift in Sources */,
7677E41329F84C2100AC6A75 /* ScreenLockUI.swift in Sources */,
667EDE6428F8D6B7001FB487 /* SDAnimatedImage+Duration.swift in Sources */,
45069FCE29D64CB300D0DD14 /* SelectionButton.swift in Sources */,
88C659B024688335002AC115 /* SelfSignedIdentity.swift in Sources */,
4C4AE6A1224AF35700D4AF6F /* SendMediaNavigationController.swift in Sources */,
@@ -17521,7 +17522,6 @@
45069FC629D3A7C800D0DD14 /* WideMediaTileViewLayout.swift in Sources */,
45906C6B29D238560025906D /* WidePhotoCell.swift in Sources */,
76616C9D2A266A05005F7001 /* WindowManager.swift in Sources */,
667EDE6428F8D6B7001FB487 /* YYAnimatedImage+Duration.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -18492,6 +18492,7 @@
668A01332C2B6088007B8808 /* Scheduler.swift in Sources */,
72C905912B9ACA3D00E586B8 /* ScreenLock.swift in Sources */,
7255A4D22B98E2B700E95368 /* ScrubbingLogFormatter.swift in Sources */,
668E403C2BE43752004B6730 /* SDAnimatedImage+Attachment.swift in Sources */,
F9C5CDEE289453B400548EEE /* SDS+Enums.swift in Sources */,
D9F6553229D6531D002A330A /* SDSCodableModel+ColumnName.swift in Sources */,
D9F6554229D67708002A330A /* SDSCodableModel+SDSSerialization.swift in Sources */,
@@ -18825,7 +18826,6 @@
F9C5CCA2289453B300548EEE /* WebSocketResources.pb.swift in Sources */,
66533E3729B7B56000E8D928 /* WhoAmIManager.swift in Sources */,
72454E802C9BCEA80084B483 /* YDBStorage.swift in Sources */,
668E403C2BE43752004B6730 /* YYImage+Attachment.swift in Sources */,
724D47B02B97BE13001BE973 /* ZkParamsMigrator.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@@ -5,7 +5,7 @@
public import SignalServiceKit
import SignalUI
import YYImage
import SDWebImage
// MARK: -
@@ -320,7 +320,7 @@ class MediaViewAdapterAnimated: MediaViewAdapter {
guard attachmentStream.contentType.isAnimatedImage else {
throw ReusableMediaError.invalidMedia
}
guard let animatedImage = try? attachmentStream.decryptedYYImage() else {
guard let animatedImage = try? attachmentStream.decryptedSDAnimatedImage() else {
throw OWSAssertionError("Invalid animated image.")
}
return animatedImage
@@ -329,7 +329,7 @@ class MediaViewAdapterAnimated: MediaViewAdapter {
func applyMedia(_ media: AnyObject) {
AssertIsOnMainThread()
guard let image = media as? YYImage else {
guard let image = media as? SDAnimatedImage else {
owsFailDebug("Media has unexpected type: \(type(of: media))")
return
}
@@ -544,7 +544,7 @@ public class MediaViewAdapterSticker: MediaViewAdapter {
throw ReusableMediaError.invalidMedia
}
if shouldBeRenderedByYY {
guard let animatedImage = try? attachmentStream.decryptedYYImage() else {
guard let animatedImage = try? attachmentStream.decryptedSDAnimatedImage() else {
throw OWSAssertionError("Invalid animated image.")
}
return animatedImage
@@ -560,7 +560,7 @@ public class MediaViewAdapterSticker: MediaViewAdapter {
AssertIsOnMainThread()
if shouldBeRenderedByYY {
guard let image = media as? YYImage else {
guard let image = media as? SDAnimatedImage else {
owsFailDebug("Media has unexpected type: \(type(of: media))")
return
}

View File

@@ -4,7 +4,6 @@
//
public import SignalServiceKit
public import YYImage
public class AttachmentSharing {
@@ -284,10 +283,3 @@ public class ShareableAttachment: NSObject, UIActivityItemSource {
}
}
}
// YYImage does not specify that the sublcass still supports secure coding,
// this is required for anything that subclasses a class that supports secure
// coding. We do so here, otherwise copy / save will not work for YYImages
extension YYImage {
open class override var supportsSecureCoding: Bool { true }
}

View File

@@ -5,11 +5,11 @@
import SignalServiceKit
import SignalUI
import YYImage
import SDWebImage
class GifPickerCell: UICollectionViewCell {
private let imageView = YYAnimatedImageView()
private let imageView = SDAnimatedImageView()
private let mp4View = LoopingVideoView()
private let activityIndicator: UIActivityIndicatorView = {
let view = UIActivityIndicatorView(style: .medium)
@@ -197,8 +197,10 @@ class GifPickerCell: UICollectionViewCell {
let video = LoopingVideo(decryptedLocalFileUrl: URL(fileURLWithPath: asset.filePath)) {
mp4View.video = video
mp4View.isHidden = false
} else if Data.ows_isValidImage(atPath: asset.filePath, mimeType: MimeType.imageGif.rawValue),
let image = YYImage(contentsOfFile: asset.filePath) {
} else if
Data.ows_isValidImage(atPath: asset.filePath, mimeType: MimeType.imageGif.rawValue),
let image = SDAnimatedImage(contentsOfFile: asset.filePath)
{
imageView.image = image
imageView.isHidden = false
} else if Data.ows_isValidImage(atPath: asset.filePath, mimeType: MimeType.imageJpeg.rawValue),

View File

@@ -9,7 +9,7 @@ import SafariServices
import SignalServiceKit
import SignalUI
import UIKit
import YYImage
import SDWebImage
protocol StoryItemMediaViewDelegate: ContextMenuButtonDelegate {
func storyItemMediaViewWantsToPause(_ storyItemMediaView: StoryItemMediaView)
@@ -252,7 +252,7 @@ class StoryItemMediaView: UIView {
// as it would cause the video to loop leading to weird UX
glyphCount = nil
}
} else if let animatedImageDuration = (yyImageView?.image as? YYAnimatedImage)?.duration {
} else if let animatedImageDuration = (yyImageView?.image as? SDAnimatedImage)?.animationDuration {
// GIFs should loop 3 times, or play for 5 seconds
// whichever is longer.
return max(5, animatedImageDuration * 3)
@@ -948,10 +948,10 @@ class StoryItemMediaView: UIView {
return playerView
}
private var yyImageView: YYAnimatedImageView?
private var yyImageView: SDAnimatedImageView?
private func buildYYImageView(attachment: AttachmentStream) -> UIView {
guard
let image = try? attachment.decryptedYYImage()
let image = try? attachment.decryptedSDAnimatedImage()
else {
owsFailDebug("Could not load attachment.")
return buildContentUnavailableView()
@@ -961,7 +961,7 @@ class StoryItemMediaView: UIView {
owsFailDebug("Attachment has invalid size.")
return buildContentUnavailableView()
}
let animatedImageView = YYAnimatedImageView()
let animatedImageView = SDAnimatedImageView()
animatedImageView.contentMode = .scaleAspectFit
animatedImageView.layer.minificationFilter = .trilinear
animatedImageView.layer.magnificationFilter = .trilinear

View File

@@ -6,7 +6,7 @@
import CoreMedia
import SignalServiceKit
import SignalUI
import YYImage
import SDWebImage
protocol MediaItemViewControllerDelegate: AnyObject {
func mediaItemViewControllerDidTapMedia(_ viewController: MediaItemViewController)
@@ -117,8 +117,8 @@ class MediaItemViewController: OWSViewController, VideoPlaybackStatusProvider {
view = buildPlaceholderView()
}
} else if attachmentStream.contentType.isAnimatedImage {
if let animatedGif = try? attachmentStream.decryptedYYImage() {
view = YYAnimatedImageView(image: animatedGif)
if let animatedGif = try? attachmentStream.decryptedSDAnimatedImage() {
view = SDAnimatedImageView(image: animatedGif)
} else {
view = buildPlaceholderView()
}

View File

@@ -6,7 +6,7 @@
import CoreMedia
import SignalServiceKit
import SignalUI
import YYImage
import SDWebImage
class ViewOnceMessageViewController: OWSViewController {
@@ -141,7 +141,7 @@ class ViewOnceMessageViewController: OWSViewController {
owsFailDebug("Attachment has invalid size.")
return nil
}
let animatedImageView = YYAnimatedImageView()
let animatedImageView = SDAnimatedImageView()
// We need to specify a contentMode since the size of the image
// might not match the aspect ratio of the view.
animatedImageView.contentMode = .scaleAspectFit

View File

@@ -4,13 +4,13 @@
//
import Foundation
public import YYImage
public import SDWebImage
public extension YYAnimatedImage {
public extension SDAnimatedImage {
/// YYAnimatedImageView's duration sometimes returns 0 duration even when this extended method works.
var duration: TimeInterval? {
let frameCount = self.animatedImageFrameCount()
/// SDAnimatedImageView's duration sometimes returns 0 duration even when this extended method works.
var animationDuration: TimeInterval? {
let frameCount = self.animatedImageFrameCount
guard frameCount > 0 else {
return nil
}

View File

@@ -6,7 +6,7 @@
public import AVFoundation
import Foundation
import MobileCoreServices
import YYImage
import SDWebImage
public enum SignalAttachmentError: Error {
case missingData
@@ -1079,7 +1079,7 @@ public class SignalAttachment: NSObject {
// CGImageSource doesn't know how to handle webp, so we have
// to pass it through YYImage. This is costly and we could
// perhaps do better, but webp images are usually small.
guard let yyImage = YYImage(data: dataSource.data) else {
guard let yyImage = UIImage.sd_image(with: dataSource.data) else {
owsFailDebug("Failed to initialized YYImage")
return nil
}

View File

@@ -5,6 +5,8 @@
import Foundation
public import LibSignalClient
import SDWebImage
import SDWebImageWebPCoder
public class AppSetup {
public init() {}
@@ -1884,6 +1886,12 @@ extension AppSetup.FinalContinuation {
@MainActor
public func runLaunchTasksIfNeededAndReloadCaches() {
// Coders are consulted in reverse order of adding, so add
// the AWebPCoder last, which used the native ImageIO, if supported
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
// Warm (or re-warm) all of the caches. In theory, every cache is
// susceptible to diverging state between the Main App & NSE and should be
// reloaded here. In practice, some caches exist but aren't used by the

View File

@@ -5,7 +5,7 @@
public import AVFoundation
import Foundation
public import YYImage
public import SDWebImage
/// Represents a downloaded attachment with the fullsize contents available on local disk.
public class AttachmentStream {
@@ -174,8 +174,8 @@ public class AttachmentStream {
let data = try self.decryptedRawData()
let image: UIImage?
if mimeType.caseInsensitiveCompare(MimeType.imageWebp.rawValue) == .orderedSame {
/// Use YYImage for webp.
image = YYImage(data: data)
/// Use SDAnimatedImage for webp.
image = SDAnimatedImage(data: data)
} else {
image = UIImage(data: data)
}
@@ -197,12 +197,12 @@ public class AttachmentStream {
}
}
public func decryptedYYImage() throws -> YYImage {
public func decryptedSDAnimatedImage() throws -> SDAnimatedImage {
switch contentType {
case .file, .invalid, .audio, .video:
throw OWSAssertionError("Requesting image from non-visual attachment")
case .image, .animatedImage:
return try YYImage.yyImage(from: self)
return try SDAnimatedImage.sdImage(from: self)
}
}

View File

@@ -3,13 +3,13 @@
// SPDX-License-Identifier: AGPL-3.0-only
//
public import YYImage
public import SDWebImage
extension YYImage {
extension SDAnimatedImage {
public static func yyImage(
public static func sdImage(
from attachment: AttachmentStream
) throws -> YYImage {
) throws -> SDAnimatedImage {
// YYImage has an initializer that takes a file path, but that
// initializer loads the entire file's data into memory.
// So we don't use any more memory at any point compared to that.
@@ -19,7 +19,7 @@ extension YYImage {
// file types other than png and jpeg and its unclear if it would work
// at all for animated images.
let data = try attachment.decryptedRawData()
guard let image = YYImage(data: data) else {
guard let image = SDAnimatedImage(data: data) else {
throw OWSAssertionError("Unable to decode image")
}
return image

View File

@@ -4,7 +4,7 @@
//
import Foundation
import YYImage
import SDWebImage
extension UIImage {
@@ -80,8 +80,8 @@ extension UIImage {
)
let image: UIImage?
if mimeType.caseInsensitiveCompare(MimeType.imageWebp.rawValue) == .orderedSame {
/// Use YYImage for webp.
image = YYImage(data: data)
/// Use SDAnimatedImage for webp.
image = SDAnimatedImage(data: data)
} else {
image = UIImage(data: data)
}

View File

@@ -5,7 +5,7 @@
public import AVFoundation
import Foundation
public import YYImage
public import SDWebImage
/// When presenting a view-once message, we:
/// 1. copy the displayable attachment contents to a tmp file
@@ -60,7 +60,7 @@ public class ViewOnceContent {
)
}
public func loadYYImage() throws -> YYImage {
public func loadYYImage() throws -> SDAnimatedImage {
// hmac and digest are validated at download time; no need to revalidate every read.
let data = try Cryptography.decryptFileWithoutValidating(
at: fileUrl,
@@ -69,7 +69,7 @@ public class ViewOnceContent {
plaintextLength: Int(plaintextLength)
)
)
guard let image = YYImage(data: data) else {
guard let image = SDAnimatedImage(data: data) else {
throw OWSAssertionError("Couldn't load image")
}
return image

View File

@@ -5,7 +5,6 @@
import Foundation
import libwebp
import YYImage
// MARK: - PNG Chunker

View File

@@ -6,7 +6,6 @@
import Foundation
import libwebp
import YYImage
extension NSData {
@objc

View File

@@ -5,8 +5,7 @@
import Foundation
import libwebp
import YYImage
import SDWebImage
public protocol OWSImageSource {
@@ -487,12 +486,8 @@ extension OWSImageSource {
guard let data = try? self.readIntoMemory() else {
return nil
}
guard let cgImage = YYCGImageCreateWithWebPData(data as CFData, false, false, false, false) else {
owsFailDebug("Could not generate still for webp image.")
return nil
}
return UIImage(cgImage: cgImage.takeRetainedValue())
return UIImage.sd_image(with: data)
}
fileprivate static func isWebp(filePath: String) -> Bool {
@@ -512,25 +507,18 @@ extension OWSImageSource {
guard let data = try? self.readIntoMemory() else {
return WebpMetadata(isValid: false, canvasWidth: 0, canvasHeight: 0, frameCount: 0)
}
return data.withUnsafeBytes {
$0.withMemoryRebound(to: UInt8.self) { buffer in
var webPData = WebPData(bytes: buffer.baseAddress, size: buffer.count)
guard let demuxer = WebPDemux(&webPData) else {
return WebpMetadata(isValid: false, canvasWidth: 0, canvasHeight: 0, frameCount: 0)
}
defer {
WebPDemuxDelete(demuxer)
}
let canvasWidth = WebPDemuxGetI(demuxer, WEBP_FF_CANVAS_WIDTH)
let canvasHeight = WebPDemuxGetI(demuxer, WEBP_FF_CANVAS_HEIGHT)
let frameCount = WebPDemuxGetI(demuxer, WEBP_FF_FRAME_COUNT)
let result = WebpMetadata(isValid: canvasWidth > 0 && canvasHeight > 0 && frameCount > 0,
canvasWidth: canvasWidth,
canvasHeight: canvasHeight,
frameCount: frameCount)
return result
}
guard let image = SDAnimatedImage(data: data) else {
return WebpMetadata(isValid: false, canvasWidth: 0, canvasHeight: 0, frameCount: 0)
}
let count = image.sd_imageFrameCount
let height = image.pixelHeight
let width = image.pixelWidth
return WebpMetadata(
isValid: width > 0 && height > 0 && count > 0,
canvasWidth: UInt32(width),
canvasHeight: UInt32(height),
frameCount: UInt32(count)
)
}
}

View File

@@ -5,7 +5,7 @@
import SignalServiceKit
import UIKit
public import YYImage
public import SDWebImage
public class CVUtils {
@@ -199,7 +199,7 @@ open class CVImageView: UIImageView, CVView {
// MARK: -
open class CVAnimatedImageView: YYAnimatedImageView, CVView {
public class CVAnimatedImageView: SDAnimatedImageView, CVView {
public override func updateConstraints() {
super.updateConstraints()

View File

@@ -4,7 +4,6 @@
//
public import SignalServiceKit
import YYImage
public enum LinkPreviewImageState: Equatable {
case none
@@ -322,7 +321,7 @@ public class LinkPreviewSent: LinkPreviewState {
DispatchQueue.global().async {
switch attachmentStream.contentType {
case .animatedImage:
guard let image = try? attachmentStream.decryptedYYImage() else {
guard let image = try? attachmentStream.decryptedSDAnimatedImage() else {
owsFailDebug("Could not load image")
return
}

View File

@@ -3,7 +3,6 @@
// SPDX-License-Identifier: AGPL-3.0-only
//
import YYImage
import SignalServiceKit
public protocol LinkPreviewViewDraftDelegate: AnyObject {

View File

@@ -5,7 +5,7 @@
import Lottie
public import SignalServiceKit
import YYImage
import SDWebImage
public class StickerView {
@@ -71,15 +71,14 @@ public class StickerView {
let stickerView: UIView
switch stickerType {
case .webp, .apng, .gif:
guard let stickerImage = YYImage(data: stickerData) else {
guard let stickerImage = SDAnimatedImage(data: stickerData) else {
owsFailDebug("Sticker could not be parsed.")
return nil
}
let yyView = YYAnimatedImageView()
yyView.alwaysInfiniteLoop = true
yyView.contentMode = .scaleAspectFit
yyView.image = stickerImage
stickerView = yyView
let sdAnimatedImageView = SDAnimatedImageView()
sdAnimatedImageView.contentMode = .scaleAspectFit
sdAnimatedImageView.image = stickerImage
stickerView = sdAnimatedImageView
}
return stickerView
}

View File

@@ -5,7 +5,6 @@
public import AVKit
public import SignalServiceKit
import YYImage
/// Model object for a looping video asset
/// Any LoopingVideoViews playing this instance will all be kept in sync

View File

@@ -5,7 +5,7 @@
import SignalServiceKit
import UIKit
import YYImage
import SDWebImage
class MediaMessageView: UIView, AudioPlayerDelegate {
@@ -138,13 +138,14 @@ class MediaMessageView: UIView, AudioPlayerDelegate {
private func createAnimatedPreview() {
guard attachment.isValidImage,
let dataUrl = attachment.dataUrl,
let image = YYImage(contentsOfFile: dataUrl.path),
image.size.width > 0 && image.size.height > 0 else {
let image = SDAnimatedImage(contentsOfFile: dataUrl.path),
image.size.width > 0 && image.size.height > 0
else {
createGenericPreview()
return
}
let animatedImageView = YYAnimatedImageView()
let animatedImageView = SDAnimatedImageView()
animatedImageView.image = image
let aspectRatio = image.size.width / image.size.height