OSS-Fuzz build does not find codec dependencies
OSS-Fuzz builds libaom, x265, and libde265, but does not find them when building libheif, resulting in only enabling the 'uncompressed' codec (mentioned in https://github.com/strukturag/libheif/issues/1345#issuecomment-2441552780). Link to Build Logs.
Additionally to fixing this, we should also enable the other codecs in the build.
The GraphicsMagick oss-fuzz build is doing much better regarding libheif. I think that currently only one useful dependency is excluded (because a pkg-config file is now missing).
Feel free to borrow ideas from GraphicsMagick's oss-fuzz support at https://foss.heptapod.net/graphicsmagick/graphicsmagick/-/tree/branch/default/fuzzing?ref_type=heads, and particularly the "oss-fuzz-build.sh" script at https://foss.heptapod.net/graphicsmagick/graphicsmagick/-/blob/branch/default/fuzzing/oss-fuzz-build.sh?ref_type=heads
If you see something that I should be doing better, please make me aware of it.
The GraphicsMagick oss-fuzz build does not actually need x265 yet, but I tried to re-add it to the oss-fuzz build while using https://bitbucket.org/multicoreware/x265_git/src/stable/ as the source repository path (as libheif's oss-fuzz build does).
The build failed while building libheif with this error:
[ 81%] Building CXX object libheif/CMakeFiles/heif.dir/plugins/encoder_mask.cc.o
cd /src/heif_build/libheif && /usr/local/bin/clang++ -DENABLE_MULTITHREADING_SUPPORT=1 -DENABLE_PARALLEL_TILE_DECODING=1 -DHAVE_AOM_DECODER=1 -DHAVE_AOM_ENCODER=1 -DHAVE_LIBDE265=1 -DHAVE_LIBSHARPYUV=1 -DHAVE_UNISTD_H -DHAVE_VISIBILITY -DHAVE_X265=1 -DIS_BIG_ENDIAN=0 -DLIBHEIF_EXPORTS -I/src/heif_build -I/src/libheif/libheif -I/src/libheif/libheif/api -I/src/libheif/include/libheif -I/src/libheif/include -I/work/include -I/work/include/webp -O1 -fno-omit-frame-pointer -gline-tables-only -Wno-error=enum-constexpr-conversion -Wno-error=incompatible-function-pointer-types -Wno-error=int-conversion -Wno-error=deprecated-declarations -Wno-error=implicit-function-declaration -Wno-error=implicit-int -Wno-error=vla-cxx-extension -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -stdlib=libc++ -g -std=c++20 -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -Werror -Wall -Wsign-compare -Wconversion -Wno-sign-conversion -Wno-error=conversion -Wno-error=unused-parameter -Wno-error=deprecated-declarations -Wno-error=tautological-compare -Wno-error=tautological-constant-out-of-range-compare -Wno-error=potentially-evaluated-expression -Wno-tautological-constant-out-of-range-compare -Werror -MD -MT libheif/CMakeFiles/heif.dir/plugins/encoder_mask.cc.o -MF CMakeFiles/heif.dir/plugins/encoder_mask.cc.o.d -o CMakeFiles/heif.dir/plugins/encoder_mask.cc.o -c /src/libheif/libheif/plugins/encoder_mask.cc
/src/libheif/libheif/plugins/encoder_x265.cc:918:23: error: cannot initialize a parameter of type 'x265_picture *' with an rvalue of type 'x265_picture **'
918 | &out_pic);
| ^~~~~~~~
/src/libheif/libheif/plugins/encoder_x265.cc:993:38: error: cannot initialize a parameter of type 'x265_picture *' with an rvalue of type 'x265_picture **'
993 | &out_pic);
| ^~~~~~~~
2 errors generated.
make[2]: *** [libheif/CMakeFiles/heif.dir/build.make:849: libheif/CMakeFiles/heif.dir/plugins/encoder_x265.cc.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory '/src/heif_build'
make[1]: *** [CMakeFiles/Makefile2:198: libheif/CMakeFiles/heif.dir/all] Error 2
make[1]: Leaving directory '/src/heif_build'
make: *** [Makefile:159: all] Error 2
The build failed while building libheif with this error:
x265 had changed the signature of the encoder_encode() function in version 212. See https://github.com/strukturag/libheif/pull/1314 and https://bitbucket.org/multicoreware/x265_git/issues/952/crash-in-libheif-tests.
It seems that they changed it back in version 213. I have adapted the #if in commit 9c39813
Now, it should compile again.
I have verified that GraphicsMagick oss-fuzz builds with everything (including x265) now, using "https://bitbucket.org/multicoreware/x265_git/src/stable/". I am not sure if GraphicsMagick should switch to using "https://bitbucket.org/multicoreware/x265_git/src/master/" since I have little knowledge of the x265 project and how stable it is on a day-to-day basis.
I'm also not sure whether there is much benefit in using x265 master instead of stable. I just know that we constantly had fuzzing alarms because of issues inside x265. Often false positives because of read access to uninitialized data (which can be happen, for example, in the border padding region of images without any noticeable effect).
I have verified that GraphicsMagick oss-fuzz builds with everything (including x265) now, using "https://bitbucket.org/multicoreware/x265_git/src/stable/". I am not sure if GraphicsMagick should switch to using "https://bitbucket.org/multicoreware/x265_git/src/master/" since I have little knowledge of the x265 project and how stable it is on a day-to-day basis.
@chenm001 Hi Min Chen, can you advise @bobfriesenhahn which branch of x265 he should use together with libheif for building GraphicsMagick?
It seems that the libheif oss-build installs the codec libraries under /src/deps/lib but then nothing in the build appears to specify that the libheif build should use that directory. I see export DEPS_PATH=/src/deps used while building other libraries, but I don't know what DEPS_PATH is.
I found that libx265 changed sometime ago (via its source/cmake/Version.cmake) such that if the source code is managed by git (has a .git directory) or does not have a specified version, then it no longer installs x265.pc. For some reason, libheif is more picky now and will fail if x265.pc is not found. Not really understanding the obtuse logic in Version.cmake, the solution I found was to temporarily move the .git directory to a different name, and then restore it.
As a point of reference, the next GraphicsMagick oss-fuzz build will result in this build status report from the libheif component:
=== Summary of compiled codecs ===
libde265 HEVC decoder : + built-in
FFMPEG HEVC decoder (HW acc) : - disabled
x265 HEVC encoder : + built-in
Kvazaar HEVC encoder : - disabled
AOM AV1 decoder : + built-in
AOM AV1 encoder : + built-in
Dav1d AV1 decoder : - disabled
SVT AV1 encoder : - disabled
Rav1e AV1 encoder : - disabled
JPEG decoder : + built-in
JPEG encoder : + built-in
OpenH264 decoder : + built-in
OpenJPEG J2K decoder : + built-in
OpenJPEG J2K encoder : + built-in
OpenJPH HT-J2K encoder : - disabled
uvg266 VVC enc. (experimental) : - disabled
vvenc VVC enc. (experimental) : - disabled
vvdec VVC dec. (experimental) : - disabled
=== Supported formats ===
format decoding encoding
AVC YES NO
AVIF YES YES
HEIC YES YES
JPEG YES YES
JPEG2000 YES YES
JPEG2000-HT YES NO
Uncompressed NO NO
VVC NO NO
Uncompressed NO NO
I'd be interested in having this oss-fuzz'd if possible. There are no dependencies for that.
Note that I am improving the GraphicsMagick oss-fuzz build and GraphicsMagick capabilities related to HEIF are still very limited. I am adding more libheif codec options to the GraphicsMagick oss-fuzz build in order to prove compilation, and also to assure that any issues are detected early when HEIF-related development commences again.
It is unclear to me what enabling support for Uncompressed will do, but I will add it.
The first thing that the libheif OSS-Fuzz build needs to accomplish is to change projects/libheif/build.sh so that it dispatches to a build script in libheif's own repository. This allows rapid development of the build script. The overhead of change submissions to the oss-fuzz repository is very high since changes may be only submitted by approved individuals, a large suite of tests needs to pass before the change is considered, and then a core oss-fuzz maintainer needs to merge the change.