Skip to content

Commit

Permalink
Merge pull request #75 from tayloraswift/validate-docs
Browse files Browse the repository at this point in the history
validate docs
  • Loading branch information
tayloraswift authored Aug 26, 2024
2 parents 99c1279 + 2e5b8fa commit 3433f53
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 135 deletions.
24 changes: 0 additions & 24 deletions .github/workflows/build-devices.yml

This file was deleted.

102 changes: 0 additions & 102 deletions .github/workflows/build.yml

This file was deleted.

59 changes: 59 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# This workflow validates the package’s documentation. Because documentation building involves
# compiling the package, this also checks that the package itself compiles successfully on each
# supported platform.
name: documentation

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
linux:
runs-on: ubuntu-24.04
name: Ubuntu 24.04

steps:
- name: Install Swift
uses: tayloraswift/swift-install-action@master
with:
swift-prefix: "swift-5.10.1-release/ubuntu2404/swift-5.10.1-RELEASE"
swift-id: "swift-5.10.1-RELEASE-ubuntu24.04"

- name: Install Unidoc
uses: tayloraswift/swift-unidoc-action@master
with:
unidoc-version: "master"

# This clobbers everything in the current directory!
- name: Checkout repository
uses: actions/checkout@v3

- name: Validate documentation
run: |
unidoc compile -I .. \
--swift-toolchain $SWIFT_INSTALLATION \
--ci fail-on-errors \
--package-name swift-png
macos:
runs-on: macos-14
name: macOS
env:
DEVELOPER_DIR: "/Applications/Xcode_15.3.app/Contents/Developer"

steps:
- name: Install Unidoc
uses: tayloraswift/swift-unidoc-action@master
with:
unidoc-version: "master"

- name: Checkout repository
uses: actions/checkout@v3

- name: Validate documentation
run: |
unidoc compile -I .. \
--ci fail-on-errors \
--package-name swift-png
89 changes: 89 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: test

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
linux:
runs-on: ubuntu-24.04
name: Ubuntu 24.04

steps:
- name: Install Swift
uses: tayloraswift/swift-install-action@master
with:
swift-prefix: "swift-5.10.1-release/ubuntu2404/swift-5.10.1-RELEASE"
swift-id: "swift-5.10.1-RELEASE-ubuntu24.04"

- name: Checkout repository
uses: actions/checkout@v3

- run: .github/pipeline

macos:
runs-on: macos-14
name: macOS
strategy:
matrix:
swift:
- toolchain: 5.10.1-RELEASE
branch: swift-5.10.1-release

env:
SWIFT_TOOLCHAIN_DIRECTORY: >-
/Library/Developer/Toolchains/swift-${{ matrix.swift.toolchain }}.xctoolchain
steps:
- name: Cache Swift toolchain
id: cache
uses: actions/cache@v2
with:
path: ~/swift-${{ matrix.swift.toolchain }}.pkg
key: macos:swift:${{ matrix.swift.toolchain }}

- name: Download toolchain
if: steps.cache.outputs.cache-hit != 'true'
run: "curl https://download.swift.org/\
${{ matrix.swift.branch }}/xcode/\
swift-${{ matrix.swift.toolchain }}/\
swift-${{ matrix.swift.toolchain }}-osx.pkg \
--output ~/swift-${{ matrix.swift.toolchain }}.pkg"

- name: Install toolchain
run: |
sudo installer -pkg ~/swift-${{ matrix.swift.toolchain }}.pkg -target /
- name: Select toolchain
run: |
echo "TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw \
$SWIFT_TOOLCHAIN_DIRECTORY/Info.plist)" >> $GITHUB_ENV
- name: Checkout repository
uses: actions/checkout@v3

- name: Run pipeline
run: .github/pipeline

devices:
runs-on: macos-14
name: macOS
strategy:
matrix:
device: [ios, tvos, watchos]
env:
DEVELOPER_DIR: "/Applications/Xcode_15.3.app/Contents/Developer"

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Build
run: |
swift --version
xcrun xcodebuild -list
xcrun xcodebuild build \
-scheme "PNG" \
-destination "generic/platform=${{ matrix.device }}"
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

***`png`***<br>`4.4`

