diff --git a/docs/api-channel.md b/docs/api-channel.md
index 079245af..e295f12a 100644
--- a/docs/api-channel.md
+++ b/docs/api-channel.md
@@ -1,6 +1,12 @@
-# extractChannel
+### Table of Contents
+
+- [extractChannel](#extractchannel)
+- [joinChannel](#joinchannel)
+- [bandbool](#bandbool)
+
+## extractChannel
Extract a single channel from a multi-channel image.
@@ -23,7 +29,7 @@ sharp(input)
Returns **Sharp**
-# joinChannel
+## joinChannel
Join one or more channels to the image.
The meaning of the added channels depends on the output colourspace, set with `toColourspace()`.
@@ -46,7 +52,7 @@ For raw pixel input, the `options` object should contain a `raw` attribute, whic
Returns **Sharp**
-# bandbool
+## bandbool
Perform a bitwise boolean operation on all input image channels (bands) to produce a single channel output image.
diff --git a/docs/api-colour.md b/docs/api-colour.md
index 2104fc4f..92664423 100644
--- a/docs/api-colour.md
+++ b/docs/api-colour.md
@@ -1,6 +1,14 @@
-# background
+### Table of Contents
+
+- [background](#background)
+- [greyscale](#greyscale)
+- [grayscale](#grayscale)
+- [toColourspace](#tocolourspace)
+- [toColorspace](#tocolorspace)
+
+## background
Set the background for the `embed`, `flatten` and `extend` operations.
The default background is `{r: 0, g: 0, b: 0, alpha: 1}`, black without transparency.
@@ -18,7 +26,7 @@ The alpha value is a float between `0` (transparent) and `1` (opaque).
Returns **Sharp**
-# greyscale
+## greyscale
Convert to 8-bit greyscale; 256 shades of grey.
This is a linear operation. If the input image is in a non-linear colour space such as sRGB, use `gamma()` with `greyscale()` for the best results.
@@ -33,7 +41,7 @@ An alpha channel may be present, and will be unchanged by the operation.
Returns **Sharp**
-# grayscale
+## grayscale
Alternative spelling of `greyscale`.
@@ -43,7 +51,7 @@ Alternative spelling of `greyscale`.
Returns **Sharp**
-# toColourspace
+## toColourspace
Set the output colourspace.
By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.
@@ -57,7 +65,7 @@ By default output image will be web-friendly sRGB, with additional channels inte
Returns **Sharp**
-# toColorspace
+## toColorspace
Alternative spelling of `toColourspace`.
diff --git a/docs/api-composite.md b/docs/api-composite.md
index 68eee27a..0fb45526 100644
--- a/docs/api-composite.md
+++ b/docs/api-composite.md
@@ -1,6 +1,10 @@
-# overlayWith
+### Table of Contents
+
+- [overlayWith](#overlaywith)
+
+## overlayWith
Overlay (composite) an image over the processed (resized, extracted etc.) image.
diff --git a/docs/api-constructor.md b/docs/api-constructor.md
index 9c6371fb..09fac196 100644
--- a/docs/api-constructor.md
+++ b/docs/api-constructor.md
@@ -1,6 +1,13 @@
-# Sharp
+### Table of Contents
+
+- [Sharp](#sharp)
+ - [format](#format)
+ - [versions](#versions)
+- [queue](#queue)
+
+## Sharp
**Parameters**
@@ -43,7 +50,7 @@ readableStream.pipe(transformer).pipe(writableStream);
Returns **[Sharp](#sharp)**
-## format
+### format
An Object containing nested boolean values representing the available input and output formats/methods.
@@ -55,7 +62,7 @@ console.log(sharp.format());
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
-## versions
+### versions
An Object containing the version numbers of libvips and its dependencies.
@@ -65,7 +72,7 @@ An Object containing the version numbers of libvips and its dependencies.
console.log(sharp.versions);
```
-# queue
+## queue
An EventEmitter that emits a `change` event when a task is either:
diff --git a/docs/api-input.md b/docs/api-input.md
index 7a9918f4..9b78b45e 100644
--- a/docs/api-input.md
+++ b/docs/api-input.md
@@ -1,6 +1,13 @@
-# clone
+### Table of Contents
+
+- [clone](#clone)
+- [metadata](#metadata)
+- [limitInputPixels](#limitinputpixels)
+- [sequentialRead](#sequentialread)
+
+## clone
Take a "snapshot" of the Sharp instance, returning a new instance.
Cloned instances inherit the input of their parent instance.
@@ -19,7 +26,7 @@ readableStream.pipe(pipeline);
Returns **Sharp**
-# metadata
+## metadata
Fast access to image metadata without decoding any compressed image data.
A Promises/A+ promise is returned when `callback` is not provided.
@@ -59,7 +66,7 @@ image
Returns **([Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)> | Sharp)**
-# limitInputPixels
+## limitInputPixels
Do not process input images where the number of pixels (width _ height) exceeds this limit.
Assumes image dimensions contained in the input metadata can be trusted.
@@ -74,7 +81,7 @@ The default limit is 268402689 (0x3FFF _ 0x3FFF) pixels.
Returns **Sharp**
-# sequentialRead
+## sequentialRead
An advanced setting that switches the libvips access method to `VIPS_ACCESS_SEQUENTIAL`.
This will reduce memory usage and can improve performance on some systems.
diff --git a/docs/api-operation.md b/docs/api-operation.md
index 3ef71bef..c11cef3f 100644
--- a/docs/api-operation.md
+++ b/docs/api-operation.md
@@ -1,6 +1,25 @@
-# rotate
+### Table of Contents
+
+- [rotate](#rotate)
+- [extract](#extract)
+- [flip](#flip)
+- [flop](#flop)
+- [sharpen](#sharpen)
+- [blur](#blur)
+- [extend](#extend)
+- [flatten](#flatten)
+- [trim](#trim)
+- [gamma](#gamma)
+- [negate](#negate)
+- [normalise](#normalise)
+- [normalize](#normalize)
+- [convolve](#convolve)
+- [threshold](#threshold)
+- [boolean](#boolean)
+
+## rotate
Rotate the output image by either an explicit angle
or auto-orient based on the EXIF `Orientation` tag.
@@ -35,7 +54,7 @@ readableStream.pipe(pipeline);
Returns **Sharp**
-# extract
+## extract
Extract a region of the image.
@@ -75,7 +94,7 @@ sharp(input)
Returns **Sharp**
-# flip
+## flip
Flip the image about the vertical Y axis. This always occurs after rotation, if any.
The use of `flip` implies the removal of the EXIF `Orientation` tag, if any.
@@ -86,7 +105,7 @@ The use of `flip` implies the removal of the EXIF `Orientation` tag, if any.
Returns **Sharp**
-# flop
+## flop
Flop the image about the horizontal X axis. This always occurs after rotation, if any.
The use of `flop` implies the removal of the EXIF `Orientation` tag, if any.
@@ -97,7 +116,7 @@ The use of `flop` implies the removal of the EXIF `Orientation` tag, if any.
Returns **Sharp**
-# sharpen
+## sharpen
Sharpen the image.
When used without parameters, performs a fast, mild sharpen of the output image.
@@ -115,7 +134,7 @@ Separate control over the level of sharpening in "flat" and "jagged" areas is av
Returns **Sharp**
-# blur
+## blur
Blur the image.
When used without parameters, performs a fast, mild blur of the output image.
@@ -130,7 +149,7 @@ When a `sigma` is provided, performs a slower, more accurate Gaussian blur.
Returns **Sharp**
-# extend
+## extend
Extends/pads the edges of the image with the colour provided to the `background` method.
This operation will always occur after resizing and extraction, if any.
@@ -159,7 +178,7 @@ sharp(input)
Returns **Sharp**
-# flatten
+## flatten
Merge alpha transparency channel, if any, with `background`.
@@ -169,7 +188,7 @@ Merge alpha transparency channel, if any, with `background`.
Returns **Sharp**
-# trim
+## trim
Trim "boring" pixels from all edges that contain values within a percentage similarity of the top-left pixel.
@@ -182,7 +201,7 @@ Trim "boring" pixels from all edges that contain values within a percentage simi
Returns **Sharp**
-# gamma
+## gamma
Apply a gamma correction by reducing the encoding (darken) pre-resize at a factor of `1/gamma`
then increasing the encoding (brighten) post-resize at a factor of `gamma`.
@@ -199,7 +218,7 @@ when applying a gamma correction.
Returns **Sharp**
-# negate
+## negate
Produce the "negative" of the image.
@@ -209,7 +228,7 @@ Produce the "negative" of the image.
Returns **Sharp**
-# normalise
+## normalise
Enhance output image contrast by stretching its luminance to cover the full dynamic range.
@@ -219,7 +238,7 @@ Enhance output image contrast by stretching its luminance to cover the full dyna
Returns **Sharp**
-# normalize
+## normalize
Alternative spelling of normalise.
@@ -229,7 +248,7 @@ Alternative spelling of normalise.
Returns **Sharp**
-# convolve
+## convolve
Convolve the image with the specified kernel.
@@ -262,7 +281,7 @@ sharp(input)
Returns **Sharp**
-# threshold
+## threshold
Any pixel value greather than or equal to the threshold value will be set to 255, otherwise it will be set to 0.
@@ -278,7 +297,7 @@ Any pixel value greather than or equal to the threshold value will be set to 255
Returns **Sharp**
-# boolean
+## boolean
Perform a bitwise boolean operation with operand image.
diff --git a/docs/api-output.md b/docs/api-output.md
index dd065b30..8db6da48 100644
--- a/docs/api-output.md
+++ b/docs/api-output.md
@@ -1,6 +1,19 @@
-# toFile
+### Table of Contents
+
+- [toFile](#tofile)
+- [toBuffer](#tobuffer)
+- [withMetadata](#withmetadata)
+- [jpeg](#jpeg)
+- [png](#png)
+- [webp](#webp)
+- [tiff](#tiff)
+- [raw](#raw)
+- [toFormat](#toformat)
+- [tile](#tile)
+
+## toFile
Write output image data to a file.
@@ -21,7 +34,7 @@ A Promises/A+ promise is returned when `callback` is not provided.
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)>** when no callback is provided
-# toBuffer
+## toBuffer
Write output to a Buffer.
JPEG, PNG, WebP, and RAW output are supported.
@@ -40,7 +53,7 @@ By default, the format will match the input image, except GIF and SVG input whic
Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Buffer](https://nodejs.org/api/buffer.html)>** when no callback is provided
-# withMetadata
+## withMetadata
Include all metadata (EXIF, XMP, IPTC) from the input image in the output image.
The default behaviour, when `withMetadata` is not used, is to strip all metadata and convert to the device-independent sRGB colour space.
@@ -56,7 +69,7 @@ This will also convert to and add a web-friendly sRGB ICC profile.
Returns **Sharp**
-# jpeg
+## jpeg
Use these JPEG options for output image.
@@ -77,7 +90,7 @@ Use these JPEG options for output image.
Returns **Sharp**
-# png
+## png
Use these PNG options for output image.
@@ -94,7 +107,7 @@ Use these PNG options for output image.
Returns **Sharp**
-# webp
+## webp
Use these WebP options for output image.
@@ -109,7 +122,7 @@ Use these WebP options for output image.
Returns **Sharp**
-# tiff
+## tiff
Use these TIFF options for output image.
@@ -124,13 +137,13 @@ Use these TIFF options for output image.
Returns **Sharp**
-# raw
+## raw
Force output to be raw, uncompressed uint8 pixel data.
Returns **Sharp**
-# toFormat
+## toFormat
Force output to a given format.
@@ -144,7 +157,7 @@ Force output to a given format.
Returns **Sharp**
-# tile
+## tile
Use tile-based deep zoom (image pyramid) output.
Set the format and options for tile images via the `toFormat`, `jpeg`, `png` or `webp` functions.
diff --git a/docs/api-resize.md b/docs/api-resize.md
index b6382402..d5886cdc 100644
--- a/docs/api-resize.md
+++ b/docs/api-resize.md
@@ -1,6 +1,16 @@
-# resize
+### Table of Contents
+
+- [resize](#resize)
+- [crop](#crop)
+- [embed](#embed)
+- [max](#max)
+- [min](#min)
+- [ignoreAspectRatio](#ignoreaspectratio)
+- [withoutEnlargement](#withoutenlargement)
+
+## resize
Resize image to `width` x `height`.
By default, the resized image is centre cropped to the exact size specified.
@@ -52,7 +62,7 @@ sharp(inputBuffer)
Returns **Sharp**
-# crop
+## crop
Crop the resized image to the exact size specified, the default behaviour.
@@ -87,7 +97,7 @@ readableStream.pipe(transformer).pipe(writableStream);
Returns **Sharp**
-# embed
+## embed
Preserving aspect ratio, resize the image to the maximum `width` or `height` specified
then embed on a background of the exact `width` and `height` specified.
@@ -114,7 +124,7 @@ sharp('input.gif')
Returns **Sharp**
-# max
+## max
Preserving aspect ratio, resize the image to be as large as possible
while ensuring its dimensions are less than or equal to the `width` and `height` specified.
@@ -137,7 +147,7 @@ sharp(inputBuffer)
Returns **Sharp**
-# min
+## min
Preserving aspect ratio, resize the image to be as small as possible
while ensuring its dimensions are greater than or equal to the `width` and `height` specified.
@@ -146,14 +156,14 @@ Both `width` and `height` must be provided via `resize` otherwise the behaviour
Returns **Sharp**
-# ignoreAspectRatio
+## ignoreAspectRatio
Ignoring the aspect ratio of the input, stretch the image to
the exact `width` and/or `height` provided via `resize`.
Returns **Sharp**
-# withoutEnlargement
+## withoutEnlargement
Do not enlarge the output image if the input image width _or_ height are already less than the required dimensions.
This is equivalent to GraphicsMagick's `>` geometry option:
diff --git a/docs/api-utility.md b/docs/api-utility.md
index 1871aee4..3b914a54 100644
--- a/docs/api-utility.md
+++ b/docs/api-utility.md
@@ -1,6 +1,13 @@
-# cache
+### Table of Contents
+
+- [cache](#cache)
+- [concurrency](#concurrency)
+- [counters](#counters)
+- [simd](#simd)
+
+## cache
Gets, or when options are provided sets, the limits of _libvips'_ operation cache.
Existing entries in the cache will be trimmed after any change in limits.
@@ -28,7 +35,7 @@ sharp.cache(false);
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
-# concurrency
+## concurrency
Gets, or when a concurrency is provided sets,
the number of threads _libvips'_ should create to process each image.
@@ -54,7 +61,7 @@ sharp.concurrency(0); // 4
Returns **[Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** concurrency
-# counters
+## counters
Provides access to internal task counters.
@@ -69,7 +76,7 @@ const counters = sharp.counters(); // { queue: 2, process: 4 }
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
-# simd
+## simd
Get and set use of SIMD vector unit instructions.
Requires libvips to have been compiled with liborc support.
diff --git a/docs/changelog.md b/docs/changelog.md
index 7d81a7b0..d11681ed 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -4,6 +4,15 @@
Requires libvips v8.4.2.
+#### v0.17.1 - TBD
+
+* Improve error messages for invalid parameters.
+ [@spikeon](https://github.com/spikeon)
+ [#644](https://github.com/lovell/sharp/pull/644)
+
+* Simplify expression for finding vips-cpp libdir.
+ [#656](https://github.com/lovell/sharp/pull/656)
+
#### v0.17.0 - 11th December 2016
* Drop support for versions of Node prior to v4.
diff --git a/lib/is.js b/lib/is.js
index ffa6cd91..d9fb06f7 100644
--- a/lib/is.js
+++ b/lib/is.js
@@ -80,6 +80,21 @@ const inArray = function (val, list) {
return list.indexOf(val) !== -1;
};
+/**
+ * Create an Error with a message relating to an invalid parameter.
+ *
+ * @param {String} name - parameter name.
+ * @param {String} expected - description of the type/value/range expected.
+ * @param {*} actual - the value received.
+ * @returns {Error} Containing the formatted message.
+ * @private
+ */
+const invalidParameterError = function (name, expected, actual) {
+ return new Error(
+ `Expected ${expected} for ${name} but received ${actual} of type ${typeof actual}`
+ );
+};
+
module.exports = {
defined: defined,
object: object,
@@ -90,5 +105,6 @@ module.exports = {
number: number,
integer: integer,
inRange: inRange,
- inArray: inArray
+ inArray: inArray,
+ invalidParameterError: invalidParameterError
};
diff --git a/lib/resize.js b/lib/resize.js
index 4f8318e2..db60b11b 100644
--- a/lib/resize.js
+++ b/lib/resize.js
@@ -104,7 +104,7 @@ const resize = function resize (width, height, options) {
if (is.integer(width) && is.inRange(width, 1, this.constructor.maximum.width)) {
this.options.width = width;
} else {
- throw new Error('Invalid width (1 to ' + this.constructor.maximum.width + ') ' + width);
+ throw is.invalidParameterError('width', `integer between 1 and ${this.constructor.maximum.width}`, width);
}
} else {
this.options.width = -1;
@@ -113,7 +113,7 @@ const resize = function resize (width, height, options) {
if (is.integer(height) && is.inRange(height, 1, this.constructor.maximum.height)) {
this.options.height = height;
} else {
- throw new Error('Invalid height (1 to ' + this.constructor.maximum.height + ') ' + height);
+ throw is.invalidParameterError('height', `integer between 1 and ${this.constructor.maximum.height}`, height);
}
} else {
this.options.height = -1;
@@ -124,7 +124,7 @@ const resize = function resize (width, height, options) {
if (is.string(kernel[options.kernel])) {
this.options.kernel = kernel[options.kernel];
} else {
- throw new Error('Invalid kernel ' + options.kernel);
+ throw is.invalidParameterError('kernel', 'valid kernel name', options.kernel);
}
}
// Interpolator
@@ -132,7 +132,7 @@ const resize = function resize (width, height, options) {
if (is.string(interpolator[options.interpolator])) {
this.options.interpolator = interpolator[options.interpolator];
} else {
- throw new Error('Invalid interpolator ' + options.interpolator);
+ throw is.invalidParameterError('interpolator', 'valid interpolator name', options.interpolator);
}
}
// Centre sampling
@@ -185,7 +185,7 @@ const crop = function crop (crop) {
// Strategy
this.options.crop = crop;
} else {
- throw new Error('Unsupported crop ' + crop);
+ throw is.invalidParameterError('crop', 'valid crop id/name/strategy', crop);
}
return this;
};
diff --git a/package.json b/package.json
index 2f7d53ad..7ace4ceb 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "sharp",
"description": "High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP and TIFF images",
- "version": "0.17.0",
+ "version": "0.17.1",
"author": "Lovell Fuller ",
"contributors": [
"Pierre Inglebert ",
@@ -60,17 +60,17 @@
],
"dependencies": {
"caw": "^2.0.0",
- "color": "^1.0.2",
- "got": "^6.6.3",
- "nan": "^2.4.0",
+ "color": "^1.0.3",
+ "got": "^6.7.1",
+ "nan": "^2.5.0",
"semver": "^5.3.0",
"tar": "^2.2.1"
},
"devDependencies": {
"async": "^2.1.4",
"bufferutil": "^1.3.0",
- "cross-env": "^3.1.3",
- "documentation": "^4.0.0-beta16",
+ "cross-env": "^3.1.4",
+ "documentation": "^4.0.0-beta.18",
"exif-reader": "^1.0.1",
"icc": "^0.0.2",
"mocha": "^3.2.0",
diff --git a/test/unit/crop.js b/test/unit/crop.js
index d84c3a06..cb6333e1 100644
--- a/test/unit/crop.js
+++ b/test/unit/crop.js
@@ -141,16 +141,16 @@ describe('Crop', function () {
it('Invalid values fail', function () {
assert.throws(function () {
sharp().crop(9);
- });
+ }, /Expected valid crop id\/name\/strategy for crop but received 9 of type number/);
assert.throws(function () {
sharp().crop(1.1);
- });
+ }, /Expected valid crop id\/name\/strategy for crop but received 1.1 of type number/);
assert.throws(function () {
sharp().crop(-1);
- });
+ }, /Expected valid crop id\/name\/strategy for crop but received -1 of type number/);
assert.throws(function () {
sharp().crop('zoinks');
- });
+ }, /Expected valid crop id\/name\/strategy for crop but received zoinks of type string/);
});
it('Uses default value when none specified', function () {
diff --git a/test/unit/resize.js b/test/unit/resize.js
index 5342d62c..1a79a1a7 100644
--- a/test/unit/resize.js
+++ b/test/unit/resize.js
@@ -66,37 +66,37 @@ describe('Resize dimensions', function () {
it('Invalid width - NaN', function () {
assert.throws(function () {
sharp().resize('spoons', 240);
- });
+ }, /Expected integer between 1 and 16383 for width but received spoons of type string/);
});
it('Invalid height - NaN', function () {
assert.throws(function () {
sharp().resize(320, 'spoons');
- });
+ }, /Expected integer between 1 and 16383 for height but received spoons of type string/);
});
it('Invalid width - float', function () {
assert.throws(function () {
sharp().resize(1.5, 240);
- });
+ }, /Expected integer between 1 and 16383 for width but received 1.5 of type number/);
});
it('Invalid height - float', function () {
assert.throws(function () {
sharp().resize(320, 1.5);
- });
+ }, /Expected integer between 1 and 16383 for height but received 1.5 of type number/);
});
it('Invalid width - too large', function () {
assert.throws(function () {
sharp().resize(0x4000, 240);
- });
+ }, /Expected integer between 1 and 16383 for width but received 16384 of type number/);
});
it('Invalid height - too large', function () {
assert.throws(function () {
sharp().resize(320, 0x4000);
- });
+ }, /Expected integer between 1 and 16383 for height but received 16384 of type number/);
});
it('WebP shrink-on-load rounds to zero, ensure recalculation is correct', function (done) {