Skip to content

Commit d27be2b

Browse files
committed
added color_primaries transfer_characteristics and matrix_coefficients option
1 parent 616b640 commit d27be2b

5 files changed

Lines changed: 114 additions & 16 deletions

File tree

README.md

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,86 @@
33
This is a plugin that adds support for AVIF files until official support has been added (see [this pull request](https://github.com/python-pillow/Pillow/pull/5201)).
44

55
To register this plugin with pillow you will need to add `import pillow_avif` somewhere in your application.
6+
7+
## how to build on Windows
8+
9+
- install miniforge
10+
- install VS2019
11+
- install git for windows
12+
- install TortoiseGit
13+
- install MSYS2 and add C:\MSYS\usr\bin to PATH environment variable
14+
- download https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/win64/nasm-2.15.05-win64.zip , unzip onto C:\apps\NASM and add D:\apps\NASM to PATH environment variable.
15+
- on Administrator miniforge prompt, pip install pillow meson
16+
- on Administrator miniforge prompt, cd to this directory, cd winbuild and python build_prepare.py
17+
- cd winbuild/build and build_dep_all.cmd and build_pillow_avif_plugin.cmd
18+
- cd to this directory and python -m pip install -e .
19+
- pip list should show pillow-avif-plugin
20+
21+
## encoding options
22+
23+
## "range"
24+
25+
| value | meanings |
26+
|-----:|-----------|
27+
| "full" | full quantization range image. ex. ST 2084 PQ requires it |
28+
| "limited" | limited quantization range image. |
29+
30+
## "subsampling"
31+
32+
| value | meanings |
33+
|-----:|-----------|
34+
| "4:4:4" | YCbCr 4:4:4 or lossless GBR encoding |
35+
| "4:2:2" | YCbCr422 |
36+
| "4:2:0" | YCbCr420 |
37+
| "4:0:0" | YCbCr400 |
38+
39+
## "depth"
40+
41+
color bitdepth. 8, 10 or 12
42+
43+
## "quality"
44+
45+
encoding quality, integer number ranging 0 to 100
46+
47+
| value | meanings |
48+
|-----:|-----------|
49+
| 0 | worst color encoding quality |
50+
| 75 | default color encoding quality |
51+
| 100 | best color encoding quality |
52+
53+
## "color_primaries"
54+
55+
| value | meanings |
56+
|-----:|-----------|
57+
| 1| BT.709, Rec.709 or sRGB |
58+
| 2| Unspecified |
59+
| 9| BT.2020, Rec.2020 or Rec.2100 |
60+
| 12| DCI P3 or SMPTE EG 432-1 |
61+
62+
## "transfer_characteristics"
63+
64+
| value | meanings |
65+
|-----:|-----------|
66+
| 1| BT.709 or Rec.709 |
67+
| 2| Unspecified |
68+
| 6| BT.601 |
69+
| 8| Linear |
70+
| 13| sRGB |
71+
| 14| BT.2020 10bit |
72+
| 15| BT.2020 12bit |
73+
| 16| ST 2084 PQ for Rec.2020 |
74+
| 18| HLG |
75+
76+
## "matrix_coefficients"
77+
78+
| value | meanings |
79+
|-----:|-----------|
80+
| 0| Identity matrix for lossless encoding. Stores color as GBR |
81+
| 1| BT.709 YCbCr |
82+
| 2| Unspecified |
83+
| 6| BT.601 YCbCr (default for lossy encodings) |
84+
| 8| YCgCo |
85+
| 9| BT.2020 non-constant luminance, BT.2100 YCbCr |
86+
| 10| BT.2020 constant luminance |
87+
| 11| SMPTE ST 2085 YDzDx |
88+
| 14| BT.2100 ICtCp |

src/pillow_avif/AvifImagePlugin.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,11 @@ def _save(im, fp, filename, save_all=False):
147147
speed = info.get("speed", 6)
148148
codec = info.get("codec", "auto")
149149
range_ = info.get("range", "full")
150+
151+
color_primaries = info.get("color_primaries", 1)
152+
transfer_characteristics = info.get("transfer_characteristics", 1)
153+
matrix_coefficients = info.get("matrix_coefficients", 6)
154+
150155
tile_rows_log2 = info.get("tile_rows", 0)
151156
tile_cols_log2 = info.get("tile_cols", 0)
152157
alpha_premultiplied = bool(info.get("alpha_premultiplied", False))
@@ -190,6 +195,10 @@ def _save(im, fp, filename, save_all=False):
190195
speed,
191196
codec,
192197
range_,
198+
qcolor,
199+
color_primaries,
200+
transfer_characteristics,
201+
matrix_coefficients,
193202
tile_rows_log2,
194203
tile_cols_log2,
195204
alpha_premultiplied,

src/pillow_avif/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33

44
__all__ = ["AvifImagePlugin"]
5-
__version__ = "1.3.1"
5+
__version__ = "1.3.1a0"

src/pillow_avif/_avif.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
216216

217217
char *codec = "auto";
218218
char *range = "full";
219+
220+
int depth = 8;
221+
int color_primaries = AVIF_COLOR_PRIMARIES_BT709;
222+
int transfer_characteristics = AVIF_TRANSFER_CHARACTERISTICS_SRGB;
223+
int matrix_coefficients = AVIF_MATRIX_COEFFICIENTS_BT601;
219224

220225
PyObject *advanced;
221226

@@ -230,6 +235,10 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
230235
&speed,
231236
&codec,
232237
&range,
238+
&depth,
239+
&color_primaries,
240+
&transfer_characteristics,
241+
&matrix_coefficients,
233242
&tile_rows_log2,
234243
&tile_cols_log2,
235244
&alpha_premultiplied,
@@ -343,12 +352,12 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
343352
// Set these in advance so any upcoming RGB -> YUV use the proper coefficients
344353
image->yuvRange = enc_options.range;
345354
image->yuvFormat = enc_options.subsampling;
346-
image->colorPrimaries = AVIF_COLOR_PRIMARIES_UNSPECIFIED;
347-
image->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED;
348-
image->matrixCoefficients = AVIF_MATRIX_COEFFICIENTS_BT601;
355+
image->colorPrimaries = color_primaries;
356+
image->transferCharacteristics = transfer_characteristics;
357+
image->matrixCoefficients = matrix_coefficients;
349358
image->width = width;
350359
image->height = height;
351-
image->depth = 8;
360+
image->depth = depth;
352361
#if AVIF_VERSION >= 90000
353362
image->alphaPremultiplied = enc_options.alpha_premultiplied;
354363
#endif
@@ -360,9 +369,6 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
360369
image,
361370
(uint8_t *)PyBytes_AS_STRING(icc_bytes),
362371
PyBytes_GET_SIZE(icc_bytes));
363-
} else {
364-
image->colorPrimaries = AVIF_COLOR_PRIMARIES_BT709;
365-
image->transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_SRGB;
366372
}
367373

