Improve consistency of validation error handling

Utilises common path of existing invalidParameterError
This commit is contained in:
Lovell Fuller 2019-07-26 14:58:49 +01:00
parent 28de243c11
commit 233b015d77
11 changed files with 110 additions and 135 deletions

View File

@ -89,8 +89,8 @@ This will also convert to and add a web-friendly sRGB ICC profile.
### Parameters ### Parameters
- `withMetadata` **[Object][5]?** - `options` **[Object][5]?**
- `withMetadata.orientation` **[Number][8]?** value between 1 and 8, used to update the EXIF `Orientation` tag. - `options.orientation` **[Number][8]?** value between 1 and 8, used to update the EXIF `Orientation` tag.
### Examples ### Examples
@ -308,14 +308,14 @@ Warning: multiple sharp instances concurrently producing tile output can expose
### Parameters ### Parameters
- `tile` **[Object][5]?** - `options` **[Object][5]?**
- `tile.size` **[Number][8]** tile size in pixels, a value between 1 and 8192. (optional, default `256`) - `options.size` **[Number][8]** tile size in pixels, a value between 1 and 8192. (optional, default `256`)
- `tile.overlap` **[Number][8]** tile overlap in pixels, a value between 0 and 8192. (optional, default `0`) - `options.overlap` **[Number][8]** tile overlap in pixels, a value between 0 and 8192. (optional, default `0`)
- `tile.angle` **[Number][8]** tile angle of rotation, must be a multiple of 90. (optional, default `0`) - `options.angle` **[Number][8]** tile angle of rotation, must be a multiple of 90. (optional, default `0`)
- `tile.depth` **[String][1]?** how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout. - `options.depth` **[String][1]?** how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout.
- `tile.skipBlanks` **[Number][8]** threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images (optional, default `-1`) - `options.skipBlanks` **[Number][8]** threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images (optional, default `-1`)
- `tile.container` **[String][1]** tile container, with value `fs` (filesystem) or `zip` (compressed file). (optional, default `'fs'`) - `options.container` **[String][1]** tile container, with value `fs` (filesystem) or `zip` (compressed file). (optional, default `'fs'`)
- `tile.layout` **[String][1]** filesystem layout, possible values are `dz`, `zoomify` or `google`. (optional, default `'dz'`) - `options.layout` **[String][1]** filesystem layout, possible values are `dz`, `zoomify` or `google`. (optional, default `'dz'`)
### Examples ### Examples

View File

@ -72,7 +72,7 @@ function extractChannel (channel) {
if (is.integer(channel) && is.inRange(channel, 0, 4)) { if (is.integer(channel) && is.inRange(channel, 0, 4)) {
this.options.extractChannel = channel; this.options.extractChannel = channel;
} else { } else {
throw new Error('Cannot extract invalid channel ' + channel); throw is.invalidParameterError('channel', 'integer or one of: red, green, blue', channel);
} }
return this; return this;
} }
@ -124,7 +124,7 @@ function bandbool (boolOp) {
if (is.string(boolOp) && is.inArray(boolOp, ['and', 'or', 'eor'])) { if (is.string(boolOp) && is.inArray(boolOp, ['and', 'or', 'eor'])) {
this.options.bandBoolOp = boolOp; this.options.bandBoolOp = boolOp;
} else { } else {
throw new Error('Invalid bandbool operation ' + boolOp); throw is.invalidParameterError('boolOp', 'one of: and, or, eor', boolOp);
} }
return this; return this;
} }

View File

