Skip to content

Commit

Permalink
Merge pull request #57 from tayloraswift/v5
Browse files Browse the repository at this point in the history
documentation + examples cleanup
  • Loading branch information
tayloraswift authored Jan 30, 2024
2 parents e774fa3 + ca3091b commit f7cd2c2
Show file tree
Hide file tree
Showing 52 changed files with 3,190 additions and 361 deletions.
Binary file removed Examples/encode-basic/example-color-rgb.png
Binary file not shown.
Binary file removed Examples/encode-basic/[email protected]
Binary file not shown.
Binary file removed Examples/encode-basic/[email protected]
Binary file not shown.
Binary file removed Examples/encode-basic/[email protected]
Binary file not shown.
Binary file removed Examples/encode-basic/[email protected]
Binary file not shown.
Binary file removed Examples/encode-basic/example-color-v.png
Binary file not shown.
Binary file removed Examples/encode-basic/example-luminance-rgb.png
Binary file not shown.
Binary file removed Examples/encode-basic/example-luminance-v.png
Binary file not shown.
1 change: 0 additions & 1 deletion Examples/encode-basic/example.rgba

This file was deleted.

44 changes: 6 additions & 38 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ let package:Package = .init(name: "swift-png",
.executable(name: "compression-benchmark", targets: ["PNGCompressionBenchmarks"]),
.executable(name: "decompression-benchmark", targets: ["PNGDecompressionBenchmarks"]),

.executable(name: "decode-basic", targets: ["PNGDecodeBasic"]),
.executable(name: "encode-basic", targets: ["PNGEncodeBasic"]),
.executable(name: "indexing", targets: ["PNGIndexing"]),
.executable(name: "iphone-optimized", targets: ["PNGiPhoneOptimized"]),
.executable(name: "metadata", targets: ["PNGMetadata"]),
Expand All @@ -39,11 +37,14 @@ let package:Package = .init(name: "swift-png",
dependencies:
[
.target(name: "LZ77"),
.target(name: "TerminalColors"),
.product(name: "CRC", package: "swift-hash"),
]),

.target(name: "TerminalColors"),
.target(name: "PNGInspection",
dependencies:
[
.target(name: "PNG"),
]),

.executableTarget(name: "LZ77Tests",
dependencies:
Expand Down Expand Up @@ -103,40 +104,7 @@ let package:Package = .init(name: "swift-png",
],
path: "Benchmarks/Decompression/Swift"),

.executableTarget(name: "PNGDecodeBasic",
dependencies:
[
.target(name: "PNG"),
],
path: "Examples/decode-basic",
exclude:
[
"example.png.rgba",
"example.png.v.png",
"example.png.rgba.png",
"example.png",
"example.png.v",
"example.png.va.png",
"example.png.va",
]),
.executableTarget(name: "PNGEncodeBasic",
dependencies:
[
.target(name: "PNG"),
],
path: "Examples/encode-basic",
exclude:
[
"[email protected]",
"[email protected]",
"example-color-v.png",
"[email protected]",
"example-color-rgb.png",
"example-luminance-rgb.png",
"example.rgba",
"[email protected]",
"example-luminance-v.png",
]),

.executableTarget(name: "PNGIndexing",
dependencies:
[
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ Swift *PNG* is [available](LICENSE) under the [Mozilla Public License 2.0](https

## [tutorials and example programs](examples/)

1. [basic decoding](examples/#basic-decoding) ([sources](examples/decode-basic/))
2. [basic encoding](examples/#basic-encoding) ([sources](examples/encode-basic/))
1. [basic decoding](Snippets/BasicDecoding.swift) ([sources](Snippets/BasicDecoding.swift/))
2. [basic encoding](Snippets/BasicEncoding.swift) ([sources](Snippets/BasicEncoding.swift/))
3. [using indexed images](examples/#using-indexed-images) ([sources](examples/indexed/))
4. [using iphone-optimized images](examples/#using-iphone-optimized-images) ([sources](examples/iphone-optimized/))
5. [working with metadata](examples/#working-with-metadata) ([sources](examples/metadata/))
Expand Down Expand Up @@ -48,7 +48,8 @@ Decode an image:
import PNG
func decode(png path:String) throws
{
guard let image:PNG.Data.Rectangular = try .decompress(path: path)
guard
let image:PNG.Data.Rectangular = try .decompress(path: path)
else
{
// failed to access file from file system
Expand Down
39 changes: 23 additions & 16 deletions Examples/decode-basic/main.swift → Snippets/BasicDecoding.swift
Original file line number Diff line number Diff line change
@@ -1,50 +1,57 @@
import PNG
import PNG

let path:String = "examples/decode-basic/example"
let path:String = "Snippets/BasicDecoding/example"

guard let image:PNG.Data.Rectangular = try .decompress(path: "\(path).png")
else
guard
let image:PNG.Data.Rectangular = try .decompress(path: "\(path).png")
else
{
fatalError("failed to open file '\(path).png'")
}

let rgba:[PNG.RGBA<UInt8>] = image.unpack(as: PNG.RGBA<UInt8>.self)
guard let _:Void = (System.File.Destination.open(path: "\(path).png.rgba")
guard
let _:Void = (System.File.Destination.open(path: "\(path).png.rgba")
{
guard let _:Void = $0.write(rgba.flatMap{ [$0.r, $0.g, $0.b, $0.a] })
else
guard
let _:Void = $0.write(rgba.flatMap{ [$0.r, $0.g, $0.b, $0.a] })
else
{
fatalError("failed to write to file '\(path).png.rgba'")
}
})
})
else
{
fatalError("failed to open file '\(path).png.rgba'")
}

let va:[PNG.VA<UInt8>] = image.unpack(as: PNG.VA<UInt8>.self)
guard let _:Void = (System.File.Destination.open(path: "\(path).png.va")
guard
let _:Void = (System.File.Destination.open(path: "\(path).png.va")
{
guard let _:Void = $0.write(va.flatMap{ [$0.v, $0.a] })
else
guard
let _:Void = $0.write(va.flatMap{ [$0.v, $0.a] })
else
{
fatalError("failed to write to file '\(path).png.va'")
}
})
})
else
{
fatalError("failed to open file '\(path).png.va'")
}

let v:[UInt8] = image.unpack(as: UInt8.self)
guard let _:Void = (System.File.Destination.open(path: "\(path).png.v")
guard
let _:Void = (System.File.Destination.open(path: "\(path).png.v")
{
guard let _:Void = $0.write(v)
else
guard
let _:Void = $0.write(v)
else
{
fatalError("failed to write to file '\(path).png.v'")
}
})
})
else
{
fatalError("failed to open file '\(path).png.v'")
Expand Down
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes
34 changes: 19 additions & 15 deletions Examples/encode-basic/main.swift → Snippets/BasicEncoding.swift
Original file line number Diff line number Diff line change
@@ -1,62 +1,66 @@
import PNG

let path:String = "examples/encode-basic/example",
size:(x:Int, y:Int) = (800, 1228)
guard let rgba:[PNG.RGBA<UInt8>] = (System.File.Source.open(path: "\(path).rgba")
/// https://commons.wikimedia.org/wiki/File:Photo_of_a_venetian_mask_in_a_studio_photo_session.jpg
let path:String = "Snippets/BasicEncoding/example"
let size:(x:Int, y:Int) = (638, 425)

guard
let rgba:[PNG.RGBA<UInt8>] = (System.File.Source.open(path: "\(path).rgba")
{
guard let data:[UInt8] = $0.read(count: 4 * size.x * size.y)
else
guard
let data:[UInt8] = $0.read(count: 4 * size.x * size.y)
else
{
fatalError("failed to read from file '\(path).rgba'")
}

return (0 ..< size.x * size.y).map
return (0 ..< size.x * size.y).map
{
(i:Int) -> PNG.RGBA<UInt8> in
.init(data[4 * i], data[4 * i + 1], data[4 * i + 2], data[4 * i + 3])
}
})
})
else
{
fatalError("failed to open file '\(path).rgba'")
}

let layout:(rgb:PNG.Layout, v:PNG.Layout) =
let layout:(rgb:PNG.Layout, v:PNG.Layout) =
(
rgb: .init(format: .rgb8(palette: [], fill: nil, key: nil)),
v: .init(format: .v8( fill: nil, key: nil))
)

do
do
{
let image:PNG.Data.Rectangular = .init(packing: rgba, size: size, layout: layout.rgb)
try image.compress(path: "\(path)-color-rgb.png", level: 9)

for level:Int in [0, 4, 8, 13]
{
try image.compress(path: "\(path)-color-rgb@\(level).png", level: level)
}
}
do
do
{
let image:PNG.Data.Rectangular = .init(packing: rgba, size: size, layout: layout.v)
try image.compress(path: "\(path)-color-v.png", level: 9)
}

let luminance:[UInt8] = rgba.map
let luminance:[UInt8] = rgba.map
{
let r:Double = .init($0.r),
let r:Double = .init($0.r),
g:Double = .init($0.g),
b:Double = .init($0.b)
let l:Double = (0.299 * r * r + 0.587 * g * g + 0.114 * b * b).squareRoot()
return .init(max(0, min(l.rounded(), 255)))
}
do
do
{
let image:PNG.Data.Rectangular = .init(packing: luminance, size: size, layout: layout.v)
try image.compress(path: "\(path)-luminance-v.png", level: 9)
}
do
do
{
let image:PNG.Data.Rectangular = .init(packing: luminance, size: size, layout: layout.rgb)
try image.compress(path: "\(path)-luminance-rgb.png", level: 9)
Expand Down
Binary file added Snippets/BasicEncoding/example-color-rgb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Snippets/BasicEncoding/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Snippets/BasicEncoding/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Snippets/BasicEncoding/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Snippets/BasicEncoding/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Snippets/BasicEncoding/example-color-v.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Snippets/BasicEncoding/example-luminance-rgb.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Snippets/BasicEncoding/example-luminance-v.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2,849 changes: 2,849 additions & 0 deletions Snippets/BasicEncoding/example.rgba

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions Sources/PNG/Decoding/PNG.Context.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,30 @@ extension PNG.Context
/// Creates a fresh decoding context.
///
/// It is expected that client applications will initialize a decoding
/// context upon encountering the first [`(Chunk).IDAT`] chunk in the image.
/// context upon encountering the first ``Chunk/IDAT`` chunk in the image.
/// - standard : Standard
/// The PNG standard of the image being decoded. This should be [`(Standard).ios`]
/// if the image began with a [`(Chunk).CgBI`] chunk, and [`(Standard).common`]
/// if the image began with a ``Chunk/CgBI`` chunk, and [`(Standard).common`]
/// otherwise.
/// - header : Header
/// The header of the image being decoded. This is expected to have been
/// parsed from a previously-encountered [`(Chunk).IHDR`] chunk.
/// parsed from a previously-encountered ``Chunk/IHDR`` chunk.
/// - palette : Palette?
/// The palette of the image being decoded, if present. If not `nil`,
/// this is expected to have been parsed from a previously-encountered
/// [`(Chunk).PLTE`] chunk.
/// ``Chunk/PLTE`` chunk.
/// - background : Background?
/// The background descriptor of the image being decoded, if present.
/// If not `nil`, this is expected to have been parsed from a
/// previously-encountered [`(Chunk).bKGD`] chunk.
/// previously-encountered ``Chunk/bKGD`` chunk.
/// - transparency : Transparency?
/// The transparency descriptor of the image being decoded, if present.
/// If not `nil`, this is expected to have been parsed from a
/// previously-encountered [`(Chunk).tRNS`] chunk.
/// previously-encountered ``Chunk/tRNS`` chunk.
/// - metadata : Metadata
/// A metadata instance. It is expected to contain metadata from all
/// previously-encountered ancillary chunks, with the exception of
/// [`(Chunk).bKGD`] and [`(Chunk).tRNS`].
/// ``Chunk/bKGD`` and ``Chunk/tRNS``.
/// - uninitialized : Swift.Bool
/// Specifies if the [`image`] [`(Data.Rectangular).storage`] should
/// be initialized. If `false`, the storage buffer will be initialized
Expand Down Expand Up @@ -80,10 +80,10 @@ extension PNG.Context
}
/// mutating func PNG.Context.push(data:overdraw:)
/// throws
/// Decompresses the contents of an [`(Chunk).IDAT`] chunk, and updates
/// Decompresses the contents of an ``Chunk/IDAT`` chunk, and updates
/// the image state with the newly-decompressed image data.
/// - data : [Swift.UInt8]
/// The contents of the [`(Chunk).IDAT`] chunk to process.
/// The contents of the ``Chunk/IDAT`` chunk to process.
/// - overdraw : Swift.Bool
/// If `true`, pixels that are not yet available will be filled-in
/// with values from nearby available pixels. This option only has an
Expand All @@ -109,20 +109,20 @@ extension PNG.Context
}
/// mutating func PNG.Context.push(ancillary:)
/// throws
/// Parses an ancillary chunk appearing after the last [`(Chunk).IDAT`]
/// Parses an ancillary chunk appearing after the last ``Chunk/IDAT``
/// chunk, and adds it to the [`image`] [`(Data.Rectangular).metadata`].
///
/// This function validates the multiplicity of the given `chunk`, and
/// its chunk ordering with respect to the [`(Chunk).IDAT`] chunks. The
/// caller is expected to have consumed all preceeding [`(Chunk).IDAT`]
/// its chunk ordering with respect to the ``Chunk/IDAT`` chunks. The
/// caller is expected to have consumed all preceeding ``Chunk/IDAT``
/// chunks in the image being decoded.
///
/// Despite its name, this function can also accept an [`(Chunk).IEND`]
/// Despite its name, this function can also accept an ``Chunk/IEND``
/// critical chunk, in which case this function will verify that the
/// compressed image data stream has been properly-terminated.
/// - chunk : (type:Chunk, data:[Swift.UInt8])
/// The chunk to process. Its `type` must be one of [`(Chunk).tIME`],
/// [`(Chunk).iTXt`], [`(Chunk).tEXt`], [`(Chunk).zTXt`], or [`(Chunk).IEND`],
/// The chunk to process. Its `type` must be one of ``Chunk/tIME``,
/// ``Chunk/iTXt``, ``Chunk/tEXt``, ``Chunk/zTXt``, or ``Chunk/IEND``,
/// or a private application data chunk type.
///
/// All other chunk types will `throw` appropriate errors.
Expand Down
12 changes: 6 additions & 6 deletions Sources/PNG/Decoding/PNG.DecodingError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ extension PNG
/// The decoder encountered a chunk of a type that is not allowed
/// to appear after a previously encountered chunk of a particular type.
///
/// If both fields are set to [`(Chunk).IDAT`], this indicates
/// a non-contiguous [`(Chunk).IDAT`] sequence.
/// If both fields are set to ``Chunk/IDAT``, this indicates
/// a non-contiguous ``Chunk/IDAT`` sequence.
/// - chunk : Chunk
/// The type of the encountered chunk.
/// - after : Chunk
Expand All @@ -40,16 +40,16 @@ extension PNG
case unexpected(chunk:PNG.Chunk, after:PNG.Chunk)

/// case PNG.DecodingError.incompleteImageDataCompressedDatastream
/// The decoder finished processing the last [`(Chunk).IDAT`] chunk
/// The decoder finished processing the last ``Chunk/IDAT`` chunk
/// before the compressed image data stream was properly terminated.
case incompleteImageDataCompressedDatastream
/// case PNG.DecodingError.extraneousImageDataCompressedData
/// The decoder encountered additional [`(Chunk).IDAT`] chunks
/// The decoder encountered additional ``Chunk/IDAT`` chunks
/// after the end of the compressed image data stream.
///
/// This error should not be confused with an [`unexpected(chunk:after:)`]
/// error with both fields set to [`(Chunk).IDAT`], which indicates a
/// non-contiguous [`(Chunk).IDAT`] sequence.
/// error with both fields set to ``Chunk/IDAT``, which indicates a
/// non-contiguous ``Chunk/IDAT`` sequence.
case extraneousImageDataCompressedData
/// case PNG.DecodingError.extraneousImageData
/// The compressed image data stream produces more uncompressed image
Expand Down
Loading

0 comments on commit f7cd2c2

Please sign in to comment.