diff --git a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift index ed5d1758fb..9606e718e1 100644 --- a/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift +++ b/submodules/AnimatedStickerNode/Sources/AnimatedStickerNode.swift @@ -614,7 +614,7 @@ private final class AnimatedStickerDirectFrameSource: AnimatedStickerFrameSource self.data = data self.width = width self.height = height - self.bytesPerRow = (4 * Int(width) + 15) & (~15) + self.bytesPerRow = DeviceGraphicsContextSettings.shared.bytesPerRow(forWidth: Int(width)) self.currentFrame = 0 let rawData = TGGUnzipData(data, 8 * 1024 * 1024) ?? data let decompressedData = transformedWithFitzModifier(data: rawData, fitzModifier: fitzModifier) diff --git a/submodules/AnimatedStickerNode/Sources/SoftwareAnimationRenderer.swift b/submodules/AnimatedStickerNode/Sources/SoftwareAnimationRenderer.swift index 6dffe0ed40..5b23eb8b1d 100644 --- a/submodules/AnimatedStickerNode/Sources/SoftwareAnimationRenderer.swift +++ b/submodules/AnimatedStickerNode/Sources/SoftwareAnimationRenderer.swift @@ -13,7 +13,7 @@ final class SoftwareAnimationRenderer: ASDisplayNode, AnimationRenderer { queue.async { [weak self] in switch type { case .argb: - let calculatedBytesPerRow = (4 * Int(width) + 15) & (~15) + let calculatedBytesPerRow = DeviceGraphicsContextSettings.shared.bytesPerRow(forWidth: Int(width)) assert(bytesPerRow == calculatedBytesPerRow) case .yuva: break diff --git a/submodules/AsyncDisplayKit/Source/ASCGImageBuffer.mm b/submodules/AsyncDisplayKit/Source/ASCGImageBuffer.mm index 6f05300e23..de397471e0 100644 --- a/submodules/AsyncDisplayKit/Source/ASCGImageBuffer.mm +++ b/submodules/AsyncDisplayKit/Source/ASCGImageBuffer.mm @@ -6,7 +6,7 @@ // Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0 // -#import "ASCGImageBuffer.h" +#import #import #import diff --git a/submodules/AsyncDisplayKit/Source/ASGraphicsContext.mm b/submodules/AsyncDisplayKit/Source/ASGraphicsContext.mm index b181ee2728..b950613d0d 100644 --- a/submodules/AsyncDisplayKit/Source/ASGraphicsContext.mm +++ b/submodules/AsyncDisplayKit/Source/ASGraphicsContext.mm @@ -7,7 +7,7 @@ // #import -#import "ASCGImageBuffer.h" +#import #import #import #import diff --git a/submodules/AsyncDisplayKit/Source/ASCGImageBuffer.h b/submodules/AsyncDisplayKit/Source/PublicHeaders/AsyncDisplayKit/ASCGImageBuffer.h similarity index 100% rename from submodules/AsyncDisplayKit/Source/ASCGImageBuffer.h rename to submodules/AsyncDisplayKit/Source/PublicHeaders/AsyncDisplayKit/ASCGImageBuffer.h diff --git a/submodules/AvatarNode/Sources/PeerAvatar.swift b/submodules/AvatarNode/Sources/PeerAvatar.swift index 2df704b1fb..455fde6074 100644 --- a/submodules/AvatarNode/Sources/PeerAvatar.swift +++ b/submodules/AvatarNode/Sources/PeerAvatar.swift @@ -161,7 +161,7 @@ public func peerAvatarImage(account: Account, peerReference: PeerReference?, aut } if shouldBlur { let imageContextSize = CGSize(width: 64.0, height: 64.0) - let imageContext = DrawingContext(size: imageContextSize, scale: 1.0, premultiplied: true, clear: true) + let imageContext = DrawingContext(size: imageContextSize, scale: 1.0, clear: true) imageContext.withFlippedContext { c in c.draw(dataImage, in: CGRect(origin: CGPoint(), size: imageContextSize)) diff --git a/submodules/Display/Source/GenerateImage.swift b/submodules/Display/Source/GenerateImage.swift index b5cab18e33..4241ca4bd7 100644 --- a/submodules/Display/Source/GenerateImage.swift +++ b/submodules/Display/Source/GenerateImage.swift @@ -1,6 +1,7 @@ import Foundation import UIKit import Accelerate +import AsyncDisplayKit public let deviceColorSpace: CGColorSpace = { if #available(iOSApplicationExtension 9.3, iOS 9.3, *) { @@ -19,38 +20,20 @@ private let grayscaleColorSpace = CGColorSpaceCreateDeviceGray() let deviceScale = UIScreen.main.scale public func generateImagePixel(_ size: CGSize, scale: CGFloat, pixelGenerator: (CGSize, UnsafeMutablePointer, Int) -> Void) -> UIImage? { - let scaledSize = CGSize(width: size.width * scale, height: size.height * scale) - let bytesPerRow = (4 * Int(scaledSize.width) + 15) & (~15) - let length = bytesPerRow * Int(scaledSize.height) - let bytes = malloc(length)!.assumingMemoryBound(to: UInt8.self) - guard let provider = CGDataProvider(dataInfo: bytes, data: bytes, size: length, releaseData: { bytes, _, _ in - free(bytes) - }) - else { - return nil - } - - pixelGenerator(scaledSize, bytes, bytesPerRow) - - let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue) - - guard let image = CGImage(width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: bytesPerRow, space: deviceColorSpace, bitmapInfo: bitmapInfo, provider: provider, decode: nil, shouldInterpolate: false, intent: .defaultIntent) - else { - return nil - } - - return UIImage(cgImage: image, scale: scale, orientation: .up) + let context = DrawingContext(size: size, scale: scale, opaque: false, clear: false) + pixelGenerator(CGSize(width: size.width * scale, height: size.height * scale), context.bytes.assumingMemoryBound(to: UInt8.self), context.bytesPerRow) + return context.generateImage() } private func withImageBytes(image: UIImage, _ f: (UnsafePointer, Int, Int, Int) -> Void) { let selectedScale = image.scale let scaledSize = CGSize(width: image.size.width * selectedScale, height: image.size.height * selectedScale) - let bytesPerRow = (4 * Int(scaledSize.width) + 15) & (~15) + let bytesPerRow = DeviceGraphicsContextSettings.shared.bytesPerRow(forWidth: Int(scaledSize.width)) let length = bytesPerRow * Int(scaledSize.height) let bytes = malloc(length)!.assumingMemoryBound(to: UInt8.self) memset(bytes, 0, length) - let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue) + let bitmapInfo = DeviceGraphicsContextSettings.shared.transparentBitmapInfo guard let context = CGContext(data: bytes, width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: deviceColorSpace, bitmapInfo: bitmapInfo.rawValue) else { return @@ -65,7 +48,7 @@ private func withImageBytes(image: UIImage, _ f: (UnsafePointer, Int, Int public func generateGrayscaleAlphaMaskImage(image: UIImage) -> UIImage? { let selectedScale = image.scale let scaledSize = CGSize(width: image.size.width * selectedScale, height: image.size.height * selectedScale) - let bytesPerRow = (1 * Int(scaledSize.width) + 15) & (~15) + let bytesPerRow = (1 * Int(scaledSize.width) + 31) & (~31) let length = bytesPerRow * Int(scaledSize.height) let bytes = malloc(length)!.assumingMemoryBound(to: UInt8.self) memset(bytes, 0, length) @@ -111,69 +94,19 @@ public func generateGrayscaleAlphaMaskImage(image: UIImage) -> UIImage? { } public func generateImage(_ size: CGSize, contextGenerator: (CGSize, CGContext) -> Void, opaque: Bool = false, scale: CGFloat? = nil) -> UIImage? { - let selectedScale = scale ?? deviceScale - let scaledSize = CGSize(width: size.width * selectedScale, height: size.height * selectedScale) - let bytesPerRow = (4 * Int(scaledSize.width) + 15) & (~15) - let length = bytesPerRow * Int(scaledSize.height) - let bytes = malloc(length)!.assumingMemoryBound(to: Int8.self) - - guard let provider = CGDataProvider(dataInfo: bytes, data: bytes, size: length, releaseData: { bytes, _, _ in - free(bytes) - }) - else { - return nil + let context = DrawingContext(size: size, scale: scale ?? 0.0, opaque: opaque, clear: false) + context.withFlippedContext { c in + contextGenerator(context.size, c) } - - let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | (opaque ? CGImageAlphaInfo.noneSkipFirst.rawValue : CGImageAlphaInfo.premultipliedFirst.rawValue)) - - guard let context = CGContext(data: bytes, width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: deviceColorSpace, bitmapInfo: bitmapInfo.rawValue) else { - return nil - } - - context.scaleBy(x: selectedScale, y: selectedScale) - - contextGenerator(size, context) - - guard let image = CGImage(width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: bytesPerRow, space: deviceColorSpace, bitmapInfo: bitmapInfo, provider: provider, decode: nil, shouldInterpolate: false, intent: .defaultIntent) - else { - return nil - } - - return UIImage(cgImage: image, scale: selectedScale, orientation: .up) + return context.generateImage() } public func generateImage(_ size: CGSize, opaque: Bool = false, scale: CGFloat? = nil, rotatedContext: (CGSize, CGContext) -> Void) -> UIImage? { - let selectedScale = scale ?? deviceScale - let scaledSize = CGSize(width: size.width * selectedScale, height: size.height * selectedScale) - let bytesPerRow = (4 * Int(scaledSize.width) + 15) & (~15) - let length = bytesPerRow * Int(scaledSize.height) - let bytes = malloc(length)!.assumingMemoryBound(to: Int8.self) - - guard let provider = CGDataProvider(dataInfo: bytes, data: bytes, size: length, releaseData: { bytes, _, _ in - free(bytes) - }) else { - return nil + let context = DrawingContext(size: size, scale: scale ?? 0.0, opaque: opaque, clear: false) + context.withContext { c in + rotatedContext(context.size, c) } - - let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | (opaque ? CGImageAlphaInfo.noneSkipFirst.rawValue : CGImageAlphaInfo.premultipliedFirst.rawValue)) - - guard let context = CGContext(data: bytes, width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: deviceColorSpace, bitmapInfo: bitmapInfo.rawValue) else { - return nil - } - - context.scaleBy(x: selectedScale, y: selectedScale) - context.translateBy(x: size.width / 2.0, y: size.height / 2.0) - context.scaleBy(x: 1.0, y: -1.0) - context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0) - - rotatedContext(size, context) - - guard let image = CGImage(width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: bytesPerRow, space: deviceColorSpace, bitmapInfo: bitmapInfo, provider: provider, decode: nil, shouldInterpolate: false, intent: .defaultIntent) - else { - return nil - } - - return UIImage(cgImage: image, scale: selectedScale, orientation: .up) + return context.generateImage() } public func generateFilledCircleImage(diameter: CGFloat, color: UIColor?, strokeColor: UIColor? = nil, strokeWidth: CGFloat? = nil, backgroundColor: UIColor? = nil) -> UIImage? { @@ -433,6 +366,47 @@ public enum DrawingContextBltMode { case Alpha } +public struct DeviceGraphicsContextSettings { + public static let shared: DeviceGraphicsContextSettings = { + UIGraphicsBeginImageContextWithOptions(CGSize(width: 1.0, height: 1.0), true, 1.0) + let refContext = UIGraphicsGetCurrentContext()! + let bytesPerRow = refContext.bytesPerRow + let bitsPerPixel = refContext.bitsPerPixel + let bitsPerComponent = refContext.bitsPerComponent + let opaqueBitmapInfo = refContext.bitmapInfo + let image = UIGraphicsGetImageFromCurrentImageContext()! + let colorSpace = image.cgImage!.colorSpace! + assert(bytesPerRow == 32) + UIGraphicsEndImageContext() + + UIGraphicsBeginImageContextWithOptions(CGSize(width: 1.0, height: 1.0), false, 1.0) + let refCtxTransparent = UIGraphicsGetCurrentContext()! + let transparentBitmapInfo = refCtxTransparent.bitmapInfo + UIGraphicsEndImageContext() + + return DeviceGraphicsContextSettings( + rowAlignment: bytesPerRow, + bitsPerPixel: bitsPerPixel, + bitsPerComponent: bitsPerComponent, + opaqueBitmapInfo: opaqueBitmapInfo, + transparentBitmapInfo: transparentBitmapInfo, + colorSpace: colorSpace + ) + }() + + public let rowAlignment: Int + public let bitsPerPixel: Int + public let bitsPerComponent: Int + public let opaqueBitmapInfo: CGBitmapInfo + public let transparentBitmapInfo: CGBitmapInfo + public let colorSpace: CGColorSpace + + public func bytesPerRow(forWidth width: Int) -> Int { + let baseValue = self.bitsPerPixel * width / 8 + return (baseValue + 31) & ~0x1F + } +} + public class DrawingContext { public let size: CGSize public let scale: CGFloat @@ -440,46 +414,33 @@ public class DrawingContext { public let bytesPerRow: Int private let bitmapInfo: CGBitmapInfo public let length: Int - public let bytes: UnsafeMutableRawPointer - let provider: CGDataProvider? - - private var _context: CGContext? + private let imageBuffer: ASCGImageBuffer + public var bytes: UnsafeMutableRawPointer { + return self.imageBuffer.mutableBytes + } + private let context: CGContext + + private var hasGeneratedImage = false public func withContext(_ f: (CGContext) -> ()) { - if self._context == nil { - if let c = CGContext(data: bytes, width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: deviceColorSpace, bitmapInfo: self.bitmapInfo.rawValue) { - c.scaleBy(x: scale, y: scale) - self._context = c - } - } - - if let _context = self._context { - _context.translateBy(x: self.size.width / 2.0, y: self.size.height / 2.0) - _context.scaleBy(x: 1.0, y: -1.0) - _context.translateBy(x: -self.size.width / 2.0, y: -self.size.height / 2.0) - - f(_context) - - _context.translateBy(x: self.size.width / 2.0, y: self.size.height / 2.0) - _context.scaleBy(x: 1.0, y: -1.0) - _context.translateBy(x: -self.size.width / 2.0, y: -self.size.height / 2.0) - } + let context = self.context + + context.translateBy(x: self.size.width / 2.0, y: self.size.height / 2.0) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -self.size.width / 2.0, y: -self.size.height / 2.0) + + f(context) + + context.translateBy(x: self.size.width / 2.0, y: self.size.height / 2.0) + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: -self.size.width / 2.0, y: -self.size.height / 2.0) } public func withFlippedContext(_ f: (CGContext) -> ()) { - if self._context == nil { - if let c = CGContext(data: bytes, width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: deviceColorSpace, bitmapInfo: self.bitmapInfo.rawValue) { - c.scaleBy(x: scale, y: scale) - self._context = c - } - } - - if let _context = self._context { - f(_context) - } + f(self.context) } - public init(size: CGSize, scale: CGFloat = 0.0, premultiplied: Bool = true, opaque: Bool = false, clear: Bool = false) { + public init(size: CGSize, scale: CGFloat = 0.0, opaque: Bool = false, clear: Bool = false) { let actualScale: CGFloat if scale.isZero { actualScale = deviceScale @@ -490,35 +451,63 @@ public class DrawingContext { self.scale = actualScale self.scaledSize = CGSize(width: size.width * actualScale, height: size.height * actualScale) - self.bytesPerRow = (4 * Int(scaledSize.width) + 15) & (~15) + self.bytesPerRow = DeviceGraphicsContextSettings.shared.bytesPerRow(forWidth: Int(scaledSize.width)) self.length = bytesPerRow * Int(scaledSize.height) + self.imageBuffer = ASCGImageBuffer(length: UInt(self.length)) + if opaque { - self.bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.noneSkipFirst.rawValue) - } else if premultiplied { - self.bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.premultipliedFirst.rawValue) + self.bitmapInfo = DeviceGraphicsContextSettings.shared.opaqueBitmapInfo } else { - self.bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.first.rawValue) + self.bitmapInfo = DeviceGraphicsContextSettings.shared.transparentBitmapInfo } - - self.bytes = malloc(length)! + + self.context = CGContext( + data: self.imageBuffer.mutableBytes, + width: Int(self.scaledSize.width), + height: Int(self.scaledSize.height), + bitsPerComponent: DeviceGraphicsContextSettings.shared.bitsPerComponent, + bytesPerRow: self.bytesPerRow, + space: DeviceGraphicsContextSettings.shared.colorSpace, + bitmapInfo: self.bitmapInfo.rawValue, + releaseCallback: nil, + releaseInfo: nil + )! + self.context.scaleBy(x: self.scale, y: self.scale) + if clear { memset(self.bytes, 0, self.length) } - self.provider = CGDataProvider(dataInfo: bytes, data: bytes, size: length, releaseData: { bytes, _, _ in - free(bytes) - }) - - assert(self.bytesPerRow % 16 == 0) - assert(Int64(Int(bitPattern: self.bytes)) % 16 == 0) } public func generateImage() -> UIImage? { if self.scaledSize.width.isZero || self.scaledSize.height.isZero { return nil } - if let image = CGImage(width: Int(scaledSize.width), height: Int(scaledSize.height), bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: bytesPerRow, space: deviceColorSpace, bitmapInfo: bitmapInfo, provider: provider!, decode: nil, shouldInterpolate: false, intent: .defaultIntent) { - return UIImage(cgImage: image, scale: scale, orientation: .up) + if self.hasGeneratedImage { + #if DEBUG + assert(false) + #endif + return nil + } + self.hasGeneratedImage = true + + let dataProvider = self.imageBuffer.createDataProviderAndInvalidate() + + if let image = CGImage( + width: Int(self.scaledSize.width), + height: Int(self.scaledSize.height), + bitsPerComponent: self.context.bitsPerComponent, + bitsPerPixel: self.context.bitsPerPixel, + bytesPerRow: self.context.bytesPerRow, + space: DeviceGraphicsContextSettings.shared.colorSpace, + bitmapInfo: self.context.bitmapInfo, + provider: dataProvider, + decode: nil, + shouldInterpolate: true, + intent: .defaultIntent + ) { + return UIImage(cgImage: image, scale: self.scale, orientation: .up) } else { return nil } diff --git a/submodules/GraphCore/Sources/Helpers/UIImage+Utils.swift b/submodules/GraphCore/Sources/Helpers/UIImage+Utils.swift index 76390fe4da..6408a97414 100644 --- a/submodules/GraphCore/Sources/Helpers/UIImage+Utils.swift +++ b/submodules/GraphCore/Sources/Helpers/UIImage+Utils.swift @@ -56,7 +56,7 @@ var deviceScale: CGFloat { func generateImage(_ size: CGSize, contextGenerator: (CGSize, CGContext) -> Void, opaque: Bool = false, scale: CGFloat? = nil) -> GImage? { let selectedScale = scale ?? deviceScale let scaledSize = CGSize(width: size.width * selectedScale, height: size.height * selectedScale) - let bytesPerRow = (4 * Int(scaledSize.width) + 15) & (~15) + let bytesPerRow = (4 * Int(scaledSize.width) + 31) & (~31) let length = bytesPerRow * Int(scaledSize.height) let bytes = malloc(length)!.assumingMemoryBound(to: Int8.self) diff --git a/submodules/LegacyComponents/Sources/TGGradientLabel.m b/submodules/LegacyComponents/Sources/TGGradientLabel.m index 317e9111ac..ca5f4212dd 100644 --- a/submodules/LegacyComponents/Sources/TGGradientLabel.m +++ b/submodules/LegacyComponents/Sources/TGGradientLabel.m @@ -113,7 +113,7 @@ _offscreenContextWidth = offscreenWidth; _offscreenContextHeight = offscreenHeight; - _offscreenContextStride = ((4 * _offscreenContextWidth + 15) & (~15)); + _offscreenContextStride = ((4 * _offscreenContextWidth + 31) & (~31)); _offscreenMemory = malloc(_offscreenContextStride * _offscreenContextHeight); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); diff --git a/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift b/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift index b28f246ed9..78fd73e01b 100644 --- a/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift +++ b/submodules/LegacyMediaPickerUI/Sources/LegacyPaintStickersContext.swift @@ -21,7 +21,7 @@ protocol LegacyPaintEntity { } private func render(width: Int, height: Int, bytesPerRow: Int, data: Data, type: AnimationRendererFrameType) -> CIImage? { - let calculatedBytesPerRow = (4 * Int(width) + 15) & (~15) + let calculatedBytesPerRow = (4 * Int(width) + 31) & (~31) assert(bytesPerRow == calculatedBytesPerRow) let image = generateImagePixel(CGSize(width: CGFloat(width), height: CGFloat(height)), scale: 1.0, pixelGenerator: { _, pixelData, bytesPerRow in diff --git a/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift b/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift index 9e4a89025a..06b6286056 100644 --- a/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift +++ b/submodules/ManagedAnimationNode/Sources/ManagedAnimationNode.swift @@ -44,7 +44,7 @@ public final class ManagedAnimationState { return nil } resolvedInstance = instance - renderContext = DrawingContext(size: displaySize, scale: UIScreenScale, premultiplied: true, clear: true) + renderContext = DrawingContext(size: displaySize, scale: UIScreenScale, clear: true) } self.item = item diff --git a/submodules/MediaPlayer/Sources/FFMpegMediaVideoFrameDecoder.swift b/submodules/MediaPlayer/Sources/FFMpegMediaVideoFrameDecoder.swift index 76037e0848..83e84af1f3 100644 --- a/submodules/MediaPlayer/Sources/FFMpegMediaVideoFrameDecoder.swift +++ b/submodules/MediaPlayer/Sources/FFMpegMediaVideoFrameDecoder.swift @@ -222,7 +222,7 @@ public final class FFMpegMediaVideoFrameDecoder: MediaTrackFrameDecoder { var srcCb = vImage_Buffer(data: frame.data[1], height: vImagePixelCount(frame.height), width: vImagePixelCount(frame.width / 2), rowBytes: Int(frame.lineSize[1])) var srcCr = vImage_Buffer(data: frame.data[2], height: vImagePixelCount(frame.height), width: vImagePixelCount(frame.width / 2), rowBytes: Int(frame.lineSize[2])) - let argbBytesPerRow = (4 * Int(frame.width) + 15) & (~15) + let argbBytesPerRow = (4 * Int(frame.width) + 31) & (~31) let argbLength = argbBytesPerRow * Int(frame.height) let argb = malloc(argbLength)! guard let provider = CGDataProvider(dataInfo: argb, data: argb, size: argbLength, releaseData: { bytes, _, _ in diff --git a/submodules/MozjpegBinding/Sources/MozjpegBinding.m b/submodules/MozjpegBinding/Sources/MozjpegBinding.m index e2cdf62782..8138b309ad 100644 --- a/submodules/MozjpegBinding/Sources/MozjpegBinding.m +++ b/submodules/MozjpegBinding/Sources/MozjpegBinding.m @@ -70,7 +70,7 @@ NSData * _Nullable compressJPEGData(UIImage * _Nonnull sourceImage) { int width = (int)(sourceImage.size.width * sourceImage.scale); int height = (int)(sourceImage.size.height * sourceImage.scale); - int targetBytesPerRow = ((4 * (int)width) + 15) & (~15); + int targetBytesPerRow = ((4 * (int)width) + 31) & (~31); uint8_t *targetMemory = malloc((int)(targetBytesPerRow * height)); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); @@ -86,7 +86,7 @@ NSData * _Nullable compressJPEGData(UIImage * _Nonnull sourceImage) { UIGraphicsPopContext(); - int bufferBytesPerRow = ((3 * (int)width) + 15) & (~15); + int bufferBytesPerRow = ((3 * (int)width) + 31) & (~31); uint8_t *buffer = malloc(bufferBytesPerRow * height); for (int y = 0; y < height; y++) { @@ -158,7 +158,7 @@ NSData * _Nullable compressMiniThumbnail(UIImage * _Nonnull image, CGSize size) int width = (int)fittedSize.width; int height = (int)fittedSize.height; - int targetBytesPerRow = ((4 * (int)width) + 15) & (~15); + int targetBytesPerRow = ((4 * (int)width) + 31) & (~31); uint8_t *targetMemory = malloc((int)(targetBytesPerRow * height)); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); @@ -174,7 +174,7 @@ NSData * _Nullable compressMiniThumbnail(UIImage * _Nonnull image, CGSize size) UIGraphicsPopContext(); - int bufferBytesPerRow = ((3 * (int)width) + 15) & (~15); + int bufferBytesPerRow = ((3 * (int)width) + 31) & (~31); uint8_t *buffer = malloc(bufferBytesPerRow * height); for (int y = 0; y < height; y++) { diff --git a/submodules/QrCode/Sources/QrCode.swift b/submodules/QrCode/Sources/QrCode.swift index 5e26ae2357..eb3cb3c082 100644 --- a/submodules/QrCode/Sources/QrCode.swift +++ b/submodules/QrCode/Sources/QrCode.swift @@ -46,7 +46,7 @@ public func qrCode(string: String, color: UIColor, backgroundColor: UIColor? = n if let output = filter.outputImage { let size = Int(output.extent.width) - let bytesPerRow = (4 * Int(size) + 15) & (~15) + let bytesPerRow = DeviceGraphicsContextSettings.shared.bytesPerRow(forWidth: Int(size)) let length = bytesPerRow * size let bitmapInfo = CGBitmapInfo(rawValue: CGBitmapInfo.byteOrder32Little.rawValue | CGImageAlphaInfo.noneSkipFirst.rawValue) diff --git a/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift b/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift index d39c63244e..a12fc19c98 100644 --- a/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift +++ b/submodules/TelegramAnimatedStickerNode/Sources/AnimatedStickerUtils.swift @@ -136,7 +136,7 @@ public func experimentalConvertCompressedLottieToCombinedMp4(data: Data, size: C return } - let bytesPerRow = (4 * Int(size.width) + 15) & (~15) + let bytesPerRow = DeviceGraphicsContextSettings.shared.bytesPerRow(forWidth: Int(size.width)) var currentFrame: Int32 = 0 diff --git a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift index 794a687508..066e69fb13 100644 --- a/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift +++ b/submodules/WallpaperBackgroundNode/Sources/WallpaperBackgroundNode.swift @@ -16,7 +16,7 @@ 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, premultiplied: true, opaque: true, clear: false) + let context = DrawingContext(size: size, scale: 1.0, opaque: true, clear: false) context.withFlippedContext { c in c.draw(image.cgImage!, in: CGRect(origin: CGPoint(), size: size)) } diff --git a/submodules/WebPBinding/Sources/UIImage+WebP.m b/submodules/WebPBinding/Sources/UIImage+WebP.m index 3f541a37c7..c4a07eed72 100644 --- a/submodules/WebPBinding/Sources/UIImage+WebP.m +++ b/submodules/WebPBinding/Sources/UIImage+WebP.m @@ -19,7 +19,7 @@ const struct { int width, height; } targetContextSize = { width, height}; - size_t targetBytesPerRow = ((4 * (int)targetContextSize.width) + 15) & (~15); + size_t targetBytesPerRow = ((4 * (int)targetContextSize.width) + 31) & (~31); void *targetMemory = malloc((int)(targetBytesPerRow * targetContextSize.height));