@ -63,7 +63,7 @@ function grayscale (grayscale) {
*/ */
function toColourspace (colourspace) { function toColourspace (colourspace) {
if (!is.string(colourspace)) { if (!is.string(colourspace)) {
throw new Error('Invalid output colourspace ' + colourspace); throw is.invalidParameterError('colourspace', 'string', colourspace);
} }
this.options.colourspace = colourspace; this.options.colourspace = colourspace;
return this; return this;

View File

@ -215,6 +215,7 @@ const Sharp = function (input, options) {
heifCompression: 'hevc', heifCompression: 'hevc',
tileSize: 256, tileSize: 256,
tileOverlap: 0, tileOverlap: 0,
tileSkipBlanks: -1,
linearA: 1, linearA: 1,
linearB: 0, linearB: 0,
// Function to notify of libvips warnings // Function to notify of libvips warnings

View File

@ -35,7 +35,7 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
if (is.bool(inputOptions.failOnError)) { if (is.bool(inputOptions.failOnError)) {
inputDescriptor.failOnError = inputOptions.failOnError; inputDescriptor.failOnError = inputOptions.failOnError;
} else { } else {
throw new Error('Invalid failOnError (boolean) ' + inputOptions.failOnError); throw is.invalidParameterError('failOnError', 'boolean', inputOptions.failOnError);
} }
} }
// Density // Density
@ -43,7 +43,7 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
if (is.inRange(inputOptions.density, 1, 2400)) { if (is.inRange(inputOptions.density, 1, 2400)) {
inputDescriptor.density = inputOptions.density; inputDescriptor.density = inputOptions.density;
} else { } else {
throw new Error('Invalid density (1 to 2400) ' + inputOptions.density); throw is.invalidParameterError('density', 'number between 1 and 2400', inputOptions.density);
} }
} }
// Raw pixel input // Raw pixel input

View File

