From 60818f56002a3b614ae3f547415905d1f55d0fa9 Mon Sep 17 00:00:00 2001 From: taylorswift Date: Tue, 20 Feb 2024 22:58:12 +0000 Subject: [PATCH] rename PNG.Data.Rectangular to just PNG.Image --- Sources/PNG/Decoding/PNG.Context.swift | 48 ++++++-------- Sources/PNG/Decoding/PNG.DecodingError.swift | 53 +++++----------- Sources/PNG/Decoding/PNG.Metadata.swift | 2 +- Sources/PNG/Decoding/PNG.Standard.swift | 10 +-- Sources/PNG/Layout/PNG.Data.Rectangular.swift | 63 +++---------------- Sources/PNG/Layout/PNG.swift | 28 +++++++++ 6 files changed, 74 insertions(+), 130 deletions(-) diff --git a/Sources/PNG/Decoding/PNG.Context.swift b/Sources/PNG/Decoding/PNG.Context.swift index 75a7dc94..c06a98c6 100644 --- a/Sources/PNG/Decoding/PNG.Context.swift +++ b/Sources/PNG/Decoding/PNG.Context.swift @@ -1,17 +1,14 @@ extension PNG { - /// struct PNG.Context - /// A decoding context. + /// A decoding context. /// - /// This type provides support for custom decoding schemes. You can - /// work through an example of its usage in the - /// [online decoding tutorial](https://github.com/tayloraswift/swift-png/tree/master/examples#online-decoding). - /// ## (contextual-decoding) + /// This type provides support for custom decoding schemes. You can + /// work through an example of its usage in the + /// [online decoding tutorial](https://github.com/tayloraswift/swift-png/tree/master/examples#online-decoding). public struct Context { - /// var PNG.Context.image : Data.Rectangular { get } - /// The current image state. + /// The current image state. public private(set) var image:PNG.Data.Rectangular @@ -21,11 +18,10 @@ extension PNG } extension PNG.Context { - /// init PNG.Context.init?(standard:header:palette:background:transparency:metadata:uninitialized:) - /// Creates a fresh decoding 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. + /// It is expected that client applications will initialize a decoding + /// context upon encountering the first ``Chunk/IDAT`` chunk in the image. /// - Parameter 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`` @@ -78,10 +74,8 @@ extension PNG.Context self.image = image self.decoder = .init(standard: standard, interlaced: image.layout.interlaced) } - /// mutating func PNG.Context.push(data:overdraw:) - /// throws - /// Decompresses the contents of an ``Chunk/IDAT`` chunk, and updates - /// the image state with the newly-decompressed image data. + /// Decompresses the contents of an ``Chunk/IDAT`` chunk, and updates + /// the image state with the newly-decompressed image data. /// - Parameter data: /// The contents of the ``Chunk/IDAT`` chunk to process. /// - Parameter overdraw: @@ -90,7 +84,6 @@ extension PNG.Context /// effect for ``Layout/interlaced`` images. /// /// The default value is `false`. - /// ## () public mutating func push(data:[UInt8], overdraw:Bool = false) throws { @@ -107,26 +100,23 @@ extension PNG.Context self.image.assign(scanline: $0, at: $1, stride: $2.x) }) } - /// mutating func PNG.Context.push(ancillary:) - /// throws - /// Parses an ancillary chunk appearing after the last ``Chunk/IDAT`` - /// chunk, and adds it to the ``image`` ``Data.Rectangular/metadata``. + /// 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`` - /// chunks in the image being decoded. + /// 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`` + /// chunks in the image being decoded. /// - /// 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. + /// 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. /// - Parameter chunk: /// 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. - /// ## () public mutating func push(ancillary chunk:(type:PNG.Chunk, data:[UInt8])) throws { diff --git a/Sources/PNG/Decoding/PNG.DecodingError.swift b/Sources/PNG/Decoding/PNG.DecodingError.swift index 4214d8fa..2454f9ba 100644 --- a/Sources/PNG/Decoding/PNG.DecodingError.swift +++ b/Sources/PNG/Decoding/PNG.DecodingError.swift @@ -1,30 +1,21 @@ extension PNG { - /// enum PNG.DecodingError - /// : Error - /// A decoding error. - /// # [See also](error-handling) - /// ## (error-handling) + /// A decoding error. public enum DecodingError { - /// case PNG.DecodingError.required(chunk:before:) - /// The decoder encountered a chunk of a type that requires a - /// previously encountered chunk of a particular type. + /// The decoder encountered a chunk of a type that requires a + /// previously encountered chunk of a particular type. /// - Parameter chunk: /// The type of the preceeding chunk required by the encountered chunk. /// - Parameter before: /// The type of the encountered chunk. - /// ## () - /// case PNG.DecodingError.duplicate(chunk:) /// The decoder encountered multiple instances of a chunk type that /// can only appear once in a PNG file. /// - Parameter chunk: /// The type of the duplicated chunk. - /// ## () - /// case PNG.DecodingError.unexpected(chunk:after:) /// The decoder encountered a chunk of a type that is not allowed /// to appear after a previously encountered chunk of a particular type. /// @@ -34,43 +25,34 @@ extension PNG /// The type of the encountered chunk. /// - Parameter after: /// The type of the preceeding chunk that precludes the encountered chunk. - /// ## () case required(chunk:PNG.Chunk, before:PNG.Chunk) case duplicate(chunk:PNG.Chunk) case unexpected(chunk:PNG.Chunk, after:PNG.Chunk) - /// case PNG.DecodingError.incompleteImageDataCompressedDatastream - /// The decoder finished processing the last ``Chunk/IDAT`` chunk - /// before the compressed image data stream was properly terminated. + /// 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 - /// after the end of the compressed image data stream. + /// 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. + /// 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. case extraneousImageDataCompressedData - /// case PNG.DecodingError.extraneousImageData - /// The compressed image data stream produces more uncompressed image - /// data than expected. + /// The compressed image data stream produces more uncompressed image + /// data than expected. case extraneousImageData } } extension PNG.DecodingError:PNG.Error { - /// static var PNG.DecodingError.namespace : Swift.String { get } - /// ?: Error - /// The string `"decoding error"`. + /// The string `"decoding error"`. public static var namespace:String { "decoding error" } - /// var PNG.DecodingError.message : Swift.String { get } - /// ?: Error - /// A human-readable summary of this error. - /// ## () + /// A human-readable summary of this error. public var message:String { @@ -88,11 +70,8 @@ extension PNG.DecodingError:PNG.Error return "invalid chunk ordering" } } - /// var PNG.DecodingError.details : Swift.String? { get } - /// ?: Error - /// An optional human-readable string providing additional details - /// about this error. - /// ## () + /// An optional human-readable string providing additional details + /// about this error. public var details:String? { diff --git a/Sources/PNG/Decoding/PNG.Metadata.swift b/Sources/PNG/Decoding/PNG.Metadata.swift index 524420ff..298dd9d5 100644 --- a/Sources/PNG/Decoding/PNG.Metadata.swift +++ b/Sources/PNG/Decoding/PNG.Metadata.swift @@ -117,7 +117,7 @@ extension PNG.Metadata /// format and `palette`. It also validates its multiplicity, and its chunk ordering with /// respect to the ``Chunk/PLTE`` chunk. /// - /// - Parameters: + /// - Parameters: /// - chunk: /// The chunk to process. /// diff --git a/Sources/PNG/Decoding/PNG.Standard.swift b/Sources/PNG/Decoding/PNG.Standard.swift index 5219ec3b..27dfbe4f 100644 --- a/Sources/PNG/Decoding/PNG.Standard.swift +++ b/Sources/PNG/Decoding/PNG.Standard.swift @@ -1,16 +1,12 @@ extension PNG { - /// enum PNG.Standard - /// A PNG standard. - /// ## (contextual-decoding) + /// A PNG standard. public enum Standard { - /// case PNG.Standard.common - /// The core PNG color formats. + /// The core PNG color formats. case common - /// case PNG.Standard.ios - /// The iphone-optimized PNG color formats. + /// The iPhone-optimized PNG color formats. case ios } } diff --git a/Sources/PNG/Layout/PNG.Data.Rectangular.swift b/Sources/PNG/Layout/PNG.Data.Rectangular.swift index 7492d658..6cdaccc4 100644 --- a/Sources/PNG/Layout/PNG.Data.Rectangular.swift +++ b/Sources/PNG/Layout/PNG.Data.Rectangular.swift @@ -1,65 +1,29 @@ extension PNG { - /// enum PNG.Data - /// A namespace containing the ``Data.Rectangular`` type. - /// ## (0:images) + /// A namespace containing the ``Data.Rectangular`` type. + @available(*, deprecated) public enum Data { - } - - // Returns the value of the paeth filter function with the given parameters. - static - func paeth(_ a:UInt8, _ b:UInt8, _ c:UInt8) -> UInt8 - { - // abs here is poorly-predicted so it benefits from this - // branchless implementation - func abs(_ x:Int16) -> Int16 - { - let mask:Int16 = x >> 15 - return (x ^ mask) + (mask & 1) - } - - let v:(Int16, Int16, Int16) = (.init(a), .init(b), .init(c)) - let d:(Int16, Int16) = (v.1 - v.2, v.0 - v.2) - let f:(Int16, Int16, Int16) = (abs(d.0), abs(d.1), abs(d.0 + d.1)) - - let p:(UInt8, UInt8, UInt8) = - ( - .init(truncatingIfNeeded: (f.1 - f.0) >> 15), // 0x00 if f.0 <= f.1 else 0xff - .init(truncatingIfNeeded: (f.2 - f.0) >> 15), - .init(truncatingIfNeeded: (f.2 - f.1) >> 15) - ) - - return ~(p.0 | p.1) & a | - (p.0 | p.1) & (b & ~p.2 | c & p.2) + @available(*, deprecated, renamed: "PNG.Image") + typealias Rectangular = PNG.Image } } -extension PNG.Data +extension PNG { - /// struct PNG.Data.Rectangular - /// A rectangular image. - /// # [Decoding an image](decoding) - /// # [Encoding an image](encoding) - /// # [Unpacking pixels](unpacking-pixels) - /// # [Packing pixels](packing-pixels) - /// ## (0:images) + /// A rectangular image. public - struct Rectangular + struct Image { - /// let PNG.Data.Rectangular.size : (x:Swift.Int, y:Swift.Int) /// The size of this image, measured in pixels. public let size:(x:Int, y:Int) - /// let PNG.Data.Rectangular.layout : Layout /// The layout of this image. public let layout:PNG.Layout - /// var PNG.Data.Rectangular.metadata : Metadata /// The metadata in this image. public var metadata:PNG.Metadata - /// var PNG.Data.Rectangular.storage : [Swift.UInt8] { get } /// The raw backing storage of the image content. /// /// Depending on the bit depth of the image, it either stores a matrix @@ -120,7 +84,6 @@ extension PNG.Data.Rectangular } } - /// func PNG.Data.Rectangular.bindStorage(to:) /// Rebinds this image to a compatible layout. /// /// This interface can be used to switch image layouts without unpacking @@ -322,9 +285,6 @@ extension PNG.Data.Rectangular } extension PNG.Data.Rectangular { - /// static func PNG.Data.Rectangular.decompress(stream:) - /// throws - /// where Source:Bytestream.Source /// Decompresses and decodes a PNG from the given bytestream. /// /// On appropriate platforms, the ``decompress(path:)`` function provides @@ -333,9 +293,6 @@ extension PNG.Data.Rectangular /// A bytestream providing the contents of a PNG file. /// - Returns: /// The decoded image. - /// # [See also](encoding-and-decoding) - /// ## (0:encoding-and-decoding) - /// ## (0:decoding) public static func decompress(stream:inout Source) throws -> Self where Source:PNG.Bytestream.Source @@ -588,9 +545,6 @@ extension PNG.Data.Rectangular // compression extension PNG.Data.Rectangular { - /// func PNG.Data.Rectangular.compress(stream:level:hint:) - /// throws - /// where Destination:Bytestream.Destination /// Encodes and compresses a PNG to the given bytestream. /// /// Compression `level` `9` is roughly equivalent to *libpng*’s maximum @@ -621,9 +575,6 @@ extension PNG.Data.Rectangular /// Setting this parameter to a value less than `1` is the same as setting /// it to `1`. Likewise, setting it to a value greater than `2147483647` /// (2^31^\ –\ 1) is the same as setting it to `2147483647`. - /// # [See also](encoding-and-decoding) - /// ## (2:encoding-and-decoding) - /// ## (0:encoding) public func compress(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15) throws diff --git a/Sources/PNG/Layout/PNG.swift b/Sources/PNG/Layout/PNG.swift index 5fd94926..accd798d 100644 --- a/Sources/PNG/Layout/PNG.swift +++ b/Sources/PNG/Layout/PNG.swift @@ -42,7 +42,35 @@ enum PNG typealias Destination = _PNGBytestreamDestination } } +extension PNG +{ + /// Returns the value of the paeth filter function with the given parameters. + static + func paeth(_ a:UInt8, _ b:UInt8, _ c:UInt8) -> UInt8 + { + // abs here is poorly-predicted so it benefits from this + // branchless implementation + func abs(_ x:Int16) -> Int16 + { + let mask:Int16 = x >> 15 + return (x ^ mask) + (mask & 1) + } + + let v:(Int16, Int16, Int16) = (.init(a), .init(b), .init(c)) + let d:(Int16, Int16) = (v.1 - v.2, v.0 - v.2) + let f:(Int16, Int16, Int16) = (abs(d.0), abs(d.1), abs(d.0 + d.1)) + + let p:(UInt8, UInt8, UInt8) = + ( + .init(truncatingIfNeeded: (f.1 - f.0) >> 15), // 0x00 if f.0 <= f.1 else 0xff + .init(truncatingIfNeeded: (f.2 - f.0) >> 15), + .init(truncatingIfNeeded: (f.2 - f.1) >> 15) + ) + return ~(p.0 | p.1) & a | + (p.0 | p.1) & (b & ~p.2 | c & p.2) + } +} extension PNG { private static