lovell / lovell/sharp

Enhancement: add support for libvips compiled with support for Radiance

Open
#3,544 3 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement help wanted
Dominant language
JavaScript
Stars
32.7k
Forks
1.4k
Avg merge
1d 14h
Merged PRs (30d)
5

Description

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
```javascript
'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
```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 > sharp@0.31.3 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]
```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with index.js and the reported sharp.format output, then trace how the locally detected libvips build is exposed during sharp installation; the install output mentions install/libvips and node-gyp. Verify the behavior against the Dockerfile’s custom libvips setup and HDR resize command; done means a .hdr input can be resized through sharp instead of being reported as unsupported.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs
Domain
backend, computer-vision
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.