Skip to content

Commit

Permalink
Enough scaffolding to run the libavif decode file example.
Browse files Browse the repository at this point in the history
  • Loading branch information
Julian committed Jan 10, 2021
1 parent 71151e3 commit 0e06b44
Show file tree
Hide file tree
Showing 20 changed files with 466 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# vim: filetype=dosini:
[run]
branch = True
source = avif
dynamic_context = test_function
4 changes: 4 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# These are supported funding model platforms

github: "Julian"
patreon: "JulianWasTaken"
20 changes: 20 additions & 0 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Security Policy

## Supported Versions

In general, only the latest released `avif` version is supported
and will receive updates.

## Reporting a Vulnerability

To report a security vulnerability, please send an email to
`Julian+Security` at `GrayVines.com` with subject line `SECURITY (avif)`.

I will do my best to respond within 48 hours to acknowledge the message
and discuss further steps.

If the vulnerability is accepted, an advisory will be sent out via
GitHub's security advisory functionality.

For non-sensitive discussion related to this policy itself, feel free to
open an issue on the issue tracker.
76 changes: 76 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: CI

on:
push:
pull_request:
release:
types: [published]
schedule:
# Daily at 9:21
- cron: '21 9 * * *'

jobs:
ci:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest]
python-version:
- name: pypy3
toxenv: pypy3-build
- name: pypy3
toxenv: pypy3-safety
- name: pypy3
toxenv: pypy3-tests
- name: 3.7
toxenv: py37-build
- name: 3.7
toxenv: py37-safety
- name: 3.7
toxenv: py37-tests
- name: 3.8
toxenv: py38-build
- name: 3.8
toxenv: py38-safety
- name: 3.8
toxenv: py38-tests
- name: 3.9
toxenv: py39-build
- name: 3.9
toxenv: py39-safety
- name: 3.9
toxenv: py39-tests
- name: 3.9
toxenv: readme
- name: 3.9
toxenv: secrets
- name: 3.9
toxenv: style

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version.name }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version.name }}
- name: Ensure we have new enough versions to respect python_version
run: python -m pip install -U pip setuptools
- name: Install docs dependencies
run: sudo apt-get install -y libenchant-dev
if: runner.os == 'Linux' && startsWith(matrix.python-version.toxenv, 'docs-')
- name: Install docs dependencies
run: brew install enchant
if: runner.os == 'macOS' && startsWith(matrix.python-version.toxenv, 'docs-')
- name: Install tox
run: python -m pip install tox
- name: Install dependencies
run: >
curl -L 'https://github.com/AOMediaCodec/libavif/archive/v0.8.4.tar.gz' | tar xzf - &&
cd libavif* &&
mkdir build && cd build &&
cmake .. -DBUILD_SHARED_LIBS=OFF &&
make -j $(($(nproc) + 1)) &&
sudo make install
- name: Run tox
run: python -m tox -e "${{ matrix.python-version.toxenv }}"
25 changes: 25 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Coverage

on:
push:
pull_request:
release:
types: [published]

jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Ensure we have new enough versions to respect python_version
run: python -m pip install -U pip setuptools
- name: Install tox
run: python -m pip install tox
- name: Collect & Upload Coverage
run: python -m tox -e py38-codecov
env:
CODECOV_TOKEN: ${{ secrets.codecov_token }}
70 changes: 70 additions & 0 deletions .github/workflows/packaging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Packaging

on:
push:
release:
types: [published]

jobs:
wheels:
name: Build ${{ matrix.os }} wheels
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-latest, ubuntu-latest]