@ -55,7 +55,7 @@ function rotate (angle, options) {
]; ];
} }
} else { } else {
throw new Error('Unsupported angle: must be a number.'); throw is.invalidParameterError('angle', 'numeric', angle);
} }
return this; return this;
} }
@ -109,7 +109,7 @@ function sharpen (sigma, flat, jagged) {
if (is.number(flat) && is.inRange(flat, 0, 10000)) { if (is.number(flat) && is.inRange(flat, 0, 10000)) {
this.options.sharpenFlat = flat; this.options.sharpenFlat = flat;
} else { } else {
throw new Error('Invalid sharpen level for flat areas (0.0 - 10000.0) ' + flat); throw is.invalidParameterError('flat', 'number between 0 and 10000', flat);
} }
} }
// Control over jagged areas // Control over jagged areas
@ -117,11 +117,11 @@ function sharpen (sigma, flat, jagged) {
if (is.number(jagged) && is.inRange(jagged, 0, 10000)) { if (is.number(jagged) && is.inRange(jagged, 0, 10000)) {
this.options.sharpenJagged = jagged; this.options.sharpenJagged = jagged;
} else { } else {
throw new Error('Invalid sharpen level for jagged areas (0.0 - 10000.0) ' + jagged); throw is.invalidParameterError('jagged', 'number between 0 and 10000', jagged);
} }
} }
} else { } else {
throw new Error('Invalid sharpen sigma (0.01 - 10000) ' + sigma); throw is.invalidParameterError('sigma', 'number between 0.01 and 10000', sigma);
} }
return this; return this;
} }
@ -141,7 +141,7 @@ function median (size) {
// Numeric argument: specific sigma // Numeric argument: specific sigma
this.options.medianSize = size; this.options.medianSize = size;
} else { } else {
throw new Error('Invalid median size ' + size); throw is.invalidParameterError('size', 'integer between 1 and 1000', size);
} }
return this; return this;
} }
@ -165,7 +165,7 @@ function blur (sigma) {
// Numeric argument: specific sigma // Numeric argument: specific sigma
this.options.blurSigma = sigma; this.options.blurSigma = sigma;
} else { } else {
throw new Error('Invalid blur sigma (0.3 - 1000.0) ' + sigma); throw is.invalidParameterError('sigma', 'number between 0.3 and 1000', sigma);
} }
return this; return this;
} }
@ -205,7 +205,7 @@ function gamma (gamma, gammaOut) {
} else if (is.number(gamma) && is.inRange(gamma, 1, 3)) { } else if (is.number(gamma) && is.inRange(gamma, 1, 3)) {
this.options.gamma = gamma; this.options.gamma = gamma;
} else { } else {
throw new Error('Invalid gamma correction (1.0 to 3.0) ' + gamma); throw is.invalidParameterError('gamma', 'number between 1.0 and 3.0', gamma);
} }
if (!is.defined(gammaOut)) { if (!is.defined(gammaOut)) {
// Default gamma correction for output is same as input // Default gamma correction for output is same as input
@ -213,7 +213,7 @@ function gamma (gamma, gammaOut) {
} else if (is.number(gammaOut) && is.inRange(gammaOut, 1, 3)) { } else if (is.number(gammaOut) && is.inRange(gammaOut, 1, 3)) {
this.options.gammaOut = gammaOut; this.options.gammaOut = gammaOut;
} else { } else {
throw new Error('Invalid output gamma correction (1.0 to 3.0) ' + gammaOut); throw is.invalidParameterError('gammaOut', 'number between 1.0 and 3.0', gammaOut);
} }
return this; return this;
} }
@ -315,7 +315,7 @@ function threshold (threshold, options) {
} else if (is.integer(threshold) && is.inRange(threshold, 0, 255)) { } else if (is.integer(threshold) && is.inRange(threshold, 0, 255)) {
this.options.threshold = threshold; this.options.threshold = threshold;
} else { } else {
throw new Error('Invalid threshold (0 to 255) ' + threshold); throw is.invalidParameterError('threshold', 'integer between 0 and 255', threshold);
} }
if (!is.object(options) || options.greyscale === true || options.grayscale === true) { if (!is.object(options) || options.greyscale === true || options.grayscale === true) {
this.options.thresholdGrayscale = true; this.options.thresholdGrayscale = true;
@ -346,7 +346,7 @@ function boolean (operand, operator, options) {
if (is.string(operator) && is.inArray(operator, ['and', 'or', 'eor'])) { if (is.string(operator) && is.inArray(operator, ['and', 'or', 'eor'])) {
this.options.booleanOp = operator; this.options.booleanOp = operator;
} else { } else {
throw new Error('Invalid boolean operator ' + operator); throw is.invalidParameterError('operator', 'one of: and, or, eor', operator);
} }
return this; return this;
} }
@ -364,17 +364,15 @@ function linear (a, b) {
} else if (is.number(a)) { } else if (is.number(a)) {
this.options.linearA = a; this.options.linearA = a;
} else { } else {
throw new Error('Invalid linear transform multiplier ' + a); throw is.invalidParameterError('a', 'numeric', a);
} }
if (!is.defined(b)) { if (!is.defined(b)) {
this.options.linearB = 0.0; this.options.linearB = 0.0;
} else if (is.number(b)) { } else if (is.number(b)) {
this.options.linearB = b; this.options.linearB = b;
} else { } else {
throw new Error('Invalid linear transform offset ' + b); throw is.invalidParameterError('b', 'numeric', b);
} }
return this; return this;
} }
@ -405,7 +403,7 @@ function recomb (inputMatrix) {
inputMatrix[2].length !== 3 inputMatrix[2].length !== 3
) { ) {
// must pass in a kernel // must pass in a kernel
throw new Error('Invalid Recomb Matrix'); throw new Error('Invalid recombination matrix');
} }
this.options.recombMatrix = [ this.options.recombMatrix = [
inputMatrix[0][0], inputMatrix[0][1], inputMatrix[0][2], inputMatrix[0][0], inputMatrix[0][1], inputMatrix[0][2],

View File

@ -91,9 +91,7 @@ function toFile (fileOut, callback) {
*/ */
function toBuffer (options, callback) { function toBuffer (options, callback) {
if (is.object(options)) { if (is.object(options)) {
if (is.bool(options.resolveWithObject)) { this._setBooleanOption('resolveWithObject', options.resolveWithObject);
this.options.resolveWithObject = options.resolveWithObject;
}
} }
return this._pipeline(is.fn(options) ? options : callback); return this._pipeline(is.fn(options) ? options : callback);
} }
@ -109,19 +107,19 @@ function toBuffer (options, callback) {
* .toFile('output-with-metadata.jpg') * .toFile('output-with-metadata.jpg')
* .then(info => { ... }); * .then(info => { ... });
* *
* @param {Object} [withMetadata] * @param {Object} [options]
* @param {Number} [withMetadata.orientation] value between 1 and 8, used to update the EXIF `Orientation` tag. * @param {Number} [options.orientation] value between 1 and 8, used to update the EXIF `Orientation` tag.
* @returns {Sharp} * @returns {Sharp}
* @throws {Error} Invalid parameters * @throws {Error} Invalid parameters
*/ */
function withMetadata (withMetadata) { function withMetadata (options) {
this.options.withMetadata = is.bool(withMetadata) ? withMetadata : true; this.options.withMetadata = is.bool(options) ? options : true;
if (is.object(withMetadata)) { if (is.object(options)) {
if (is.defined(withMetadata.orientation)) { if (is.defined(options.orientation)) {
if (is.integer(withMetadata.orientation) && is.inRange(withMetadata.orientation, 1, 8)) { if (is.integer(options.orientation) && is.inRange(options.orientation, 1, 8)) {
this.options.withMetadataOrientation = withMetadata.orientation; this.options.withMetadataOrientation = options.orientation;
} else { } else {
throw new Error('Invalid orientation (1 to 8) ' + withMetadata.orientation); throw is.invalidParameterError('orientation', 'integer between 1 and 8', options.orientation);
} }
} }
} }
@ -162,7 +160,7 @@ function jpeg (options) {
if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) { if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
this.options.jpegQuality = options.quality; this.options.jpegQuality = options.quality;
} else { } else {
throw new Error('Invalid quality (integer, 1-100) ' + options.quality); throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality);
} }
} }
if (is.defined(options.progressive)) { if (is.defined(options.progressive)) {
@ -172,7 +170,7 @@ function jpeg (options) {
if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) { if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) {
this.options.jpegChromaSubsampling = options.chromaSubsampling; this.options.jpegChromaSubsampling = options.chromaSubsampling;
} else { } else {
throw new Error('Invalid chromaSubsampling (4:2:0, 4:4:4) ' + options.chromaSubsampling); throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling);
} }
} }
const trellisQuantisation = is.bool(options.trellisQuantization) ? options.trellisQuantization : options.trellisQuantisation; const trellisQuantisation = is.bool(options.trellisQuantization) ? options.trellisQuantization : options.trellisQuantisation;
@ -198,7 +196,7 @@ function jpeg (options) {
if (is.integer(quantisationTable) && is.inRange(quantisationTable, 0, 8)) { if (is.integer(quantisationTable) && is.inRange(quantisationTable, 0, 8)) {
this.options.jpegQuantisationTable = quantisationTable; this.options.jpegQuantisationTable = quantisationTable;
} else { } else {
throw new Error('Invalid quantisation table (integer, 0-8) ' + quantisationTable); throw is.invalidParameterError('quantisationTable', 'integer between 0 and 8', quantisationTable);
} }
} }
} }
@ -239,7 +237,7 @@ function png (options) {
if (is.integer(options.compressionLevel) && is.inRange(options.compressionLevel, 0, 9)) { if (is.integer(options.compressionLevel) && is.inRange(options.compressionLevel, 0, 9)) {
this.options.pngCompressionLevel = options.compressionLevel; this.options.pngCompressionLevel = options.compressionLevel;
} else { } else {
throw new Error('Invalid compressionLevel (integer, 0-9) ' + options.compressionLevel); throw is.invalidParameterError('compressionLevel', 'integer between 0 and 9', options.compressionLevel);
} }
} }
if (is.defined(options.adaptiveFiltering)) { if (is.defined(options.adaptiveFiltering)) {
@ -364,59 +362,47 @@ function tiff (options) {
if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) { if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
this.options.tiffQuality = options.quality; this.options.tiffQuality = options.quality;
} else { } else {
throw new Error('Invalid quality (integer, 1-100) ' + options.quality); throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality);
} }
} }
if (is.defined(options.squash)) { if (is.defined(options.squash)) {
if (is.bool(options.squash)) { this._setBooleanOption('tiffSquash', options.squash);
this.options.tiffSquash = options.squash;
} else {
throw new Error('Invalid Value for squash ' + options.squash + ' Only Boolean Values allowed for options.squash.');
}
} }
// tiling // tiling
if (is.defined(options.tile)) { if (is.defined(options.tile)) {
if (is.bool(options.tile)) { this._setBooleanOption('tiffTile', options.tile);
this.options.tiffTile = options.tile;
} else {
throw new Error('Invalid Value for tile ' + options.tile + ' Only Boolean values allowed for options.tile');
}
} }
if (is.defined(options.tileWidth)) { if (is.defined(options.tileWidth)) {
if (is.number(options.tileWidth) && options.tileWidth > 0) { if (is.integer(options.tileWidth) && options.tileWidth > 0) {
this.options.tiffTileWidth = options.tileWidth; this.options.tiffTileWidth = options.tileWidth;
} else { } else {
throw new Error('Invalid Value for tileWidth ' + options.tileWidth + ' Only positive numeric values allowed for options.tileWidth'); throw is.invalidParameterError('tileWidth', 'integer greater than zero', options.tileWidth);
} }
} }
if (is.defined(options.tileHeight)) { if (is.defined(options.tileHeight)) {
if (is.number(options.tileHeight) && options.tileHeight > 0) { if (is.integer(options.tileHeight) && options.tileHeight > 0) {
this.options.tiffTileHeight = options.tileHeight; this.options.tiffTileHeight = options.tileHeight;
} else { } else {
throw new Error('Invalid Value for tileHeight ' + options.tileHeight + ' Only positive numeric values allowed for options.tileHeight'); throw is.invalidParameterError('tileHeight', 'integer greater than zero', options.tileHeight);
} }
} }
// pyramid // pyramid
if (is.defined(options.pyramid)) { if (is.defined(options.pyramid)) {
if (is.bool(options.pyramid)) { this._setBooleanOption('tiffPyramid', options.pyramid);
this.options.tiffPyramid = options.pyramid;
} else {
throw new Error('Invalid Value for pyramid ' + options.pyramid + ' Only Boolean values allowed for options.pyramid');
}
} }
// resolution // resolution
if (is.defined(options.xres)) { if (is.defined(options.xres)) {
if (is.number(options.xres)) { if (is.number(options.xres) && options.xres > 0) {
this.options.tiffXres = options.xres; this.options.tiffXres = options.xres;
} else { } else {
throw new Error('Invalid Value for xres ' + options.xres + ' Only numeric values allowed for options.xres'); throw is.invalidParameterError('xres', 'number greater than zero', options.xres);
} }
} }
if (is.defined(options.yres)) { if (is.defined(options.yres)) {
if (is.number(options.yres)) { if (is.number(options.yres) && options.yres > 0) {
this.options.tiffYres = options.yres; this.options.tiffYres = options.yres;
} else { } else {
throw new Error('Invalid Value for yres ' + options.yres + ' Only numeric values allowed for options.yres'); throw is.invalidParameterError('yres', 'number greater than zero', options.yres);
} }
} }
// compression // compression
@ -424,8 +410,7 @@ function tiff (options) {
if (is.string(options.compression) && is.inArray(options.compression, ['lzw', 'deflate', 'jpeg', 'ccittfax4', 'none'])) { if (is.string(options.compression) && is.inArray(options.compression, ['lzw', 'deflate', 'jpeg', 'ccittfax4', 'none'])) {
this.options.tiffCompression = options.compression; this.options.tiffCompression = options.compression;
} else { } else {
const message = `Invalid compression option "${options.compression}". Should be one of: lzw, deflate, jpeg, ccittfax4, none`; throw is.invalidParameterError('compression', 'one of: lzw, deflate, jpeg, ccittfax4, none', options.compression);
throw new Error(message);
} }
} }
// predictor // predictor
@ -433,8 +418,7 @@ function tiff (options) {
if (is.string(options.predictor) && is.inArray(options.predictor, ['none', 'horizontal', 'float'])) { if (is.string(options.predictor) && is.inArray(options.predictor, ['none', 'horizontal', 'float'])) {
this.options.tiffPredictor = options.predictor; this.options.tiffPredictor = options.predictor;
} else { } else {
const message = `Invalid predictor option "${options.predictor}". Should be one of: none, horizontal, float`; throw is.invalidParameterError('predictor', 'one of: none, horizontal, float', options.predictor);
throw new Error(message);
} }
} }
} }
@ -523,7 +507,7 @@ function toFormat (format, options) {
} }
if (format === 'jpg') format = 'jpeg'; if (format === 'jpg') format = 'jpeg';
if (!is.inArray(format, ['jpeg', 'png', 'webp', 'tiff', 'raw'])) { if (!is.inArray(format, ['jpeg', 'png', 'webp', 'tiff', 'raw'])) {
throw new Error('Unsupported output format ' + format); throw is.invalidParameterError('format', 'one of: jpeg, png, webp, tiff, raw', format);
} }
return this[format](options); return this[format](options);
} }
@ -546,95 +530,87 @@ function toFormat (format, options) {
* // output_files contains 512x512 tiles grouped by zoom level * // output_files contains 512x512 tiles grouped by zoom level
* }); * });
* *
* @param {Object} [tile] * @param {Object} [options]
* @param {Number} [tile.size=256] tile size in pixels, a value between 1 and 8192. * @param {Number} [options.size=256] tile size in pixels, a value between 1 and 8192.
* @param {Number} [tile.overlap=0] tile overlap in pixels, a value between 0 and 8192. * @param {Number} [options.overlap=0] tile overlap in pixels, a value between 0 and 8192.
* @param {Number} [tile.angle=0] tile angle of rotation, must be a multiple of 90. * @param {Number} [options.angle=0] tile angle of rotation, must be a multiple of 90.
* @param {String} [tile.depth] how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout. * @param {String} [options.depth] how deep to make the pyramid, possible values are `onepixel`, `onetile` or `one`, default based on layout.
* @param {Number} [tile.skipBlanks=-1] threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images * @param {Number} [options.skipBlanks=-1] threshold to skip tile generation, a value 0 - 255 for 8-bit images or 0 - 65535 for 16-bit images
* @param {String} [tile.container='fs'] tile container, with value `fs` (filesystem) or `zip` (compressed file). * @param {String} [options.container='fs'] tile container, with value `fs` (filesystem) or `zip` (compressed file).
* @param {String} [tile.layout='dz'] filesystem layout, possible values are `dz`, `zoomify` or `google`. * @param {String} [options.layout='dz'] filesystem layout, possible values are `dz`, `zoomify` or `google`.
* @returns {Sharp} * @returns {Sharp}
* @throws {Error} Invalid parameters * @throws {Error} Invalid parameters
*/ */
function tile (tile) { function tile (options) {
if (is.object(tile)) { if (is.object(options)) {
// Size of square tiles, in pixels // Size of square tiles, in pixels
if (is.defined(tile.size)) { if (is.defined(options.size)) {
if (is.integer(tile.size) && is.inRange(tile.size, 1, 8192)) { if (is.integer(options.size) && is.inRange(options.size, 1, 8192)) {
this.options.tileSize = tile.size; this.options.tileSize = options.size;
} else { } else {
throw new Error('Invalid tile size (1 to 8192) ' + tile.size); throw is.invalidParameterError('size', 'integer between 1 and 8192', options.size);
} }
} }
// Overlap of tiles, in pixels // Overlap of tiles, in pixels
if (is.defined(tile.overlap)) { if (is.defined(options.overlap)) {
if (is.integer(tile.overlap) && is.inRange(tile.overlap, 0, 8192)) { if (is.integer(options.overlap) && is.inRange(options.overlap, 0, 8192)) {
if (tile.overlap > this.options.tileSize) { if (options.overlap > this.options.tileSize) {
throw new Error('Tile overlap ' + tile.overlap + ' cannot be larger than tile size ' + this.options.tileSize); throw is.invalidParameterError('overlap', `<= size (${this.options.tileSize})`, options.overlap);
} }
this.options.tileOverlap = tile.overlap; this.options.tileOverlap = tile.overlap;
} else { } else {
throw new Error('Invalid tile overlap (0 to 8192) ' + tile.overlap); throw is.invalidParameterError('overlap', 'integer between 0 and 8192', options.overlap);
} }
} }
// Container // Container
if (is.defined(tile.container)) { if (is.defined(options.container)) {
if (is.string(tile.container) && is.inArray(tile.container, ['fs', 'zip'])) { if (is.string(options.container) && is.inArray(options.container, ['fs', 'zip'])) {
this.options.tileContainer = tile.container; this.options.tileContainer = options.container;
} else { } else {
throw new Error('Invalid tile container ' + tile.container); throw is.invalidParameterError('container', 'one of: fs, zip', options.container);
} }
} }
// Layout // Layout
if (is.defined(tile.layout)) { if (is.defined(options.layout)) {
if (is.string(tile.layout) && is.inArray(tile.layout, ['dz', 'google', 'zoomify'])) { if (is.string(options.layout) && is.inArray(options.layout, ['dz', 'google', 'zoomify'])) {
this.options.tileLayout = tile.layout; this.options.tileLayout = options.layout;
} else { } else {
throw new Error('Invalid tile layout ' + tile.layout); throw is.invalidParameterError('layout', 'one of: dz, google, zoomify', options.layout);
} }
} }
// Angle of rotation, // Angle of rotation,
if (is.defined(tile.angle)) { if (is.defined(options.angle)) {
if (is.integer(tile.angle) && !(tile.angle % 90)) { if (is.integer(options.angle) && !(options.angle % 90)) {
this.options.tileAngle = tile.angle; this.options.tileAngle = options.angle;
} else { } else {
throw new Error('Unsupported angle: angle must be a positive/negative multiple of 90 ' + tile.angle); throw is.invalidParameterError('angle', 'positive/negative multiple of 90', options.angle);
} }
} }
// Depth of tiles // Depth of tiles
if (is.defined(tile.depth)) { if (is.defined(options.depth)) {
if (is.string(tile.depth) && is.inArray(tile.depth, ['onepixel', 'onetile', 'one'])) { if (is.string(options.depth) && is.inArray(options.depth, ['onepixel', 'onetile', 'one'])) {
this.options.tileDepth = tile.depth; this.options.tileDepth = options.depth;
} else { } else {
throw new Error("Invalid tile depth '" + tile.depth + "', should be one of 'onepixel', 'onetile' or 'one'"); throw is.invalidParameterError('depth', 'one of: onepixel, onetile, one', options.depth);
} }
} }
// Threshold to skip blank tiles
// Threshold of skipping blanks, if (is.defined(options.skipBlanks)) {
if (is.defined(tile.skipBlanks)) { if (is.integer(options.skipBlanks) && is.inRange(options.skipBlanks, -1, 65535)) {
if (is.integer(tile.skipBlanks) && is.inRange(tile.skipBlanks, -1, 65535)) { this.options.tileSkipBlanks = options.skipBlanks;
this.options.skipBlanks = tile.skipBlanks;
} else { } else {
throw new Error('Invalid skipBlank threshold (-1 to 255/65535) ' + tile.skipBlanks); throw is.invalidParameterError('skipBlanks', 'integer between -1 and 255/65535', options.skipBlanks);
}
} else {
if (is.defined(tile.layout) && tile.layout === 'google') {
this.options.skipBlanks = 5;
} else {
this.options.skipBlanks = -1;
} }
} else if (is.defined(options.layout) && options.layout === 'google') {
this.options.tileSkipBlanks = 5;
} }
} }
// Format // Format
if (is.inArray(this.options.formatOut, ['jpeg', 'png', 'webp'])) { if (is.inArray(this.options.formatOut, ['jpeg', 'png', 'webp'])) {
this.options.tileFormat = this.options.formatOut; this.options.tileFormat = this.options.formatOut;
} else if (this.options.formatOut !== 'input') { } else if (this.options.formatOut !== 'input') {
throw new Error('Invalid tile format ' + this.options.formatOut); throw is.invalidParameterError('format', 'one of: jpeg, png, webp', this.options.formatOut);
} }
return this._updateFormatOut('dz'); return this._updateFormatOut('dz');
} }
@ -665,7 +641,7 @@ function _setBooleanOption (key, val) {
if (is.bool(val)) { if (is.bool(val)) {
this.options[key] = val; this.options[key] = val;
} else { } else {
throw new Error('Invalid ' + key + ' (boolean) ' + val); throw is.invalidParameterError(key, 'boolean', val);
} }
} }

