Skip to content

Commit 8561523

Browse files
duswieNyholm
andauthored
Imagick: build with support for AVIF format by aom encoder (#566)
* imagick: increase test coverage * imagick: build with support for AVIF format * imagick: use platform independent gcc package --------- Co-authored-by: Tobias Nyholm <[email protected]>
1 parent 9587793 commit 8561523

File tree

8 files changed

+91
-53
lines changed

8 files changed

+91
-53
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Change log
22

3+
## 1.8.0
4+
5+
- Upgrade Imagick to version 7.1.1-38 and build with support for AVIF format (aom encoder).
6+
37
## 1.7.2
48

59
- Update the tideways extension

layers/imagick/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
testoutput

layers/imagick/Dockerfile

+47-48
Original file line numberDiff line numberDiff line change
@@ -3,68 +3,67 @@ ARG BREF_VERSION
33
FROM bref/build-php-$PHP_VERSION:$BREF_VERSION AS ext
44
ARG PHP_VERSION
55

6+
ENV IMAGICK_VERSION="7.1.1-38"
7+
ENV AOM_VERSION="3.10.0"
8+
ENV LIBHEIF_VERSION="1.19.3"
9+
ENV LIBDE265_VERSION="1.0.15"
10+
ENV LIBWEBP_VERSION="1.4.0"
11+
ENV GS_VERSION="9.56.1"
12+
ENV IMAGICK_EXT_COMMIT="28f27044e435a2b203e32675e942eb8de620ee58"
13+
614
# Prepare environment
715
ENV IMAGICK_BUILD_DIR=${BUILD_DIR}/imagick
816
RUN mkdir -p ${IMAGICK_BUILD_DIR}
9-
RUN LD_LIBRARY_PATH= yum -y install libpng-devel libjpeg-devel lcms2-devel ImageMagick-devel
17+
WORKDIR ${IMAGICK_BUILD_DIR}
18+
RUN LD_LIBRARY_PATH= yum -y install libpng-devel libjpeg-devel lcms2-devel ImageMagick-devel nasm gcc10 gcc10-c++
19+
20+
# Use gcc10 as the default compiler, needed for AOM
21+
ENV CXX="/usr/bin/gcc10-g++"
22+
ENV CC="/usr/bin/gcc10-gcc"
1023

1124
# Compile libwebp since AL2 ships with v0.3, and v0.4 or higher is required to builder the other libs
12-
WORKDIR ${IMAGICK_BUILD_DIR}
13-
RUN curl -Ls -o libwebp.tar.gz https://github.com/webmproject/libwebp/archive/refs/tags/v1.4.0.tar.gz
14-
RUN tar xzf libwebp.tar.gz
15-
WORKDIR ${IMAGICK_BUILD_DIR}/libwebp-1.4.0
16-
RUN autoreconf -i && automake && autoconf
17-
RUN ./configure --prefix ${INSTALL_DIR} --exec-prefix ${INSTALL_DIR}
18-
RUN make -j $(nproc) && make install
25+
RUN curl -Ls -o libwebp.tar.gz https://github.com/webmproject/libwebp/archive/refs/tags/v${LIBWEBP_VERSION}.tar.gz && tar xzf libwebp.tar.gz && rm libwebp.tar.gz \
26+
&& cd ${IMAGICK_BUILD_DIR}/libwebp-${LIBWEBP_VERSION} \
27+
&& autoreconf -i && automake && autoconf \
28+
&& ./configure --prefix ${INSTALL_DIR} --exec-prefix ${INSTALL_DIR} \
29+
&& make -j $(nproc) && make install && rm -rf ${IMAGICK_BUILD_DIR}/libwebp-${LIBWEBP_VERSION}
30+
31+
# Compile AOM (libavif dependency for AVIF support)
32+
RUN git clone -b v${AOM_VERSION} --depth 1 https://aomedia.googlesource.com/aom \
33+
&& mkdir -p ${IMAGICK_BUILD_DIR}/aom_build && cd ${IMAGICK_BUILD_DIR}/aom_build \
34+
&& cmake ../aom -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_SHARED_LIBS=1 -DENABLE_DOCS=0 -DENABLE_EXAMPLES=0 -DENABLE_TESTDATA=0 -DENABLE_TESTS=0 -DENABLE_TOOLS=0 \
35+
&& make -j $(nproc) && make install && rm -rf ${IMAGICK_BUILD_DIR}/aom && rm -rf ${IMAGICK_BUILD_DIR}/aom_build
1936

2037
# Compile libde265 (libheif dependency)
21-
WORKDIR ${IMAGICK_BUILD_DIR}
22-
RUN curl -Ls -o libde265.tar.gz https://github.com/strukturag/libde265/releases/download/v1.0.15/libde265-1.0.15.tar.gz && tar xzf libde265.tar.gz
23-
WORKDIR ${IMAGICK_BUILD_DIR}/libde265-1.0.15
24-
RUN ./configure --prefix ${INSTALL_DIR} --exec-prefix ${INSTALL_DIR}
25-
RUN make -j $(nproc) && make install
38+
RUN curl -Ls -o libde265.tar.gz https://github.com/strukturag/libde265/releases/download/v${LIBDE265_VERSION}/libde265-${LIBDE265_VERSION}.tar.gz && tar xzf libde265.tar.gz && rm libde265.tar.gz \
39+
&& cd ${IMAGICK_BUILD_DIR}/libde265-${LIBDE265_VERSION} \
40+
&& ./configure --prefix ${INSTALL_DIR} --exec-prefix ${INSTALL_DIR} \
41+
&& make -j $(nproc) && make install && rm -rf ${IMAGICK_BUILD_DIR}/libde265-${LIBDE265_VERSION}
2642

2743
# Compile libheif
28-
WORKDIR ${IMAGICK_BUILD_DIR}
29-
RUN curl -Ls -o libheif.tar.gz https://github.com/strukturag/libheif/releases/download/v1.13.0/libheif-1.13.0.tar.gz && tar xzf libheif.tar.gz
30-
WORKDIR ${IMAGICK_BUILD_DIR}/libheif-1.13.0
31-
RUN ./configure --prefix ${INSTALL_DIR} --exec-prefix ${INSTALL_DIR}
32-
RUN make -j $(nproc) && make install
44+
RUN curl -Ls -o libheif.tar.gz https://github.com/strukturag/libheif/releases/download/v${LIBHEIF_VERSION}/libheif-${LIBHEIF_VERSION}.tar.gz \
45+
&& tar xzf libheif.tar.gz && rm libheif.tar.gz && mkdir -p ${IMAGICK_BUILD_DIR}/libheif-${LIBHEIF_VERSION}/build && cd ${IMAGICK_BUILD_DIR}/libheif-${LIBHEIF_VERSION}/build \
46+
&& cmake --preset=release-noplugins .. -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \
47+
&& make -j $(nproc) && make install && rm -rf ${IMAGICK_BUILD_DIR}/libheif-${LIBHEIF_VERSION}
3348

3449
# Compile gs
35-
WORKDIR ${IMAGICK_BUILD_DIR}
36-
RUN curl -Ls -o ghostscript.tar.gz https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs9561/ghostscript-9.56.1.tar.gz && tar xzf ghostscript.tar.gz
37-
WORKDIR ${IMAGICK_BUILD_DIR}/ghostscript-9.56.1
38-
RUN ./configure --prefix ${INSTALL_DIR} --exec-prefix ${INSTALL_DIR} --without-x
39-
RUN make -j $(nproc) && cp bin/gs /tmp/gs
50+
RUN curl -Ls -o ghostscript.tar.gz https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs9561/ghostscript-${GS_VERSION}.tar.gz && tar xzf ghostscript.tar.gz && rm ghostscript.tar.gz \
51+
&& mkdir -p ${IMAGICK_BUILD_DIR}/ghostscript-${GS_VERSION} && cd ${IMAGICK_BUILD_DIR}/ghostscript-${GS_VERSION} \
52+
&& ./configure --prefix ${INSTALL_DIR} --exec-prefix ${INSTALL_DIR} --without-x \
53+
&& make -j $(nproc) && cp bin/gs /tmp/gs && rm -rf ${IMAGICK_BUILD_DIR}/ghostscript-${GS_VERSION}
4054

4155
# Compile the ImageMagick library
42-
WORKDIR ${IMAGICK_BUILD_DIR}
43-
RUN curl -Ls -o ImageMagick.tar.gz https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.1-38.tar.gz && tar xzf ImageMagick.tar.gz
44-
WORKDIR ${IMAGICK_BUILD_DIR}/ImageMagick-7.1.1-38
45-
RUN ./configure --prefix ${INSTALL_DIR} --exec-prefix ${INSTALL_DIR} --with-webp --with-heic --disable-static --with-freetype=yes
46-
RUN make -j $(nproc)
47-
RUN make install
48-
49-
# Show how ImageMagick is configured. See the "delicate" section
50-
RUN convert -list configure
51-
52-
# Compile the php imagick extension
53-
WORKDIR ${IMAGICK_BUILD_DIR}
54-
RUN git clone https://github.com/Imagick/imagick
55-
WORKDIR ${IMAGICK_BUILD_DIR}/imagick
56-
# TODO; update the commit hash when there's a new release
57-
RUN git reset --hard 28f27044e435a2b203e32675e942eb8de620ee58
58-
RUN phpize
59-
RUN ./configure --with-imagick=${INSTALL_DIR}
60-
RUN make -j $(nproc)
61-
RUN make install
62-
63-
RUN cp `php-config --extension-dir`/imagick.so /tmp/imagick.so
64-
RUN strip --strip-debug /tmp/imagick.so
65-
RUN echo 'extension=imagick.so' > /tmp/ext.ini
56+
RUN curl -Ls -o ImageMagick.tar.gz https://github.com/ImageMagick/ImageMagick/archive/refs/tags/${IMAGICK_VERSION}.tar.gz && tar xzf ImageMagick.tar.gz && rm ImageMagick.tar.gz \
57+
&& cd ${IMAGICK_BUILD_DIR}/ImageMagick-${IMAGICK_VERSION} \
58+
&& ./configure --prefix ${INSTALL_DIR} --exec-prefix ${INSTALL_DIR} --with-webp --with-heic --disable-static --with-freetype=yes \
59+
&& make -j $(nproc) && make install && rm -rf ${IMAGICK_BUILD_DIR}/ImageMagick-${IMAGICK_VERSION} && convert -list configure
6660

67-
RUN php /bref/lib-copy/copy-dependencies.php /tmp/imagick.so /tmp/extension-libs
61+
# Compile the php imagick extension and copy the dependencies
62+
RUN git clone https://github.com/Imagick/imagick && cd imagick \
63+
&&git reset --hard ${IMAGICK_EXT_COMMIT} \
64+
&& phpize && ./configure --with-imagick=${INSTALL_DIR} \
65+
&& make -j $(nproc) && make install && cp `php-config --extension-dir`/imagick.so /tmp/imagick.so && strip --strip-debug /tmp/imagick.so && echo 'extension=imagick.so' > /tmp/ext.ini \
66+
&& php /bref/lib-copy/copy-dependencies.php /tmp/imagick.so /tmp/extension-libs
6867

6968
# Build the final image with just the files we need
7069
FROM scratch

layers/imagick/test.php

+39-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
exit(1);
66
}
77

