v0.31.0 - AVIF output after sharpen operation assumes high bit rate, crashes with aom built without support for this
It was working fine until 0.30. As soon as we upgrade library to 0.31.0, docker containers start crashing in production when request count goes high. No error in log, nothing in Kubernetes. It just simply crashes when lot of requests come. Kubernetes restarts it but it again crashes leading to downtime.
Please provide significantly more information, at least enough so that someone else can reproduce the problem, including sample code and, as you're using Docker, the Dockerfile.
Apologies for frustratingly low amount of information. We wanted to report issue because we thought this might be widespread issue affecting everyone and it would be best if someone can start looking into this early.
Btw, we can re-produce this on local machine now. Here is code which immediately results in segmentation fault.
The problem appears when avif output is used with sharpen()
import sharp from "sharp";
import got from "got";
async function image_process() {
let response = await got.get("https://static.samyakk.com/pub/media/catalog/product/p/g/pg3239-b_1.jpg",{
responseType: 'buffer'
});
let transform = sharp(response.body, {
failOnError: false,
page: 0,
density: 144
});
transform.timeout({seconds:60});
transform.sharpen(); // if this is commented, everything works fine.
transform.avif({
quality: 75,
lossless: false,
effort: 0
});
let data = transform.toBuffer({resolveWithObject: true});
}
image_process();
I would also like to add that this one seems issue with libvips 8.13 rather than sharp. If sharp 0.30.6 is given custom built libvips 8.13 the same issue occurs. Everything works fine in 8.12.
I could reproduce this with the pre-built binaries provided by sharp and NetVips. It looks like PR https://github.com/lovell/sharp-libvips/pull/94 would conflict with commit https://github.com/libvips/libvips/commit/e985e23c0910517fb48a2c62334c34dd71d4b26a (i.e. writing a high bit rate AVIF image while aom is configured with -DCONFIG_AV1_HIGHBITDEPTH=0 would cause a segfault).
$ curl -LO https://images.weserv.nl/zebra.jpg
$ cat <<EOT > sharpen-mild.mat
3 3 24
-1 -1 -1
-1 32 -1
-1 -1 -1
EOT
# Test with system provided aom
$ vips convf zebra.jpg x.avif sharpen-mild.mat
$ echo $?
0
# Test with the pre-built binaries
$ mkdir -p vips-8.13.1/
$ curl -Ls https://github.com/kleisauke/libvips-packaging/releases/download/v8.13.1/libvips-8.13.1-linux-x64.tar.gz | tar xzC vips-8.13.1/
$ LD_PRELOAD=vips-8.13.1/lib/libvips.so.42 vips convf pg3239-b_1.jpg x.avif sharpen-mild.mat
Segmentation fault (core dumped)
# Rebuild aom with -DCONFIG_AV1_HIGHBITDEPTH=0
$ mkdir -p aom-3.4.0/aom_build/
$ curl https://storage.googleapis.com/aom-releases/libaom-3.4.0.tar.gz | tar xzC aom-3.4.0/ --strip-components=1
$ cd aom-3.4.0/aom_build
$ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_SHARED_LIBS=1 -DENABLE_{DOCS,TESTS,TESTDATA,TOOLS,EXAMPLES}=0 -DENABLE_NASM=1 -DCONFIG_AV1_HIGHBITDEPTH=0 -DCONFIG_WEBM_IO=0 ..
$ cmake --build . -- -j$(nproc)
$ sudo cmake --install .
$ cd ../../
# Test with aom configured with -DCONFIG_AV1_HIGHBITDEPTH=0
$ vips convf zebra.jpg x.avif sharpen-mild.mat
Segmentation fault (core dumped)
Thanks Kleis, great work, the convolution output is float, therefore heifsave assumes 16-bit.
I'm not sure there's a way of querying aom to see what bitdepths it has been compiled with support for, so I guess we can fix this by forcing a bitdepth of 8. We could also explicitly cast to uchar rather than rely on the implicit float to ushort to uchar.
Just curious. What would be behaviour with -DCONFIG_AV1_HIGHBITDEPTH=1? Would everything work fine or it will have unintended consequences?
I am just thinking if there can be a quick fix.
We tried above and it fixes the crash.
It seems doing this results in completely black image.
Commit https://github.com/lovell/sharp/commit/28b87db760533390ebe14c7e634f5ccc0575002c ensures a bitdepth of 8 is always used, and adds a test that would previously have failed.
v0.31.1 now available