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

Suit #991

Closed
wants to merge 12 commits into from
Closed

Suit #991

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src/libvips/* linguist-vendored
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ test/saliency/Image*
test/saliency/[Uu]serData*
!test/saliency/userData.js
vendor
packaging/libvips*
packaging/*.log
!packaging/build
.gitattributes
.DS_Store
.nyc_output
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ matrix:
dist: trusty
sudo: false
node_js: "8"
allow_failures:
- os: osx
osx_image: xcode8
node_js: "4"
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ New bugs are assigned a `triage` label whilst under investigation.

If a [similar request](https://github.com/lovell/sharp/labels/enhancement) exists, it's probably fastest to add a comment to it about your requirement.

Implementation is usually straightforward if _libvips_ [already supports](http://www.vips.ecs.soton.ac.uk/supported/current/doc/html/libvips/ch03.html) the feature you need.
Implementation is usually straightforward if _libvips_ [already supports](https://jcupitt.github.io/libvips/API/current/) the feature you need.

## Submit a Pull Request to fix a bug

Expand All @@ -41,8 +41,8 @@ Any change that modifies the existing public API should be added to the relevant

| Release | WIP branch |
| ------: | :--------- |
| v0.18.0 | ridge |
| v0.19.0 | suit |
| v0.20.0 | teeth |

Please squash your changes into a single commit using a command like `git rebase -i upstream/<wip-branch>`.

Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ the installation of any external runtime dependencies.
## Examples

```javascript
import sharp from 'sharp';
const sharp = require('sharp');
```

```javascript
Expand All @@ -33,8 +33,6 @@ sharp(inputBuffer)
// A Promises/A+ promise is returned when callback is not provided.
```



```javascript
sharp('input.jpg')
.rotate()
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ environment:
matrix:
- nodejs_version: "4"
- nodejs_version: "6"
- nodejs_version: "7"
- nodejs_version: "8"
install:
- ps: Install-Product node $env:nodejs_version x64
- npm install -g npm@latest
Expand Down
8 changes: 6 additions & 2 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@
'copies': [{
'destination': 'build/Release',
'files': [
'vendor/lib/GNU.Gettext.dll',
'vendor/lib/libasprintf-0.dll',
'vendor/lib/libcairo-2.dll',
'vendor/lib/libcairo-gobject-2.dll',
Expand All @@ -245,19 +244,24 @@
'vendor/lib/libfreetype-6.dll',
'vendor/lib/libgcc_s_seh-1.dll',
'vendor/lib/libgdk_pixbuf-2.0-0.dll',
'vendor/lib/libgettextlib-0-19-8.dll',
'vendor/lib/libgettextpo-1.dll',
'vendor/lib/libgettextsrc-0-19-8.dll',
'vendor/lib/libgif-7.dll',
'vendor/lib/libgio-2.0-0.dll',
'vendor/lib/libglib-2.0-0.dll',
'vendor/lib/libgmodule-2.0-0.dll',
'vendor/lib/libgobject-2.0-0.dll',
'vendor/lib/libgsf-1-114.dll',
'vendor/lib/libgthread-2.0-0.dll',
'vendor/lib/libharfbuzz-0.dll',
'vendor/lib/libiconv-2.dll',
'vendor/lib/libintl-8.dll',
'vendor/lib/libintl-9.dll',
'vendor/lib/libjpeg-62.dll',
'vendor/lib/liblcms2-2.dll',
'vendor/lib/libpango-1.0-0.dll',
'vendor/lib/libpangocairo-1.0-0.dll',
'vendor/lib/libpangoft2-1.0-0.dll',
'vendor/lib/libpangowin32-1.0-0.dll',
'vendor/lib/libpixman-1-0.dll',
'vendor/lib/libpng16-16.dll',
Expand Down
121 changes: 51 additions & 70 deletions binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,15 @@ const semver = require('semver');
const tar = require('tar');
const detectLibc = require('detect-libc');

const distBaseUrl = process.env.SHARP_DIST_BASE_URL || 'https://dl.bintray.com/lovell/sharp/';
const platform = require('./lib/platform');

// Use NPM-provided environment variable where available, falling back to require-based method for Electron
const minimumLibvipsVersion = process.env.npm_package_config_libvips || require('./package.json').config.libvips;

const platform = process.env.npm_config_platform || process.platform;

const arch = process.env.npm_config_arch || process.arch;
const distBaseUrl = process.env.SHARP_DIST_BASE_URL || `https://github.com/lovell/sharp-libvips/releases/download/v${minimumLibvipsVersion}/`;

// -- Helpers

// Does this file exist?
const isFile = function (file) {
try {
return fs.statSync(file).isFile();
} catch (err) {}
};

const unpack = function (tarPath, done) {
const vendorPath = path.join(__dirname, 'vendor');
fs.mkdirSync(vendorPath);
Expand All @@ -41,78 +32,68 @@ const unpack = function (tarPath, done) {
.catch(error);
};

const platformId = function () {
const platformId = [platform];
if (arch === 'arm' || arch === 'armhf' || arch === 'arm64') {
const armVersion = (arch === 'arm64') ? '8' : process.env.npm_config_armv || process.config.variables.arm_version || '6';
platformId.push('armv' + armVersion);
} else {
platformId.push(arch);
}
return platformId.join('-');
};

// Error
const error = function (msg) {
if (msg instanceof Error) {
msg = msg.message;
}
process.stderr.write('ERROR: ' + msg + '\n');
process.stderr.write(`sharp: ${msg}\n`);
process.exit(1);
};

// -- Binary downloaders

module.exports.download_vips = function () {
// Has vips been installed locally?
const vipsHeaderPath = path.join(__dirname, 'vendor', 'include', 'vips', 'vips.h');
if (!isFile(vipsHeaderPath)) {
// Ensure Intel 64-bit or ARM
if (arch === 'ia32') {
error('Intel Architecture 32-bit systems require manual installation of libvips - please see http://sharp.dimens.io/page/install');
}
// Ensure glibc Linux
if (detectLibc.isNonGlibcLinux) {
error(`Use with ${detectLibc.family} libc requires manual installation of libvips - please see http://sharp.dimens.io/page/install`);
}
// Ensure glibc >= 2.13
if (detectLibc.family === detectLibc.GLIBC && detectLibc.version && semver.lt(`${detectLibc.version}.0`, '2.13.0')) {
error(`Use with glibc version ${detectLibc.version} requires manual installation of libvips - please see http://sharp.dimens.io/page/install`);
}
// Arch/platform-specific .tar.gz
const tarFilename = ['libvips', minimumLibvipsVersion, platformId()].join('-') + '.tar.gz';
const tarPathLocal = path.join(__dirname, 'packaging', tarFilename);
if (isFile(tarPathLocal)) {
unpack(tarPathLocal);
// Check for existing vendored binaries and verify platform matches
const currentPlatformId = platform();
try {
const vendorPlatformId = require(path.join(__dirname, 'vendor', 'platform.json'));
if (currentPlatformId === vendorPlatformId) {
return;
} else {
// Download to per-process temporary file
const tarPathTemp = path.join(os.tmpdir(), process.pid + '-' + tarFilename);
const tmpFile = fs.createWriteStream(tarPathTemp).on('finish', function () {
unpack(tarPathTemp, function () {
// Attempt to remove temporary file
try {
fs.unlinkSync(tarPathTemp);
} catch (err) {}
});
});
const url = distBaseUrl + tarFilename;
const simpleGetOpt = {
url: url,
agent: caw(null, {
protocol: 'https'
})
};
simpleGet(simpleGetOpt, function (err, response) {
if (err) {
error('Download of ' + url + ' failed: ' + err.message);
}
if (response.statusCode !== 200) {
error(url + ' status code ' + response.statusCode);
}
response.pipe(tmpFile);
});
error(`'${vendorPlatformId}' binaries cannot be used on the '${currentPlatformId}' platform. Please remove the 'node_modules/sharp/vendor' directory and run 'npm install'.`);
}
} catch (err) {}
// Ensure Intel 64-bit or ARM
const arch = process.env.npm_config_arch || process.arch;
if (arch === 'ia32') {
error('Intel Architecture 32-bit systems require manual installation of libvips - please see http://sharp.dimens.io/page/install');
}
// Ensure glibc Linux
if (detectLibc.isNonGlibcLinux) {
error(`Use with ${detectLibc.family} libc requires manual installation of libvips - please see http://sharp.dimens.io/page/install`);
}
// Ensure glibc >= 2.13
if (detectLibc.family === detectLibc.GLIBC && detectLibc.version && semver.lt(`${detectLibc.version}.0`, '2.13.0')) {
error(`Use with glibc version ${detectLibc.version} requires manual installation of libvips - please see http://sharp.dimens.io/page/install`);
}
// Arch/platform-specific .tar.gz
const tarFilename = ['libvips', minimumLibvipsVersion, currentPlatformId].join('-') + '.tar.gz';
// Download to per-process temporary file
const tarPathTemp = path.join(os.tmpdir(), `${process.pid}-${tarFilename}`);
const tmpFile = fs.createWriteStream(tarPathTemp).on('finish', function () {
unpack(tarPathTemp, function () {
// Attempt to remove temporary file
try {
fs.unlinkSync(tarPathTemp);
} catch (err) {}
});
});
const url = distBaseUrl + tarFilename;
const simpleGetOpt = {
url: url,
agent: caw(null, {
protocol: 'https'
})
};
simpleGet(simpleGetOpt, function (err, response) {
if (err) {
error(`${url} download failed: ${err.message}`);
}
if (response.statusCode !== 200) {
error(`${url} download failed: status ${response.statusCode}`);
}
response.pipe(tmpFile);
});
};

module.exports.use_global_vips = function () {
Expand Down
8 changes: 0 additions & 8 deletions circle.yml

This file was deleted.

3 changes: 3 additions & 0 deletions docs/api-constructor.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
a 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 not present.
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)?** if present, is an Object with optional attributes.
- `options.failOnError` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** by default apply a "best effort"
to decode images, even if the data is corrupt or invalid. Set this flag to true
if you'd rather halt processing and raise an error when loading invalid images. (optional, default `false`)
- `options.density` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** integral number representing the DPI for vector images. (optional, default `72`)
- `options.raw` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)?** describes raw pixel input image data. See `raw()` for pixel ordering.
- `options.raw.width` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
Expand Down
5 changes: 3 additions & 2 deletions docs/api-output.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ A Promises/A+ promise is returned when `callback` is not provided.
- `callback` **[Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)?** called on completion with two arguments `(err, info)`.
`info` contains the output image `format`, `size` (bytes), `width`, `height`,
`channels` and `premultiplied` (indicating if premultiplication was used).
When using a crop strategy also contains `cropOffsetLeft` and `cropOffsetTop`.


- Throws **[Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)** Invalid parameters
Expand Down Expand Up @@ -102,8 +103,8 @@ Use these PNG options for output image.

- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)?**
- `options.progressive` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** use progressive (interlace) scan (optional, default `false`)
- `options.compressionLevel` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** zlib compression level (optional, default `6`)
- `options.adaptiveFiltering` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** use adaptive row filtering (optional, default `true`)
- `options.compressionLevel` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** zlib compression level, 0-9 (optional, default `9`)
- `options.adaptiveFiltering` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** use adaptive row filtering (optional, default `false`)
- `options.force` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** force PNG output, otherwise attempt to use input format (optional, default `true`)


Expand Down
18 changes: 4 additions & 14 deletions docs/api-resize.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,20 @@
Resize image to `width` x `height`.
By default, the resized image is centre cropped to the exact size specified.

Possible reduction kernels are:
Possible kernels are:

- `nearest`: Use [nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation).
- `cubic`: Use a [Catmull-Rom spline](https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline).
- `lanczos2`: Use a [Lanczos kernel](https://en.wikipedia.org/wiki/Lanczos_resampling#Lanczos_kernel) with `a=2`.
- `lanczos3`: Use a Lanczos kernel with `a=3` (the default).

Possible enlargement interpolators are:

- `nearest`: Use [nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation).
- `bilinear`: Use [bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation), faster than bicubic but with less smooth results.
- `vertexSplitQuadraticBasisSpline`: Use the smoother [VSQBS interpolation](https://github.com/jcupitt/libvips/blob/master/libvips/resample/vsqbs.cpp#L48) to prevent "staircasing" when enlarging.
- `bicubic`: Use [bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation) (the default).
- `locallyBoundedBicubic`: Use [LBB interpolation](https://github.com/jcupitt/libvips/blob/master/libvips/resample/lbb.cpp#L100), which prevents some "[acutance](http://en.wikipedia.org/wiki/Acutance)" but typically reduces performance by a factor of 2.
- `nohalo`: Use [Nohalo interpolation](http://eprints.soton.ac.uk/268086/), which prevents acutance but typically reduces performance by a factor of 3.

**Parameters**

- `width` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** pixels wide the resultant image should be. Use `null` or `undefined` to auto-scale the width to match the height.
- `height` **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)?** pixels high the resultant image should be. Use `null` or `undefined` to auto-scale the height to match the width.
- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)?**
- `options.kernel` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the kernel to use for image reduction. (optional, default `'lanczos3'`)
- `options.interpolator` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** the interpolator to use for image enlargement. (optional, default `'bicubic'`)
- `options.fastShrinkOnLoad` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** take greater advantage of the JPEG and WebP shrink-on-load feature, which can lead to a slight moiré pattern on some images. (optional, default `true`)
- `options.centreSampling` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** use \*magick centre sampling convention instead of corner sampling. (optional, default `false`)
- `options.centerSampling` **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** alternative spelling of centreSampling. (optional, default `false`)

Expand All @@ -46,15 +37,14 @@ Possible enlargement interpolators are:
```javascript
sharp(inputBuffer)
.resize(200, 300, {
kernel: sharp.kernel.lanczos2,
interpolator: sharp.interpolator.nohalo
kernel: sharp.kernel.nearest
})
.background('white')
.embed()
.toFile('output.tiff')
.then(function() {
// output.tiff is a 200 pixels wide and 300 pixels high image
// containing a lanczos2/nohalo scaled version, embedded on a white canvas,
// containing a nearest-neighbour scaled version, embedded on a white canvas,
// of the image data in inputBuffer
});
```
Expand Down
22 changes: 22 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# Changelog

### v0.19 - "*suit*"

Requires libvips v8.6.0.

#### v0.19.0 - TBD

* Expose offset coordinates of strategy-based crop.
[#868](https://github.com/lovell/sharp/issues/868)
[@mirohristov-com](https://github.com/mirohristov-com)

* PNG output now defaults to adaptiveFiltering=false, compressionLevel=9
[#872](https://github.com/lovell/sharp/issues/872)
[@wmertens](https://github.com/wmertens)

* Add failOnError option to fail-fast on bad input image data.
[#976](https://github.com/lovell/sharp/pull/976)
[@mceachen](https://github.com/mceachen)

* Resize: switch to libvips' implementation, make fastShrinkOnLoad optional, remove interpolators.
[#977](https://github.com/lovell/sharp/pull/977)
[@jardakotesovec](https://github.com/jardakotesovec)

### v0.18 - "*ridge*"

Requires libvips v8.5.5.
Expand Down
6 changes: 4 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ without having to use separate command line tools like
[jpegoptim](https://github.com/tjko/jpegoptim) and
[jpegtran](http://jpegclub.org/jpegtran/).

PNG filtering can be disabled,
PNG filtering is disabled by default,
which for diagrams and line art often produces the same result
as [pngcrush](http://pmt.sourceforge.net/pngcrush/).
as [pngcrush](https://pmt.sourceforge.io/pngcrush/).

### Contributing

Expand Down Expand Up @@ -102,6 +102,8 @@ the help and code contributions of the following people:
* [Yves Bos](https://github.com/YvesBos)
* [Nicolas Coden](https://github.com/ncoden)
* [Matt Parrish](https://github.com/pbomb)
* [Matthew McEachen](https://github.com/mceachen)
* [Jarda Kotěšovec](https://github.com/jardakotesovec)

Thank you!

Expand Down
Loading