env:
CIBW_BEFORE_BUILD: >
curl -L 'https://github.com/AOMediaCodec/libavif/archive/v0.8.4.tar.gz' | tar xzf - &&
cd libavif* &&
mkdir build && cd build &&
cmake .. -DBUILD_SHARED_LIBS=OFF &&
make -j $(($(nproc) + 1)) &&
make install
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install cibuildwheel
run: python -m pip install cibuildwheel
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
- uses: actions/upload-artifact@master
with:
name: wheelhouse-${{ matrix.os }}
path: wheelhouse
- name: Publish package
run: python -m pip install twine && python -m twine upload wheelhouse/*
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.pypi_password }}

sdist:
name: Build source distribution
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install python-build
run: python -m pip install build
- name: Create packages
run: python -m build .
- uses: actions/upload-artifact@master
with:
name: dist
path: dist
- name: Publish package
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@master
with:
user: __token__
password: ${{ secrets.pypi_password }}
13 changes: 13 additions & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: pre-commit

on:
pull_request:
push:

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: pre-commit/[email protected]
19 changes: 19 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
exclude: json/

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0
hooks:
- id: check-ast
- id: check-docstring-first
- id: check-json
- id: check-toml
- id: check-vcs-permalinks
- id: check-yaml
- id: debug-statements
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/timothycrosley/isort
rev: 5.7.0
hooks:
- id: isort
5 changes: 5 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
include *.rst
include .coveragerc
include COPYING
include pyproject.toml
include tox.ini
21 changes: 21 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
========
``avif``
========

|PyPI| |Pythons| |CI|

.. |PyPI| image:: https://img.shields.io/pypi/v/avif.svg
:alt: PyPI version
:target: https://pypi.org/project/avif/

.. |Pythons| image:: https://img.shields.io/pypi/pyversions/avif.svg
:alt: Supported Python versions
:target: https://pypi.org/project/avif/

.. |CI| image:: https://github.com/Julian/avif/workflows/CI/badge.svg
:alt: Build status
:target: https://github.com/Julian/avif/actions?query=workflow%3ACI


Python bindings for `libavif <https://github.com/AOMediaCodec/libavif>`_ (via
`CFFI <https://cffi.readthedocs.io/en/latest/>`_)
Empty file added avif/__init__.py
Empty file.
57 changes: 57 additions & 0 deletions avif/_build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from cffi import FFI

ffi = FFI()


ffi.set_source(
"_avif",
"""
#include "avif/avif.h"
""",
libraries=["avif"],
)

ffi.cdef(
"""
typedef struct {
// Image information
uint32_t width;
uint32_t height;
uint32_t depth; // all planes must share this depth; if depth>8, all planes are uint16_t internally
...;
} avifImage;
typedef struct {
avifImage * image;
...;
} avifDecoder;
typedef enum {
AVIF_RESULT_OK = ...,
} avifResult;
typedef struct {
uint32_t width; // must match associated avifImage
uint32_t height; // must match associated avifImage
uint32_t depth; // legal depths [8, 10, 12, 16]. if depth>8, pixels must be uint16_t internally
uint8_t * pixels;
...;
} avifRGBImage;
void avifRGBImageSetDefaults(avifRGBImage * rgb, const avifImage * image);
void avifRGBImageAllocatePixels(avifRGBImage * rgb);
void avifRGBImageFreePixels(avifRGBImage * rgb);
avifResult avifImageRGBToYUV(avifImage * image, const avifRGBImage * rgb);
avifResult avifImageYUVToRGB(const avifImage * image, avifRGBImage * rgb);
avifDecoder * avifDecoderCreate(void);
avifResult avifDecoderSetIOMemory(avifDecoder * decoder, const uint8_t * data, size_t size);
avifResult avifDecoderSetIOFile(avifDecoder * decoder, const char * filename);
avifResult avifDecoderParse(avifDecoder * decoder);
avifResult avifDecoderNextImage(avifDecoder * decoder);
""",
)


if __name__ == "__main__":
ffi.compile()
Empty file added avif/tests/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions avif/tests/test_avif.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def test_it_imports():
import _avif
_avif
5 changes: 5 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
coverage:
status:
patch:
default:
target: 100%
33 changes: 33 additions & 0 deletions examples/avif_example_decode_file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""
Python-equivalent of ``avif_example_decode_file.c``.
"""

import os
import sys

from _avif import ffi, lib


def main():
filename = os.fsencode(sys.argv[1])

rgb = ffi.new("avifRGBImage*")
decoder = lib.avifDecoderCreate()
result = lib.avifDecoderSetIOFile(decoder, filename) # TODO: nonexistent file

result = lib.avifDecoderParse(decoder) # TODO: failed decode

image = decoder.image
print(f"Parsed AVIF: {image.width}x{image.height} ({image.depth}bpc)")

while lib.avifDecoderNextImage(decoder) == lib.AVIF_RESULT_OK:
lib.avifRGBImageSetDefaults(rgb, decoder.image)
lib.avifRGBImageAllocatePixels(rgb)
lib.avifImageYUVToRGB(decoder.image, rgb)

first_pixel = tuple(rgb.pixels[0:4])
print(f" * First pixel: RGBA{first_pixel}\n")


if __name__ == "__main__":
main()
15 changes: 15 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[build-system]
requires = [
"cffi>=1.0.0",
"setuptools>=40.6.0",
"setuptools_scm[toml]>=3.4",
"wheel",
]
build-backend = "setuptools.build_meta"

[tool.isort]
from_first = true
include_trailing_comma = true
multi_line_output = 3

[tool.setuptools_scm]
Loading

0 comments on commit 0e06b44

Please sign in to comment.