harvard-lts / kakadu-vips

Kakadu JP2 reader and writer for libvips
Apache License 2.0
2 stars 0 forks source link

vips: unknown action "kakaduload" #20

Closed justinlittman closed 1 month ago

justinlittman commented 1 month ago

In a docker image on an M1 Mac (so KAKADU_ARCH=Linux-arm-64-gcc):

root@b0b269925730:/kakadu-vips/src# vips kakaduload
vips: unknown action "kakaduload"

root@b0b269925730:/kakadu-vips/src# vips kakaduload -p vips-kakadu
plugin: unable to open plugin "vips-kakadu"
plugin: vips-kakadu.so: cannot open shared object file: No such file or directory

root@b0b269925730:/kakadu-vips/src# vips --vips-config
enable debug: false
enable deprecated: true
enable modules: true
enable cplusplus: true
enable RAD load/save: true
enable Analyze7 load/save: true
enable PPM load/save: true
enable GIF load: true
use fftw for FFTs: true
SIMD support with highway: false
accelerate loops with ORC: true
ICC profile support with lcms: true
zlib: true
text rendering with pangocairo: true
font file support with fontconfig: true
EXIF metadata support with libexif: true
JPEG load/save with libjpeg: true
JXL load/save with libjxl: false (dynamic module: false)
JPEG2000 load/save with OpenJPEG: false
PNG load/save with libspng: false
PNG load/save with libpng: true
selected quantisation package: imagequant
TIFF load/save with libtiff: true
image pyramid save with libarchive: true
HEIC/AVIF load/save with libheif: true (dynamic module: true)
WebP load/save with libwebp: true
PDF load with PDFium: false
PDF load with poppler-glib: true (dynamic module: true)
SVG load with librsvg: true
EXR load with OpenEXR: true
OpenSlide load: true (dynamic module: true)
Matlab load with libmatio: true
NIfTI load/save with niftiio: false
FITS load/save with cfitsio: true
GIF save with cgif: true
selected Magick package: MagickCore (dynamic module: true)
Magick API version: magick6
Magick load: true
Magick save: true

root@b0b269925730:/kakadu-vips/src# ls /usr/local/lib/aarch64-linux-gnu
libvips-cpp.so  libvips-cpp.so.42  libvips-cpp.so.42.17.2  libvips.so  libvips.so.42  libvips.so.42.17.2  pkgconfig  vips-modules-8.15
root@b0b269925730:/kakadu-vips/src# ls /usr/local/lib/aarch64-linux-gnu/vips-modules-8.15/
vips-heif.so  vips-kakadu.so  vips-magick.so  vips-openslide.so  vips-poppler.so

root@b0b269925730:/kakadu-vips/src# cat /etc/issue
Ubuntu 24.04 LTS \n \l

I have a similar working directly on an x86 Ubuntu VM.

Thanks in advance for your assistance.

justinlittman commented 1 month ago

Here's the Dockerfile:

FROM ubuntu:latest

ARG KDU_VERSION=v8_3-02138L
ARG KAKADU_ARCH=Linux-arm-64-gcc
ARG RUBY=3.3.1
ARG VIPS_VERSION=8.15.2

RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
    && apt-get -y install --no-install-recommends \
    # For VIPS
    build-essential \
    libnuma-dev \
    meson \
    ninja-build \
    libjpeg-turbo8-dev \
    libexif-dev \
    librsvg2-dev \
    libpoppler-glib-dev \
    libarchive-dev \
    libtiff-dev \
    libfftw3-dev \
    liblcms2-dev \
    libpng-dev \
    libimagequant-dev \
    libmagickcore-dev \
    libmagickwand-dev \
    libpango1.0-dev \
    libmatio-dev \
    libcfitsio-dev \
    libwebp-dev \
    libopenslide-dev \
    libheif-dev \
    libcgif-dev \
    liborc-0.4-dev \
    curl \
    # For Kakadu VIPS
    libnuma-dev \
    # For Ruby
    autoconf \
    patch \
    rustc \
    libssl-dev \
    libyaml-dev \
    libreadline6-dev \
    zlib1g-dev \
    libgmp-dev \
    libncurses5-dev \
    libffi-dev \
    libgdbm6 \
    libgdbm-dev \
    libdb-dev \
    uuid-dev \
    ca-certificates

# Allow ImageMagick to write PDFs
RUN sed -i 's/<policy domain="coder" rights="none" pattern="PDF" \/>/<!-- <policy domain="coder" rights="none" pattern="PDF" \/> -->/' /etc/ImageMagick-6/policy.xml

# Install Ruby
SHELL ["/bin/bash", "-c"]
ADD https://github.com/rbenv/ruby-build/archive/refs/tags/v20240530.1.tar.gz /tmp/ruby-build.tar.gz
WORKDIR /tmp
RUN tar -xzf ruby-build.tar.gz
RUN PREFIX=/usr/local ./ruby-build-*/install.sh
RUN ruby-build ${RUBY} /opt/ruby
ENV PATH="/opt/ruby/bin:$PATH"

