diff --git a/Benchmarks/Compression/Swift/Main.swift b/Benchmarks/Compression/Swift/Main.swift index 171e68be..ee4303d6 100644 --- a/Benchmarks/Compression/Swift/Main.swift +++ b/Benchmarks/Compression/Swift/Main.swift @@ -41,7 +41,7 @@ enum Benchmark } } } -extension Benchmark.Encode.Blob:PNG.Bytestream.Destination +extension Benchmark.Encode.Blob:PNG.BytestreamDestination { mutating func write(_ data:[UInt8]) -> Void? diff --git a/Benchmarks/Decompression/Swift/Main.swift b/Benchmarks/Decompression/Swift/Main.swift index ab1a8ff2..acefd043 100644 --- a/Benchmarks/Decompression/Swift/Main.swift +++ b/Benchmarks/Decompression/Swift/Main.swift @@ -43,7 +43,7 @@ enum Benchmark } } } -extension Benchmark.Decode.Blob:PNG.Bytestream.Source +extension Benchmark.Decode.Blob:PNG.BytestreamSource { static func load(path:String) -> Self? diff --git a/Notes/improving-deflate-compression-speed.md b/Notes/improving-deflate-compression-speed.md index 07f5f70d..a95170a4 100644 --- a/Notes/improving-deflate-compression-speed.md +++ b/Notes/improving-deflate-compression-speed.md @@ -22,7 +22,7 @@ clang -lpng ${prefix}/main.c -o ${binary} The same script also builds an equivalent Swift program in [`Benchmarks/compression/swift/`](../Benchmarks/compression/swift) using the Swift Package Manager. The Swift program, of course, invokes Swift *PNG* instead of *libpng*. -Disk latency contributes a noticeable (but not overwhelming) proportion of the time needed to encode a PNG file, especially at low compression levels. To avoid this problem, the C and Swift benchmarks both have their respective backends configured to write output images to memory instead of the file system. For *libpng*, you can do this by creating a custom buffer context and passing a callback function to `png_set_write_fn(_:_:_:_:)`. For Swift *PNG*, you can do this statically by conforming a buffer type of your choice to the `PNG.Bytestream.Destination` protocol. +Disk latency contributes a noticeable (but not overwhelming) proportion of the time needed to encode a PNG file, especially at low compression levels. To avoid this problem, the C and Swift benchmarks both have their respective backends configured to write output images to memory instead of the file system. For *libpng*, you can do this by creating a custom buffer context and passing a callback function to `png_set_write_fn(_:_:_:_:)`. For Swift *PNG*, you can do this statically by conforming a buffer type of your choice to the `PNG.BytestreamDestination` protocol. The memory target for the baseline C program is a `malloc`-based vector which uses the following reallocation rule: diff --git a/Snippets/PNG/ImagesInMemory.swift b/Snippets/PNG/ImagesInMemory.swift index c292b755..2b0ebdd4 100644 --- a/Snippets/PNG/ImagesInMemory.swift +++ b/Snippets/PNG/ImagesInMemory.swift @@ -12,7 +12,7 @@ extension System } } -extension System.Blob:PNG.Bytestream.Source, PNG.Bytestream.Destination +extension System.Blob:PNG.BytestreamSource, PNG.BytestreamDestination { init(_ data:[UInt8]) { diff --git a/Snippets/PNG/OnlineDecoding.swift b/Snippets/PNG/OnlineDecoding.swift index 406040d5..cb9b7e8d 100644 --- a/Snippets/PNG/OnlineDecoding.swift +++ b/Snippets/PNG/OnlineDecoding.swift @@ -10,7 +10,7 @@ struct Stream available:Int } -extension Stream:PNG.Bytestream.Source +extension Stream:PNG.BytestreamSource { init(_ data:[UInt8]) { diff --git a/Snippets/README.md b/Snippets/README.md index 6e204ef6..fc53bde9 100644 --- a/Snippets/README.md +++ b/Snippets/README.md @@ -957,10 +957,10 @@ extension System } ``` -There are two **bytestream protocols** a custom data stream type can support: [`PNG.Bytestream.Source`](https://tayloraswift.github.io/swift-png/PNG/Bytestream/Source), and [`PNG.Bytestream.Destination`](https://tayloraswift.github.io/swift-png/PNG/Bytestream/Destination). The first one enables image decoding, while the second one enables image encoding. We can conform to both with the following implementations: +There are two **bytestream protocols** a custom data stream type can support: [`PNG.BytestreamSource`](https://tayloraswift.github.io/swift-png/PNG/Bytestream/Source), and [`PNG.BytestreamDestination`](https://tayloraswift.github.io/swift-png/PNG/Bytestream/Destination). The first one enables image decoding, while the second one enables image encoding. We can conform to both with the following implementations: ```swift -extension System.Blob:PNG.Bytestream.Source, PNG.Bytestream.Destination +extension System.Blob:PNG.BytestreamSource, PNG.BytestreamDestination { init(_ data:[UInt8]) { @@ -1103,7 +1103,7 @@ struct Stream Each time we try to [`read`](https://tayloraswift.github.io/swift-png/PNG/Bytestream/Source/read(count:)/) from this stream, it will either return data from the available portion of the buffer, or it will return `nil` and “download” an additional 4 KB of the file. We also allow for rewinding the current file position to an earlier state. ```swift -extension Stream:PNG.Bytestream.Source +extension Stream:PNG.BytestreamSource { init(_ data:[UInt8]) { @@ -1196,7 +1196,7 @@ func chunk() throws -> (type:PNG.Chunk, data:[UInt8]) A valid PNG file consists of a signature, followed by a sequence of chunks. -The lexer functions are provided as extensions on the [`PNG.Bytestream.Source`](https://tayloraswift.github.io/swift-png/PNG/Bytestream/Source/) protocol, so they are available on any conforming data stream type, including our custom `Stream` type. +The lexer functions are provided as extensions on the [`PNG.BytestreamSource`](https://tayloraswift.github.io/swift-png/PNG/Bytestream/Source/) protocol, so they are available on any conforming data stream type, including our custom `Stream` type. Normally, the three aforementioned errors would indicate an unexpected end-of-stream. In this case, they just mean that there is not enough data available yet, so the client needs to wait for more of the file to arrive before decoding can proceed. To allow the lexing functions to recover on end-of-stream instead of crashing the application, we wrap them in the following `waitSignature(stream:)` and `waitChunk(stream:)` functions, making sure to reset the file position if end-of-stream is encountered. diff --git a/Sources/PNG/PNG.Image.swift b/Sources/PNG/PNG.Image.swift index c73dde7e..f6ee7791 100644 --- a/Sources/PNG/PNG.Image.swift +++ b/Sources/PNG/PNG.Image.swift @@ -295,7 +295,7 @@ extension PNG.Image /// The decoded image. public static func decompress(stream:inout Source) throws -> Self - where Source:PNG.Bytestream.Source + where Source:PNG.BytestreamSource { try stream.signature() let (standard, header):(PNG.Standard, PNG.Header) = try @@ -574,7 +574,7 @@ extension PNG.Image public func compress(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15) throws - where Destination:PNG.Bytestream.Destination + where Destination:PNG.BytestreamDestination { try stream.signature() diff --git a/Sources/PNG/System.swift b/Sources/PNG/System.swift index 18b16f59..d931e69f 100644 --- a/Sources/PNG/System.swift +++ b/Sources/PNG/System.swift @@ -226,10 +226,10 @@ extension System.File.Destination } // declare conformance (as a formality) -extension System.File.Source:PNG.Bytestream.Source +extension System.File.Source:PNG.BytestreamSource { } -extension System.File.Destination:PNG.Bytestream.Destination +extension System.File.Destination:PNG.BytestreamDestination { } diff --git a/Sources/PNG/__Entrypoint.swift b/Sources/PNG/__Entrypoint.swift index e9ef277c..b27a765b 100644 --- a/Sources/PNG/__Entrypoint.swift +++ b/Sources/PNG/__Entrypoint.swift @@ -66,7 +66,7 @@ extension __Entrypoint } } } -extension __Entrypoint.Benchmark.Decode.Blob:PNG.Bytestream.Source +extension __Entrypoint.Benchmark.Decode.Blob:PNG.BytestreamSource { static func load(path:String) -> Self? @@ -103,7 +103,7 @@ extension __Entrypoint.Benchmark.Decode.Blob:PNG.Bytestream.Source self.count = self.buffer.count } } -extension __Entrypoint.Benchmark.Encode.Blob:PNG.Bytestream.Destination +extension __Entrypoint.Benchmark.Encode.Blob:PNG.BytestreamDestination { mutating func write(_ data:[UInt8]) -> Void?