Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement: add support for libvips compiled with support for Radiance #3544

Open
sb55555 opened this issue Feb 2, 2023 · 1 comment
Open

Comments

@sb55555
Copy link

sb55555 commented Feb 2, 2023

System:
OS: Linux 5.15 Amazon Linux 2
CPU: (8) x64 Intel(R) Core(TM) i7-8650U CPU @ 1.90GHz
Memory: 7.44 GB / 15.53 GB
Container: Yes
Shell: 4.2.46 - /bin/bash
Binaries:
Node: 16.18.1 - /var/lang/bin/node
npm: 8.19.2 - /var/lang/bin/npm
npmPackages:
sharp: ^0.31.3 => 0.31.3

What are the steps to reproduce?

index.js

'use strict';

const sharp = require('sharp');
const util = require('util');

const run = async () => {
  console.log('sharp.format', util.inspect(sharp.format, false, null, true));
  console.log('sharp.versions', util.inspect(sharp.versions, false, null, true));
  console.log('sharp.vendor', util.inspect(sharp.vendor, false, null, true));

  // perform the resize operation
  const buffer = await sharp('vestibule_4k.hdr')
    .resize(256, 256)
    .toBuffer();
};

run();

Run the below Dockerfile with docker build -t dev-lambda . --progress plain --no-cache

Dockerfile

FROM amazon/aws-lambda-nodejs:16
# FROM amazonlinux:2

ARG BUILD_DIR="/var/build"
ARG FUNCTION_DIR="/var/task"
ARG VERSION_VIPS=8.14.1

RUN \
  yum -q -y groupinstall "Development Tools"

RUN \
  yum -q -y install \
    nano \
    cmake3 \
    wget \
    gobject-introspection-devel \
    glib2-devel \
    expat-devel \
    orc-devel \
    lcms2-devel \
    libexif-devel \
    libgsf-devel \
    libjpeg-turbo-devel \
    libpng-devel \
    giflib-devel \
    libwebp-devel \
    fftw-devel \
    libtiff-devel \
    ImageMagick-devel \
  && ln -s /usr/bin/cmake3 /usr/bin/cmake

RUN \
  pip3 install \
    meson \
    ninja

# Install awscli
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" -s
RUN unzip -q awscliv2.zip
RUN ./aws/install

# Create build directory
RUN mkdir -p ${BUILD_DIR}

RUN \
  cd ${BUILD_DIR} \
  && wget https://github.com/libvips/libvips/archive/refs/tags/v${VERSION_VIPS}.tar.gz \
  && tar xf v${VERSION_VIPS}.tar.gz

RUN \
  cd ${BUILD_DIR}/libvips-${VERSION_VIPS} \
  && meson setup build-dir \
      --buildtype=release \
      -Dexamples=false \
  && cd build-dir \
  && ninja \
  && ninja install \
  && ln -s /usr/local/lib64/libvips-cpp.so.42 /usr/lib64/libvips-cpp.so.42 \
  && ln -s /usr/local/lib64/libvips.so.42 /usr/lib64/libvips.so.42

# Create function directory
RUN mkdir -p ${FUNCTION_DIR}

# Copy handler function
COPY index.js ${FUNCTION_DIR}

RUN cd ${FUNCTION_DIR} && npm init -f -y \
     && PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig npm install --verbose --foreground-scripts sharp aws-sdk

CMD [ "index.handler" ]

What is the expected behaviour?

With a custom build of libvips that enables Rad (Radiance HDR), I expect sharp to be able to resize .hdr files.

Libvips installs says that Radiance HDR is enabled
#13 12.96 enable RAD load/save : YES

#13 12.96 vips 8.14.1
#13 12.96 
#13 12.96   Build options
#13 12.96     enable debug                      : NO
#13 12.96     enable deprecated                 : YES
#13 12.96     enable modules                    : YES
#13 12.96     enable gtk-doc                    : NO
#13 12.96     enable doxygen                    : NO
#13 12.96     enable introspection              : YES
#13 12.96     enable examples                   : NO
#13 12.96     enable cplusplus                  : YES
#13 12.96     enable RAD load/save              : YES
#13 12.96     enable Analyze7 load/save         : YES
#13 12.96     enable PPM load/save              : YES
#13 12.96     enable GIF load                   : YES
#13 12.96 
#13 12.96   Optional external packages
#13 12.96     use fftw for FFTs                 : YES
#13 12.96     accelerate loops with ORC         : YES
#13 12.96     ICC profile support with lcms     : YES
#13 12.96     zlib                              : YES
#13 12.96     text rendering with pangocairo    : NO
#13 12.96     font file support with fontconfig : NO
#13 12.96     EXIF metadata support with libexif: YES
#13 14.19 
#13 14.19   External image format libraries
#13 14.19     JPEG load/save with libjpeg       : YES
#13 14.19     JXL load/save with libjxl         : NO (dynamic module: NO)
#13 14.19     JPEG2000 load/save with OpenJPEG  : NO
#13 14.19     PNG load/save with libspng        : NO
#13 14.19     PNG load/save with libpng         : YES
#13 14.19     selected quantisation package     : none
#13 14.19     TIFF load/save with libtiff       : YES
#13 14.19     image pyramid save with libgsf    : YES
#13 14.19     HEIC/AVIF load/save with libheif  : NO (dynamic module: NO)
#13 14.19     WebP load/save with libwebp       : NO
#13 14.19     PDF load with PDFium              : NO
#13 14.19     PDF load with poppler-glib        : NO (dynamic module: NO)
#13 14.19     SVG load with librsvg             : NO
#13 14.19     EXR load with OpenEXR             : NO
#13 14.19     OpenSlide load                    : NO (dynamic module: NO)
#13 14.19     Matlab load with libmatio         : NO
#13 14.19     NIfTI load/save with niftiio      : NO
#13 14.19     FITS load/save with cfitsio       : NO
#13 14.19     GIF save with cgif                : NO
#13 14.19     selected Magick package           : MagickCore (dynamic module: YES)
#13 14.19     Magick API version                : magick6
#13 14.19     Magick load                       : YES
#13 14.19     Magick save                       : YES
#13 14.19 
#13 14.19   User defined options
#13 14.19     buildtype                         : release
#13 14.19     examples                          : false
#13 14.19 

