mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
81 lines
2.8 KiB
Swift
81 lines
2.8 KiB
Swift
import Foundation
|
|
import Compression
|
|
import YuvConversion
|
|
|
|
func compressFrame(width: Int, height: Int, rgbData: Data, unpremultiply: Bool) -> Data? {
|
|
let bytesPerRow = rgbData.count / height
|
|
|
|
let yuvaPixelsPerAlphaRow = (Int(width) + 1) & (~1)
|
|
assert(yuvaPixelsPerAlphaRow % 2 == 0)
|
|
|
|
let yuvaLength = Int(width) * Int(height) * 2 + yuvaPixelsPerAlphaRow * Int(height) / 2
|
|
let yuvaFrameData = malloc(yuvaLength)!
|
|
defer {
|
|
free(yuvaFrameData)
|
|
}
|
|
memset(yuvaFrameData, 0, yuvaLength)
|
|
|
|
var compressedFrameData = Data(count: yuvaLength)
|
|
let compressedFrameDataLength = compressedFrameData.count
|
|
|
|
let scratchData = malloc(compression_encode_scratch_buffer_size(COMPRESSION_LZFSE))!
|
|
defer {
|
|
free(scratchData)
|
|
}
|
|
|
|
var rgbData = rgbData
|
|
rgbData.withUnsafeMutableBytes { (buffer: UnsafeMutableRawBufferPointer) -> Void in
|
|
if let baseAddress = buffer.baseAddress {
|
|
encodeRGBAToYUVA(yuvaFrameData.assumingMemoryBound(to: UInt8.self), baseAddress.assumingMemoryBound(to: UInt8.self), Int32(width), Int32(height), Int32(bytesPerRow), true, unpremultiply)
|
|
}
|
|
}
|
|
|
|
var maybeResultSize: Int?
|
|
|
|
compressedFrameData.withUnsafeMutableBytes { buffer -> Void in
|
|
guard let bytes = buffer.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
|
|
return
|
|
}
|
|
let length = compression_encode_buffer(bytes, compressedFrameDataLength, yuvaFrameData.assumingMemoryBound(to: UInt8.self), yuvaLength, scratchData, COMPRESSION_LZFSE)
|
|
maybeResultSize = length
|
|
}
|
|
|
|
guard let resultSize = maybeResultSize else {
|
|
return nil
|
|
}
|
|
compressedFrameData.count = resultSize
|
|
return compressedFrameData
|
|
}
|
|
|
|
func compressFrame(width: Int, height: Int, yuvaData: Data) -> Data? {
|
|
let yuvaLength = yuvaData.count
|
|
|
|
var compressedFrameData = Data(count: yuvaLength)
|
|
let compressedFrameDataLength = compressedFrameData.count
|
|
|
|
let scratchData = malloc(compression_encode_scratch_buffer_size(COMPRESSION_LZFSE))!
|
|
defer {
|
|
free(scratchData)
|
|
}
|
|
|
|
var maybeResultSize: Int?
|
|
|
|
yuvaData.withUnsafeBytes { yuvaBuffer -> Void in
|
|
if let yuvaFrameData = yuvaBuffer.baseAddress {
|
|
compressedFrameData.withUnsafeMutableBytes { buffer -> Void in
|
|
guard let bytes = buffer.baseAddress?.assumingMemoryBound(to: UInt8.self) else {
|
|
return
|
|
}
|
|
let length = compression_encode_buffer(bytes, compressedFrameDataLength, yuvaFrameData.assumingMemoryBound(to: UInt8.self), yuvaLength, scratchData, COMPRESSION_LZFSE)
|
|
maybeResultSize = length
|
|
}
|
|
}
|
|
}
|
|
|
|
guard let resultSize = maybeResultSize else {
|
|
return nil
|
|
}
|
|
compressedFrameData.count = resultSize
|
|
return compressedFrameData
|
|
}
|