368374
if (PyBytes_GET_SIZE(exif_bytes)) {
@@ -462,7 +468,7 @@ _encoder_add(AvifEncoderObject *self, PyObject *args) {
462468
frame->matrixCoefficients = image->matrixCoefficients;
463469
frame->yuvRange = image->yuvRange;
464470
frame->yuvFormat = image->yuvFormat;
465-
frame->depth = image->depth;
471+
frame->depth = self->image->depth;
466472
#if AVIF_VERSION >= 90000
467473
frame->alphaPremultiplied = image->alphaPremultiplied;
468474
#endif
@@ -474,7 +480,7 @@ _encoder_add(AvifEncoderObject *self, PyObject *args) {
474480
memset(&rgb, 0, sizeof(avifRGBImage));
475481

476482
avifRGBImageSetDefaults(&rgb, frame);
477-
rgb.depth = 8;
483+
rgb.depth = self->image->depth;
478484

479485
if (strcmp(mode, "RGBA") == 0) {
480486
rgb.format = AVIF_RGB_FORMAT_RGBA;

winbuild/build_prepare.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ def cmd_cmake(params=None, file="."):
121121
"bins": ["cjpeg.exe", "djpeg.exe"],
122122
},
123123
"zlib": {
124-
"url": "http://zlib.net/zlib1211.zip",
125-
"filename": "zlib1211.zip",
126-
"dir": "zlib-1.2.11",
124+
"url": "http://zlib.net/zlib1213.zip",
125+
"filename": "zlib1213.zip",
126+
"dir": "zlib-1.2.13",
127127
"build": [
128128
cmd_nmake(r"win32\Makefile.msc", "clean"),
129129
cmd_nmake(r"win32\Makefile.msc", "zlib.lib"),
@@ -147,9 +147,9 @@ def cmd_cmake(params=None, file="."):
147147
"libs": [r"libpng16.lib"],
148148
},
149149
"libavif": {
150-
"url": "https://github.com/AOMediaCodec/libavif/archive/v0.11.0.tar.gz",
151-
"filename": "libavif-0.11.0.tar.gz",
152-
"dir": "libavif-0.11.0",
150+
"url": "https://github.com/AOMediaCodec/libavif/archive/v0.11.1.tar.gz",
151+
"filename": "libavif-0.11.1.tar.gz",
152+
"dir": "libavif-0.11.1",
153153
"patch": {
154154
"src/codec_aom.c": {
155155
"if (aomCpuUsed >= 7)": "if (0)",

0 commit comments

Comments
 (0)