View File

@ -307,7 +307,7 @@ function extend (extend) {
this.options.extendRight = extend.right; this.options.extendRight = extend.right;
this._setColourOption('extendBackground', extend.background); this._setColourOption('extendBackground', extend.background);
} else { } else {
throw new Error('Invalid edge extension ' + extend); throw is.invalidParameterError('extend', 'integer or object', extend);
} }
return this; return this;
} }
@ -349,7 +349,7 @@ function extract (options) {
if (is.integer(value) && value >= 0) { if (is.integer(value) && value >= 0) {
this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value; this.options[name + (name === 'left' || name === 'top' ? 'Offset' : '') + suffix] = value;
} else { } else {
throw new Error('Non-integer value for ' + name + ' of ' + value); throw is.invalidParameterError(name, 'integer', value);
} }
}, this); }, this);
// Ensure existing rotation occurs before pre-resize extraction // Ensure existing rotation occurs before pre-resize extraction

View File

@ -108,11 +108,11 @@
"async": "^3.1.0", "async": "^3.1.0",
"cc": "^1.0.2", "cc": "^1.0.2",
"decompress-zip": "^0.3.2", "decompress-zip": "^0.3.2",
"documentation": "^12.0.1", "documentation": "^12.0.3",
"exif-reader": "^1.0.2", "exif-reader": "^1.0.2",
"icc": "^1.0.0", "icc": "^1.0.0",
"license-checker": "^25.0.1", "license-checker": "^25.0.1",
"mocha": "^6.1.4", "mocha": "^6.2.0",
"mock-fs": "^4.10.1", "mock-fs": "^4.10.1",
"nyc": "^14.1.1", "nyc": "^14.1.1",
"prebuild": "^9.0.1", "prebuild": "^9.0.1",