[![ci status](https://github.com/tayloraswift/swift-png/actions/workflows/build.yml/badge.svg)](https://github.com/tayloraswift/swift-png/actions/workflows/build.yml)
[![ci status](https://github.com/tayloraswift/swift-png/actions/workflows/test.yml/badge.svg)](https://github.com/tayloraswift/swift-png/actions/workflows/test.yml)
[![ci status](https://github.com/tayloraswift/swift-png/actions/workflows/docs.yml/badge.svg)](https://github.com/tayloraswift/swift-png/actions/workflows/docs.yml)


[![swift package index versions](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Ftayloraswift%2Fswift-png%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/tayloraswift/swift-png)
Expand Down
2 changes: 1 addition & 1 deletion Sources/LZ77/Inflator/LZ77.StreamHeaderError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extension LZ77
///
/// The header check bits should not be confused with the modular redundancy checksum,
/// which corresponds to the
/// ``PNG.LexingError.invalidStreamChecksum(declared:computed:)`` error.
/// ``DecompressionError.invalidStreamChecksum(declared:computed:)`` error.
case invalidCheckBits

/// A compressed data stream contains a stream dictionary, which is not allowed in a
Expand Down
8 changes: 4 additions & 4 deletions Sources/PNG/docs.docc/BasicEncoding/BasicEncoding.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ This tutorial will assume you have the image you want to encode stored as an arr

@Snippet(id: "BasicEncoding", slice: "LOAD_RGBA")

The first step to encoding a PNG file is to define an [*image layout*](#st:image%20layout). Here, we have defined an 8-bit RGB layout, as well as an 8-bit grayscale layout which we will use later.
The first step to encoding a PNG file is to define an [*image layout*](#st:image-layout). Here, we have defined an 8-bit RGB layout, as well as an 8-bit grayscale layout which we will use later.

@Snippet(id: "BasicEncoding", slice: "LAYOUT")

Expand All @@ -42,7 +42,7 @@ The signature of the ``PNG.Layout`` initializer is given below:
init(format:PNG.Format, interlaced:Bool = false)
```

The `format` parameter specifies the [*color format*](#st:color%20format) of the layout.
The `format` parameter specifies the [*color format*](#st:color-format) of the layout.

We can enable [*interlacing*](#st:interlacing) by setting the `interlaced` parameter to `true`. This parameter is `false` by default. There is rarely a good reason to enable it, and it usually hurts the compression ratio, so we have omitted it in this example. We will explore a possible use case for it in the <doc:OnlineDecoding> tutorial.

Expand Down Expand Up @@ -72,7 +72,7 @@ The library supports all fifteen standard PNG color formats, plus two formats fr
| ``PNG.Format/rgba8(palette:fill:)`` | RGBA | 8 | 8 | core |
| ``PNG.Format/rgba16(palette:fill:)`` | RGBA | 16 | 16 | core |

The `fill` field specifies a solid background color which some PNG viewers use to display the image. Formats that lack a full alpha channel also have a `key` field, which specifies a [*chroma key*](#st:chroma%20key). The type of the `fill` and `key` fields varies depending on the color format. For example, they are `(r:UInt8, g:UInt8, b:UInt8)` tuples in the ``PNG/Format/rgb8(palette:fill:key:)`` format, and ``Int`` indices in the ``PNG/Format/indexed8(palette:fill:)`` format. Indexed images do not support chroma keys, because they contain a full alpha channel.
The `fill` field specifies a solid background color which some PNG viewers use to display the image. Formats that lack a full alpha channel also have a `key` field, which specifies a [*chroma key*](#st:chroma-key). The type of the `fill` and `key` fields varies depending on the color format. For example, they are `(r:UInt8, g:UInt8, b:UInt8)` tuples in the ``PNG/Format/rgb8(palette:fill:key:)`` format, and ``Int`` indices in the ``PNG/Format/indexed8(palette:fill:)`` format. Indexed images do not support chroma keys, because they contain a full alpha channel.

Most PNG viewers ignore the `fill` field, and a few ignore the `key` field as well. It is common to leave both fields as nil to disable this functionality.

Expand All @@ -84,7 +84,7 @@ To create a rectangular image data instance, use the ``PNG/Image/init(packing:si

On platforms with built-in file system support, we can compress it to a file using the ``PNG/Image/compress(path:level:hint:)`` method. The `hint` argument provides a size hint for the emitted image data chunks. Its default value is `32768`, which is fine for almost all use cases. We will explore the `hint` parameter in more detail in the <doc:OnlineDecoding> tutorial.

The `level` argument specifies the [*compression level*](#st:compression%20level). Its default value is `9`. Setting `level` to a value less than `0` is the same as setting it to `0`. Likewise, setting it to a value greater than `13` is the same as setting it to `13`.
The `level` argument specifies the [*compression level*](#st:compression-level). Its default value is `9`. Setting `level` to a value less than `0` is the same as setting it to `0`. Likewise, setting it to a value greater than `13` is the same as setting it to `13`.

Compression level `9` is roughly equivalent to *libpng*’s maximum compression setting in terms of compression ratio and encoding speed. The higher levels (`10` through `13`) are very computationally expensive, so you should only use them if you really need to optimize for file size.

Expand Down
4 changes: 2 additions & 2 deletions Sources/PNG/docs.docc/Indexing/Indexing.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ We can visualize the gradient using the same APIs we used in the <doc:BasicEncod
A visualization of the generated gradient.
}

We can create an indexed image by defining an indexed layout, and passing the grayscale samples we obtained earlier to one of the pixel-packing APIs. The ``PNG/Image/init(packing:size:layout:metadata:) [8AEMD]`` initializer will treat the grayscale samples as pixel colors, not indices, and will try to match the pixel colors to entries in the given palette. This is not what we want, so we need to use a variant of that function, ``PNG/Image/init(packing:size:layout:metadata:indexer:) [7UEEA]``, and pass it a custom [*indexing function*](#st:indexing%20function).
We can create an indexed image by defining an indexed layout, and passing the grayscale samples we obtained earlier to one of the pixel-packing APIs. The ``PNG/Image/init(packing:size:layout:metadata:) [8AEMD]`` initializer will treat the grayscale samples as pixel colors, not indices, and will try to match the pixel colors to entries in the given palette. This is not what we want, so we need to use a variant of that function, ``PNG/Image/init(packing:size:layout:metadata:indexer:) [7UEEA]``, and pass it a custom [*indexing function*](#st:indexing-function).

@Snippet(id: "Indexing", slice: "PACK_EXAMPLE")

Expand Down Expand Up @@ -77,7 +77,7 @@ The return value of the outer function is an *inner function* of type `(UInt8) -

Its default implementation [encloses](https://en.wikipedia.org/wiki/Closure_%28computer_programming%29) the dictionary variable, and uses it to look up the palette index of the function’s grayscale sample argument, expanded to RGBA form. If there is no matching palette entry, it returns index `0`. As you might expect, this can be inefficient for some use cases (though not terribly so), so the custom indexing APIs are useful if you want to manipulate indices without re-indexing the entire image.

Depending on the color target, the inner function may take a tuple argument instead of a scalar. For the [`PNG.VA<T>`](PNG/VA) color target, the inner function recieves `(UInt8, UInt8)` tuples. For the [`PNG.RGBA<T>`](PNG/RGBA) color target, it receives `(UInt8, UInt8, UInt8, UInt8)` tuples. (The return type is always ``Int``.) In this library, the inner function argument is called a [*palette aggregate*](#st:palette%20aggregate).
Depending on the color target, the inner function may take a tuple argument instead of a scalar. For the [`PNG.VA<T>`](PNG/VA) color target, the inner function recieves `(UInt8, UInt8)` tuples. For the [`PNG.RGBA<T>`](PNG/RGBA) color target, it receives `(UInt8, UInt8, UInt8, UInt8)` tuples. (The return type is always ``Int``.) In this library, the inner function argument is called a [*palette aggregate*](#st:palette-aggregate).

Let’s go back to the custom indexing function:

Expand Down
2 changes: 1 addition & 1 deletion Sources/PNG/docs.docc/iPhoneOptimized/iPhoneOptimized.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ bgra8(palette: [], fill: nil)

The ``PNG/Format/bgra8(palette:fill:)`` format is one of two iPhone-optimized color formats. It is analogous to the ``PNG/Format/rgba8(palette:fill:)`` format. Another possibility is ``PNG/Format/bgr8(palette:fill:key:)``, which lacks an alpha channel, and is analogous to ``PNG/Format/rgb8(palette:fill:key:)``.

We can unpack iPhone-optimized images to any color target. iPhone-optimized images use [*premultiplied alpha*](#st:premultiplied%20alpha). We can convert the pixels back to **straight alpha** using the ``PNG/RGBA.straightened`` or ``PNG/VA.straightened`` computed properties.
We can unpack iPhone-optimized images to any color target. iPhone-optimized images use [*premultiplied alpha*](#st:premultiplied-alpha). We can convert the pixels back to **straight alpha** using the ``PNG/RGBA.straightened`` or ``PNG/VA.straightened`` computed properties.

@Snippet(id: "iPhoneOptimized", slice: "STRAIGHTEN")

Expand Down

0 comments on commit 3433f53

Please sign in to comment.