From 96a994a4c05194a60f4c805057915fcd7fab5161 Mon Sep 17 00:00:00 2001 From: Lovell Fuller Date: Fri, 3 Jan 2020 20:58:57 +0000 Subject: [PATCH] Move functions to improve logical ordering of docs --- docs/api-constructor.md | 42 ++++++++----------------- docs/api-input.md | 19 ------------ docs/api-output.md | 44 +++++++++++++------------- docs/api-utility.md | 37 ++++++++++++++++++++++ docs/index.md | 5 ++- lib/constructor.js | 66 +++++++++++++++++++-------------------- lib/input.js | 32 ------------------- lib/output.js | 68 ++++++++++++++++++++--------------------- lib/utility.js | 38 +++++++++++++++++++++++ 9 files changed, 176 insertions(+), 175 deletions(-) diff --git a/docs/api-constructor.md b/docs/api-constructor.md index 1f98241c..2451a879 100644 --- a/docs/api-constructor.md +++ b/docs/api-constructor.md @@ -67,43 +67,25 @@ sharp({ Returns **[Sharp][8]** -### format +## clone -An Object containing nested boolean values representing the available input and output formats/methods. - -#### Examples - -```javascript -console.log(sharp.format); -``` - -Returns **[Object][3]** - -### versions - -An Object containing the version numbers of libvips and its dependencies. - -#### Examples - -```javascript -console.log(sharp.versions); -``` - -## queue - -An EventEmitter that emits a `change` event when a task is either: - -- queued, waiting for _libuv_ to provide a worker thread -- complete +Take a "snapshot" of the Sharp instance, returning a new instance. +Cloned instances inherit the input of their parent instance. +This allows multiple output Streams and therefore multiple processing pipelines to share a single input Stream. ### Examples ```javascript -sharp.queue.on('change', function(queueLength) { - console.log('Queue contains ' + queueLength + ' task(s)'); -}); +const pipeline = sharp().rotate(); +pipeline.clone().resize(800, 600).pipe(firstWritableStream); +pipeline.clone().extract({ left: 20, top: 20, width: 100, height: 100 }).pipe(secondWritableStream); +readableStream.pipe(pipeline); +// firstWritableStream receives auto-rotated, resized readableStream +// secondWritableStream receives auto-rotated, extracted region of readableStream ``` +Returns **[Sharp][8]** + [1]: https://nodejs.org/api/buffer.html [2]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String diff --git a/docs/api-input.md b/docs/api-input.md index 734744ea..0455f59a 100644 --- a/docs/api-input.md +++ b/docs/api-input.md @@ -1,24 +1,5 @@ -## clone - -Take a "snapshot" of the Sharp instance, returning a new instance. -Cloned instances inherit the input of their parent instance. -This allows multiple output Streams and therefore multiple processing pipelines to share a single input Stream. - -### Examples - -```javascript -const pipeline = sharp().rotate(); -pipeline.clone().resize(800, 600).pipe(firstWritableStream); -pipeline.clone().extract({ left: 20, top: 20, width: 100, height: 100 }).pipe(secondWritableStream); -readableStream.pipe(pipeline); -// firstWritableStream receives auto-rotated, resized readableStream -// secondWritableStream receives auto-rotated, extracted region of readableStream -``` - -Returns **Sharp** - ## metadata Fast access to (uncached) image metadata without decoding any compressed image data. diff --git a/docs/api-output.md b/docs/api-output.md index 28b1de49..54d7a120 100644 --- a/docs/api-output.md +++ b/docs/api-output.md @@ -112,6 +112,28 @@ sharp('input.jpg') Returns **Sharp** +## toFormat + +Force output to a given format. + +### Parameters + +- `format` **([String][2] \| [Object][6])** as a String or an Object with an 'id' attribute +- `options` **[Object][6]** output options + +### Examples + +```javascript +// Convert any input to PNG output +const data = await sharp(input) + .toFormat('png') + .toBuffer(); +``` + +- Throws **[Error][4]** unsupported format or options + +Returns **Sharp** + ## jpeg Use these JPEG options for output image. @@ -287,28 +309,6 @@ const { data, info } = await sharp('input.jpg') Returns **Sharp** -## toFormat - -Force output to a given format. - -### Parameters - -- `format` **([String][2] \| [Object][6])** as a String or an Object with an 'id' attribute -- `options` **[Object][6]** output options - -### Examples - -```javascript -// Convert any input to PNG output -const data = await sharp(input) - .toFormat('png') - .toBuffer(); -``` - -- Throws **[Error][4]** unsupported format or options - -Returns **Sharp** - ## tile Use tile-based deep zoom (image pyramid) output. diff --git a/docs/api-utility.md b/docs/api-utility.md index 3c6413e8..3cea51e1 100644 --- a/docs/api-utility.md +++ b/docs/api-utility.md @@ -1,5 +1,27 @@ +## format + +An Object containing nested boolean values representing the available input and output formats/methods. + +### Examples + +```javascript +console.log(sharp.format); +``` + +Returns **[Object][1]** + +## versions + +An Object containing the version numbers of libvips and its dependencies. + +### Examples + +```javascript +console.log(sharp.versions); +``` + ## cache Gets or, when options are provided, sets the limits of _libvips'_ operation cache. @@ -54,6 +76,21 @@ sharp.concurrency(0); // 4 Returns **[Number][3]** concurrency +## queue + +An EventEmitter that emits a `change` event when a task is either: + +- queued, waiting for _libuv_ to provide a worker thread +- complete + +### Examples + +```javascript +sharp.queue.on('change', function(queueLength) { + console.log('Queue contains ' + queueLength + ' task(s)'); +}); +``` + ## counters Provides access to internal task counters. diff --git a/docs/index.md b/docs/index.md index 2f56b2de..2578e517 100644 --- a/docs/index.md +++ b/docs/index.md @@ -34,15 +34,14 @@ A single input Stream can be split into multiple processing pipelines and output Deep Zoom image pyramids can be generated, suitable for use with "slippy map" tile viewers like -[OpenSeadragon](https://github.com/openseadragon/openseadragon) -and [Leaflet](https://github.com/turban/Leaflet.Zoomify). +[OpenSeadragon](https://github.com/openseadragon/openseadragon). ### Fast This module is powered by the blazingly fast [libvips](https://github.com/libvips/libvips) image processing library, originally created in 1989 at Birkbeck College -and currently maintained by +and currently maintained by a small team led by [John Cupitt](https://github.com/jcupitt). Only small regions of uncompressed image data diff --git a/lib/constructor.js b/lib/constructor.js index 3736aef2..ad475c44 100644 --- a/lib/constructor.js +++ b/lib/constructor.js @@ -2,15 +2,13 @@ const util = require('util'); const stream = require('stream'); -const events = require('events'); const is = require('./is'); require('./libvips').hasVendoredLibvips(); -let sharp; /* istanbul ignore next */ try { - sharp = require('../build/Release/sharp.node'); + require('../build/Release/sharp.node'); } catch (err) { // Bail early if bindings aren't available const help = ['', 'Something went wrong installing the "sharp" module', '', err.message, '']; @@ -33,7 +31,7 @@ try { const debuglog = util.debuglog('sharp'); /** - * @class Sharp + * @constructs sharp * * Constructor factory to create an instance of `sharp`, to which further methods are chained. * @@ -220,7 +218,7 @@ const Sharp = function (input, options) { debuglog: debuglog, // Function to notify of queue length changes queueListener: function (queueLength) { - queue.emit('change', queueLength); + Sharp.queue.emit('change', queueLength); } }; this.options.input = this._createInputDescriptor(input, options, { allowStream: true }); @@ -229,38 +227,36 @@ const Sharp = function (input, options) { util.inherits(Sharp, stream.Duplex); /** - * An EventEmitter that emits a `change` event when a task is either: - * - queued, waiting for _libuv_ to provide a worker thread - * - complete - * @member + * Take a "snapshot" of the Sharp instance, returning a new instance. + * Cloned instances inherit the input of their parent instance. + * This allows multiple output Streams and therefore multiple processing pipelines to share a single input Stream. + * * @example - * sharp.queue.on('change', function(queueLength) { - * console.log('Queue contains ' + queueLength + ' task(s)'); - * }); + * const pipeline = sharp().rotate(); + * pipeline.clone().resize(800, 600).pipe(firstWritableStream); + * pipeline.clone().extract({ left: 20, top: 20, width: 100, height: 100 }).pipe(secondWritableStream); + * readableStream.pipe(pipeline); + * // firstWritableStream receives auto-rotated, resized readableStream + * // secondWritableStream receives auto-rotated, extracted region of readableStream + * + * @returns {Sharp} */ -const queue = new events.EventEmitter(); -Sharp.queue = queue; - -/** - * An Object containing nested boolean values representing the available input and output formats/methods. - * @example - * console.log(sharp.format); - * @returns {Object} - */ -Sharp.format = sharp.format(); - -/** - * An Object containing the version numbers of libvips and its dependencies. - * @member - * @example - * console.log(sharp.versions); - */ -Sharp.versions = { - vips: sharp.libvipsVersion() -}; -try { - Sharp.versions = require('../vendor/versions.json'); -} catch (err) {} +function clone () { + // Clone existing options + const clone = this.constructor.call(); + clone.options = Object.assign({}, this.options); + // Pass 'finish' event to clone for Stream-based input + if (this._isStreamInput()) { + this.on('finish', () => { + // Clone inherits input data + this._flattenBufferIn(); + clone.options.bufferIn = this.options.bufferIn; + clone.emit('finish'); + }); + } + return clone; +} +Object.assign(Sharp.prototype, { clone }); /** * Export constructor. diff --git a/lib/input.js b/lib/input.js index caf4fe73..082693d8 100644 --- a/lib/input.js +++ b/lib/input.js @@ -152,37 +152,6 @@ function _isStreamInput () { return Array.isArray(this.options.input.buffer); } -/** - * Take a "snapshot" of the Sharp instance, returning a new instance. - * Cloned instances inherit the input of their parent instance. - * This allows multiple output Streams and therefore multiple processing pipelines to share a single input Stream. - * - * @example - * const pipeline = sharp().rotate(); - * pipeline.clone().resize(800, 600).pipe(firstWritableStream); - * pipeline.clone().extract({ left: 20, top: 20, width: 100, height: 100 }).pipe(secondWritableStream); - * readableStream.pipe(pipeline); - * // firstWritableStream receives auto-rotated, resized readableStream - * // secondWritableStream receives auto-rotated, extracted region of readableStream - * - * @returns {Sharp} - */ -function clone () { - // Clone existing options - const clone = this.constructor.call(); - clone.options = Object.assign({}, this.options); - // Pass 'finish' event to clone for Stream-based input - if (this._isStreamInput()) { - this.on('finish', () => { - // Clone inherits input data - this._flattenBufferIn(); - clone.options.bufferIn = this.options.bufferIn; - clone.emit('finish'); - }); - } - return clone; -} - /** * Fast access to (uncached) image metadata without decoding any compressed image data. * A `Promise` is returned when `callback` is not provided. @@ -382,7 +351,6 @@ module.exports = function (Sharp) { _flattenBufferIn, _isStreamInput, // Public - clone, metadata, stats, limitInputPixels, diff --git a/lib/output.js b/lib/output.js index a49b0591..a61a0469 100644 --- a/lib/output.js +++ b/lib/output.js @@ -3,6 +3,17 @@ const is = require('./is'); const sharp = require('../build/Release/sharp.node'); +const formats = new Map([ + ['heic', 'heif'], + ['heif', 'heif'], + ['jpeg', 'jpeg'], + ['jpg', 'jpeg'], + ['png', 'png'], + ['raw', 'raw'], + ['tiff', 'tiff'], + ['webp', 'webp'] +]); + /** * Write output image data to a file. * @@ -135,6 +146,28 @@ function withMetadata (options) { return this; } +/** + * Force output to a given format. + * + * @example + * // Convert any input to PNG output + * const data = await sharp(input) + * .toFormat('png') + * .toBuffer(); + * + * @param {(String|Object)} format - as a String or an Object with an 'id' attribute + * @param {Object} options - output options + * @returns {Sharp} + * @throws {Error} unsupported format or options + */ +function toFormat (format, options) { + const actualFormat = formats.get(is.object(format) && is.string(format.id) ? format.id : format); + if (!actualFormat) { + throw is.invalidParameterError('format', `one of: ${[...formats.keys()].join(', ')}`, format); + } + return this[actualFormat](options); +} + /** * Use these JPEG options for output image. * @@ -498,39 +531,6 @@ function raw () { return this._updateFormatOut('raw'); } -const formats = new Map([ - ['heic', 'heif'], - ['heif', 'heif'], - ['jpeg', 'jpeg'], - ['jpg', 'jpeg'], - ['png', 'png'], - ['raw', 'raw'], - ['tiff', 'tiff'], - ['webp', 'webp'] -]); - -/** - * Force output to a given format. - * - * @example - * // Convert any input to PNG output - * const data = await sharp(input) - * .toFormat('png') - * .toBuffer(); - * - * @param {(String|Object)} format - as a String or an Object with an 'id' attribute - * @param {Object} options - output options - * @returns {Sharp} - * @throws {Error} unsupported format or options - */ -function toFormat (format, options) { - const actualFormat = formats.get(is.object(format) && is.string(format.id) ? format.id : format); - if (!actualFormat) { - throw is.invalidParameterError('format', `one of: ${[...formats.keys()].join(', ')}`, format); - } - return this[actualFormat](options); -} - /** * Use tile-based deep zoom (image pyramid) output. * Set the format and options for tile images via the `toFormat`, `jpeg`, `png` or `webp` functions. @@ -779,13 +779,13 @@ module.exports = function (Sharp) { toFile, toBuffer, withMetadata, + toFormat, jpeg, png, webp, tiff, heif, raw, - toFormat, tile, // Private _updateFormatOut, diff --git a/lib/utility.js b/lib/utility.js index 83c06d14..8bbad182 100644 --- a/lib/utility.js +++ b/lib/utility.js @@ -1,8 +1,31 @@ 'use strict'; +const events = require('events'); const is = require('./is'); const sharp = require('../build/Release/sharp.node'); +/** + * An Object containing nested boolean values representing the available input and output formats/methods. + * @member + * @example + * console.log(sharp.format); + * @returns {Object} + */ +const format = sharp.format(); + +/** + * An Object containing the version numbers of libvips and its dependencies. + * @member + * @example + * console.log(sharp.versions); + */ +let versions = { + vips: sharp.libvipsVersion() +}; +try { + versions = require('../vendor/versions.json'); +} catch (err) {} + /** * 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. @@ -61,6 +84,18 @@ function concurrency (concurrency) { return sharp.concurrency(is.integer(concurrency) ? concurrency : null); } +/** + * An EventEmitter that emits a `change` event when a task is either: + * - queued, waiting for _libuv_ to provide a worker thread + * - complete + * @member + * @example + * sharp.queue.on('change', function(queueLength) { + * console.log('Queue contains ' + queueLength + ' task(s)'); + * }); + */ +const queue = new events.EventEmitter(); + /** * Provides access to internal task counters. * - queue is the number of tasks this module has queued waiting for _libuv_ to provide a worker thread from its pool. @@ -110,4 +145,7 @@ module.exports = function (Sharp) { ].forEach(function (f) { Sharp[f.name] = f; }); + Sharp.format = format; + Sharp.versions = versions; + Sharp.queue = queue; };