# Install VIPS
SHELL ["/bin/sh", "-c"]
ENV VIPSHOME="/opt/vips"
RUN mkdir -p ${VIPSHOME}
WORKDIR ${VIPSHOME}
RUN curl -L https://github.com/libvips/libvips/releases/download/v${VIPS_VERSION}/vips-${VIPS_VERSION}.tar.xz --output vips-${VIPS_VERSION}.tar.xz
RUN tar -xf vips-${VIPS_VERSION}.tar.xz
ENV VIPSVERSIONHOME="${VIPSHOME}/vips-${VIPS_VERSION}"
RUN cd ${VIPSVERSIONHOME} && meson setup build --buildtype=release -Dopenjpeg=disabled
WORKDIR ${VIPSVERSIONHOME}/build
RUN meson compile
RUN meson test
RUN meson install

ENV LD_LIBRARY_PATH="/usr/local/lib/aarch64-linux-gnu:${LD_LIBRARY_PATH}"

# Install Kakadu
ENV KAKADUVIPSHOME="/kakadu-vips"
COPY kakadu ${KAKADUVIPSHOME}/kakadu/

ENV KAKADUHOME="${KAKADUVIPSHOME}/kakadu/${KDU_VERSION}"

RUN cd ${KAKADUHOME}/make && make -f Makefile-${KAKADU_ARCH} clean
RUN cd ${KAKADUHOME}/coresys/make && make -f Makefile-${KAKADU_ARCH}
RUN cd ${KAKADUHOME}/managed/make && make -f Makefile-${KAKADU_ARCH} all_but_jni
RUN cd ${KAKADUHOME}/apps/make && make -f Makefile-${KAKADU_ARCH}

ENV PATH="${KAKADUHOME}/bin/${KAKADU_ARCH}:$PATH"
ENV LD_LIBRARY_PATH="${KAKADUHOME}/lib/${KAKADU_ARCH}:$LD_LIBRARY_PATH"

# Install Kakadu VIPS
COPY src ${KAKADUVIPSHOME}/src/
COPY test/images/church.jp2 ${KAKADUVIPSHOME}/church.jp2

RUN cd ${KAKADUVIPSHOME}/src && make && make install

RUN useradd -m -s /bin/bash ruby
RUN chown -R ruby:ruby /opt/ruby

USER ruby
WORKDIR ${KAKADUVIPSHOME}

# Build with: docker build . -t sul-dlss/kakadu-vips:latest
# Build and run: docker run --rm -it $(docker build -q .)
# Test with: vips kakaduload church.jp2 x.jpg
jcupitt commented 1 month ago

Hello @justinlittman, I'll see if I can reproduce this on my mac mini.

jcupitt commented 1 month ago

I think I found the problem. You can use VIPS_INFO to see a debug log of startup:

root@3ed5c16d2f39:~# VIPS_INFO=1 vips kakaduload
VIPS-INFO: 11:37:11.372: VIPSHOME = /opt/vips
VIPS-INFO: 11:37:11.372: VIPS_PREFIX = /usr/local
VIPS-INFO: 11:37:11.372: VIPS_LIBDIR = /usr/local/lib/aarch64-linux-gnu
VIPS-INFO: 11:37:11.372: prefix = /opt/vips
VIPS-INFO: 11:37:11.372: libdir = /opt/vips/aarch64-linux-gnu
VIPS-INFO: 11:37:11.373: searching "/opt/vips/aarch64-linux-gnu/vips-modules-8.15"
VIPS-INFO: 11:37:11.373: searching "/opt/vips/aarch64-linux-gnu/vips-plugins-8.15"
VIPS-INFO: 11:37:11.373: im_load_plugins: searching "/opt/vips/aarch64-linux-gnu/vips-8.15"
VIPS-INFO: 11:37:11.373: im_load_plugins: searching "/opt/vips/aarch64-linux-gnu"
vips: unknown action "kakaduload"

So your VIPSHOME setting is making libvips look for plugins there. If I unset that, it seems to work:

root@3ed5c16d2f39:~# unset VIPSHOME
root@3ed5c16d2f39:~# vips kakaduload
load JPEG2000 image
usage:
   kakaduload filename out [--option-name option-value ...]
where:
   filename     - Filename to load from, input gchararray
   out          - Output image, output VipsImage
optional arguments:
   page         - Load this page from the image, input gint
            default: 0
            min: 0, max: 100000
   flags        - Flags for this file, output VipsForeignFlags
            default flags: 
            allowed flags: none, partial, bigendian, sequential, all
   memory       - Force open via memory, input gboolean
            default: false
   access       - Required access pattern for this file, input VipsAccess
            default enum: random
            allowed enums: random, sequential, sequential-unbuffered
   fail-on      - Error level to fail on, input VipsFailOn
            default enum: none
            allowed enums: none, truncated, error, warning
   revalidate   - Don't use a cached result for this operation, input gboolean
            default: false
operation flags: untrusted 
jcupitt commented 1 month ago

I think I would not use /opt or /kakadu-vips -- I'd just put everything into /usr/local, with eg. /usr/local/src/kakadu-vips and /usr/local/src/vips for the build areas.

jcupitt commented 1 month ago

... I should have said, libvips is a relocatable package, meaning you can build to one prefix, but then run at another. At runtime, it'll normally look for data files in the compile prefix (like all linux packages), but if the VIPSHOME env var is set, it'll look there instead.

Anyway, either don't define VIPSHOME (call it eg. VIPS_HOME instead), or if you do set VIPSHOME, make sure that it's set to the install prefix.

justinlittman commented 1 month ago

That did it! And thanks for the additional tips.