我正在尝试使用Swift Compression包解压缩lz4压缩的png图像,但代码以零大小退出。 我的代码如下,解压缩文件预计为240Kb。
[更新2] 我在Apple的文档中偶然发现了这个:
此处记录框架,以便您可以轻松地包装另一个LZ4 编码器/解码器在必要时产生/消耗相同的数据流。 LZ4编码的缓冲区是块序列,每个块开始 带头。有三种可能的标题:
压缩块头包含八位字节0x62,0x76,0x34和 0x31,后跟解码(明文)数据的字节大小 由块和编码数据的大小(以字节为单位)表示 存储在块中。两个大小字段都存储为(可能 未对齐的)32位小端值。压缩块头是 紧接着是实际的LZ4编码数据流。
流标头的末尾由八位字节0x62,0x76,0x34和 0x24并标记LZ4帧的结束。没有进一步的数据 超出此标题的书面或阅读。
所以我相应地添加了页眉和页脚,它的工作原理。但是 - 在解压缩之前,我怎么知道“解码(明文)数据的字节大小”?
[更新1]
我给你一个LZ4文件进行测试,以及用于从主包中解压缩的代码用法。
LZ4文件使用sw“LZ4命令行界面64位v1.8.0,由Yann Collet”压缩,可在互联网上广泛使用
https://drive.google.com/file/d/1eQ204LJs_xsHRwJ_jUcl1Up9NFo8monO/view?usp=sharing
LZ4减压使用
if let url = Bundle.main.url(forResource: "TestImage300.png", withExtension: "lz4") {
if let compressed = try? Data(contentsOf: url) {
if let decompressed = compressed.lz4Decompress() {
if let image = UIImage(data: decompressed) {
self.sourceImages.append(image)
print("Unittest: Decompressed image as \(image)")
}
}
}
}
LZ4解压缩数据扩展代码:
import Foundation
import Compression
extension Data {
func lz4Decompress() -> Data? {
let destinationBufferSize: size_t = 480000
let destinationBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: destinationBufferSize)
let sourceBufferSize = count
let decompressed = withUnsafeBytes { (sourceBuffer: UnsafePointer<UInt8>) -> Data? in
let size = compression_decode_buffer(
destinationBuffer, destinationBufferSize,
sourceBuffer, sourceBufferSize,
nil, // scratch buffer automatically handled
COMPRESSION_LZ4
)
if size == 0 {
print("Error ")
return nil
}
print("Original compressed size: \(sourceBufferSize) | Decompressed size: \(size)")
return Data(bytesNoCopy: destinationBuffer, count: size, deallocator: .free)
}
return decompressed
}
}
答案 0 :(得分:1)
let intArray: [Int8] = [-16, 1, 1, 39, 0, 19, 11, -30, 7, 10, 29, 14, 0, 0, 0, 0, 96, 9, 6, 0, 1, 2, 0, 17, 14, 6, 0, 2, 2, 0, 18, 14, 7, 0, 65, 0, 0, 0, -51, 6, 0, 0, 2, 0, 0, 43, 0, 16, 2, 9, 0, -1, 13, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 10, 4, 0, 64, 33, -105, 58, 115, 0, 12, 2, 0, 80, 0, 0, 0, 0, 0]
let uintArray = intArray.map { UInt8(bitPattern: $0) }
//出于可见性,uintArray的无符号值为[240,1,1,39,0,19,11,226,7,10,29,14,14,0,0,0,0,96,9,6, 0、1、2、0、17、14、6、0、2、2、0、18、14、7、0、65、0、0、0、205、6、0、0、2、0, 0、43、0、16、2、9、0、255、13、0、0、0、1、0、0、0、3、0、0、0、5、0、0、0、6 0,0,0,7,0,0,0,8,0,0,0,10,4,4,0,64,33,151,58,115,0,12,2,0,80,0, 0,0,0,0]
var encodedData = Data.init(bytes:uintArray)
let decodedCapacity = 205
let decodedDestinationBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: decodedCapacity)
let decodedData = encodedData.withUnsafeBytes {
(encodedSourceBuffer: UnsafePointer<UInt8>) -> Data? in
let decodedCharCount = compression_decode_buffer(decodedDestinationBuffer,
decodedCapacity,
encodedSourceBuffer,
encodedData.count,
nil,
COMPRESSION_LZ4_RAW)
if decodedCharCount == 0 {
fatalError("Decoding failed.")
}
print("Before: \(encodedSourceBuffer) | After: \(decodedCharCount)")
return Data(bytesNoCopy: decodedDestinationBuffer, count: decodedCharCount, deallocator: .free)
}
在压缩中未定义标题的情况下,应使用COMPRESSION_LZ4_RAW