diff --git a/submodules/AnimatedStickerNode/Sources/DirectAnimatedStickerNode.swift b/submodules/AnimatedStickerNode/Sources/DirectAnimatedStickerNode.swift index 38f1c5267f..ca911ce2c6 100644 --- a/submodules/AnimatedStickerNode/Sources/DirectAnimatedStickerNode.swift +++ b/submodules/AnimatedStickerNode/Sources/DirectAnimatedStickerNode.swift @@ -304,18 +304,19 @@ public final class DirectAnimatedStickerNode: ASDisplayNode, AnimatedStickerNode if !task.isCancelled { if let lottieInstance = lottieInstance { - let drawingContext = DrawingContext(size: playbackSize, scale: 1.0, opaque: false, clear: false) - lottieInstance.renderFrame(with: Int32(frameIndex), into: drawingContext.bytes.assumingMemoryBound(to: UInt8.self), width: Int32(drawingContext.scaledSize.width), height: Int32(drawingContext.scaledSize.height), bytesPerRow: Int32(drawingContext.bytesPerRow)) - - image = drawingContext.generateImage() - } else if let videoSource = videoSource { - if let frame = videoSource.takeFrame(draw: true) { - let drawingContext = DrawingContext(size: CGSize(width: frame.width, height: frame.height), scale: 1.0, opaque: false, clear: false, bytesPerRow: frame.bytesPerRow) - - frame.data.copyBytes(to: drawingContext.bytes.assumingMemoryBound(to: UInt8.self), from: 0 ..< min(frame.data.count, drawingContext.length)) + if let drawingContext = DrawingContext(size: playbackSize, scale: 1.0, opaque: false, clear: false) { + lottieInstance.renderFrame(with: Int32(frameIndex), into: drawingContext.bytes.assumingMemoryBound(to: UInt8.self), width: Int32(drawingContext.scaledSize.width), height: Int32(drawingContext.scaledSize.height), bytesPerRow: Int32(drawingContext.bytesPerRow)) image = drawingContext.generateImage() } + } else if let videoSource = videoSource { + if let frame = videoSource.takeFrame(draw: true) { + if let drawingContext = DrawingContext(size: CGSize(width: frame.width, height: frame.height), scale: 1.0, opaque: false, clear: false, bytesPerRow: frame.bytesPerRow) { + frame.data.copyBytes(to: drawingContext.bytes.assumingMemoryBound(to: UInt8.self), from: 0 ..< min(frame.data.count, drawingContext.length)) + + image = drawingContext.generateImage() + } + } } } diff --git a/submodules/AnimatedStickerNode/Sources/VideoStickerFrameSource.swift b/submodules/AnimatedStickerNode/Sources/VideoStickerFrameSource.swift index 3d8516d823..3331868289 100644 --- a/submodules/AnimatedStickerNode/Sources/VideoStickerFrameSource.swift +++ b/submodules/AnimatedStickerNode/Sources/VideoStickerFrameSource.swift @@ -345,7 +345,9 @@ final class VideoStickerDirectFrameSource: AnimatedStickerFrameSource { self.currentFrame += 1 if draw { if let image = self.image { - let context = DrawingContext(size: CGSize(width: self.width, height: self.height), scale: 1.0, opaque: false, clear: true, bytesPerRow: self.bytesPerRow) + guard let context = DrawingContext(size: CGSize(width: self.width, height: self.height), scale: 1.0, opaque: false, clear: true, bytesPerRow: self.bytesPerRow) else { + return nil + } context.withFlippedContext { c in c.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: context.size)) } diff --git a/submodules/AvatarNode/Sources/PeerAvatar.swift b/submodules/AvatarNode/Sources/PeerAvatar.swift index 3ac553f992..a9b5701f9f 100644 --- a/submodules/AvatarNode/Sources/PeerAvatar.swift +++ b/submodules/AvatarNode/Sources/PeerAvatar.swift @@ -177,25 +177,26 @@ public func peerAvatarImage(account: Account, peerReference: PeerReference?, aut } if shouldBlur { let imageContextSize = size.width > 200.0 ? CGSize(width: 192.0, height: 192.0) : CGSize(width: 64.0, height: 64.0) - let imageContext = DrawingContext(size: imageContextSize, scale: 1.0, clear: true) - imageContext.withFlippedContext { c in - c.draw(dataImage, in: CGRect(origin: CGPoint(), size: imageContextSize)) + if let imageContext = DrawingContext(size: imageContextSize, scale: 1.0, clear: true) { + imageContext.withFlippedContext { c in + c.draw(dataImage, in: CGRect(origin: CGPoint(), size: imageContextSize)) + + context.setBlendMode(.saturation) + context.setFillColor(UIColor(rgb: 0xffffff, alpha: 1.0).cgColor) + context.fill(CGRect(origin: CGPoint(), size: size)) + context.setBlendMode(.copy) + } - context.setBlendMode(.saturation) - context.setFillColor(UIColor(rgb: 0xffffff, alpha: 1.0).cgColor) - context.fill(CGRect(origin: CGPoint(), size: size)) - context.setBlendMode(.copy) + telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes) + if size.width > 200.0 { + telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes) + telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes) + telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes) + telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes) + } + + dataImage = imageContext.generateImage()!.cgImage! } - - telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes) - if size.width > 200.0 { - telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes) - telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes) - telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes) - telegramFastBlurMore(Int32(imageContext.size.width * imageContext.scale), Int32(imageContext.size.height * imageContext.scale), Int32(imageContext.bytesPerRow), imageContext.bytes) - } - - dataImage = imageContext.generateImage()!.cgImage! } context.draw(dataImage, in: CGRect(origin: CGPoint(), size: displayDimensions).insetBy(dx: inset, dy: inset)) diff --git a/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift b/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift index eac694d4dd..413f41ec20 100644 --- a/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift +++ b/submodules/Components/ReactionImageComponent/Sources/ReactionImageComponent.swift @@ -45,16 +45,17 @@ public func reactionStaticImage(context: AccountContext, animation: TelegramMedi } func add(with drawingBlock: (AnimationCacheItemDrawingSurface) -> Double?, proposedWidth: Int, proposedHeight: Int, insertKeyframe: Bool) { - let renderContext = DrawingContext(size: CGSize(width: proposedWidth, height: proposedHeight), scale: 1.0, clear: true) - let _ = drawingBlock(AnimationCacheItemDrawingSurface( - argb: renderContext.bytes.assumingMemoryBound(to: UInt8.self), - width: Int(renderContext.scaledSize.width), - height: Int(renderContext.scaledSize.height), - bytesPerRow: renderContext.bytesPerRow, - length: renderContext.length - )) - if let image = renderContext.generateImage() { - self.frameReceived(image) + if let renderContext = DrawingContext(size: CGSize(width: proposedWidth, height: proposedHeight), scale: 1.0, clear: true) { + let _ = drawingBlock(AnimationCacheItemDrawingSurface( + argb: renderContext.bytes.assumingMemoryBound(to: UInt8.self), + width: Int(renderContext.scaledSize.width), + height: Int(renderContext.scaledSize.height), + bytesPerRow: renderContext.bytesPerRow, + length: renderContext.length + )) + if let image = renderContext.generateImage() { + self.frameReceived(image) + } } } diff --git a/submodules/DirectMediaImageCache/Sources/DirectMediaImageCache.swift b/submodules/DirectMediaImageCache/Sources/DirectMediaImageCache.swift index 0b71087ed0..57ee73149c 100644 --- a/submodules/DirectMediaImageCache/Sources/DirectMediaImageCache.swift +++ b/submodules/DirectMediaImageCache/Sources/DirectMediaImageCache.swift @@ -12,7 +12,9 @@ import ManagedFile private func generateBlurredThumbnail(image: UIImage) -> UIImage? { let thumbnailContextSize = CGSize(width: 32.0, height: 32.0) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) + guard let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) else { + return nil + } let filledSize = image.size.aspectFilled(thumbnailContextSize) let imageRect = CGRect(origin: CGPoint(x: (thumbnailContextSize.width - filledSize.width) / 2.0, y: (thumbnailContextSize.height - filledSize.height) / 2.0), size: filledSize) @@ -129,7 +131,9 @@ private func loadImage(data: Data) -> UIImage? { source.rowBytes = Int(width * 2) source.data = UnsafeMutableRawPointer(mutating: sourceBytes.advanced(by: 4 + 2 + 2)) - let context = DrawingContext(size: CGSize(width: CGFloat(width), height: CGFloat(height)), scale: 1.0, opaque: true, clear: false) + guard let context = DrawingContext(size: CGSize(width: CGFloat(width), height: CGFloat(height)), scale: 1.0, opaque: true, clear: false) else { + return nil + } var target = vImage_Buffer() target.width = UInt(width) @@ -218,7 +222,11 @@ public final class DirectMediaImageCache { let data = dataSignal.start(next: { data in if let data = data, let image = UIImage(data: data) { let scaledSize = CGSize(width: CGFloat(width), height: CGFloat(width)) - let scaledContext = DrawingContext(size: scaledSize, scale: 1.0, opaque: true) + guard let scaledContext = DrawingContext(size: scaledSize, scale: 1.0, opaque: true) else { + subscriber.putNext(nil) + subscriber.putCompletion() + return + } scaledContext.withFlippedContext { context in let filledSize = image.size.aspectFilled(scaledSize) let imageRect = CGRect(origin: CGPoint(x: (scaledSize.width - filledSize.width) / 2.0, y: (scaledSize.height - filledSize.height) / 2.0), size: filledSize) diff --git a/submodules/Display/Source/GenerateImage.swift b/submodules/Display/Source/GenerateImage.swift index 397b4f2a64..97cd118f4d 100644 --- a/submodules/Display/Source/GenerateImage.swift +++ b/submodules/Display/Source/GenerateImage.swift @@ -21,7 +21,9 @@ private let grayscaleColorSpace = CGColorSpaceCreateDeviceGray() let deviceScale = UIScreen.main.scale public func generateImagePixel(_ size: CGSize, scale: CGFloat, pixelGenerator: (CGSize, UnsafeMutablePointer, Int) -> Void) -> UIImage? { - let context = DrawingContext(size: size, scale: scale, opaque: false, clear: false) + guard let context = DrawingContext(size: size, scale: scale, opaque: false, clear: false) else { + return nil + } pixelGenerator(CGSize(width: size.width * scale, height: size.height * scale), context.bytes.assumingMemoryBound(to: UInt8.self), context.bytesPerRow) return context.generateImage() } @@ -98,7 +100,9 @@ public func generateImage(_ size: CGSize, contextGenerator: (CGSize, CGContext) if size.width.isZero || size.height.isZero { return nil } - let context = DrawingContext(size: size, scale: scale ?? 0.0, opaque: opaque, clear: false) + guard let context = DrawingContext(size: size, scale: scale ?? 0.0, opaque: opaque, clear: false) else { + return nil + } context.withFlippedContext { c in contextGenerator(context.size, c) } @@ -109,7 +113,9 @@ public func generateImage(_ size: CGSize, opaque: Bool = false, scale: CGFloat? if size.width.isZero || size.height.isZero { return nil } - let context = DrawingContext(size: size, scale: scale ?? 0.0, opaque: opaque, clear: false) + guard let context = DrawingContext(size: size, scale: scale ?? 0.0, opaque: opaque, clear: false) else { + return nil + } context.withContext { c in rotatedContext(context.size, c) } @@ -560,7 +566,11 @@ public class DrawingContext { f(self.context) } - public init(size: CGSize, scale: CGFloat = 0.0, opaque: Bool = false, clear: Bool = false, bytesPerRow: Int? = nil) { + public init?(size: CGSize, scale: CGFloat = 0.0, opaque: Bool = false, clear: Bool = false, bytesPerRow: Int? = nil) { + if size.width <= 0.0 || size.height <= 0.0 { + return nil + } + assert(!size.width.isZero && !size.height.isZero) let size: CGSize = CGSize(width: max(1.0, size.width), height: max(1.0, size.height)) @@ -585,7 +595,7 @@ public class DrawingContext { self.bitmapInfo = DeviceGraphicsContextSettings.shared.transparentBitmapInfo } - self.context = CGContext( + guard let context = CGContext( data: self.imageBuffer.mutableBytes, width: Int(self.scaledSize.width), height: Int(self.scaledSize.height), @@ -595,7 +605,10 @@ public class DrawingContext { bitmapInfo: self.bitmapInfo.rawValue, releaseCallback: nil, releaseInfo: nil - )! + ) else { + return nil + } + self.context = context self.context.scaleBy(x: self.scale, y: self.scale) if clear { diff --git a/submodules/Display/Source/ImageCorners.swift b/submodules/Display/Source/ImageCorners.swift index 62dbc83251..d18ffc8cff 100644 --- a/submodules/Display/Source/ImageCorners.swift +++ b/submodules/Display/Source/ImageCorners.swift @@ -44,7 +44,7 @@ private func cornerContext(_ corner: Corner) -> DrawingContext { if let cached = cached { return cached } else { - let context = DrawingContext(size: CGSize(width: CGFloat(corner.radius), height: CGFloat(corner.radius)), clear: true) + let context = DrawingContext(size: CGSize(width: CGFloat(corner.radius), height: CGFloat(corner.radius)), clear: true)! context.withContext { c in c.clear(CGRect(origin: CGPoint(), size: CGSize(width: CGFloat(corner.radius), height: CGFloat(corner.radius)))) diff --git a/submodules/Display/Source/StatusBarProxyNode.swift b/submodules/Display/Source/StatusBarProxyNode.swift index cb29181ec1..f8104f9ce8 100644 --- a/submodules/Display/Source/StatusBarProxyNode.swift +++ b/submodules/Display/Source/StatusBarProxyNode.swift @@ -86,7 +86,9 @@ private class StatusBarItemNode: ASDisplayNode { func update() { let containingBounds = maxSubviewBounds(self.targetView) - let context = DrawingContext(size: containingBounds.size, clear: true) + guard let context = DrawingContext(size: containingBounds.size, clear: true) else { + return + } if let contents = self.targetView.layer.contents, (self.targetView.layer.sublayers?.count ?? 0) == 0 && CFGetTypeID(contents as CFTypeRef) == CGImage.typeID && false { let image = contents as! CGImage diff --git a/submodules/GalleryUI/Sources/GalleryVideoDecoration.swift b/submodules/GalleryUI/Sources/GalleryVideoDecoration.swift index 3a57b5d066..ac93529926 100644 --- a/submodules/GalleryUI/Sources/GalleryVideoDecoration.swift +++ b/submodules/GalleryUI/Sources/GalleryVideoDecoration.swift @@ -51,7 +51,9 @@ public final class GalleryVideoDecoration: UniversalVideoDecoration { let boundingSize: CGSize = CGSize(width: max(corners.topLeft.radius, corners.bottomLeft.radius) + max(corners.topRight.radius, corners.bottomRight.radius), height: max(corners.topLeft.radius, corners.topRight.radius) + max(corners.bottomLeft.radius, corners.bottomRight.radius)) let size: CGSize = CGSize(width: boundingSize.width + corners.extendedEdges.left + corners.extendedEdges.right, height: boundingSize.height + corners.extendedEdges.top + corners.extendedEdges.bottom) let arguments = TransformImageArguments(corners: corners, imageSize: size, boundingSize: boundingSize, intrinsicInsets: UIEdgeInsets()) - let context = DrawingContext(size: size, clear: true) + guard let context = DrawingContext(size: size, clear: true) else { + return + } context.withContext { ctx in ctx.setFillColor(UIColor.black.cgColor) ctx.fill(arguments.drawingRect) diff --git a/submodules/GradientBackground/Sources/SoftwareGradientBackground.swift b/submodules/GradientBackground/Sources/SoftwareGradientBackground.swift index ae33e87612..59b5e3965f 100644 --- a/submodules/GradientBackground/Sources/SoftwareGradientBackground.swift +++ b/submodules/GradientBackground/Sources/SoftwareGradientBackground.swift @@ -103,7 +103,7 @@ private func generateGradient(size: CGSize, colors inputColors: [UIColor], posit positionFloats.advanced(by: i * 2 + 1).pointee = Float(1.0 - positions[i].y) } - let context = DrawingContext(size: CGSize(width: CGFloat(width), height: CGFloat(height)), scale: 1.0, opaque: true, clear: false) + let context = DrawingContext(size: CGSize(width: CGFloat(width), height: CGFloat(height)), scale: 1.0, opaque: true, clear: false)! let imageBytes = context.bytes.assumingMemoryBound(to: UInt8.self) for y in 0 ..< height { diff --git a/submodules/ImageTransparency/Sources/ImageTransparency.swift b/submodules/ImageTransparency/Sources/ImageTransparency.swift index 8f73dcbd9e..54277c8e66 100644 --- a/submodules/ImageTransparency/Sources/ImageTransparency.swift +++ b/submodules/ImageTransparency/Sources/ImageTransparency.swift @@ -61,12 +61,14 @@ public func imageHasTransparency(_ cgImage: CGImage) -> Bool { return false } -private func scaledDrawingContext(_ cgImage: CGImage, maxSize: CGSize) -> DrawingContext { +private func scaledDrawingContext(_ cgImage: CGImage, maxSize: CGSize) -> DrawingContext? { var size = CGSize(width: cgImage.width, height: cgImage.height) if (size.width > maxSize.width && size.height > maxSize.height) { size = size.aspectFilled(maxSize) } - let context = DrawingContext(size: size, scale: 1.0, clear: true) + guard let context = DrawingContext(size: size, scale: 1.0, clear: true) else { + return nil + } context.withFlippedContext { context in context.draw(cgImage, in: CGRect(origin: CGPoint(), size: size)) } @@ -81,7 +83,9 @@ public func imageRequiresInversion(_ cgImage: CGImage) -> Bool { return false } - let context = scaledDrawingContext(cgImage, maxSize: CGSize(width: 128.0, height: 128.0)) + guard let context = scaledDrawingContext(cgImage, maxSize: CGSize(width: 128.0, height: 128.0)) else { + return false + } if let cgImage = context.generateImage()?.cgImage, let (histogramBins, alphaBinIndex) = generateHistogram(cgImage: cgImage) { var hasAlpha = false for i in 0 ..< 255 { @@ -92,7 +96,9 @@ public func imageRequiresInversion(_ cgImage: CGImage) -> Bool { } if hasAlpha { - let probingContext = DrawingContext(size: CGSize(width: cgImage.width, height: cgImage.height)) + guard let probingContext = DrawingContext(size: CGSize(width: cgImage.width, height: cgImage.height)) else { + return false + } probingContext.withContext { c in c.draw(cgImage, in: CGRect(origin: CGPoint(), size: probingContext.size)) } diff --git a/submodules/LocationResources/Sources/MapResources.swift b/submodules/LocationResources/Sources/MapResources.swift index 259388cd80..08de2db8ef 100644 --- a/submodules/LocationResources/Sources/MapResources.swift +++ b/submodules/LocationResources/Sources/MapResources.swift @@ -113,7 +113,9 @@ public func chatMapSnapshotImage(engine: TelegramEngine, resource: MapSnapshotMe return signal |> map { fullSizeData in return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } var fullSizeImage: CGImage? if let fullSizeData = fullSizeData { diff --git a/submodules/LocationResources/Sources/VenueIconResources.swift b/submodules/LocationResources/Sources/VenueIconResources.swift index 08ce086052..16d1ed09c2 100644 --- a/submodules/LocationResources/Sources/VenueIconResources.swift +++ b/submodules/LocationResources/Sources/VenueIconResources.swift @@ -139,7 +139,9 @@ public func venueIcon(engine: TelegramEngine, type: String, background: Bool) -> let data: Signal = isBuiltinIcon ? .single(nil) : venueIconData(engine: engine, resource: VenueIconResource(type: type)) return data |> map { data in return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } var iconImage: UIImage? if let data = data, let image = UIImage(data: data) { diff --git a/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift b/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift index c68a5459f9..82517c8ce0 100644 --- a/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift +++ b/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift @@ -61,7 +61,9 @@ public final class ManagedAnimationState { } func draw() -> UIImage? { - let renderContext = DrawingContext(size: self.displaySize, scale: UIScreenScale, clear: true) + guard let renderContext = DrawingContext(size: self.displaySize, scale: UIScreenScale, clear: true) else { + return nil + } self.instance.renderFrame(with: Int32(self.frameIndex ?? 0), into: renderContext.bytes.assumingMemoryBound(to: UInt8.self), width: Int32(renderContext.size.width * renderContext.scale), height: Int32(renderContext.size.height * renderContext.scale), bytesPerRow: Int32(renderContext.bytesPerRow)) return renderContext.generateImage() diff --git a/submodules/OpenInExternalAppUI/Sources/OpenInAppIconResources.swift b/submodules/OpenInExternalAppUI/Sources/OpenInAppIconResources.swift index ef28d57c61..9af464ac9d 100644 --- a/submodules/OpenInExternalAppUI/Sources/OpenInAppIconResources.swift +++ b/submodules/OpenInExternalAppUI/Sources/OpenInAppIconResources.swift @@ -136,7 +136,9 @@ public func openInAppIcon(engine: TelegramEngine, appIcon: OpenInAppIcon) -> Sig case let .resource(resource): return openInAppIconData(engine: engine, appIcon: resource) |> map { data in return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } var sourceImage: UIImage? if let data = data, let image = UIImage(data: data) { @@ -161,7 +163,9 @@ public func openInAppIcon(engine: TelegramEngine, appIcon: OpenInAppIcon) -> Sig } case let .image(image): return .single({ arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } context.withFlippedContext { c in c.draw(image.cgImage!, in: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: arguments.drawingSize)) diff --git a/submodules/PasscodeUI/Sources/PasscodeBackground.swift b/submodules/PasscodeUI/Sources/PasscodeBackground.swift index aff1c5812a..c3901f496a 100644 --- a/submodules/PasscodeUI/Sources/PasscodeBackground.swift +++ b/submodules/PasscodeUI/Sources/PasscodeBackground.swift @@ -88,7 +88,7 @@ final class ImageBasedPasscodeBackground: PasscodeBackground { self.size = size let contextSize = size.aspectFilled(CGSize(width: 320.0, height: 320.0)) - let foregroundContext = DrawingContext(size: contextSize, scale: 1.0) + let foregroundContext = DrawingContext(size: contextSize, scale: 1.0)! let bounds = CGRect(origin: CGPoint(), size: contextSize) let filledImageSize = image.size.aspectFilled(contextSize) @@ -109,7 +109,7 @@ final class ImageBasedPasscodeBackground: PasscodeBackground { } self.foregroundImage = foregroundContext.generateImage()! - let backgroundContext = DrawingContext(size: contextSize, scale: 1.0) + let backgroundContext = DrawingContext(size: contextSize, scale: 1.0)! backgroundContext.withFlippedContext { c in c.interpolationQuality = .medium c.draw(image.cgImage!, in: filledImageRect) diff --git a/submodules/Pdf/Sources/PDF.swift b/submodules/Pdf/Sources/PDF.swift index 08cc6438f7..0a4aed234e 100644 --- a/submodules/Pdf/Sources/PDF.swift +++ b/submodules/Pdf/Sources/PDF.swift @@ -12,7 +12,9 @@ public func generatePdfPreviewImage(data: Data, size: CGSize) -> UIImage? { guard let document = CGPDFDocument(provider) else { return nil } guard let firstPage = document.page(at: 1) else { return nil } - let context = DrawingContext(size: size) + guard let context = DrawingContext(size: size) else { + return nil + } context.withContext { c in var pageRect = firstPage.getBoxRect(.mediaBox) let pdfScale = 320.0 / pageRect.size.width diff --git a/submodules/PhotoResources/Sources/PhotoResources.swift b/submodules/PhotoResources/Sources/PhotoResources.swift index c26cc9c06d..22d5fca5e4 100644 --- a/submodules/PhotoResources/Sources/PhotoResources.swift +++ b/submodules/PhotoResources/Sources/PhotoResources.swift @@ -663,36 +663,40 @@ public func chatMessagePhotoInternal(photoData: Signal thumbnailContextSize.width { - let additionalContextSize = thumbnailContextFittingSize - let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) - additionalBlurContext.withFlippedContext { c in - c.interpolationQuality = .default - if let image = thumbnailContext.generateImage()?.cgImage { - c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) - } + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5)) + if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 { + thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0)) + } + + if thumbnailContextFittingSize.width > thumbnailContextSize.width { + let additionalContextSize = thumbnailContextFittingSize + if let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) { + additionalBlurContext.withFlippedContext { c in + c.interpolationQuality = .default + if let image = thumbnailContext.generateImage()?.cgImage { + c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) + } + } + imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) + blurredThumbnailImage = additionalBlurContext.generateImage() + } + } else { + blurredThumbnailImage = thumbnailContext.generateImage() } - imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) - blurredThumbnailImage = additionalBlurContext.generateImage() - } else { - blurredThumbnailImage = thumbnailContext.generateImage() } } } if let blurredThumbnailImage = blurredThumbnailImage, fullSizeImage == nil, arguments.corners.isEmpty { - let context = DrawingContext(size: blurredThumbnailImage.size, scale: blurredThumbnailImage.scale, clear: true) + guard let context = DrawingContext(size: blurredThumbnailImage.size, scale: blurredThumbnailImage.scale, clear: true) else { + return nil + } context.withFlippedContext { c in c.setBlendMode(.copy) if let cgImage = blurredThumbnailImage.cgImage { @@ -704,7 +708,9 @@ public func chatMessagePhotoInternal(photoData: Signal thumbnailContextSize.width { let additionalContextSize = thumbnailContextFittingSize - let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) - additionalBlurContext.withFlippedContext { c in - c.interpolationQuality = .default - if let image = thumbnailContext.generateImage()?.cgImage { - c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) + if let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) { + additionalBlurContext.withFlippedContext { c in + c.interpolationQuality = .default + if let image = thumbnailContext.generateImage()?.cgImage { + c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) + } } + imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) + sideBlurredImage = additionalBlurContext.generateImage() } - imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) - sideBlurredImage = additionalBlurContext.generateImage() } else { sideBlurredImage = thumbnailContext.generateImage() } @@ -845,7 +854,9 @@ public func chatMessagePhotoThumbnail(account: Account, photoReference: ImageMed let fullSizeData = value._1 let fullSizeComplete = value._2 return { arguments in - let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect var fittedSize = arguments.imageSize @@ -890,14 +901,15 @@ public func chatMessagePhotoThumbnail(account: Account, photoReference: ImageMed if let thumbnailImage = thumbnailImage { let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height) let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0)) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + blurredThumbnailImage = thumbnailContext.generateImage() } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - blurredThumbnailImage = thumbnailContext.generateImage() } context.withFlippedContext { c in @@ -936,7 +948,9 @@ public func chatMessageVideoThumbnail(account: Account, fileReference: FileMedia let fullSizeData = value._1 let fullSizeComplete = value._2 return { arguments in - let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect var fittedSize = arguments.imageSize @@ -989,14 +1003,15 @@ public func chatMessageVideoThumbnail(account: Account, fileReference: FileMedia } else { let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height) let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0)) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + blurredThumbnailImage = thumbnailContext.generateImage() } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - blurredThumbnailImage = thumbnailContext.generateImage() } } @@ -1035,7 +1050,9 @@ public func chatSecretPhoto(account: Account, photoReference: ImageMediaReferenc let fullSizeData = value._1 let fullSizeComplete = value._3 return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect var fittedSize = arguments.imageSize @@ -1057,24 +1074,26 @@ public func chatSecretPhoto(account: Account, photoReference: ImageMediaReferenc if let imageSource = CGImageSourceCreateWithData(fullSizeData as CFData, nil), let image = CGImageSourceCreateImageAtIndex(imageSource, 0, options as CFDictionary) { let thumbnailSize = CGSize(width: image.width, height: image.height) let thumbnailContextSize = thumbnailSize.aspectFilled(CGSize(width: 20.0, height: 20.0)) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) - } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - let thumbnailContext2Size = thumbnailSize.aspectFitted(CGSize(width: 100.0, height: 100.0)) - let thumbnailContext2 = DrawingContext(size: thumbnailContext2Size, scale: 1.0) - thumbnailContext2.withFlippedContext { c in - c.interpolationQuality = .none - if let image = thumbnailContext.generateImage()?.cgImage { - c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContext2Size)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + let thumbnailContext2Size = thumbnailSize.aspectFitted(CGSize(width: 100.0, height: 100.0)) + if let thumbnailContext2 = DrawingContext(size: thumbnailContext2Size, scale: 1.0) { + thumbnailContext2.withFlippedContext { c in + c.interpolationQuality = .none + if let image = thumbnailContext.generateImage()?.cgImage { + c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContext2Size)) + } + } + imageFastBlur(Int32(thumbnailContext2Size.width), Int32(thumbnailContext2Size.height), Int32(thumbnailContext2.bytesPerRow), thumbnailContext2.bytes) + + blurredImage = thumbnailContext2.generateImage() } } - imageFastBlur(Int32(thumbnailContext2Size.width), Int32(thumbnailContext2Size.height), Int32(thumbnailContext2.bytesPerRow), thumbnailContext2.bytes) - - blurredImage = thumbnailContext2.generateImage() } } } @@ -1083,24 +1102,26 @@ public func chatSecretPhoto(account: Account, photoReference: ImageMediaReferenc if let thumbnailData = thumbnailData, let imageSource = CGImageSourceCreateWithData(thumbnailData as CFData, nil), let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) { let thumbnailSize = CGSize(width: image.width, height: image.height) let thumbnailContextSize = thumbnailSize.aspectFilled(CGSize(width: 20.0, height: 20.0)) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) - } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - let thumbnailContext2Size = thumbnailSize.aspectFitted(CGSize(width: 100.0, height: 100.0)) - let thumbnailContext2 = DrawingContext(size: thumbnailContext2Size, scale: 1.0) - thumbnailContext2.withFlippedContext { c in - c.interpolationQuality = .none - if let image = thumbnailContext.generateImage()?.cgImage { - c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContext2Size)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + let thumbnailContext2Size = thumbnailSize.aspectFitted(CGSize(width: 100.0, height: 100.0)) + if let thumbnailContext2 = DrawingContext(size: thumbnailContext2Size, scale: 1.0) { + thumbnailContext2.withFlippedContext { c in + c.interpolationQuality = .none + if let image = thumbnailContext.generateImage()?.cgImage { + c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContext2Size)) + } + } + imageFastBlur(Int32(thumbnailContext2Size.width), Int32(thumbnailContext2Size.height), Int32(thumbnailContext2.bytesPerRow), thumbnailContext2.bytes) + + blurredImage = thumbnailContext2.generateImage() } } - imageFastBlur(Int32(thumbnailContext2Size.width), Int32(thumbnailContext2Size.height), Int32(thumbnailContext2.bytesPerRow), thumbnailContext2.bytes) - - blurredImage = thumbnailContext2.generateImage() } } @@ -1211,7 +1232,9 @@ public func avatarGalleryThumbnailPhoto(account: Account, representations: [Imag let fullSizeComplete = value._2 return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect let fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize) @@ -1250,14 +1273,15 @@ public func avatarGalleryThumbnailPhoto(account: Account, representations: [Imag if let thumbnailImage = thumbnailImage { let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height) let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0)) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + blurredThumbnailImage = thumbnailContext.generateImage() } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - blurredThumbnailImage = thumbnailContext.generateImage() } context.withFlippedContext { c in @@ -1302,7 +1326,9 @@ public func mediaGridMessagePhoto(account: Account, photoReference: ImageMediaRe let fullSizeData = value._1 let fullSizeComplete = value._3 return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect let fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize) @@ -1344,16 +1370,17 @@ public func mediaGridMessagePhoto(account: Account, photoReference: ImageMediaRe } else { let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height) let thumbnailContextSize = thumbnailSize.aspectFilled(CGSize(width: 90.0, height: 90.0)) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + if !useMiniThumbnailIfAvailable { + telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + } + + blurredThumbnailImage = thumbnailContext.generateImage() } - if !useMiniThumbnailIfAvailable { - telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - } - - blurredThumbnailImage = thumbnailContext.generateImage() } } @@ -1405,7 +1432,10 @@ public func gifPaneVideoThumbnail(account: Account, videoReference: FileMediaRef |> map { data in let thumbnailData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } + let drawingRect = arguments.drawingRect let fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize) let fittedRect = CGRect(origin: CGPoint(x: drawingRect.origin.x + (drawingRect.size.width - fittedSize.width) / 2.0, y: drawingRect.origin.y + (drawingRect.size.height - fittedSize.height) / 2.0), size: fittedSize) @@ -1419,14 +1449,15 @@ public func gifPaneVideoThumbnail(account: Account, videoReference: FileMediaRef if let thumbnailImage = thumbnailImage { let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height) let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0)) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + blurredThumbnailImage = thumbnailContext.generateImage() } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - blurredThumbnailImage = thumbnailContext.generateImage() } context.withFlippedContext { c in @@ -1500,7 +1531,9 @@ public func internalMediaGridMessageVideo(postbox: Postbox, videoReference: File } } - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect var drawingSize: CGSize @@ -1553,30 +1586,32 @@ public func internalMediaGridMessageVideo(postbox: Postbox, videoReference: File let initialThumbnailContextFittingSize = drawingSize.fitted(CGSize(width: 90.0, height: 90.0)) let thumbnailContextSize = thumbnailSize.aspectFitted(initialThumbnailContextFittingSize) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) - } - telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5)) - if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 { - thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0)) - } - - if thumbnailContextFittingSize.width > thumbnailContextSize.width { - let additionalContextSize = thumbnailContextFittingSize - let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) - additionalBlurContext.withFlippedContext { c in - c.interpolationQuality = .default - if let image = thumbnailContext.generateImage()?.cgImage { - c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) - } + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5)) + if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 { + thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0)) + } + + if thumbnailContextFittingSize.width > thumbnailContextSize.width { + let additionalContextSize = thumbnailContextFittingSize + if let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) { + additionalBlurContext.withFlippedContext { c in + c.interpolationQuality = .default + if let image = thumbnailContext.generateImage()?.cgImage { + c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) + } + } + imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) + blurredThumbnailImage = additionalBlurContext.generateImage() + } + } else { + blurredThumbnailImage = thumbnailContext.generateImage() } - imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) - blurredThumbnailImage = additionalBlurContext.generateImage() - } else { - blurredThumbnailImage = thumbnailContext.generateImage() } } } @@ -1594,41 +1629,43 @@ public func internalMediaGridMessageVideo(postbox: Postbox, videoReference: File let initialThumbnailContextFittingSize = drawingSize.fitted(CGSize(width: 100.0, height: 100.0)) let thumbnailContextSize = thumbnailSize.aspectFitted(initialThumbnailContextFittingSize) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(fullSizeImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) - } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5)) - if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 { - thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0)) - } - - if thumbnailContextFittingSize.width > thumbnailContextSize.width { - let additionalContextSize = thumbnailContextFittingSize - let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) - additionalBlurContext.withFlippedContext { c in - c.interpolationQuality = .default - if let image = thumbnailContext.generateImage()?.cgImage { - c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) - } + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(fullSizeImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5)) + if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 { + thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0)) + } + + if thumbnailContextFittingSize.width > thumbnailContextSize.width { + let additionalContextSize = thumbnailContextFittingSize + if let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) { + additionalBlurContext.withFlippedContext { c in + c.interpolationQuality = .default + if let image = thumbnailContext.generateImage()?.cgImage { + c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) + } + } + imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) + sideBlurredImage = additionalBlurContext.generateImage() + } + } else { + sideBlurredImage = thumbnailContext.generateImage() + } + + if let blurredImage = sideBlurredImage { + let filledSize = thumbnailSize.aspectFilled(arguments.drawingRect.size) + c.interpolationQuality = .medium + c.draw(blurredImage.cgImage!, in: CGRect(origin: CGPoint(x: arguments.drawingRect.minX + (arguments.drawingRect.width - filledSize.width) / 2.0, y: arguments.drawingRect.minY + (arguments.drawingRect.height - filledSize.height) / 2.0), size: filledSize)) + c.setBlendMode(.normal) + c.setFillColor((arguments.emptyColor ?? UIColor.white).withAlphaComponent(0.05).cgColor) + c.fill(arguments.drawingRect) + c.setBlendMode(.copy) } - imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) - sideBlurredImage = additionalBlurContext.generateImage() - } else { - sideBlurredImage = thumbnailContext.generateImage() - } - - if let blurredImage = sideBlurredImage { - let filledSize = thumbnailSize.aspectFilled(arguments.drawingRect.size) - c.interpolationQuality = .medium - c.draw(blurredImage.cgImage!, in: CGRect(origin: CGPoint(x: arguments.drawingRect.minX + (arguments.drawingRect.width - filledSize.width) / 2.0, y: arguments.drawingRect.minY + (arguments.drawingRect.height - filledSize.height) / 2.0), size: filledSize)) - c.setBlendMode(.normal) - c.setFillColor((arguments.emptyColor ?? UIColor.white).withAlphaComponent(0.05).cgColor) - c.fill(arguments.drawingRect) - c.setBlendMode(.copy) } } else { c.fill(arguments.drawingRect) @@ -1817,7 +1854,9 @@ public func chatWebpageSnippetFile(account: Account, mediaReference: AnyMediaRef } if let fullSizeImage = fullSizeImage { - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let fittedSize = CGSize(width: fullSizeImage.width, height: fullSizeImage.height).aspectFilled(arguments.boundingSize) let drawingRect = arguments.drawingRect @@ -1844,7 +1883,9 @@ public func chatWebpageSnippetFile(account: Account, mediaReference: AnyMediaRef return context } else { if let emptyColor = arguments.emptyColor { - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } context.withFlippedContext { c in c.setBlendMode(.copy) @@ -1879,7 +1920,9 @@ public func chatWebpageSnippetPhoto(account: Account, photoReference: ImageMedia } if let fullSizeImage = fullSizeImage { - let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) else { + return nil + } let fittedSize = CGSize(width: fullSizeImage.width, height: fullSizeImage.height).aspectFilled(arguments.boundingSize) let drawingRect = arguments.drawingRect @@ -1942,9 +1985,12 @@ public func chatSecretMessageVideo(account: Account, videoReference: FileMediaRe return signal |> map { thumbnailData in return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } + if arguments.drawingSize.width.isLessThanOrEqualTo(0.0) || arguments.drawingSize.height.isLessThanOrEqualTo(0.0) { - return context + return nil } let drawingRect = arguments.drawingRect @@ -1957,24 +2003,26 @@ public func chatSecretMessageVideo(account: Account, videoReference: FileMediaRe if let thumbnailData = thumbnailData, let imageSource = CGImageSourceCreateWithData(thumbnailData as CFData, nil), let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) { let thumbnailSize = CGSize(width: image.width, height: image.height) let thumbnailContextSize = thumbnailSize.aspectFilled(CGSize(width: 20.0, height: 20.0)) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) - } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - let thumbnailContext2Size = thumbnailSize.aspectFitted(CGSize(width: 100.0, height: 100.0)) - let thumbnailContext2 = DrawingContext(size: thumbnailContext2Size, scale: 1.0) - thumbnailContext2.withFlippedContext { c in - c.interpolationQuality = .none - if let image = thumbnailContext.generateImage()?.cgImage { - c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContext2Size)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + let thumbnailContext2Size = thumbnailSize.aspectFitted(CGSize(width: 100.0, height: 100.0)) + if let thumbnailContext2 = DrawingContext(size: thumbnailContext2Size, scale: 1.0) { + thumbnailContext2.withFlippedContext { c in + c.interpolationQuality = .none + if let image = thumbnailContext.generateImage()?.cgImage { + c.draw(image, in: CGRect(origin: CGPoint(), size: thumbnailContext2Size)) + } + } + imageFastBlur(Int32(thumbnailContext2Size.width), Int32(thumbnailContext2Size.height), Int32(thumbnailContext2.bytesPerRow), thumbnailContext2.bytes) + + blurredImage = thumbnailContext2.generateImage() } } - imageFastBlur(Int32(thumbnailContext2Size.width), Int32(thumbnailContext2Size.height), Int32(thumbnailContext2.bytesPerRow), thumbnailContext2.bytes) - - blurredImage = thumbnailContext2.generateImage() } } @@ -2105,7 +2153,9 @@ public func chatMessageImageFile(account: Account, fileReference: FileMediaRefer let fullSizeComplete = value._2 return { arguments in assertNotOnMainThread() - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect var fittedSize: CGSize @@ -2164,31 +2214,33 @@ public func chatMessageImageFile(account: Account, fileReference: FileMediaRefer let initialThumbnailContextFittingSize = fittedSize.fitted(CGSize(width: 100.0, height: 100.0)) let thumbnailContextSize = thumbnailSize.aspectFitted(initialThumbnailContextFittingSize) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0, clear: clearContext) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) - } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5)) - if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 { - thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0)) - } - - if thumbnailContextFittingSize.width > thumbnailContextSize.width { - let additionalContextSize = thumbnailContextFittingSize - let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0, clear: clearContext) - additionalBlurContext.withFlippedContext { c in - c.interpolationQuality = .default - if let image = thumbnailContext.generateImage()?.cgImage { - c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) - } + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0, clear: clearContext) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5)) + if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 { + thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0)) + } + + if thumbnailContextFittingSize.width > thumbnailContextSize.width { + let additionalContextSize = thumbnailContextFittingSize + if let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0, clear: clearContext) { + additionalBlurContext.withFlippedContext { c in + c.interpolationQuality = .default + if let image = thumbnailContext.generateImage()?.cgImage { + c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) + } + } + imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) + blurredThumbnailImage = additionalBlurContext.generateImage() + } + } else { + blurredThumbnailImage = thumbnailContext.generateImage() } - imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) - blurredThumbnailImage = additionalBlurContext.generateImage() - } else { - blurredThumbnailImage = thumbnailContext.generateImage() } } } @@ -2231,7 +2283,9 @@ public func instantPageImageFile(account: Account, fileReference: FileMediaRefer let fullSizeComplete = value._2 return { arguments in assertNotOnMainThread() - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect let fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize) @@ -2290,7 +2344,9 @@ public func svgIconImageFile(account: Account, fileReference: FileMediaReference let fullSizePath = value.path let fullSizeComplete = value.complete return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect var fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize) @@ -2473,35 +2529,39 @@ public func chatAvatarGalleryPhoto(account: Account, representations: [ImageRepr let initialThumbnailContextFittingSize = fittedSize.fitted(CGSize(width: 90.0, height: 90.0)) let thumbnailContextSize = thumbnailSize.aspectFitted(initialThumbnailContextFittingSize) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) - } - telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5)) - if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 { - thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0)) - } - - if thumbnailContextFittingSize.width > thumbnailContextSize.width { - let additionalContextSize = thumbnailContextFittingSize - let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) - additionalBlurContext.withFlippedContext { c in - c.interpolationQuality = .default - if let image = thumbnailContext.generateImage()?.cgImage { - c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) - } + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5)) + if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 { + thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0)) + } + + if thumbnailContextFittingSize.width > thumbnailContextSize.width { + let additionalContextSize = thumbnailContextFittingSize + if let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) { + additionalBlurContext.withFlippedContext { c in + c.interpolationQuality = .default + if let image = thumbnailContext.generateImage()?.cgImage { + c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) + } + } + imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) + blurredThumbnailImage = additionalBlurContext.generateImage() + } + } else { + blurredThumbnailImage = thumbnailContext.generateImage() } - imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) - blurredThumbnailImage = additionalBlurContext.generateImage() - } else { - blurredThumbnailImage = thumbnailContext.generateImage() } } } - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } context.withFlippedContext { c in c.setBlendMode(.copy) @@ -2533,7 +2593,9 @@ public func chatWebFileImage(account: Account, file: TelegramMediaWebFile) -> Si return account.postbox.mediaBox.resourceData(file.resource) |> map { fullSizeData in return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } var fullSizeImage: CGImage? var imageOrientation: UIImage.Orientation = .up @@ -2761,7 +2823,9 @@ public func playerAlbumArt(postbox: Postbox, engine: TelegramEngine, fileReferen let remoteFullSizeData = remoteArtworkData._1 let remoteFullSizeComplete = remoteArtworkData._2 return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } var sourceImage: UIImage? if let fileArtworkData = fileArtworkData, let image = UIImage(data: fileArtworkData) { @@ -2857,7 +2921,9 @@ public func securePhotoInternal(account: Account, resource: TelegramMediaResourc } if let fullSizeImage = fullSizeImage { - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let fittedSize = CGSize(width: fullSizeImage.width, height: fullSizeImage.height).aspectFilled(arguments.boundingSize) let drawingRect = arguments.drawingRect @@ -2886,7 +2952,9 @@ public func securePhotoInternal(account: Account, resource: TelegramMediaResourc public func callDefaultBackground() -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { return .single({ arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } context.withFlippedContext { c in let colors = [UIColor(rgb: 0x466f92).cgColor, UIColor(rgb: 0x244f74).cgColor] var locations: [CGFloat] = [1.0, 0.0] diff --git a/submodules/PremiumUI/Sources/PhoneDemoComponent.swift b/submodules/PremiumUI/Sources/PhoneDemoComponent.swift index a26da3191d..5ffa1162f2 100644 --- a/submodules/PremiumUI/Sources/PhoneDemoComponent.swift +++ b/submodules/PremiumUI/Sources/PhoneDemoComponent.swift @@ -568,7 +568,9 @@ private final class VideoDecoration: UniversalVideoDecoration { let boundingSize: CGSize = CGSize(width: max(corners.topLeft.radius, corners.bottomLeft.radius) + max(corners.topRight.radius, corners.bottomRight.radius), height: max(corners.topLeft.radius, corners.topRight.radius) + max(corners.bottomLeft.radius, corners.bottomRight.radius)) let size: CGSize = CGSize(width: boundingSize.width + corners.extendedEdges.left + corners.extendedEdges.right, height: boundingSize.height + corners.extendedEdges.top + corners.extendedEdges.bottom) let arguments = TransformImageArguments(corners: corners, imageSize: size, boundingSize: boundingSize, intrinsicInsets: UIEdgeInsets()) - let context = DrawingContext(size: size, clear: true) + guard let context = DrawingContext(size: size, clear: true) else { + return + } context.withContext { ctx in ctx.setFillColor(UIColor.black.cgColor) ctx.fill(arguments.drawingRect) diff --git a/submodules/QrCode/Sources/QrCode.swift b/submodules/QrCode/Sources/QrCode.swift index eb3cb3c082..ba0074e0e7 100644 --- a/submodules/QrCode/Sources/QrCode.swift +++ b/submodules/QrCode/Sources/QrCode.swift @@ -70,7 +70,9 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n } |> map { data, size, bytesPerRow in return (size, { arguments in - let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect let fittedSize = arguments.imageSize.aspectFilled(arguments.boundingSize).fitted(arguments.imageSize) @@ -105,7 +107,9 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n } let squareSize = CGSize(width: side, height: side) - let tmpContext = DrawingContext(size: CGSize(width: squareSize.width * 4.0, height: squareSize.height), scale: arguments.scale ?? 0.0, clear: true) + guard let tmpContext = DrawingContext(size: CGSize(width: squareSize.width * 4.0, height: squareSize.height), scale: arguments.scale ?? 0.0, clear: true) else { + return nil + } tmpContext.withContext { c in if let backgroundColor = backgroundColor { c.setFillColor(backgroundColor.cgColor) diff --git a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift index 168098f8c2..abec3b6999 100644 --- a/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift +++ b/submodules/SettingsUI/Sources/Themes/SettingsThemeWallpaperNode.swift @@ -13,7 +13,9 @@ import GradientBackground private func whiteColorImage(theme: PresentationTheme, color: UIColor) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { return .single({ arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } context.withFlippedContext { c in c.setFillColor(color.cgColor) @@ -30,7 +32,9 @@ private func whiteColorImage(theme: PresentationTheme, color: UIColor) -> Signal } private let blackColorImage: UIImage? = { - let context = DrawingContext(size: CGSize(width: 1.0, height: 1.0), scale: 1.0, opaque: true, clear: false) + guard let context = DrawingContext(size: CGSize(width: 1.0, height: 1.0), scale: 1.0, opaque: true, clear: false) else { + return nil + } context.withContext { c in c.setFillColor(UIColor.black.cgColor) c.fill(CGRect(origin: CGPoint(), size: CGSize(width: 1.0, height: 1.0))) diff --git a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift index a868b85e56..81c8810792 100644 --- a/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift +++ b/submodules/SettingsUI/Sources/Themes/ThemeSettingsThemeItem.swift @@ -172,7 +172,9 @@ private func createThemeImage(theme: PresentationTheme) -> Signal<(TransformImag return .single(theme) |> map { theme -> (TransformImageArguments) -> DrawingContext? in return { arguments in - let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect context.withContext { c in diff --git a/submodules/StickerResources/Sources/StickerResources.swift b/submodules/StickerResources/Sources/StickerResources.swift index 3c3f88d1d6..4e89fa8e74 100644 --- a/submodules/StickerResources/Sources/StickerResources.swift +++ b/submodules/StickerResources/Sources/StickerResources.swift @@ -282,7 +282,9 @@ public func chatMessageLegacySticker(account: Account, file: TelegramMediaFile, let arguments = TransformImageArguments(corners: preArguments.corners, imageSize: contextSize, boundingSize: contextSize, intrinsicInsets: preArguments.intrinsicInsets) - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let thumbnailImage: CGImage? = nil @@ -290,14 +292,15 @@ public func chatMessageLegacySticker(account: Account, file: TelegramMediaFile, if let thumbnailImage = thumbnailImage { let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height) let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0)) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) - thumbnailContext.withFlippedContext { c in - c.interpolationQuality = .none - c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.interpolationQuality = .none + c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + blurredThumbnailImage = thumbnailContext.generateImage() } - imageFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - blurredThumbnailImage = thumbnailContext.generateImage() } context.withFlippedContext { c in @@ -341,7 +344,9 @@ public func chatMessageStickerPackThumbnail(postbox: Postbox, resource: MediaRes } } - let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: arguments.emptyColor == nil) + guard let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: arguments.emptyColor == nil) else { + return nil + } let drawingRect = arguments.drawingRect let fittedSize = arguments.imageSize @@ -403,7 +408,9 @@ public func chatMessageSticker(postbox: Postbox, file: TelegramMediaFile, small: return nil } - let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: arguments.emptyColor == nil) + guard let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: arguments.emptyColor == nil) else { + return nil + } let drawingRect = arguments.drawingRect let fittedSize = arguments.imageSize @@ -432,20 +439,21 @@ public func chatMessageSticker(postbox: Postbox, file: TelegramMediaFile, small: let thumbnailDrawingSize = thumbnailContextSize thumbnailContextSize.width += thumbnailInset * 2.0 thumbnailContextSize.height += thumbnailInset * 2.0 - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0, clear: true) - thumbnailContext.withFlippedContext { c in - if let cgImage = thumbnailImage.0.cgImage, let cgImageAlpha = thumbnailImage.1.cgImage { - c.setBlendMode(.normal) - c.interpolationQuality = .medium - - let mask = CGImage(maskWidth: cgImageAlpha.width, height: cgImageAlpha.height, bitsPerComponent: cgImageAlpha.bitsPerComponent, bitsPerPixel: cgImageAlpha.bitsPerPixel, bytesPerRow: cgImageAlpha.bytesPerRow, provider: cgImageAlpha.dataProvider!, decode: nil, shouldInterpolate: true) - - c.draw(cgImage.masking(mask!)!, in: CGRect(origin: CGPoint(x: thumbnailInset, y: thumbnailInset), size: thumbnailDrawingSize)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0, clear: true) { + thumbnailContext.withFlippedContext { c in + if let cgImage = thumbnailImage.0.cgImage, let cgImageAlpha = thumbnailImage.1.cgImage { + c.setBlendMode(.normal) + c.interpolationQuality = .medium + + let mask = CGImage(maskWidth: cgImageAlpha.width, height: cgImageAlpha.height, bitsPerComponent: cgImageAlpha.bitsPerComponent, bitsPerPixel: cgImageAlpha.bitsPerPixel, bytesPerRow: cgImageAlpha.bytesPerRow, provider: cgImageAlpha.dataProvider!, decode: nil, shouldInterpolate: true) + + c.draw(cgImage.masking(mask!)!, in: CGRect(origin: CGPoint(x: thumbnailInset, y: thumbnailInset), size: thumbnailDrawingSize)) + } } + stickerThumbnailAlphaBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + blurredThumbnailImage = thumbnailContext.generateImage() } - stickerThumbnailAlphaBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - blurredThumbnailImage = thumbnailContext.generateImage() } context.withFlippedContext { c in @@ -498,7 +506,9 @@ public func chatMessageAnimatedSticker(postbox: Postbox, file: TelegramMediaFile return nil } - let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect let fittedSize = arguments.imageSize @@ -526,20 +536,21 @@ public func chatMessageAnimatedSticker(postbox: Postbox, file: TelegramMediaFile let thumbnailDrawingSize = thumbnailContextSize thumbnailContextSize.width += thumbnailInset * 2.0 thumbnailContextSize.height += thumbnailInset * 2.0 - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0, clear: true) - thumbnailContext.withFlippedContext { c in - if let cgImage = thumbnailImage.0.cgImage, let cgImageAlpha = thumbnailImage.1.cgImage { - c.setBlendMode(.normal) - c.interpolationQuality = .medium - - let mask = CGImage(maskWidth: cgImageAlpha.width, height: cgImageAlpha.height, bitsPerComponent: cgImageAlpha.bitsPerComponent, bitsPerPixel: cgImageAlpha.bitsPerPixel, bytesPerRow: cgImageAlpha.bytesPerRow, provider: cgImageAlpha.dataProvider!, decode: nil, shouldInterpolate: true) - - c.draw(cgImage.masking(mask!)!, in: CGRect(origin: CGPoint(x: thumbnailInset, y: thumbnailInset), size: thumbnailDrawingSize)) + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0, clear: true) { + thumbnailContext.withFlippedContext { c in + if let cgImage = thumbnailImage.0.cgImage, let cgImageAlpha = thumbnailImage.1.cgImage { + c.setBlendMode(.normal) + c.interpolationQuality = .medium + + let mask = CGImage(maskWidth: cgImageAlpha.width, height: cgImageAlpha.height, bitsPerComponent: cgImageAlpha.bitsPerComponent, bitsPerPixel: cgImageAlpha.bitsPerPixel, bytesPerRow: cgImageAlpha.bytesPerRow, provider: cgImageAlpha.dataProvider!, decode: nil, shouldInterpolate: true) + + c.draw(cgImage.masking(mask!)!, in: CGRect(origin: CGPoint(x: thumbnailInset, y: thumbnailInset), size: thumbnailDrawingSize)) + } } + stickerThumbnailAlphaBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + blurredThumbnailImage = thumbnailContext.generateImage() } - stickerThumbnailAlphaBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) - - blurredThumbnailImage = thumbnailContext.generateImage() } context.withFlippedContext { c in diff --git a/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift b/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift index 176236668a..33cc6c6bf2 100644 --- a/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift +++ b/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift @@ -35,7 +35,10 @@ public func fetchCompressedLottieFirstFrameAJpeg(data: Data, size: CGSize, fitzM return } - let context = DrawingContext(size: size, scale: 1.0, clear: true) + guard let context = DrawingContext(size: size, scale: 1.0, clear: true) else { + subscriber.putCompletion() + return + } player.renderFrame(with: 0, into: context.bytes.assumingMemoryBound(to: UInt8.self), width: Int32(size.width), height: Int32(size.height), bytesPerRow: Int32(context.bytesPerRow)) let yuvaPixelsPerAlphaRow = (Int(size.width) + 1) & (~1) @@ -53,7 +56,9 @@ public func fetchCompressedLottieFirstFrameAJpeg(data: Data, size: CGSize, fitzM decodeYUVAToRGBA(yuvaFrameData.assumingMemoryBound(to: UInt8.self), context.bytes.assumingMemoryBound(to: UInt8.self), Int32(size.width), Int32(size.height), Int32(context.bytesPerRow)) if let colorSourceImage = context.generateImage(), let alphaImage = generateGrayscaleAlphaMaskImage(image: colorSourceImage) { - let colorContext = DrawingContext(size: size, scale: 1.0, clear: false) + guard let colorContext = DrawingContext(size: size, scale: 1.0, clear: false) else { + return + } colorContext.withFlippedContext { c in c.setFillColor(UIColor.black.cgColor) c.fill(CGRect(origin: CGPoint(), size: size)) diff --git a/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift b/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift index 9ae6a5dd69..6da2641fe0 100644 --- a/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift +++ b/submodules/TelegramPresentationData/Sources/ChatMessageBubbleImages.swift @@ -32,7 +32,7 @@ func mediaBubbleCornerImage(incoming: Bool, radius: CGFloat, inset: CGFloat) -> let imageSize = CGSize(width: radius + 7.0, height: 8.0) let fixedMainDiameter: CGFloat = 33.0 - let formContext = DrawingContext(size: imageSize) + let formContext = DrawingContext(size: imageSize)! formContext.withFlippedContext { context in context.clear(CGRect(origin: CGPoint(), size: imageSize)) context.translateBy(x: imageSize.width / 2.0, y: imageSize.height / 2.0) @@ -205,7 +205,7 @@ public func messageBubbleImage(maxCornerRadius: CGFloat, minCornerRadius: CGFloa let bottomEllipse = CGRect(origin: CGPoint(x: 24.0, y: 16.0), size: CGSize(width: 27.0, height: 17.0)) let topEllipse = CGRect(origin: CGPoint(x: 33.0, y: 14.0), size: CGSize(width: 23.0, height: 21.0)) - let formContext = DrawingContext(size: imageSize) + let formContext = DrawingContext(size: imageSize)! formContext.withFlippedContext { context in context.clear(CGRect(origin: CGPoint(), size: rawSize)) context.translateBy(x: additionalInset + strokeInset, y: additionalInset + strokeInset) @@ -240,7 +240,7 @@ public func messageBubbleImage(maxCornerRadius: CGFloat, minCornerRadius: CGFloa } let formImage = formContext.generateImage()! - let outlineContext = DrawingContext(size: imageSize) + let outlineContext = DrawingContext(size: imageSize)! outlineContext.withFlippedContext { context in context.clear(CGRect(origin: CGPoint(), size: rawSize)) context.translateBy(x: additionalInset + strokeInset, y: additionalInset + strokeInset) @@ -298,7 +298,7 @@ public func messageBubbleImage(maxCornerRadius: CGFloat, minCornerRadius: CGFloa context.addLine(to: CGPoint(x: fixedMainDiameter + borderOffset, y: outlineBottomEllipse.midY)) context.strokePath() - let bubbleTailContext = DrawingContext(size: imageSize) + let bubbleTailContext = DrawingContext(size: imageSize)! bubbleTailContext.withFlippedContext { context in context.clear(CGRect(origin: CGPoint(), size: rawSize)) context.translateBy(x: additionalInset + strokeInset, y: additionalInset + strokeInset) @@ -358,7 +358,7 @@ public func messageBubbleImage(maxCornerRadius: CGFloat, minCornerRadius: CGFloa context.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: size)) })! - let drawingContext = DrawingContext(size: imageSize) + let drawingContext = DrawingContext(size: imageSize)! drawingContext.withFlippedContext { context in if onlyShadow { context.clear(CGRect(origin: CGPoint(), size: rawSize)) diff --git a/submodules/TelegramPresentationData/Sources/PresentationData.swift b/submodules/TelegramPresentationData/Sources/PresentationData.swift index 15b333c5c7..de5a3c55bb 100644 --- a/submodules/TelegramPresentationData/Sources/PresentationData.swift +++ b/submodules/TelegramPresentationData/Sources/PresentationData.swift @@ -444,7 +444,7 @@ private func serviceColor(for data: Signal) -> Signa } public func averageColor(from image: UIImage) -> UIColor { - let context = DrawingContext(size: CGSize(width: 1.0, height: 1.0), scale: 1.0, clear: false) + let context = DrawingContext(size: CGSize(width: 1.0, height: 1.0), scale: 1.0, clear: false)! context.withFlippedContext({ context in if let cgImage = image.cgImage { context.draw(cgImage, in: CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0)) diff --git a/submodules/TelegramUI/Components/LottieAnimationCache/Sources/LottieAnimationCache.swift b/submodules/TelegramUI/Components/LottieAnimationCache/Sources/LottieAnimationCache.swift index 7762f7aaa4..96b56e41c0 100644 --- a/submodules/TelegramUI/Components/LottieAnimationCache/Sources/LottieAnimationCache.swift +++ b/submodules/TelegramUI/Components/LottieAnimationCache/Sources/LottieAnimationCache.swift @@ -50,7 +50,9 @@ public func cacheStillSticker(path: String, width: Int, height: Int, writer: Ani let work: () -> Void = { if let data = try? Data(contentsOf: URL(fileURLWithPath: path)), let image = WebP.convert(fromWebP: data) { writer.add(with: { surface in - let context = DrawingContext(size: CGSize(width: CGFloat(surface.width), height: CGFloat(surface.height)), scale: 1.0, opaque: false, clear: true, bytesPerRow: surface.bytesPerRow) + guard let context = DrawingContext(size: CGSize(width: CGFloat(surface.width), height: CGFloat(surface.height)), scale: 1.0, opaque: false, clear: true, bytesPerRow: surface.bytesPerRow) else { + return 1.0 + } context.withFlippedContext { c in UIGraphicsPushContext(c) c.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: context.size)) diff --git a/submodules/TelegramUI/Components/MultiAnimationRenderer/Sources/MultiAnimationRenderer.swift b/submodules/TelegramUI/Components/MultiAnimationRenderer/Sources/MultiAnimationRenderer.swift index a9d3598093..6c2b72a6ed 100644 --- a/submodules/TelegramUI/Components/MultiAnimationRenderer/Sources/MultiAnimationRenderer.swift +++ b/submodules/TelegramUI/Components/MultiAnimationRenderer/Sources/MultiAnimationRenderer.swift @@ -106,7 +106,9 @@ private final class ItemAnimationContext { switch frame.format { case let .rgba(data, width, height, bytesPerRow): - let context = DrawingContext(size: CGSize(width: CGFloat(width), height: CGFloat(height)), scale: 1.0, opaque: false, bytesPerRow: bytesPerRow) + guard let context = DrawingContext(size: CGSize(width: CGFloat(width), height: CGFloat(height)), scale: 1.0, opaque: false, bytesPerRow: bytesPerRow) else { + return nil + } data.withUnsafeBytes { bytes -> Void in memcpy(context.bytes, bytes.baseAddress!, height * bytesPerRow) @@ -133,7 +135,9 @@ private final class ItemAnimationContext { case let .rgba(data, width, height, bytesPerRow): let blurredWidth = 12 let blurredHeight = 12 - let context = DrawingContext(size: CGSize(width: CGFloat(blurredWidth), height: CGFloat(blurredHeight)), scale: 1.0, opaque: true, bytesPerRow: bytesPerRow) + guard let context = DrawingContext(size: CGSize(width: CGFloat(blurredWidth), height: CGFloat(blurredHeight)), scale: 1.0, opaque: true, bytesPerRow: bytesPerRow) else { + return nil + } let size = CGSize(width: CGFloat(blurredWidth), height: CGFloat(blurredHeight)) diff --git a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift index a7850d9fce..fccd6bdaf1 100644 --- a/submodules/TelegramUI/Sources/ChatBotInfoItem.swift +++ b/submodules/TelegramUI/Sources/ChatBotInfoItem.swift @@ -544,7 +544,9 @@ private final class VideoDecoration: UniversalVideoDecoration { let boundingSize: CGSize = CGSize(width: max(corners.topLeft.radius, corners.bottomLeft.radius) + max(corners.topRight.radius, corners.bottomRight.radius), height: max(corners.topLeft.radius, corners.topRight.radius) + max(corners.bottomLeft.radius, corners.bottomRight.radius)) let size: CGSize = CGSize(width: boundingSize.width + corners.extendedEdges.left + corners.extendedEdges.right, height: boundingSize.height + corners.extendedEdges.top + corners.extendedEdges.bottom) let arguments = TransformImageArguments(corners: corners, imageSize: size, boundingSize: boundingSize, intrinsicInsets: UIEdgeInsets()) - let context = DrawingContext(size: size, clear: true) + guard let context = DrawingContext(size: size, clear: true) else { + return + } context.withContext { ctx in ctx.setFillColor(UIColor.black.cgColor) ctx.fill(arguments.drawingRect) diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift index 25fcb05613..a4a9f474b4 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift @@ -413,7 +413,9 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio let boundingSize: CGSize = CGSize(width: max(corners.topLeft.radius, corners.bottomLeft.radius) + max(corners.topRight.radius, corners.bottomRight.radius), height: max(corners.topLeft.radius, corners.topRight.radius) + max(corners.bottomLeft.radius, corners.bottomRight.radius)) let size: CGSize = CGSize(width: boundingSize.width + corners.extendedEdges.left + corners.extendedEdges.right, height: boundingSize.height + corners.extendedEdges.top + corners.extendedEdges.bottom) let arguments = TransformImageArguments(corners: corners, imageSize: size, boundingSize: boundingSize, intrinsicInsets: UIEdgeInsets()) - let context = DrawingContext(size: size, clear: true) + guard let context = DrawingContext(size: size, clear: true) else { + return + } context.withContext { ctx in ctx.setFillColor(UIColor.black.cgColor) ctx.fill(arguments.drawingRect) diff --git a/submodules/TelegramUI/Sources/EmojiResources.swift b/submodules/TelegramUI/Sources/EmojiResources.swift index 7b961272ca..5664627054 100644 --- a/submodules/TelegramUI/Sources/EmojiResources.swift +++ b/submodules/TelegramUI/Sources/EmojiResources.swift @@ -264,7 +264,9 @@ func largeEmoji(postbox: Postbox, emoji: String, outline: Bool = true) -> Signal return combineLatest(queue: nil, dataSignals) |> map { datas in return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } var sourceImages: [UIImage] = [] for resourceData in datas { diff --git a/submodules/TelegramUI/Sources/FetchCachedRepresentations.swift b/submodules/TelegramUI/Sources/FetchCachedRepresentations.swift index e4a1f97b65..525c76dad6 100644 --- a/submodules/TelegramUI/Sources/FetchCachedRepresentations.swift +++ b/submodules/TelegramUI/Sources/FetchCachedRepresentations.swift @@ -533,7 +533,9 @@ private func fetchEmojiThumbnailRepresentation(account: Account, resource: Media textSize = CGSize(width: ceil(textSize.width) + 1.0, height: ceil(textSize.height) + 1.0) let emojiSize = CGSize(width: 52.0, height: 52.0) - let context = DrawingContext(size: emojiSize, clear: true) + guard let context = DrawingContext(size: emojiSize, clear: true) else { + return EmptyDisposable + } context.withFlippedContext { context in let size = textSize let bounds = CGRect(origin: CGPoint(), size: size) @@ -637,7 +639,9 @@ private func fetchEmojiRepresentation(account: Account, resource: MediaResource, let size = CGSize(width: 160.0, height: 160.0) let spacing: CGFloat = 16.0 - let context = DrawingContext(size: size, clear: true) + guard let context = DrawingContext(size: size, clear: true) else { + return EmptyDisposable + } context.withFlippedContext { context in let origin: CGPoint switch representation.tile { diff --git a/submodules/TelegramUI/Sources/SpotlightContacts.swift b/submodules/TelegramUI/Sources/SpotlightContacts.swift index 581686a4bb..54be6ceca6 100644 --- a/submodules/TelegramUI/Sources/SpotlightContacts.swift +++ b/submodules/TelegramUI/Sources/SpotlightContacts.swift @@ -134,16 +134,17 @@ private final class SpotlightIndexStorage { if let updatedAvatarSourcePathValue = updatedAvatarSourcePath, let avatarData = try? Data(contentsOf: URL(fileURLWithPath: self.appBasePath + "/" + updatedAvatarSourcePathValue)), let image = UIImage(data: avatarData) { let size = CGSize(width: 120.0, height: 120.0) - let context = DrawingContext(size: size, scale: 1.0, clear: true) - context.withFlippedContext { c in - c.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: size)) - c.setBlendMode(.destinationOut) - c.draw(roundCorners.cgImage!, in: CGRect(origin: CGPoint(), size: size)) - } - if let resultImage = context.generateImage(), let resultData = resultImage.pngData(), let _ = try? resultData.write(to: URL(fileURLWithPath: avatarPath)) { - resolvedAvatarPath = avatarPath - } else { - updatedAvatarSourcePath = nil + if let context = DrawingContext(size: size, scale: 1.0, clear: true) { + context.withFlippedContext { c in + c.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: size)) + c.setBlendMode(.destinationOut) + c.draw(roundCorners.cgImage!, in: CGRect(origin: CGPoint(), size: size)) + } + if let resultImage = context.generateImage(), let resultData = resultImage.pngData(), let _ = try? resultData.write(to: URL(fileURLWithPath: avatarPath)) { + resolvedAvatarPath = avatarPath + } else { + updatedAvatarSourcePath = nil + } } } } diff --git a/submodules/TelegramUniversalVideoContent/Sources/ChatBubbleVideoDecoration.swift b/submodules/TelegramUniversalVideoContent/Sources/ChatBubbleVideoDecoration.swift index 89b5ae6718..46b641a0e2 100644 --- a/submodules/TelegramUniversalVideoContent/Sources/ChatBubbleVideoDecoration.swift +++ b/submodules/TelegramUniversalVideoContent/Sources/ChatBubbleVideoDecoration.swift @@ -47,7 +47,9 @@ public final class ChatBubbleVideoDecoration: UniversalVideoDecoration { let boundingSize: CGSize = CGSize(width: max(corners.topLeft.radius, corners.bottomLeft.radius) + max(corners.topRight.radius, corners.bottomRight.radius), height: max(corners.topLeft.radius, corners.topRight.radius) + max(corners.bottomLeft.radius, corners.bottomRight.radius)) let size: CGSize = CGSize(width: boundingSize.width + corners.extendedEdges.left + corners.extendedEdges.right, height: boundingSize.height + corners.extendedEdges.top + corners.extendedEdges.bottom) let arguments = TransformImageArguments(corners: corners, imageSize: size, boundingSize: boundingSize, intrinsicInsets: UIEdgeInsets()) - let context = DrawingContext(size: size, clear: true) + guard let context = DrawingContext(size: size, clear: true) else { + return + } context.withContext { ctx in ctx.setFillColor(UIColor.black.cgColor) ctx.fill(arguments.drawingRect) diff --git a/submodules/TelegramUniversalVideoContent/Sources/YoutubeEmbedImplementation.swift b/submodules/TelegramUniversalVideoContent/Sources/YoutubeEmbedImplementation.swift index 6f7e3496e7..2bd15c231a 100644 --- a/submodules/TelegramUniversalVideoContent/Sources/YoutubeEmbedImplementation.swift +++ b/submodules/TelegramUniversalVideoContent/Sources/YoutubeEmbedImplementation.swift @@ -495,7 +495,9 @@ private func youtubeEmbedStoryboardImage(account: Account, resource: YoutubeEmbe return signal |> map { fullSizeData in let drawingSize = CGSize(width: CGFloat(size.width), height: CGFloat(size.height)) - let context = DrawingContext(size: drawingSize, clear: true) + guard let context = DrawingContext(size: drawingSize, clear: true) else { + return nil + } var fullSizeImage: CGImage? if let fullSizeData = fullSizeData { diff --git a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm index 0ca3837f05..b3ac7582b2 100644 --- a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm +++ b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm @@ -812,6 +812,7 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL; RTCAudioSessionConfiguration *sharedConfiguration = [RTCAudioSessionConfiguration webRTCConfiguration]; sharedConfiguration.mode = AVAudioSessionModeVoiceChat; sharedConfiguration.categoryOptions |= AVAudioSessionCategoryOptionMixWithOthers; + sharedConfiguration.categoryOptions |= AVAudioSessionCategoryOptionAllowBluetoothA2DP; sharedConfiguration.outputNumberOfChannels = 1; [RTCAudioSessionConfiguration setWebRTCConfiguration:sharedConfiguration]; @@ -895,6 +896,7 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL; sharedConfiguration.mode = AVAudioSessionModeVoiceChat; } sharedConfiguration.categoryOptions |= AVAudioSessionCategoryOptionMixWithOthers; + sharedConfiguration.categoryOptions |= AVAudioSessionCategoryOptionAllowBluetoothA2DP; sharedConfiguration.outputNumberOfChannels = 1; [RTCAudioSessionConfiguration setWebRTCConfiguration:sharedConfiguration]; @@ -1495,6 +1497,7 @@ private: RTCAudioSessionConfiguration *sharedConfiguration = [RTCAudioSessionConfiguration webRTCConfiguration]; sharedConfiguration.mode = AVAudioSessionModeVoiceChat; sharedConfiguration.categoryOptions |= AVAudioSessionCategoryOptionMixWithOthers; + sharedConfiguration.categoryOptions |= AVAudioSessionCategoryOptionAllowBluetoothA2DP; if (disableAudioInput) { sharedConfiguration.outputNumberOfChannels = 2; } else { diff --git a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift index 28861aec25..f9f4928b4b 100644 --- a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift @@ -20,7 +20,9 @@ private let motionAmount: CGFloat = 32.0 private func generateBlurredContents(image: UIImage) -> UIImage? { let size = image.size.aspectFitted(CGSize(width: 64.0, height: 64.0)) - let context = DrawingContext(size: size, scale: 1.0, opaque: true, clear: false) + guard let context = DrawingContext(size: size, scale: 1.0, opaque: true, clear: false) else { + return nil + } context.withFlippedContext { c in c.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: size)) } diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index 0c459b1e73..90b2e83923 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -215,30 +215,33 @@ public func wallpaperImage(account: Account, accountManager: AccountManager thumbnailContextSize.width { - let additionalContextSize = thumbnailContextFittingSize - let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) - additionalBlurContext.withFlippedContext { c in - c.interpolationQuality = .default - if let image = thumbnailContext.generateImage()?.cgImage { - c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) - } + if let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) { + thumbnailContext.withFlippedContext { c in + c.draw(fullSizeImageValue, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) + } + telegramFastBlurMore(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes) + + var thumbnailContextFittingSize = CGSize(width: floor(arguments.drawingSize.width * 0.5), height: floor(arguments.drawingSize.width * 0.5)) + if thumbnailContextFittingSize.width < 150.0 || thumbnailContextFittingSize.height < 150.0 { + thumbnailContextFittingSize = thumbnailContextFittingSize.aspectFilled(CGSize(width: 150.0, height: 150.0)) + } + + if false, thumbnailContextFittingSize.width > thumbnailContextSize.width { + let additionalContextSize = thumbnailContextFittingSize + guard let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) else { + return nil + } + additionalBlurContext.withFlippedContext { c in + c.interpolationQuality = .default + if let image = thumbnailContext.generateImage()?.cgImage { + c.draw(image, in: CGRect(origin: CGPoint(), size: additionalContextSize)) + } + } + imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) + fullSizeImage = additionalBlurContext.generateImage()?.cgImage + } else { + fullSizeImage = thumbnailContext.generateImage()?.cgImage } - imageFastBlur(Int32(additionalContextSize.width), Int32(additionalContextSize.height), Int32(additionalBlurContext.bytesPerRow), additionalBlurContext.bytes) - fullSizeImage = additionalBlurContext.generateImage()?.cgImage - } else { - fullSizeImage = thumbnailContext.generateImage()?.cgImage } } @@ -254,7 +257,9 @@ public func wallpaperImage(account: Account, accountManager: AccountManager thumbnailContextSize.width { let additionalContextSize = thumbnailContextFittingSize - let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) + guard let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) else { + return nil + } additionalBlurContext.withFlippedContext { c in c.interpolationQuality = .default if let image = thumbnailContext.generateImage()?.cgImage { @@ -282,7 +289,9 @@ public func wallpaperImage(account: Account, accountManager: AccountManager Signal<(TransformImageArguments) -> DrawingContext?, NoError> { return .single({ arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } context.withFlippedContext { c in c.setFillColor(color.withAlphaComponent(1.0).cgColor) @@ -713,7 +728,9 @@ public func gradientImage(_ colors: [UIColor], rotation: Int32? = nil) -> Signal } } return .single({ arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: !arguments.corners.isEmpty) + guard let context = DrawingContext(size: arguments.drawingSize, clear: !arguments.corners.isEmpty) else { + return nil + } let drawingRect = arguments.drawingRect @@ -768,7 +785,9 @@ private func builtinWallpaperData() -> Signal { public func settingsBuiltinWallpaperImage(account: Account, thumbnail: Bool = false) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> { return builtinWallpaperData() |> map { fullSizeImage in return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect var fittedSize = fullSizeImage.size.aspectFilled(drawingRect.size) @@ -811,7 +830,9 @@ public func photoWallpaper(postbox: Postbox, photoLibraryResource: PhotoLibraryM let isThumbnail = result?.1 ?? false return { arguments in - let context = DrawingContext(size: arguments.drawingSize, scale: 1.0, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, scale: 1.0, clear: true) else { + return nil + } let dimensions = sourceImage?.size @@ -829,7 +850,9 @@ public func photoWallpaper(postbox: Postbox, photoLibraryResource: PhotoLibraryM let initialThumbnailContextFittingSize = fittedSize.fitted(CGSize(width: 100.0, height: 100.0)) let thumbnailContextSize = thumbnailSize.aspectFitted(initialThumbnailContextFittingSize) - let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) + guard let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0) else { + return nil + } thumbnailContext.withFlippedContext { c in c.interpolationQuality = .none c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize)) @@ -843,7 +866,9 @@ public func photoWallpaper(postbox: Postbox, photoLibraryResource: PhotoLibraryM if thumbnailContextFittingSize.width > thumbnailContextSize.width { let additionalContextSize = thumbnailContextFittingSize - let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) + guard let additionalBlurContext = DrawingContext(size: additionalContextSize, scale: 1.0) else { + return nil + } additionalBlurContext.withFlippedContext { c in c.interpolationQuality = .default if let image = thumbnailContext.generateImage()?.cgImage { @@ -1230,7 +1255,9 @@ public func themeImage(account: Account, accountManager: AccountManager map { colors in return { arguments in - let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: arguments.emptyColor == nil) + guard let context = DrawingContext(size: arguments.drawingSize, scale: arguments.scale ?? 0.0, clear: arguments.emptyColor == nil) else { + return nil + } let drawingRect = arguments.drawingRect context.withContext { c in @@ -1530,7 +1563,9 @@ public func themeIconImage(account: Account, accountManager: AccountManager map { image in if let image = image { return { arguments in - let context = DrawingContext(size: arguments.drawingSize, clear: true) + guard let context = DrawingContext(size: arguments.drawingSize, clear: true) else { + return nil + } let drawingRect = arguments.drawingRect let imageSize = image.size let fittedSize = imageSize.aspectFilled(arguments.boundingSize).fitted(imageSize)