View File

@ -972,7 +972,7 @@ class PipelineWorker : public Nan::AsyncWorker {
->set("layout", baton->tileLayout) ->set("layout", baton->tileLayout)
->set("suffix", const_cast<char*>(suffix.data())) ->set("suffix", const_cast<char*>(suffix.data()))
->set("angle", CalculateAngleRotation(baton->tileAngle)) ->set("angle", CalculateAngleRotation(baton->tileAngle))
->set("skip-blanks", baton->skipBlanks); ->set("skip_blanks", baton->tileSkipBlanks);
// libvips chooses a default depth based on layout. Instead of replicating that logic here by // libvips chooses a default depth based on layout. Instead of replicating that logic here by
// not passing anything - libvips will handle choice // not passing anything - libvips will handle choice
@ -1380,7 +1380,7 @@ NAN_METHOD(pipeline) {
baton->tileOverlap = AttrTo<uint32_t>(options, "tileOverlap"); baton->tileOverlap = AttrTo<uint32_t>(options, "tileOverlap");
std::string tileContainer = AttrAsStr(options, "tileContainer"); std::string tileContainer = AttrAsStr(options, "tileContainer");
baton->tileAngle = AttrTo<int32_t>(options, "tileAngle"); baton->tileAngle = AttrTo<int32_t>(options, "tileAngle");
baton->skipBlanks = AttrTo<int32_t>(options, "skipBlanks"); baton->tileSkipBlanks = AttrTo<int32_t>(options, "tileSkipBlanks");
if (tileContainer == "zip") { if (tileContainer == "zip") {
baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_ZIP; baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_ZIP;
} else { } else {

View File

@ -174,7 +174,7 @@ struct PipelineBaton {
VipsForeignDzLayout tileLayout; VipsForeignDzLayout tileLayout;
std::string tileFormat; std::string tileFormat;
int tileAngle; int tileAngle;
int skipBlanks; int tileSkipBlanks;
VipsForeignDzDepth tileDepth; VipsForeignDzDepth tileDepth;
std::unique_ptr<double[]> recombMatrix; std::unique_ptr<double[]> recombMatrix;
@ -279,7 +279,7 @@ struct PipelineBaton {
tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS), tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),
tileLayout(VIPS_FOREIGN_DZ_LAYOUT_DZ), tileLayout(VIPS_FOREIGN_DZ_LAYOUT_DZ),
tileAngle(0), tileAngle(0),
skipBlanks(-1), tileSkipBlanks(-1),
tileDepth(VIPS_FOREIGN_DZ_DEPTH_LAST) {} tileDepth(VIPS_FOREIGN_DZ_DEPTH_LAST) {}
}; };