diff --git a/README.md b/README.md index 3f9aaf06..211c34c9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # sharp The typical use case for this high speed Node.js module -is to convert large images of many formats to +is to convert large images in common formats to smaller, web-friendly JPEG, PNG and WebP images of varying dimensions. Resizing an image is typically 4x faster than using the diff --git a/binding.gyp b/binding.gyp index 78770753..2f85ff31 100644 --- a/binding.gyp +++ b/binding.gyp @@ -132,23 +132,33 @@ '<(module_root_dir)/lib/libglib-2.0.so', '<(module_root_dir)/lib/libgobject-2.0.so', # Dependencies of dependencies, included for openSUSE support - '<(module_root_dir)/lib/libGraphicsMagick.so', - '<(module_root_dir)/lib/libGraphicsMagickWand.so', + '<(module_root_dir)/lib/libcairo.so', + '<(module_root_dir)/lib/libcroco-0.6.so', '<(module_root_dir)/lib/libexif.so', + '<(module_root_dir)/lib/libffi.so', + '<(module_root_dir)/lib/libfontconfig.so', + '<(module_root_dir)/lib/libfreetype.so', + '<(module_root_dir)/lib/libgdk_pixbuf-2.0.so', + '<(module_root_dir)/lib/libgif.so', '<(module_root_dir)/lib/libgio-2.0.so', '<(module_root_dir)/lib/libgmodule-2.0.so', '<(module_root_dir)/lib/libgsf-1.so', + '<(module_root_dir)/lib/libgthread-2.0.so', + '<(module_root_dir)/lib/libharfbuzz.so', '<(module_root_dir)/lib/libjpeg.so', + '<(module_root_dir)/lib/liblcms2.so', + '<(module_root_dir)/lib/liborc-0.4.so', + '<(module_root_dir)/lib/libpango-1.0.so', + '<(module_root_dir)/lib/libpangocairo-1.0.so', + '<(module_root_dir)/lib/libpangoft2-1.0.so', + '<(module_root_dir)/lib/libpixman-1.so', '<(module_root_dir)/lib/libpng.so', + '<(module_root_dir)/lib/libpng16.so', + '<(module_root_dir)/lib/librsvg-2.so', '<(module_root_dir)/lib/libtiff.so', '<(module_root_dir)/lib/libwebp.so', - '<(module_root_dir)/lib/libz.so', - '<(module_root_dir)/lib/libffi.so', - '<(module_root_dir)/lib/libgthread-2.0.so', - '<(module_root_dir)/lib/liblcms2.so', - '<(module_root_dir)/lib/libpng16.so', '<(module_root_dir)/lib/libxml2.so', - '<(module_root_dir)/lib/liborc-0.4.so', + '<(module_root_dir)/lib/libz.so', # Ensure runtime linking is relative to sharp.node '-Wl,-rpath=\'$${ORIGIN}/../../lib\'' ] @@ -199,12 +209,11 @@ 'destination': '<(module_root_dir)/build/Release', 'files': [ '<(module_root_dir)/lib/GNU.Gettext.dll', - '<(module_root_dir)/lib/libMagickCore-6.Q16-2.dll', - '<(module_root_dir)/lib/libMagickWand-6.Q16-2.dll', '<(module_root_dir)/lib/libasprintf-0.dll', '<(module_root_dir)/lib/libcairo-2.dll', '<(module_root_dir)/lib/libcairo-gobject-2.dll', '<(module_root_dir)/lib/libcairo-script-interpreter-2.dll', + '<(module_root_dir)/lib/libcroco-0.6-3.dll', '<(module_root_dir)/lib/libexif-12.dll', '<(module_root_dir)/lib/libexpat-1.dll', '<(module_root_dir)/lib/libffi-6.dll', @@ -213,6 +222,7 @@ '<(module_root_dir)/lib/libfreetype-6.dll', '<(module_root_dir)/lib/libgcc_s_seh-1.dll', '<(module_root_dir)/lib/libgdk_pixbuf-2.0-0.dll', + '<(module_root_dir)/lib/libgif-4.dll', '<(module_root_dir)/lib/libgio-2.0-0.dll', '<(module_root_dir)/lib/libglib-2.0-0.dll', '<(module_root_dir)/lib/libgmodule-2.0-0.dll', @@ -222,18 +232,18 @@ '<(module_root_dir)/lib/libintl-8.dll', '<(module_root_dir)/lib/libjpeg-62.dll', '<(module_root_dir)/lib/liblcms2-2.dll', - '<(module_root_dir)/lib/libopenjp2.dll', - '<(module_root_dir)/lib/libopenslide-0.dll', '<(module_root_dir)/lib/libpango-1.0-0.dll', '<(module_root_dir)/lib/libpangocairo-1.0-0.dll', '<(module_root_dir)/lib/libpangowin32-1.0-0.dll', '<(module_root_dir)/lib/libpixman-1-0.dll', '<(module_root_dir)/lib/libpng16-16.dll', '<(module_root_dir)/lib/libquadmath-0.dll', - '<(module_root_dir)/lib/libsqlite3-0.dll', + '<(module_root_dir)/lib/librsvg-2-2.dll', '<(module_root_dir)/lib/libssp-0.dll', + '<(module_root_dir)/lib/libstdc++-6.dll', '<(module_root_dir)/lib/libtiff-5.dll', '<(module_root_dir)/lib/libvips-42.dll', + '<(module_root_dir)/lib/libwebp-6.dll', '<(module_root_dir)/lib/libxml2-2.dll', '<(module_root_dir)/lib/zlib1.dll' ] diff --git a/docs/api.md b/docs/api.md index 519953bc..9e20e22e 100644 --- a/docs/api.md +++ b/docs/api.md @@ -13,7 +13,7 @@ Constructor to which further methods are chained. `input`, if present, can be one of: * Buffer containing JPEG, PNG, WebP, GIF, SVG, TIFF or raw pixel image data, or -* String containing the path to an image file, with most major formats supported. +* String containing the path to an JPEG, PNG, WebP, GIF, SVG or TIFF image file. JPEG, PNG, WebP, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when `input` is `null` or `undefined`. @@ -57,7 +57,7 @@ Fast access to image metadata without decoding any compressed image data. `callback`, if present, gets the arguments `(err, metadata)` where `metadata` has the attributes: -* `format`: Name of decoder to be used to decompress image data e.g. `jpeg`, `png`, `webp` (for file-based input additionally `tiff`, `magick`, `openslide`, `ppm`, `fits`) +* `format`: Name of decoder used to decompress image data e.g. `jpeg`, `png`, `webp`, `gif`, `svg` * `width`: Number of pixels wide * `height`: Number of pixels high * `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `scrgb`, `cmyk`, `lab`, `xyz`, `b-w` [...](https://github.com/jcupitt/libvips/blob/master/libvips/iofuncs/enumtypes.c#L522) @@ -615,9 +615,6 @@ for example: tiff: { id: 'tiff', input: { file: true, buffer: true, stream: true }, output: { file: true, buffer: false, stream: false } }, - magick: { id: 'magick', - input: { file: true, buffer: true, stream: true }, - output: { file: false, buffer: false, stream: false } }, raw: { id: 'raw', input: { file: false, buffer: false, stream: false }, output: { file: false, buffer: true, stream: true } } } @@ -641,22 +638,7 @@ sharp.queue.on('change', function(queueLength) { An Object containing the version numbers of libvips and, on Linux, its dependencies. ```javascript -> console.log(sharp.versions); - -{ zlib: '1.2.8', - ffi: '3.2.1', - glib: '2.46.2', - xml: '2.9.2', - gsf: '1.14.34', - exif: '0.6.21', - jpeg: '1.4.2', - png: '1.6.19', - lcms: '2.7', - webp: '0.4.4', - tiff: '4.0.6', - magick: '6.9.2-6', - orc: '0.4.24', - vips: '8.1.1' } +console.log(sharp.versions); ``` ### Utilities diff --git a/docs/changelog.md b/docs/changelog.md index d53e6be9..0731a456 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -3,6 +3,8 @@ ### v0.15 - "*outfit*" * Take advantage of libvips 8.3 features. + Add support for libvips' new native loaders, including GIF and SVG. + Pre-built binaries now include giflib and librsvg, exclude *magick. Use shrink-on-load for WebP input. Break existing sharpen API to accept sigma and improve precision. [#369](https://github.com/lovell/sharp/issues/369) diff --git a/docs/index.md b/docs/index.md index 6a321ae0..ee8f5866 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,7 +1,7 @@ # sharp The typical use case for this high speed Node.js module -is to convert large images of many formats to +is to convert large images in common formats to smaller, web-friendly JPEG, PNG and WebP images of varying dimensions. Resizing an image is typically 4x faster than using the @@ -23,8 +23,7 @@ to install the libvips dependency. ### Formats -This module supports reading JPEG, PNG, WebP, TIFF, OpenSlide, -GIF and most other libmagick-supported formats. +This module supports reading JPEG, PNG, WebP, TIFF, GIF and SVG images. Output images can be in JPEG, PNG and WebP formats as well as uncompressed raw pixel data. diff --git a/docs/install.md b/docs/install.md index 20de7e8b..aa2703db 100644 --- a/docs/install.md +++ b/docs/install.md @@ -6,7 +6,7 @@ npm install sharp ### Prerequisites -* C++11 compatible compiler such as gcc 4.6+ (Node v4+ requires gcc 4.8+), clang 3.0+ or MSVC 2013 +* C++11 compatible compiler such as gcc 4.8+, clang 3.0+ or MSVC 2013+ * [node-gyp](https://github.com/TooTallNate/node-gyp#installation) ### Linux @@ -15,12 +15,12 @@ npm install sharp [![Linux Build Status](https://circleci.com/gh/lovell/sharp.svg?style=svg&circle-token=6cb6d1d287a51af83722b19ed8885377fbc85e5c)](https://circleci.com/gh/lovell/sharp) libvips and its dependencies are fetched and stored within `node_modules/sharp/lib` during `npm install`. -This involves an automated HTTPS download of approximately 6MB. +This involves an automated HTTPS download of approximately 7MB. Most recent Linux-based operating systems with glibc running on x64 and ARMv6+ CPUs should "just work", e.g.: * Debian 7, 8 -* Ubuntu 12.04, 14.04, 14.10, 15.04, 15.10 +* Ubuntu 12.04, 14.04, 15.04, 15.10, 16.04 * Centos 7 * Fedora 21, 22, 23 * openSUSE 13.2 @@ -69,10 +69,10 @@ This can be achieved via homebrew: brew install homebrew/science/vips ``` -For GIF input and WebP output suppport use: +For WebP suppport use: ```sh -brew install homebrew/science/vips --with-imagemagick --with-webp +brew install homebrew/science/vips --with-webp ``` A missing or incorrectly configured _Xcode Command Line Tools_ installation @@ -93,7 +93,6 @@ libvips and its dependencies are fetched and stored within `node_modules\sharp` This involves an automated HTTPS download of approximately 9MB. Only 64-bit (x64) `node.exe` is supported. -The WebP format is currently unavailable on Windows. ### FreeBSD diff --git a/package.json b/package.json index 654e8c24..1877a711 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sharp", - "version": "0.14.1", + "version": "0.15.0", "author": "Lovell Fuller ", "contributors": [ "Pierre Inglebert ", @@ -73,7 +73,7 @@ }, "license": "Apache-2.0", "config": { - "libvips": "8.2.3" + "libvips": "8.3.0" }, "engines": { "node": ">=0.10" diff --git a/packaging/build.sh b/packaging/build.sh index 2d8d619a..9cc4bca4 100755 --- a/packaging/build.sh +++ b/packaging/build.sh @@ -1,6 +1,6 @@ #!/bin/sh -VERSION_VIPS=8.2.3 +VERSION_VIPS=8.3.0 # Is docker available? @@ -9,7 +9,7 @@ if ! type docker >/dev/null; then exit 1 fi -# TODO: docker v1.9.0 will allow build-time args - https://github.com/docker/docker/pull/15182 +# TODO: docker v1.9.0 allows build-time args - https://github.com/docker/docker/pull/15182 # Windows diff --git a/packaging/lin/Dockerfile b/packaging/lin/Dockerfile index c057e4a2..12206772 100644 --- a/packaging/lin/Dockerfile +++ b/packaging/lin/Dockerfile @@ -10,28 +10,40 @@ ENV DEPS=/deps \ RUN mkdir ${DEPS} && mkdir ${TARGET} # Common build paths and flags -ENV PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:${TARGET}/lib/pkgconfig \ - PATH=${PATH}:${TARGET}/bin \ - CPPFLAGS=-I${TARGET}/include \ - LDFLAGS=-L${TARGET}/lib \ +ENV PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${TARGET}/lib/pkgconfig" \ + PATH="${PATH}:${TARGET}/bin" \ + CPPFLAGS="-I${TARGET}/include" \ + LDFLAGS="-L${TARGET}/lib" \ CFLAGS="-O3" \ CXXFLAGS="-O3" # Dependency version numbers ENV VERSION_ZLIB=1.2.8 \ VERSION_FFI=3.2.1 \ - VERSION_GLIB=2.47.6 \ + VERSION_GLIB=2.48.0 \ VERSION_XML2=2.9.3 \ - VERSION_GSF=1.14.34 \ + VERSION_GSF=1.14.36 \ VERSION_EXIF=0.6.21 \ VERSION_LCMS2=2.7 \ - VERSION_GM=1.3.23 \ - VERSION_JPEG=1.4.2 \ + VERSION_JPEG=1.4.90 \ VERSION_PNG16=1.6.21 \ VERSION_WEBP=0.5.0 \ VERSION_TIFF=4.0.6 \ VERSION_ORC=0.4.25 \ - VERSION_VIPS=8.2.3 + VERSION_GDKPIXBUF=2.34.0 \ + VERSION_FREETYPE=2.6.3 \ + VERSION_FONTCONFIG=2.11.95 \ + VERSION_HARFBUZZ=1.2.6 \ + VERSION_PIXMAN=0.34.0 \ + VERSION_CAIRO=1.14.6 \ + VERSION_PANGO=1.40.1 \ + VERSION_CROCO=0.6.11 \ + VERSION_SVG=2.40.15 \ + VERSION_GIF=5.1.4 \ + VERSION_VIPS=8.3.0 + +# Least out-of-sync Sourceforge mirror +ENV SOURCEFORGE_MIRROR=netix RUN mkdir ${DEPS}/zlib RUN curl -Ls http://zlib.net/zlib-${VERSION_ZLIB}.tar.xz | tar xJC ${DEPS}/zlib --strip-components=1 @@ -45,14 +57,18 @@ WORKDIR ${DEPS}/ffi RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --disable-builddir && make install-strip RUN mkdir ${DEPS}/glib -RUN curl -Ls https://download.gnome.org/sources/glib/2.47/glib-${VERSION_GLIB}.tar.xz | tar xJC ${DEPS}/glib --strip-components=1 +RUN curl -Ls https://download.gnome.org/sources/glib/2.48/glib-${VERSION_GLIB}.tar.xz | tar xJC ${DEPS}/glib --strip-components=1 WORKDIR ${DEPS}/glib -RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --with-pcre=internal && make install-strip +RUN CFLAGS="${CFLAGS} -Wl,--default-symver" CXXFLAGS="${CXXFLAGS} -Wl,--default-symver" \ + ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --with-pcre=internal && make install-strip RUN mkdir ${DEPS}/xml2 RUN curl -Ls http://xmlsoft.org/sources/libxml2-${VERSION_XML2}.tar.gz | tar xzC ${DEPS}/xml2 --strip-components=1 WORKDIR ${DEPS}/xml2 -RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-python --with-zlib=${TARGET} && make install-strip +RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \ + --without-python --without-debug --without-docbook --without-ftp --without-html --without-legacy \ + --without-pattern --without-push --without-regexps --without-schemas --without-schematron --with-zlib=${TARGET} \ + && make install-strip RUN mkdir ${DEPS}/gsf RUN curl -Ls https://download.gnome.org/sources/libgsf/1.14/libgsf-${VERSION_GSF}.tar.xz | tar xJC ${DEPS}/gsf --strip-components=1 @@ -60,27 +76,22 @@ WORKDIR ${DEPS}/gsf RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip RUN mkdir ${DEPS}/exif -RUN curl -Ls http://heanet.dl.sourceforge.net/project/libexif/libexif/${VERSION_EXIF}/libexif-${VERSION_EXIF}.tar.bz2 | tar xjC ${DEPS}/exif --strip-components=1 +RUN curl -Ls http://${SOURCEFORGE_MIRROR}.dl.sourceforge.net/project/libexif/libexif/${VERSION_EXIF}/libexif-${VERSION_EXIF}.tar.bz2 | tar xjC ${DEPS}/exif --strip-components=1 WORKDIR ${DEPS}/exif RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip RUN mkdir ${DEPS}/lcms2 -RUN curl -Ls http://heanet.dl.sourceforge.net/project/lcms/lcms/${VERSION_LCMS2}/lcms2-${VERSION_LCMS2}.tar.gz | tar xzC ${DEPS}/lcms2 --strip-components=1 +RUN curl -Ls http://${SOURCEFORGE_MIRROR}.dl.sourceforge.net/project/lcms/lcms/${VERSION_LCMS2}/lcms2-${VERSION_LCMS2}.tar.gz | tar xzC ${DEPS}/lcms2 --strip-components=1 WORKDIR ${DEPS}/lcms2 RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip -RUN mkdir ${DEPS}/gm -RUN curl -Ls http://heanet.dl.sourceforge.net/project/graphicsmagick/graphicsmagick/${VERSION_GM}/GraphicsMagick-${VERSION_GM}.tar.xz | tar xJC ${DEPS}/gm --strip-components=1 -WORKDIR ${DEPS}/gm -RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --without-magick-plus-plus && make install-strip - RUN mkdir ${DEPS}/jpeg -RUN curl -Ls http://heanet.dl.sourceforge.net/project/libjpeg-turbo/${VERSION_JPEG}/libjpeg-turbo-${VERSION_JPEG}.tar.gz | tar xzC ${DEPS}/jpeg --strip-components=1 +RUN curl -Ls https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${VERSION_JPEG}.tar.gz | tar xzC ${DEPS}/jpeg --strip-components=1 WORKDIR ${DEPS}/jpeg -RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --with-jpeg8 --without-turbojpeg && make install-strip +RUN autoreconf -fiv && ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --with-jpeg8 --without-turbojpeg && make install-strip RUN mkdir ${DEPS}/png16 -RUN curl -Ls http://heanet.dl.sourceforge.net/project/libpng/libpng16/${VERSION_PNG16}/libpng-${VERSION_PNG16}.tar.xz | tar xJC ${DEPS}/png16 --strip-components=1 +RUN curl -Ls http://${SOURCEFORGE_MIRROR}.dl.sourceforge.net/project/libpng/libpng16/${VERSION_PNG16}/libpng-${VERSION_PNG16}.tar.xz | tar xJC ${DEPS}/png16 --strip-components=1 WORKDIR ${DEPS}/png16 RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip @@ -99,12 +110,74 @@ RUN mkdir ${DEPS}/orc RUN curl -Ls http://gstreamer.freedesktop.org/data/src/orc/orc-${VERSION_ORC}.tar.xz | tar xJC ${DEPS}/orc --strip-components=1 WORKDIR ${DEPS}/orc RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip +RUN rm ${TARGET}/lib/liborc-test-* + +RUN mkdir ${DEPS}/gdkpixbuf +RUN curl -Ls https://download.gnome.org/sources/gdk-pixbuf/2.34/gdk-pixbuf-${VERSION_GDKPIXBUF}.tar.xz | tar xJC ${DEPS}/gdkpixbuf --strip-components=1 +WORKDIR ${DEPS}/gdkpixbuf +RUN LD_LIBRARY_PATH=${TARGET}/lib ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \ + --disable-introspection --disable-modules --without-libpng --without-libjpeg --without-libtiff --without-gdiplus --with-included-loaders= \ + && make install-strip + +RUN mkdir ${DEPS}/freetype +RUN curl -Ls http://download.savannah.gnu.org/releases/freetype/freetype-${VERSION_FREETYPE}.tar.gz | tar xzC ${DEPS}/freetype --strip-components=1 +WORKDIR ${DEPS}/freetype +RUN ./configure --prefix=${TARGET} --enable-shared --disable-static && make install + +RUN mkdir ${DEPS}/fontconfig +RUN curl -Ls https://www.freedesktop.org/software/fontconfig/release/fontconfig-${VERSION_FONTCONFIG}.tar.bz2 | tar xjC ${DEPS}/fontconfig --strip-components=1 +WORKDIR ${DEPS}/fontconfig +RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --enable-libxml2 && make install-strip + +RUN mkdir ${DEPS}/harfbuzz +RUN curl -Ls https://www.freedesktop.org/software/harfbuzz/release/harfbuzz-${VERSION_HARFBUZZ}.tar.bz2 | tar xjC ${DEPS}/harfbuzz --strip-components=1 +WORKDIR ${DEPS}/harfbuzz +RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip + +RUN mkdir ${DEPS}/pixman +RUN curl -Ls http://cairographics.org/releases/pixman-${VERSION_PIXMAN}.tar.gz | tar xzC ${DEPS}/pixman --strip-components=1 +WORKDIR ${DEPS}/pixman +RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking --disable-libpng && make install-strip + +RUN mkdir ${DEPS}/cairo +RUN curl -Ls http://cairographics.org/releases/cairo-${VERSION_CAIRO}.tar.xz | tar xJC ${DEPS}/cairo --strip-components=1 +WORKDIR ${DEPS}/cairo +RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \ + --disable-xlib --disable-xcb --disable-quartz --disable-win32 --disable-egl --disable-glx --disable-wgl \ + --disable-script --disable-ps --disable-gobject --disable-trace --disable-interpreter \ + && make install-strip + +RUN mkdir ${DEPS}/pango +RUN curl -Ls https://download.gnome.org/sources/pango/1.40/pango-${VERSION_PANGO}.tar.xz | tar xJC ${DEPS}/pango --strip-components=1 +WORKDIR ${DEPS}/pango +RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip + +RUN mkdir ${DEPS}/croco +RUN curl -Ls https://download.gnome.org/sources/libcroco/0.6/libcroco-${VERSION_CROCO}.tar.xz | tar xJC ${DEPS}/croco --strip-components=1 +WORKDIR ${DEPS}/croco +RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip + +RUN mkdir ${DEPS}/svg +RUN curl -Ls https://download.gnome.org/sources/librsvg/2.40/librsvg-${VERSION_SVG}.tar.xz | tar xJC ${DEPS}/svg --strip-components=1 +WORKDIR ${DEPS}/svg +RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \ + --disable-introspection --disable-tools \ + && make install-strip + +RUN mkdir ${DEPS}/gif +RUN curl -Ls http://${SOURCEFORGE_MIRROR}.dl.sourceforge.net/project/giflib/giflib-${VERSION_GIF}.tar.gz | tar xzC ${DEPS}/gif --strip-components=1 +WORKDIR ${DEPS}/gif +RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking && make install-strip RUN mkdir ${DEPS}/vips -RUN curl -Ls http://www.vips.ecs.soton.ac.uk/supported/8.2/vips-${VERSION_VIPS}.tar.gz | tar xzC ${DEPS}/vips --strip-components=1 +#RUN curl -Ls http://www.vips.ecs.soton.ac.uk/supported/8.3/vips-${VERSION_VIPS}.tar.gz | tar xzC ${DEPS}/vips --strip-components=1 +RUN apt-get install -y swig gobject-introspection gettext glib2.0-dev +RUN curl -Ls https://github.com/jcupitt/libvips/archive/master.tar.gz | tar xzC ${DEPS}/vips --strip-components=1 WORKDIR ${DEPS}/vips +RUN ./bootstrap.sh RUN ./configure --prefix=${TARGET} --enable-shared --disable-static --disable-dependency-tracking \ - --disable-debug --disable-introspection --without-python --without-fftw --with-magickpackage=GraphicsMagick \ + --disable-debug --disable-introspection --without-python --without-fftw \ + --without-magick --without-pangoft2 --without-ppm --without-analyze --without-radiance \ --with-zip-includes=${TARGET}/include --with-zip-libraries=${TARGET}/lib \ --with-jpeg-includes=${TARGET}/include --with-jpeg-libraries=${TARGET}/lib \ && make install-strip @@ -118,20 +191,29 @@ RUN rm -rf pkgconfig .libs *.la libvipsCC* # Create JSON file of version numbers WORKDIR ${TARGET} RUN echo "{\n\ + \"cairo\": \"${VERSION_CAIRO}\",\n\ + \"croco\": \"${VERSION_CROCO}\",\n\ \"exif\": \"${VERSION_EXIF}\",\n\ \"ffi\": \"${VERSION_FFI}\",\n\ + \"fontconfig\": \"${VERSION_FONTCONFIG}\",\n\ + \"freetype\": \"${VERSION_FREETYPE}\",\n\ + \"gdkpixbuf\": \"${VERSION_GDKPIXBUF}\",\n\ + \"gif\": \"${VERSION_GIF}\",\n\ \"glib\": \"${VERSION_GLIB}\",\n\ \"gsf\": \"${VERSION_GSF}\",\n\ + \"harfbuzz\": \"${VERSION_HARFBUZZ}\",\n\ \"jpeg\": \"${VERSION_JPEG}\",\n\ \"lcms\": \"${VERSION_LCMS2}\",\n\ - \"gm\": \"${VERSION_GM}\",\n\ \"orc\": \"${VERSION_ORC}\",\n\ + \"pango\": \"${VERSION_PANGO}\",\n\ + \"pixman\": \"${VERSION_PIXMAN}\",\n\ \"png\": \"${VERSION_PNG16}\",\n\ + \"svg\": \"${VERSION_SVG}\",\n\ \"tiff\": \"${VERSION_TIFF}\",\n\ - \"vips\": \"${VERSION_VIPS}\"\n\ + \"vips\": \"${VERSION_VIPS}\",\n\ \"webp\": \"${VERSION_WEBP}\",\n\ \"xml\": \"${VERSION_XML2}\",\n\ - \"zlib\": \"${VERSION_ZLIB}\",\n\ + \"zlib\": \"${VERSION_ZLIB}\"\n\ }" >lib/versions.json # Create .tar.gz diff --git a/packaging/win/Dockerfile b/packaging/win/Dockerfile index 07c49c9c..a63e4abb 100644 --- a/packaging/win/Dockerfile +++ b/packaging/win/Dockerfile @@ -3,18 +3,21 @@ MAINTAINER Lovell Fuller RUN apt-get update && apt-get install -y curl zip -ENV VERSION_VIPS=8.2.3 +ENV VERSION_VIPS=8.3.0 # Fetch and unzip RUN mkdir /vips WORKDIR /vips -RUN curl -O http://www.vips.ecs.soton.ac.uk/supported/8.2/win32/vips-dev-w64-8.2.zip -RUN unzip vips-dev-w64-8.2.zip +RUN curl -L -O https://github.com/lovell/build-win64/releases/download/v${VERSION_VIPS}/vips-dev-w64-web-8.3.zip +RUN unzip vips-dev-w64-web-8.3.zip # Clean and zip -WORKDIR /vips/vips-dev-8.2 -RUN rm bin/libvipsCC-42.dll bin/libvips-cpp-42.dll bin/libgsf-win32-1-114.dll bin/libstdc++-6.dll +WORKDIR /vips/vips-dev-8.3 +RUN rm bin/libvipsCC-42.dll bin/libvips-cpp-42.dll bin/libgsf-win32-1-114.dll RUN cp bin/*.dll lib/ RUN cp -r lib64/* lib/ +# Patch VImage8.h for MSVC support, can be removed with libvips v8.3.1+ +RUN curl -o include/vips/VImage8.h https://raw.githubusercontent.com/jcupitt/libvips/baa175c4c0f99201d436edd035d58bbb3471e489/cplusplus/include/vips/VImage8.h + RUN GZIP=-9 tar czf /libvips-${VERSION_VIPS}-win.tar.gz include lib/glib-2.0 lib/libvips.lib lib/libglib-2.0.lib lib/libgobject-2.0.lib lib/*.dll diff --git a/src/common.cc b/src/common.cc index 5af70e6a..0afe6a65 100644 --- a/src/common.cc +++ b/src/common.cc @@ -66,6 +66,9 @@ namespace sharp { case ImageType::PNG: id = "png"; break; case ImageType::WEBP: id = "webp"; break; case ImageType::TIFF: id = "tiff"; break; + case ImageType::GIF: id = "gif"; break; + case ImageType::SVG: id = "svg"; break; + case ImageType::PDF: id = "pdf"; break; case ImageType::MAGICK: id = "magick"; break; case ImageType::OPENSLIDE: id = "openslide"; break; case ImageType::PPM: id = "ppm"; break; @@ -92,6 +95,12 @@ namespace sharp { imageType = ImageType::WEBP; } else if (EndsWith(loader, "TiffBuffer")) { imageType = ImageType::TIFF; + } else if (EndsWith(loader, "GifBuffer")) { + imageType = ImageType::GIF; + } else if (EndsWith(loader, "SvgBuffer")) { + imageType = ImageType::SVG; + } else if (EndsWith(loader, "PdfBuffer")) { + imageType = ImageType::PDF; } else if (EndsWith(loader, "MagickBuffer")) { imageType = ImageType::MAGICK; } @@ -117,6 +126,12 @@ namespace sharp { imageType = ImageType::OPENSLIDE; } else if (EndsWith(loader, "TiffFile")) { imageType = ImageType::TIFF; + } else if (EndsWith(loader, "GifFile")) { + imageType = ImageType::GIF; + } else if (EndsWith(loader, "SvgFile")) { + imageType = ImageType::SVG; + } else if (EndsWith(loader, "PdfFile")) { + imageType = ImageType::PDF; } else if (EndsWith(loader, "Ppm")) { imageType = ImageType::PPM; } else if (EndsWith(loader, "Fits")) { diff --git a/src/common.h b/src/common.h index e2e3ce4e..41c02aed 100644 --- a/src/common.h +++ b/src/common.h @@ -11,16 +11,19 @@ using vips::VImage; namespace sharp { enum class ImageType { - UNKNOWN, JPEG, PNG, WEBP, TIFF, + GIF, + SVG, + PDF, MAGICK, OPENSLIDE, PPM, FITS, - RAW + RAW, + UNKNOWN }; // How many tasks are in the queue? diff --git a/src/libvips/cplusplus/VImage.cpp b/src/libvips/cplusplus/VImage.cpp index 26c06728..a2d8101f 100644 --- a/src/libvips/cplusplus/VImage.cpp +++ b/src/libvips/cplusplus/VImage.cpp @@ -711,4 +711,499 @@ VImage::maxpos( VOption *options ) return( std::complex( x, y ) ); } +// Operator overloads + +VImage +VImage::operator[]( int index ) +{ + return( this->extract_band( index ) ); +} + +std::vector +VImage::operator()( int x, int y ) +{ + return( this->getpoint( x, y ) ); +} + +VImage +operator+( VImage a, VImage b ) +{ + return( a.add( b ) ); +} + +VImage +operator+( double a, VImage b ) +{ + return( b.linear( 1.0, a ) ); +} + +VImage +operator+( VImage a, double b ) +{ + return( a.linear( 1.0, b ) ); +} + +VImage +operator+( std::vector a, VImage b ) +{ + return( b.linear( 1.0, a ) ); +} + +VImage +operator+( VImage a, std::vector b ) +{ + return( a.linear( 1.0, b ) ); +} + +VImage +operator-( VImage a, VImage b ) +{ + return( a.subtract( b ) ); +} + +VImage operator-( double a, VImage b ) +{ + return( b.linear( -1.0, a ) ); +} + +VImage +operator-( VImage a, double b ) +{ + return( a.linear( 1.0, -b ) ); +} + +VImage +operator-( std::vector a, VImage b ) +{ + return( b.linear( -1.0, a ) ); +} + +VImage +operator-( VImage a, std::vector b ) +{ + return( a.linear( 1.0, vips::negate( b ) ) ); +} + +VImage +operator-( VImage a ) +{ + return( a * -1 ); +} + +VImage +operator*( VImage a, VImage b ) +{ + return( a.multiply( b ) ); +} + +VImage +operator*( double a, VImage b ) +{ + return( b.linear( a, 0.0 ) ); +} + +VImage +operator*( VImage a, double b ) +{ + return( a.linear( b, 0.0 ) ); +} + +VImage +operator*( std::vector a, VImage b ) +{ + return( b.linear( a, 0.0 ) ); +} + +VImage +operator*( VImage a, std::vector b ) +{ + return( a.linear( b, 0.0 ) ); +} + +VImage +operator/( VImage a, VImage b ) +{ + return( a.divide( b ) ); +} + +VImage +operator/( double a, VImage b ) +{ + return( b.pow( -1.0 ).linear( a, 0.0 ) ); +} + +VImage +operator/( VImage a, double b ) +{ + return( a.linear( 1.0 / b, 0.0 ) ); +} + +VImage +operator/( std::vector a, VImage b ) +{ + return( b.pow( -1.0 ).linear( a, 0.0 ) ); +} + +VImage +operator/( VImage a, std::vector b ) +{ + return( a.linear( vips::invert( b ), 0.0 ) ); +} + +VImage +operator%( VImage a, VImage b ) +{ + return( a.remainder( b ) ); +} + +VImage +operator%( VImage a, double b ) +{ + return( a.remainder_const( to_vector( b ) ) ); +} + +VImage +operator%( VImage a, std::vector b ) +{ + return( a.remainder_const( b ) ); +} + +VImage +operator<( VImage a, VImage b ) +{ + return( a.relational( b, VIPS_OPERATION_RELATIONAL_LESS ) ); +} + +VImage +operator<( double a, VImage b ) +{ + return( b.relational_const( to_vector( a ), + VIPS_OPERATION_RELATIONAL_MORE ) ); +} + +VImage +operator<( VImage a, double b ) +{ + return( a.relational_const( to_vector( b ), + VIPS_OPERATION_RELATIONAL_LESS ) ); +} + +VImage +operator<( std::vector a, VImage b ) +{ + return( b.relational_const( a, + VIPS_OPERATION_RELATIONAL_MORE ) ); +} + +VImage +operator<( VImage a, std::vector b ) +{ + return( a.relational_const( b, + VIPS_OPERATION_RELATIONAL_LESS ) ); +} + +VImage +operator<=( VImage a, VImage b ) +{ + return( a.relational( b, VIPS_OPERATION_RELATIONAL_LESSEQ ) ); +} + +VImage +operator<=( double a, VImage b ) +{ + return( b.relational_const( to_vector( a ), + VIPS_OPERATION_RELATIONAL_MOREEQ ) ); +} + +VImage +operator<=( VImage a, double b ) +{ + return( a.relational_const( to_vector( b ), + VIPS_OPERATION_RELATIONAL_LESSEQ ) ); +} + +VImage +operator<=( std::vector a, VImage b ) +{ + return( b.relational_const( a, + VIPS_OPERATION_RELATIONAL_MOREEQ ) ); +} + +VImage +operator<=( VImage a, std::vector b ) +{ + return( a.relational_const( b, + VIPS_OPERATION_RELATIONAL_LESSEQ ) ); +} + +VImage +operator>( VImage a, VImage b ) +{ + return( a.relational( b, VIPS_OPERATION_RELATIONAL_MORE ) ); +} + +VImage +operator>( double a, VImage b ) +{ + return( b.relational_const( to_vector( a ), + VIPS_OPERATION_RELATIONAL_LESS ) ); +} + +VImage +operator>( VImage a, double b ) +{ + return( a.relational_const( to_vector( b ), + VIPS_OPERATION_RELATIONAL_MORE ) ); +} + +VImage +operator>( std::vector a, VImage b ) +{ + return( b.relational_const( a, + VIPS_OPERATION_RELATIONAL_LESS ) ); +} + +VImage +operator>( VImage a, std::vector b ) +{ + return( a.relational_const( b, + VIPS_OPERATION_RELATIONAL_MORE ) ); +} + +VImage +operator>=( VImage a, VImage b ) +{ + return( a.relational( b, VIPS_OPERATION_RELATIONAL_MOREEQ ) ); +} + +VImage +operator>=( double a, VImage b ) +{ + return( b.relational_const( to_vector( a ), + VIPS_OPERATION_RELATIONAL_LESSEQ ) ); +} + +VImage +operator>=( VImage a, double b ) +{ + return( a.relational_const( to_vector( b ), + VIPS_OPERATION_RELATIONAL_MOREEQ ) ); +} + +VImage +operator>=( std::vector a, VImage b ) +{ + return( b.relational_const( a, + VIPS_OPERATION_RELATIONAL_LESSEQ ) ); +} + +VImage +operator>=( VImage a, std::vector b ) +{ + return( a.relational_const( b, + VIPS_OPERATION_RELATIONAL_MOREEQ ) ); +} + +VImage +operator==( VImage a, VImage b ) +{ + return( a.relational( b, VIPS_OPERATION_RELATIONAL_EQUAL ) ); +} + +VImage +operator==( double a, VImage b ) +{ + return( b.relational_const( to_vector( a ), + VIPS_OPERATION_RELATIONAL_EQUAL ) ); +} + +VImage +operator==( VImage a, double b ) +{ + return( a.relational_const( to_vector( b ), + VIPS_OPERATION_RELATIONAL_EQUAL ) ); +} + +VImage +operator==( std::vector a, VImage b ) +{ + return( b.relational_const( a, + VIPS_OPERATION_RELATIONAL_EQUAL ) ); +} + +VImage +operator==( VImage a, std::vector b ) +{ + return( a.relational_const( b, + VIPS_OPERATION_RELATIONAL_EQUAL ) ); +} + +VImage +operator!=( VImage a, VImage b ) +{ + return( a.relational( b, VIPS_OPERATION_RELATIONAL_NOTEQ ) ); +} + +VImage +operator!=( double a, VImage b ) +{ + return( b.relational_const( to_vector( a ), + VIPS_OPERATION_RELATIONAL_NOTEQ ) ); +} + +VImage +operator!=( VImage a, double b ) +{ + return( a.relational_const( to_vector( b ), + VIPS_OPERATION_RELATIONAL_NOTEQ ) ); +} + +VImage +operator!=( std::vector a, VImage b ) +{ + return( b.relational_const( a, + VIPS_OPERATION_RELATIONAL_NOTEQ ) ); +} + +VImage +operator!=( VImage a, std::vector b ) +{ + return( a.relational_const( b, + VIPS_OPERATION_RELATIONAL_NOTEQ ) ); +} + +VImage +operator&( VImage a, VImage b ) +{ + return( a.boolean( b, VIPS_OPERATION_BOOLEAN_AND ) ); +} + +VImage +operator&( double a, VImage b ) +{ + return( b.boolean_const( to_vector( a ), + VIPS_OPERATION_BOOLEAN_AND ) ); +} + +VImage +operator&( VImage a, double b ) +{ + return( a.boolean_const( to_vector( b ), + VIPS_OPERATION_BOOLEAN_AND ) ); +} + +VImage +operator&( std::vector a, VImage b ) +{ + return( b.boolean_const( a, VIPS_OPERATION_BOOLEAN_AND ) ); +} + +VImage +operator&( VImage a, std::vector b ) +{ + return( a.boolean_const( b, VIPS_OPERATION_BOOLEAN_AND ) ); +} + +VImage +operator|( VImage a, VImage b ) +{ + return( a.boolean( b, VIPS_OPERATION_BOOLEAN_OR ) ); +} + +VImage +operator|( double a, VImage b ) +{ + return( b.boolean_const( to_vector( a ), + VIPS_OPERATION_BOOLEAN_OR ) ); +} + +VImage +operator|( VImage a, double b ) +{ + return( a.boolean_const( to_vector( b ), + VIPS_OPERATION_BOOLEAN_OR ) ); +} + +VImage +operator|( std::vector a, VImage b ) +{ + return( b.boolean_const( a, VIPS_OPERATION_BOOLEAN_OR ) ); +} + +VImage +operator|( VImage a, std::vector b ) +{ + return( a.boolean_const( b, VIPS_OPERATION_BOOLEAN_OR ) ); +} + +VImage +operator^( VImage a, VImage b ) +{ + return( a.boolean( b, VIPS_OPERATION_BOOLEAN_EOR ) ); +} + +VImage +operator^( double a, VImage b ) +{ + return( b.boolean_const( to_vector( a ), + VIPS_OPERATION_BOOLEAN_EOR ) ); +} + +VImage +operator^( VImage a, double b ) +{ + return( a.boolean_const( to_vector( b ), + VIPS_OPERATION_BOOLEAN_EOR ) ); +} + +VImage +operator^( std::vector a, VImage b ) +{ + return( b.boolean_const( a, VIPS_OPERATION_BOOLEAN_EOR ) ); +} + +VImage +operator^( VImage a, std::vector b ) +{ + return( a.boolean_const( b, VIPS_OPERATION_BOOLEAN_EOR ) ); +} + +VImage +operator<<( VImage a, VImage b ) +{ + return( a.boolean( b, VIPS_OPERATION_BOOLEAN_LSHIFT ) ); +} + +VImage +operator<<( VImage a, double b ) +{ + return( a.boolean_const( to_vector( b ), + VIPS_OPERATION_BOOLEAN_LSHIFT ) ); +} + +VImage +operator<<( VImage a, std::vector b ) +{ + return( a.boolean_const( b, VIPS_OPERATION_BOOLEAN_LSHIFT ) ); +} + +VImage +operator>>( VImage a, VImage b ) +{ + return( a.boolean( b, VIPS_OPERATION_BOOLEAN_RSHIFT ) ); +} + +VImage +operator>>( VImage a, double b ) +{ + return( a.boolean_const( to_vector( b ), + VIPS_OPERATION_BOOLEAN_RSHIFT ) ); +} + +VImage +operator>>( VImage a, std::vector b ) +{ + return( a.boolean_const( b, VIPS_OPERATION_BOOLEAN_RSHIFT ) ); +} + VIPS_NAMESPACE_END diff --git a/src/libvips/cplusplus/vips-operators.cpp b/src/libvips/cplusplus/vips-operators.cpp index e6c0ba57..257234ad 100644 --- a/src/libvips/cplusplus/vips-operators.cpp +++ b/src/libvips/cplusplus/vips-operators.cpp @@ -1,5 +1,5 @@ // bodies for vips operations -// Sat Jan 9 15:05:58 GMT 2016 +// Fri Feb 12 20:03:53 GMT 2016 // this file is generated automatically, do not edit! void VImage::system( char * cmd_format , VOption *options ) @@ -1408,6 +1408,78 @@ VImage VImage::vipsload( char * filename , VOption *options ) return( out ); } +VImage VImage::pdfload( char * filename , VOption *options ) +{ + VImage out; + + call( "pdfload" , + (options ? options : VImage::option()) -> + set( "filename", filename ) -> + set( "out", &out ) ); + + return( out ); +} + +VImage VImage::pdfload_buffer( VipsBlob * buffer , VOption *options ) +{ + VImage out; + + call( "pdfload_buffer" , + (options ? options : VImage::option()) -> + set( "buffer", buffer ) -> + set( "out", &out ) ); + + return( out ); +} + +VImage VImage::svgload( char * filename , VOption *options ) +{ + VImage out; + + call( "svgload" , + (options ? options : VImage::option()) -> + set( "filename", filename ) -> + set( "out", &out ) ); + + return( out ); +} + +VImage VImage::svgload_buffer( VipsBlob * buffer , VOption *options ) +{ + VImage out; + + call( "svgload_buffer" , + (options ? options : VImage::option()) -> + set( "buffer", buffer ) -> + set( "out", &out ) ); + + return( out ); +} + +VImage VImage::gifload( char * filename , VOption *options ) +{ + VImage out; + + call( "gifload" , + (options ? options : VImage::option()) -> + set( "filename", filename ) -> + set( "out", &out ) ); + + return( out ); +} + +VImage VImage::gifload_buffer( VipsBlob * buffer , VOption *options ) +{ + VImage out; + + call( "gifload_buffer" , + (options ? options : VImage::option()) -> + set( "buffer", buffer ) -> + set( "out", &out ) ); + + return( out ); +} + VImage VImage::pngload( char * filename , VOption *options ) { VImage out; @@ -1783,11 +1855,37 @@ VImage VImage::shrinkv( int yshrink , VOption *options ) return( out ); } -VImage VImage::shrink2( double xshrink , double yshrink , VOption *options ) +VImage VImage::reduceh( double xshrink , VOption *options ) { VImage out; - call( "shrink2" , + call( "reduceh" , + (options ? options : VImage::option()) -> + set( "in", *this ) -> + set( "out", &out ) -> + set( "xshrink", xshrink ) ); + + return( out ); +} + +VImage VImage::reducev( double yshrink , VOption *options ) +{ + VImage out; + + call( "reducev" , + (options ? options : VImage::option()) -> + set( "in", *this ) -> + set( "out", &out ) -> + set( "yshrink", yshrink ) ); + + return( out ); +} + +VImage VImage::reduce( double xshrink , double yshrink , VOption *options ) +{ + VImage out; + + call( "reduce" , (options ? options : VImage::option()) -> set( "in", *this ) -> set( "out", &out ) -> diff --git a/src/pipeline.cc b/src/pipeline.cc index 209a2e6d..1bbe8108 100644 --- a/src/pipeline.cc +++ b/src/pipeline.cc @@ -123,11 +123,16 @@ class PipelineWorker : public AsyncWorker { if (inputImageType != ImageType::UNKNOWN) { try { VOption *option = VImage::option()->set("access", baton->accessMethod); + if (inputImageType == ImageType::SVG || inputImageType == ImageType::PDF) { + option->set("dpi", static_cast(baton->density)); + } if (inputImageType == ImageType::MAGICK) { option->set("density", std::to_string(baton->density).data()); } image = VImage::new_from_buffer(baton->bufferIn, baton->bufferInLength, nullptr, option); - if (inputImageType == ImageType::MAGICK) { + if (inputImageType == ImageType::SVG || + inputImageType == ImageType::PDF || + inputImageType == ImageType::MAGICK) { SetDensity(image, baton->density); } } catch (...) { @@ -144,11 +149,16 @@ class PipelineWorker : public AsyncWorker { if (inputImageType != ImageType::UNKNOWN) { try { VOption *option = VImage::option()->set("access", baton->accessMethod); + if (inputImageType == ImageType::SVG || inputImageType == ImageType::PDF) { + option->set("dpi", static_cast(baton->density)); + } if (inputImageType == ImageType::MAGICK) { option->set("density", std::to_string(baton->density).data()); } image = VImage::new_from_file(baton->fileIn.data(), option); - if (inputImageType == ImageType::MAGICK) { + if (inputImageType == ImageType::SVG || + inputImageType == ImageType::PDF || + inputImageType == ImageType::MAGICK) { SetDensity(image, baton->density); } } catch (...) { diff --git a/src/utilities.cc b/src/utilities.cc index de37e24b..3cc686d2 100644 --- a/src/utilities.cc +++ b/src/utilities.cc @@ -138,7 +138,9 @@ NAN_METHOD(format) { // Which load/save operations are available for each compressed format? Local format = New(); - for (std::string f : {"jpeg", "png", "webp", "tiff", "magick", "openslide", "dz"}) { + for (std::string f : { + "jpeg", "png", "webp", "tiff", "magick", "openslide", "dz", "ppm", "fits", "gif", "svg", "pdf" + }) { // Input Local hasInputFile = New(vips_type_find("VipsOperation", (f + "load").c_str())); diff --git a/test/fixtures/expected/svg1200.png b/test/fixtures/expected/svg1200.png index 3b921436..8861d7d5 100644 Binary files a/test/fixtures/expected/svg1200.png and b/test/fixtures/expected/svg1200.png differ diff --git a/test/fixtures/expected/svg72.png b/test/fixtures/expected/svg72.png index 6d37045a..a372da8e 100644 Binary files a/test/fixtures/expected/svg72.png and b/test/fixtures/expected/svg72.png differ diff --git a/test/fixtures/free-gearhead-pack.psd b/test/fixtures/free-gearhead-pack.psd deleted file mode 100644 index 1aa55cd5..00000000 Binary files a/test/fixtures/free-gearhead-pack.psd and /dev/null differ diff --git a/test/fixtures/index.js b/test/fixtures/index.js index 73c0681e..57924121 100644 --- a/test/fixtures/index.js +++ b/test/fixtures/index.js @@ -86,7 +86,6 @@ module.exports = { inputTiff: getPath('G31D.TIF'), // http://www.fileformat.info/format/tiff/sample/e6c9a6e5253348f4aef6d17b534360ab/index.htm inputGif: getPath('Crash_test.gif'), // http://upload.wikimedia.org/wikipedia/commons/e/e3/Crash_test.gif inputSvg: getPath('check.svg'), // http://dev.w3.org/SVG/tools/svgweb/samples/svg-files/check.svg - inputPsd: getPath('free-gearhead-pack.psd'), // https://dribbble.com/shots/1624241-Free-Gearhead-Vector-Pack inputSvs: getPath('CMU-1-Small-Region.svs'), // http://openslide.cs.cmu.edu/download/openslide-testdata/Aperio/CMU-1-Small-Region.svs diff --git a/test/unit/io.js b/test/unit/io.js index c112971b..0483a8db 100644 --- a/test/unit/io.js +++ b/test/unit/io.js @@ -668,29 +668,25 @@ describe('Input/output', function() { }); }); - if (sharp.format.magick.input.file) { + if (sharp.format.svg.input.file) { it('Convert SVG to PNG at default 72DPI', function(done) { sharp(fixtures.inputSvg) .resize(1024) .extract({left: 290, top: 760, width: 40, height: 40}) .toFormat('png') .toBuffer(function(err, data, info) { - if (err) { - assert.strictEqual(0, err.message.indexOf('Input file is missing or of an unsupported image format')); - done(); - } else { - assert.strictEqual('png', info.format); - assert.strictEqual(40, info.width); - assert.strictEqual(40, info.height); - fixtures.assertSimilar(fixtures.expected('svg72.png'), data, function(err) { + if (err) throw err; + assert.strictEqual('png', info.format); + assert.strictEqual(40, info.width); + assert.strictEqual(40, info.height); + fixtures.assertSimilar(fixtures.expected('svg72.png'), data, function(err) { + if (err) throw err; + sharp(data).metadata(function(err, info) { if (err) throw err; - sharp(data).metadata(function(err, info) { - if (err) throw err; - assert.strictEqual(72, info.density); - done(); - }); + assert.strictEqual(72, info.density); + done(); }); - } + }); }); }); it('Convert SVG to PNG at 300DPI', function(done) { @@ -699,38 +695,18 @@ describe('Input/output', function() { .extract({left: 290, top: 760, width: 40, height: 40}) .toFormat('png') .toBuffer(function(err, data, info) { - if (err) { - assert.strictEqual(0, err.message.indexOf('Input file is missing or of an unsupported image format')); - done(); - } else { - assert.strictEqual('png', info.format); - assert.strictEqual(40, info.width); - assert.strictEqual(40, info.height); - fixtures.assertSimilar(fixtures.expected('svg1200.png'), data, function(err) { - if (err) throw err; - sharp(data).metadata(function(err, info) { - if (err) throw err; - assert.strictEqual(1200, info.density); - done(); - }); - }); - } - }); - }); - } - - if (sharp.format.magick.input.file) { - it('Convert PSD to PNG', function(done) { - sharp(fixtures.inputPsd) - .resize(320, 240) - .toFormat(sharp.format.png) - .toFile(fixtures.path('output.psd.png'), function(err, info) { if (err) throw err; - assert.strictEqual(true, info.size > 0); assert.strictEqual('png', info.format); - assert.strictEqual(320, info.width); - assert.strictEqual(240, info.height); - done(); + assert.strictEqual(40, info.width); + assert.strictEqual(40, info.height); + fixtures.assertSimilar(fixtures.expected('svg1200.png'), data, function(err) { + if (err) throw err; + sharp(data).metadata(function(err, info) { + if (err) throw err; + assert.strictEqual(1200, info.density); + done(); + }); + }); }); }); } @@ -753,7 +729,7 @@ describe('Input/output', function() { }); } - if (sharp.format.magick.input.buffer) { + if (sharp.format.gif.input.buffer) { it('Load GIF from Buffer', function(done) { var inputGifBuffer = fs.readFileSync(fixtures.inputGif); sharp(inputGifBuffer) diff --git a/test/unit/metadata.js b/test/unit/metadata.js index 6613a367..66e089c8 100644 --- a/test/unit/metadata.js +++ b/test/unit/metadata.js @@ -133,7 +133,24 @@ describe('Image metadata', function() { }); } - if (sharp.format.magick.input.file) { + if (sharp.format.gif.input.file) { + it('GIF via giflib', function(done) { + sharp(fixtures.inputGif).metadata(function(err, metadata) { + if (err) throw err; + assert.strictEqual('gif', metadata.format); + assert.strictEqual(800, metadata.width); + assert.strictEqual(533, metadata.height); + assert.strictEqual(4, metadata.channels); + assert.strictEqual('undefined', typeof metadata.density); + assert.strictEqual(false, metadata.hasProfile); + assert.strictEqual(true, metadata.hasAlpha); + assert.strictEqual('undefined', typeof metadata.orientation); + assert.strictEqual('undefined', typeof metadata.exif); + assert.strictEqual('undefined', typeof metadata.icc); + done(); + }); + }); + } else if (sharp.format.magick.input.file) { it('GIF via libmagick', function(done) { sharp(fixtures.inputGif).metadata(function(err, metadata) { if (err) throw err;