Skip to content

Commit

Permalink
Merge pull request #58 from tayloraswift/gzip
Browse files Browse the repository at this point in the history
Gzip
  • Loading branch information
tayloraswift authored Feb 1, 2024
2 parents 8dec7c9 + 93ad782 commit cac5248
Show file tree
Hide file tree
Showing 37 changed files with 1,245 additions and 628 deletions.
6 changes: 4 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ let package:Package = .init(name: "swift-png",
],
targets:
[
.target(name: "LZ77"),
.target(name: "LZ77", dependencies:
[
.product(name: "CRC", package: "swift-hash"),
]),

.target(name: "PNG",
dependencies:
[
.target(name: "LZ77"),
.product(name: "CRC", package: "swift-hash"),
]),

.target(name: "PNGInspection",
Expand Down
40 changes: 40 additions & 0 deletions Snippets/GzipCompression.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import LZ77
import PNG

let path:String = "Snippets/GzipCompression/example"

guard
let original:[UInt8] = (System.File.Source.open(path: "\(path).gz")
{
(source:inout System.File.Source) -> [UInt8]? in

guard let count:Int = source.count
else
{
return nil
}
return source.read(count: count)
} ?? nil)
else
{
fatalError("failed to open or read file '\(path).gz'")
}

var inflator:Gzip.Inflator = .init()
try inflator.push(original[...])

let utf8:[UInt8] = inflator.pull()
let text:String = .init(decoding: utf8, as: Unicode.UTF8.self)

print(text)

var deflator:Gzip.Deflator = .init(level: 13, exponent: 15, hint: 128 << 10)
deflator.push(utf8[...], last: true)

let _:Void? = System.File.Destination.open(path: "\(path).txt.gz")
{
while let part:[UInt8] = deflator.pull()
{
$0.write(part)
}
}
Binary file added Snippets/GzipCompression/example.gz
Binary file not shown.
Binary file added Snippets/GzipCompression/example.txt.gz
Binary file not shown.
53 changes: 10 additions & 43 deletions Sources/LZ77/Deflator/LZ77.Deflator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,21 @@ extension LZ77
struct Deflator
{
private
var stream:Stream
var buffers:DeflatorBuffers<LZ77.Format>

public
init(format:LZ77.Format = .zlib, level:Int, exponent:Int = 15, hint:Int = 1 << 12)
{
self.buffers = .init(format: format, level: level, exponent: exponent, hint: hint)
}
}
}
extension LZ77.Deflator
{
public
init(format:LZ77.DeflateFormat = .zlib, level:Int, exponent:Int = 15, hint:Int = 1 << 12)
{
let e:Int
switch format
{
case .zlib: e = exponent
case .ios : e = 15
}

self.stream = .init(format: format, level: level, exponent: e, hint: hint)
self.stream.start(exponent: e)
}

public mutating
func push(_ data:ArraySlice<UInt8>, last:Bool = false)
{
// rebase input buffer
if !data.isEmpty
{
self.stream.input.enqueue(contentsOf: data)
}
guard self.stream.input.count > 4096 || last
else
{
return
}

while let _:Void = self.stream.compress(all: last)
{
self.stream.block(final: false)
}
if last
{
self.stream.block(final: true)
self.stream.checksum()
}
self.buffers.push(data, last: last)
}

/// Returns a block of compressed data from this deflator, if available. If no compressed
Expand All @@ -58,20 +31,14 @@ extension LZ77.Deflator
public mutating
func pull() -> [UInt8]?
{
if let complete:[UInt8] = self.pop()
{
return complete
}

let flushed:[UInt8] = self.stream.output.pull()
return flushed.isEmpty ? nil : flushed
self.buffers.pull()
}

/// Removes and returns a complete block of compressed data from this deflator, if
/// available.
public mutating
func pop() -> [UInt8]?
{
self.stream.output.pop()
self.buffers.pop()
}
}
Loading

0 comments on commit cac5248

Please sign in to comment.