libvips (sharp) で一部の heif が変換できない問題
特定の画像で以下のエラーが出ていた。一応解決したのでメモ。
code:error
Error: Input buffer has corrupt header: source: bad seek to 3294742
heif: Invalid input: Unspecified: Too many auxiliary image references (2.0)
code:error
Error: Input buffer has corrupt header: source: bad seek to 3294742
heifload_buffer: not all pages are the same size
結論
完全な問題調査はできていないが、動作する状態にはできた
libvips 8.16.0
ソースからビルド
必要に応じてプラグインを入れる
libheif 1.19.5
ソースからビルド
デコーダーを入れる
libde256 1.0.11
sharpをソースからビルドしてグローバルの libvips を参照させる
壊れてた環境
debian 12 / linux arm64
deno 2.1.4
sharp@0.33.5
prebuilt の libvips 8.15.3 を使っている
内蔵されている libheif は 1.18.2
これが古い。
prebuilt されてるプラグインは以下で見れる。
code:repl
sharp.versions
{
aom: '3.9.1',
archive: '3.7.4',
cairo: '1.18.0',
cgif: '0.4.1',
exif: '0.6.24',
expat: '2.6.2',
ffi: '3.4.6',
fontconfig: '2.15.0',
freetype: '2.13.2',
fribidi: '1.0.15',
glib: '2.81.1',
harfbuzz: '9.0.0',
heif: '1.18.2',
highway: '1.2.0',
imagequant: '2.4.1',
lcms: '2.16',
mozjpeg: '4.1.5',
pango: '1.54.0',
pixman: '0.43.4',
png: '1.6.43',
'proxy-libintl': '0.4',
rsvg: '2.58.93',
spng: '0.7.4',
tiff: '4.6.0',
vips: '8.15.3',
webp: '1.4.0',
xml: '2.13.3',
'zlib-ng': '2.2.1',
sharp: '0.33.5'
}
ちなみにここで、以下のように出ればグローバルにインストールされている libvips を参照できている。libvips のプラグインは表示されない。
code:repl
sharp.versions
{ vips: "8.16.0", sharp: "0.33.5" }
調査
どうやら状況はこれに関連する。
libheif v1.18.0 で修正されていると書いてあるが、現行 sharp に内蔵されている v1.18.2 では動作していない。
libheif v1.19.5 が最新なので、ひとまずこれを動かしてみる。
必要な依存はHEVCコーデックのデコード用に libde256
最初は libde265 1.0.15 をソースからビルドしていたが、動的リンクがうまく通らず中断。apt 経由で入れた 1.0.11 で問題なく動作。(より詳細な調査が必要)
エンコードには libx256 または kvazaar が使える
今回はエンコードは使わないので不要だったのだが、libx256 はGLPなので汚染に注意
libheif のビルド
特に詰まることはない
heif-dec --list-decoder でデコーダをチェックできる
heic-dec sample.heic などコマンドを叩いてチェック
ちなみにubuntu環境ではソースからビルドせずともここに最新がある。
ppa:strukturag/libheif
libvips のビルド
必要なプラグインを入れておく
自分は png, tiff, jpeg, webp あたりのフォーマットと、fft, exif などの外部パッケージを入れておいた。
libspng-dev libtiff5-dev libjpeg62-turbo-dev libwebp-dev liborc-0.4-dev libexif-dev libfftw3-dev liblcms2-dev
以下のsetupを走らせたときにdetectされているか確認できる
meson setup build --libdir=lib --buildtype=release -Dintrospection=disabled
.soができたら ldconfig 忘れずに
lld で共有ライブラリが not found になってたら要更新
vips --vips-config で有効なプラグインをチェック
vips copy sample.heic out.png を叩いてチェック
sharpのビルド
自分はdeno2環境なのですこし特殊
ビルドに必要な依存をいれる
npm: node-addon-api node-gyp
python3
node-gyp用
nodejs
自分はdeno環境なので、install script を実行するために必要
そのほか、依存パッケージ。build-essential など。
ランタイムではこれらは消すが、npm経由で入れた依存はlockの関係でめんどいのでそのまま。
SHARP_FORCE_GLOBAL_LIBVIPS=1 deno install --allow-scripts=npm:sharp --frozen
package.json deno.lock 必要
その他の環境 (動作未確認)
SHARP_FORCE_GLOBAL_LIBVIPS=1 npm install --build-from-source
SHARP_FORCE_GLOBAL_LIBVIPS=1 npm_config_build_from_source=sharp pnpm i
sharp.versions で 8.16.0 が認識されていればOK。わらわらとプラグインのバージョンまで表示されたらprebuiltが使われてしまっているので失敗。
再ビルドするときは node_modules を都度削除する
sharp
sharp(buffer, { animated: true }) はダメそう。ライブフォトが原因?
テスト用に作ったフルのDockerfileはこんな感じ。
イメージサイズはprebuilt版に比べて+30MB程度 (圧縮かけて+7MB) だった。マルチステージビルド便利。
code:Dockerfile
FROM denoland/deno:2.1.9 AS base
FROM base AS builder
WORKDIR /tmp
RUN apt update && \
apt install -y --no-install-recommends \
build-essential cmake automake autoconf libtool m4 pkg-config ninja-build curl nodejs python3-pip \
libde265-dev libglib2.0-dev libexpat1-dev libspng-dev libtiff5-dev libjpeg62-turbo-dev libwebp-dev liborc-0.4-dev libexif-dev libfftw3-dev liblcms2-dev
RUN pip3 install meson --break-system-packages
RUN LIBHEIF_VERSION=1.19.5 && \
tar -xvf libheif-${LIBHEIF_VERSION}.tar.gz && \
cd libheif-${LIBHEIF_VERSION} && \
mkdir build && \
cd build && \
cmake --preset=release .. && \
make && \
make install && \
ldconfig
RUN VIPS_VERSION=8.16.0 && \
tar -xvf vips-${VIPS_VERSION}.tar.xz && \
cd vips-${VIPS_VERSION} && \
meson setup build --libdir=lib --buildtype=release -Dintrospection=disabled && \
cd build && \
meson compile && \
meson install && \
ldconfig
WORKDIR /app
COPY deno.lock .
COPY package.json .
RUN SHARP_FORCE_GLOBAL_LIBVIPS=1 deno install --allow-scripts=npm:sharp --frozen
FROM base
COPY --from=builder /usr/local/lib /usr/local/lib
COPY --from=builder /app/node_modules /app/node_modules
RUN apt update && \
apt install -y --no-install-recommends \
libglib2.0-0 libexpat1 libde265-0 libspng0 libtiff6 libjpeg62-turbo libwebp7 libwebpdemux2 libwebpmux3 liborc-0.4-0 libexif12 libfftw3-double3 liblcms2-2 && \
apt clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
WORKDIR /app
COPY deno.json .
COPY deno.lock .
COPY package.json .
COPY main.ts .
COPY sample.heic .
RUN deno cache main.ts