8-
foreach (['PNG', 'JPG', 'GIF', 'WEBP', 'HEIC'] as $format) {
8+
$expected_formats = ['PNG', 'JPG', 'GIF', 'WEBP', 'HEIC', 'AVIF'];
9+
10+
foreach ( $expected_formats as $format) {
911
if (!\Imagick::queryFormats($format)) {
1012
echo sprintf('FAIL: Imagick does not support "%s".', $format).PHP_EOL;
1113
exit(1);
@@ -27,16 +29,48 @@
2729
exit(1);
2830
}
2931

32+
3033
try {
31-
$image = new \Imagick(__DIR__.'/test.pdf');
32-
$image->writeImage('/tmp/imagick-test.jpg');
33-
assert(file_exists('/tmp/imagick-test.jpg'));
34+
$tmpdir = '/tmp/imagicktest';
35+
mkdir($tmpdir);
36+
37+
foreach ($expected_formats as $format) {
38+
//for all files in the testfiles directory
39+
foreach (glob(__DIR__.'/testfiles/*') as $file) {
40+
$image = new \Imagick($file);
41+
$output_path = $tmpdir . '/' .pathinfo($file, PATHINFO_FILENAME) . '.' . strtolower($format);
42+
$image->writeImage($output_path);
43+
validateImageFile($output_path);
44+
}
45+
}
46+
47+
// compare the size of the AVIF image with the original JPG, buggy builds may just copy the jpg
48+
assert(filesize( $tmpdir . '/jpg_test.avif') < filesize(__DIR__.'/testfiles/jpg_test.jpg') * 0.9);
49+
50+
// copy the output files to the testoutput directory, if it exists. Useful for local testing
51+
if (file_exists('/var/task/testoutput')){
52+
foreach (glob($tmpdir.'/*') as $file) {
53+
copy($file, '/var/task/testoutput/'.basename($file));
54+
}
55+
}
56+
3457
} catch(\ImagickException $e) {
35-
echo sprintf('FAIL: Imagick cannot convert PDF "%s".', $e->getMessage()).PHP_EOL;
58+
echo sprintf('FAIL: Imagick failed to write image "%s".', $e->getMessage()).PHP_EOL;
3659
exit(1);
3760
} catch (\Throwable $e) {
3861
echo sprintf('FAIL: Imagick failed with "%s" exception: %s', get_class($e), $e->getMessage()).PHP_EOL;
3962
exit(1);
4063
}
4164

65+
// some basic image validation
66+
function validateImageFile($file) {
67+
assert(file_exists($file), 'File does not exist: ' . $file);
68+
assert(filesize($file) > 128, 'File size ( '. filesize($file) .' byte ) is < byte for ' . $file );
69+
// only for supported formats
70+
if (in_array(pathinfo($file, PATHINFO_EXTENSION), ['png', 'jpg', 'webp', 'avif']) && version_compare(phpversion(), '8.3', '>=')) {
71+
assert(getimagesize($file) !== false, 'getimagesize failed for ' . $file);
72+
}
73+
74+
}
75+
4276
exit(0);
1.31 KB
Binary file not shown.

layers/imagick/testfiles/jpg_test.jpg

5.28 KB
Loading
File renamed without changes.

layers/imagick/testfiles/png_test.png

4.97 KB
Loading

0 commit comments

Comments
 (0)