Skip to content

Commit

Permalink
rename PNG.Data.Rectangular to just PNG.Image
Browse files Browse the repository at this point in the history
  • Loading branch information
tayloraswift committed Feb 20, 2024
1 parent e9b09e2 commit 60818f5
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 130 deletions.
48 changes: 19 additions & 29 deletions Sources/PNG/Decoding/PNG.Context.swift
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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``
Expand Down Expand Up @@ -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:
Expand All @@ -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
{
Expand All @@ -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
{
Expand Down
53 changes: 16 additions & 37 deletions Sources/PNG/Decoding/PNG.DecodingError.swift
Original file line number Diff line number Diff line change
@@ -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.
///
Expand All @@ -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
{
Expand All @@ -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?
{
Expand Down
2 changes: 1 addition & 1 deletion Sources/PNG/Decoding/PNG.Metadata.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down
10 changes: 3 additions & 7 deletions Sources/PNG/Decoding/PNG.Standard.swift
Original file line number Diff line number Diff line change
@@ -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
}
}
63 changes: 7 additions & 56 deletions Sources/PNG/Layout/PNG.Data.Rectangular.swift
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -322,9 +285,6 @@ extension PNG.Data.Rectangular
}
extension PNG.Data.Rectangular
{
/// static func PNG.Data.Rectangular.decompress<Source>(stream:)
/// throws
/// where Source:Bytestream.Source
/// Decompresses and decodes a PNG from the given bytestream.
///
/// On appropriate platforms, the ``decompress(path:)`` function provides
Expand All @@ -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<Source>(stream:inout Source) throws -> Self
where Source:PNG.Bytestream.Source
Expand Down Expand Up @@ -588,9 +545,6 @@ extension PNG.Data.Rectangular
// compression
extension PNG.Data.Rectangular
{
/// func PNG.Data.Rectangular.compress<Destination>(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
Expand Down Expand Up @@ -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<Destination>(stream:inout Destination, level:Int = 9, hint:Int = 1 << 15)
throws
Expand Down
28 changes: 28 additions & 0 deletions Sources/PNG/Layout/PNG.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 60818f5

Please sign in to comment.