sharp build from source says that local libvips is found

#17 10.48 > [email protected] install
#17 10.48 > (node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)
#17 10.48 
#17 10.72 sharp: Detected globally-installed libvips v8.14.1
#17 10.72 sharp: Building from source via node-gyp

Im able to resize a Radiance HDR with vips cmdline

docker run -it --entrypoint "/bin/bash" --rm dev-lambda
wget https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/4k/vestibule_4k.hdr
vips resize vestibule_4k.hdr vestibule_256.hdr 0.125

but sharp raises an error

node index.js 
bash-4.2# node index.js 
sharp.format {
  jpeg: {
    id: 'jpeg',
    input: {
      file: true,
      buffer: true,
      stream: true,
      fileSuffix: [ '.jpg', '.jpeg', '.jpe' ]
    },
    output: { file: true, buffer: true, stream: true, alias: [ 'jpe', 'jpg' ] }
  },
  png: {
    id: 'png',
    input: { file: true, buffer: true, stream: true, fileSuffix: [ '.png' ] },
    output: { file: true, buffer: true, stream: true }
  },
  webp: {
    id: 'webp',
    input: { file: false, buffer: false, stream: false },
    output: { file: false, buffer: false, stream: false }
  },
  tiff: {
    id: 'tiff',
    input: {
      file: true,
      buffer: true,
      stream: true,
      fileSuffix: [ '.tif', '.tiff' ]
    },
    output: { file: true, buffer: true, stream: true, alias: [ 'tif' ] }
  },
  magick: {
    id: 'magick',
    input: { file: true, buffer: true, stream: true },
    output: { file: true, buffer: true, stream: true }
  },
  openslide: {
    id: 'openslide',
    input: { file: false, buffer: false, stream: false },
    output: { file: false, buffer: false, stream: false }
  },
  dz: {
    id: 'dz',
    input: { file: false, buffer: false, stream: false },
    output: { file: true, buffer: true, stream: true }
  },
  ppm: {
    id: 'ppm',
    input: {
      file: true,
      buffer: false,
      stream: false,
      fileSuffix: [ '.pbm', '.pgm', '.ppm', '.pfm', '.pnm' ]
    },
    output: { file: true, buffer: false, stream: false }
  },
  fits: {
    id: 'fits',
    input: { file: false, buffer: false, stream: false },
    output: { file: false, buffer: false, stream: false }
  },
  gif: {
    id: 'gif',
    input: { file: true, buffer: true, stream: true, fileSuffix: [ '.gif' ] },
    output: { file: false, buffer: false, stream: false }
  },
  svg: {
    id: 'svg',
    input: { file: false, buffer: false, stream: false },
    output: { file: false, buffer: false, stream: false }
  },
  heif: {
    id: 'heif',
    input: { file: false, buffer: false, stream: false },
    output: {
      file: false,
      buffer: false,
      stream: false,
      alias: [ 'avif', 'heic' ]
    }
  },
  pdf: {
    id: 'pdf',
    input: { file: false, buffer: false, stream: false },
    output: { file: false, buffer: false, stream: false }
  },
  vips: {
    id: 'vips',
    input: {
      file: true,
      buffer: false,
      stream: false,
      fileSuffix: [ '.v', '.vips' ]
    },
    output: { file: true, buffer: false, stream: false }
  },
  jp2k: {
    id: 'jp2k',
    input: { file: false, buffer: false, stream: false },
    output: {
      file: false,
      buffer: false,
      stream: false,
      alias: [ 'j2c', 'j2k', 'jp2', 'jpx' ]
    }
  },
  jxl: {
    id: 'jxl',
    input: { file: false, buffer: false, stream: false },
    output: { file: false, buffer: false, stream: false }
  },
  raw: {
    id: 'raw',
    input: { file: false, buffer: true, stream: true },
    output: { file: false, buffer: true, stream: true }
  }
}
sharp.versions { vips: '8.14.1' }
sharp.vendor { current: 'linux-x64', installed: [] }
node:internal/process/promises:279
            triggerUncaughtException(err, true /* fromPromise */);
            ^

[Error: Input file contains unsupported image format]
@sb55555 sb55555 added the triage label Feb 2, 2023
@lovell lovell added enhancement and removed triage labels Feb 2, 2023
@lovell lovell changed the title HDR Support with custom libvips "Input buffer contains unsupported image format" error Enhancement: add support for libvips compiled with support for Radiance Feb 2, 2023
@lovell
Copy link
Owner

lovell commented Feb 2, 2023

I don't think the radload feature is supported at present so we'd need to add it.

Happy to accept a PR, if you're able.

The ImageTypeId function and loaderToType map are a couple of places we'd need to do this for Radiance input.

std::string ImageTypeId(ImageType const imageType) {

std::map<std::string, ImageType> loaderToType = {

For Radiance output, we would need some custom saving logic; perhaps look at the jp2 code for guidance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants