'use strict';
const path = require('path');
const is = require('./is');
const sharp = require('./sharp');
const formats = new Map([
['heic', 'heif'],
['heif', 'heif'],
['avif', 'avif'],
['jpeg', 'jpeg'],
['jpg', 'jpeg'],
['jpe', 'jpeg'],
['tile', 'tile'],
['dz', 'tile'],
['png', 'png'],
['raw', 'raw'],
['tiff', 'tiff'],
['tif', 'tiff'],
['webp', 'webp'],
['gif', 'gif'],
['jp2', 'jp2'],
['jpx', 'jp2'],
['j2k', 'jp2'],
['j2c', 'jp2'],
['jxl', 'jxl']
]);
const jp2Regex = /\.(jp[2x]|j2[kc])$/i;
const errJp2Save = () => new Error('JP2 output requires libvips with support for OpenJPEG');
const bitdepthFromColourCount = (colours) => 1 << 31 - Math.clz32(Math.ceil(Math.log2(colours)));
function toFile (fileOut, callback) {
let err;
if (!is.string(fileOut)) {
err = new Error('Missing output file path');
} else if (is.string(this.options.input.file) && path.resolve(this.options.input.file) === path.resolve(fileOut)) {
err = new Error('Cannot use same file for input and output');
} else if (jp2Regex.test(path.extname(fileOut)) && !this.constructor.format.jp2k.output.file) {
err = errJp2Save();
}
if (err) {
if (is.fn(callback)) {
callback(err);
} else {
return Promise.reject(err);
}
} else {
this.options.fileOut = fileOut;
return this._pipeline(callback);
}
return this;
}
function toBuffer (options, callback) {
if (is.object(options)) {
this._setBooleanOption('resolveWithObject', options.resolveWithObject);
} else if (this.options.resolveWithObject) {
this.options.resolveWithObject = false;
}
this.options.fileOut = '';
return this._pipeline(is.fn(options) ? options : callback);
}
function withMetadata (options) {
this.options.withMetadata = is.bool(options) ? options : true;
if (is.object(options)) {
if (is.defined(options.orientation)) {
if (is.integer(options.orientation) && is.inRange(options.orientation, 1, 8)) {
this.options.withMetadataOrientation = options.orientation;
} else {
throw is.invalidParameterError('orientation', 'integer between 1 and 8', options.orientation);
}
}
if (is.defined(options.density)) {
if (is.number(options.density) && options.density > 0) {
this.options.withMetadataDensity = options.density;
} else {
throw is.invalidParameterError('density', 'positive number', options.density);
}
}
if (is.defined(options.icc)) {
if (is.string(options.icc)) {
this.options.withMetadataIcc = options.icc;
} else {
throw is.invalidParameterError('icc', 'string filesystem path to ICC profile', options.icc);
}
}
if (is.defined(options.exif)) {
if (is.object(options.exif)) {
for (const [ifd, entries] of Object.entries(options.exif)) {
if (is.object(entries)) {
for (const [k, v] of Object.entries(entries)) {
if (is.string(v)) {
this.options.withMetadataStrs[`exif-${ifd.toLowerCase()}-${k}`] = v;
} else {
throw is.invalidParameterError(`exif.${ifd}.${k}`, 'string', v);
}
}
} else {
throw is.invalidParameterError(`exif.${ifd}`, 'object', entries);
}
}
} else {
throw is.invalidParameterError('exif', 'object', options.exif);
}
}
}
return this;
}
function toFormat (format, options) {
const actualFormat = formats.get((is.object(format) && is.string(format.id) ? format.id : format).toLowerCase());
if (!actualFormat) {
throw is.invalidParameterError('format', `one of: ${[...formats.keys()].join(', ')}`, format);
}
return this[actualFormat](options);
}
function jpeg (options) {
if (is.object(options)) {
if (is.defined(options.quality)) {
if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
this.options.jpegQuality = options.quality;
} else {
throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality);
}
}
if (is.defined(options.progressive)) {
this._setBooleanOption('jpegProgressive', options.progressive);
}
if (is.defined(options.chromaSubsampling)) {
if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) {
this.options.jpegChromaSubsampling = options.chromaSubsampling;
} else {
throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling);
}
}
const optimiseCoding = is.bool(options.optimizeCoding) ? options.optimizeCoding : options.optimiseCoding;
if (is.defined(optimiseCoding)) {
this._setBooleanOption('jpegOptimiseCoding', optimiseCoding);
}
if (is.defined(options.mozjpeg)) {
if (is.bool(options.mozjpeg)) {
if (options.mozjpeg) {
this.options.jpegTrellisQuantisation = true;
this.options.jpegOvershootDeringing = true;
this.options.jpegOptimiseScans = true;
this.options.jpegProgressive = true;
this.options.jpegQuantisationTable = 3;
}
} else {
throw is.invalidParameterError('mozjpeg', 'boolean', options.mozjpeg);
}
}
const trellisQuantisation = is.bool(options.trellisQuantization) ? options.trellisQuantization : options.trellisQuantisation;
if (is.defined(trellisQuantisation)) {
this._setBooleanOption('jpegTrellisQuantisation', trellisQuantisation);
}
if (is.defined(options.overshootDeringing)) {
this._setBooleanOption('jpegOvershootDeringing', options.overshootDeringing);
}
const optimiseScans = is.bool(options.optimizeScans) ? options.optimizeScans : options.optimiseScans;
if (is.defined(optimiseScans)) {
this._setBooleanOption('jpegOptimiseScans', optimiseScans);
if (optimiseScans) {
this.options.jpegProgressive = true;
}
}
const quantisationTable = is.number(options.quantizationTable) ? options.quantizationTable : options.quantisationTable;
if (is.defined(quantisationTable)) {
if (is.integer(quantisationTable) && is.inRange(quantisationTable, 0, 8)) {
this.options.jpegQuantisationTable = quantisationTable;
} else {
throw is.invalidParameterError('quantisationTable', 'integer between 0 and 8', quantisationTable);
}
}
}
return this._updateFormatOut('jpeg', options);
}
function png (options) {
if (is.object(options)) {
if (is.defined(options.progressive)) {
this._setBooleanOption('pngProgressive', options.progressive);
}
if (is.defined(options.compressionLevel)) {
if (is.integer(options.compressionLevel) && is.inRange(options.compressionLevel, 0, 9)) {
this.options.pngCompressionLevel = options.compressionLevel;
} else {
throw is.invalidParameterError('compressionLevel', 'integer between 0 and 9', options.compressionLevel);
}
}
if (is.defined(options.adaptiveFiltering)) {
this._setBooleanOption('pngAdaptiveFiltering', options.adaptiveFiltering);
}
const colours = options.colours || options.colors;
if (is.defined(colours)) {
if (is.integer(colours) && is.inRange(colours, 2, 256)) {
this.options.pngBitdepth = bitdepthFromColourCount(colours);
} else {
throw is.invalidParameterError('colours', 'integer between 2 and 256', colours);
}
}
if (is.defined(options.palette)) {
this._setBooleanOption('pngPalette', options.palette);
} else if ([options.quality, options.effort, options.colours, options.colors, options.dither].some(is.defined)) {
this._setBooleanOption('pngPalette', true);
}
if (this.options.pngPalette) {
if (is.defined(options.quality)) {
if (is.integer(options.quality) && is.inRange(options.quality, 0, 100)) {
this.options.pngQuality = options.quality;
} else {
throw is.invalidParameterError('quality', 'integer between 0 and 100', options.quality);
}
}
if (is.defined(options.effort)) {
if (is.integer(options.effort) && is.inRange(options.effort, 1, 10)) {
this.options.pngEffort = options.effort;
} else {
throw is.invalidParameterError('effort', 'integer between 1 and 10', options.effort);
}
}
if (is.defined(options.dither)) {
if (is.number(options.dither) && is.inRange(options.dither, 0, 1)) {
this.options.pngDither = options.dither;
} else {
throw is.invalidParameterError('dither', 'number between 0.0 and 1.0', options.dither);
}
}
}
}
return this._updateFormatOut('png', options);
}
function webp (options) {
if (is.object(options)) {
if (is.defined(options.quality)) {
if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
this.options.webpQuality = options.quality;
} else {
throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality);
}
}
if (is.defined(options.alphaQuality)) {
if (is.integer(options.alphaQuality) && is.inRange(options.alphaQuality, 0, 100)) {
this.options.webpAlphaQuality = options.alphaQuality;
} else {
throw is.invalidParameterError('alphaQuality', 'integer between 0 and 100', options.alphaQuality);
}
}
if (is.defined(options.lossless)) {
this._setBooleanOption('webpLossless', options.lossless);
}
if (is.defined(options.nearLossless)) {
this._setBooleanOption('webpNearLossless', options.nearLossless);
}
if (is.defined(options.smartSubsample)) {
this._setBooleanOption('webpSmartSubsample', options.smartSubsample);
}
if (is.defined(options.preset)) {
if (is.string(options.preset) && is.inArray(options.preset, ['default', 'photo', 'picture', 'drawing', 'icon', 'text'])) {
this.options.webpPreset = options.preset;
} else {
throw is.invalidParameterError('preset', 'one of: default, photo, picture, drawing, icon, text', options.preset);
}
}
if (is.defined(options.effort)) {
if (is.integer(options.effort) && is.inRange(options.effort, 0, 6)) {
this.options.webpEffort = options.effort;
} else {
throw is.invalidParameterError('effort', 'integer between 0 and 6', options.effort);
}
}
if (is.defined(options.minSize)) {
this._setBooleanOption('webpMinSize', options.minSize);
}
if (is.defined(options.mixed)) {
this._setBooleanOption('webpMixed', options.mixed);
}
}
trySetAnimationOptions(options, this.options);
return this._updateFormatOut('webp', options);
}
function gif (options) {
if (is.object(options)) {
if (is.defined(options.reuse)) {
this._setBooleanOption('gifReuse', options.reuse);
}
if (is.defined(options.progressive)) {
this._setBooleanOption('gifProgressive', options.progressive);
}
const colours = options.colours || options.colors;
if (is.defined(colours)) {
if (is.integer(colours) && is.inRange(colours, 2, 256)) {
this.options.gifBitdepth = bitdepthFromColourCount(colours);
} else {
throw is.invalidParameterError('colours', 'integer between 2 and 256', colours);
}
}
if (is.defined(options.effort)) {
if (is.number(options.effort) && is.inRange(options.effort, 1, 10)) {
this.options.gifEffort = options.effort;
} else {
throw is.invalidParameterError('effort', 'integer between 1 and 10', options.effort);
}
}
if (is.defined(options.dither)) {
if (is.number(options.dither) && is.inRange(options.dither, 0, 1)) {
this.options.gifDither = options.dither;
} else {
throw is.invalidParameterError('dither', 'number between 0.0 and 1.0', options.dither);
}
}
if (is.defined(options.interFrameMaxError)) {
if (is.number(options.interFrameMaxError) && is.inRange(options.interFrameMaxError, 0, 32)) {
this.options.gifInterFrameMaxError = options.interFrameMaxError;
} else {
throw is.invalidParameterError('interFrameMaxError', 'number between 0.0 and 32.0', options.interFrameMaxError);
}
}
if (is.defined(options.interPaletteMaxError)) {
if (is.number(options.interPaletteMaxError) && is.inRange(options.interPaletteMaxError, 0, 256)) {
this.options.gifInterPaletteMaxError = options.interPaletteMaxError;
} else {
throw is.invalidParameterError('interPaletteMaxError', 'number between 0.0 and 256.0', options.interPaletteMaxError);
}
}
}
trySetAnimationOptions(options, this.options);
return this._updateFormatOut('gif', options);
}
function jp2 (options) {
if (!this.constructor.format.jp2k.output.buffer) {
throw errJp2Save();
}
if (is.object(options)) {
if (is.defined(options.quality)) {
if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
this.options.jp2Quality = options.quality;
} else {
throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality);
}
}
if (is.defined(options.lossless)) {
if (is.bool(options.lossless)) {
this.options.jp2Lossless = options.lossless;
} else {
throw is.invalidParameterError('lossless', 'boolean', options.lossless);
}
}
if (is.defined(options.tileWidth)) {
if (is.integer(options.tileWidth) && is.inRange(options.tileWidth, 1, 32768)) {
this.options.jp2TileWidth = options.tileWidth;
} else {
throw is.invalidParameterError('tileWidth', 'integer between 1 and 32768', options.tileWidth);
}
}
if (is.defined(options.tileHeight)) {
if (is.integer(options.tileHeight) && is.inRange(options.tileHeight, 1, 32768)) {
this.options.jp2TileHeight = options.tileHeight;
} else {
throw is.invalidParameterError('tileHeight', 'integer between 1 and 32768', options.tileHeight);
}
}
if (is.defined(options.chromaSubsampling)) {
if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) {
this.options.jp2ChromaSubsampling = options.chromaSubsampling;
} else {
throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling);
}
}
}
return this._updateFormatOut('jp2', options);
}
function trySetAnimationOptions (source, target) {
if (is.object(source) && is.defined(source.loop)) {
if (is.integer(source.loop) && is.inRange(source.loop, 0, 65535)) {
target.loop = source.loop;
} else {
throw is.invalidParameterError('loop', 'integer between 0 and 65535', source.loop);
}
}
if (is.object(source) && is.defined(source.delay)) {
if (is.integer(source.delay) && is.inRange(source.delay, 0, 65535)) {
target.delay = [source.delay];
} else if (
Array.isArray(source.delay) &&
source.delay.every(is.integer) &&
source.delay.every(v => is.inRange(v, 0, 65535))) {
target.delay = source.delay;
} else {
throw is.invalidParameterError('delay', 'integer or an array of integers between 0 and 65535', source.delay);
}
}
}
function tiff (options) {
if (is.object(options)) {
if (is.defined(options.quality)) {
if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
this.options.tiffQuality = options.quality;
} else {
throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality);
}
}
if (is.defined(options.bitdepth)) {
if (is.integer(options.bitdepth) && is.inArray(options.bitdepth, [1, 2, 4, 8])) {
this.options.tiffBitdepth = options.bitdepth;
} else {
throw is.invalidParameterError('bitdepth', '1, 2, 4 or 8', options.bitdepth);
}
}
if (is.defined(options.tile)) {
this._setBooleanOption('tiffTile', options.tile);
}
if (is.defined(options.tileWidth)) {
if (is.integer(options.tileWidth) && options.tileWidth > 0) {
this.options.tiffTileWidth = options.tileWidth;
} else {
throw is.invalidParameterError('tileWidth', 'integer greater than zero', options.tileWidth);
}
}
if (is.defined(options.tileHeight)) {
if (is.integer(options.tileHeight) && options.tileHeight > 0) {
this.options.tiffTileHeight = options.tileHeight;
} else {
throw is.invalidParameterError('tileHeight', 'integer greater than zero', options.tileHeight);
}
}
if (is.defined(options.pyramid)) {
this._setBooleanOption('tiffPyramid', options.pyramid);
}
if (is.defined(options.xres)) {
if (is.number(options.xres) && options.xres > 0) {
this.options.tiffXres = options.xres;
} else {
throw is.invalidParameterError('xres', 'number greater than zero', options.xres);
}
}
if (is.defined(options.yres)) {
if (is.number(options.yres) && options.yres > 0) {
this.options.tiffYres = options.yres;
} else {
throw is.invalidParameterError('yres', 'number greater than zero', options.yres);
}
}
if (is.defined(options.compression)) {
if (is.string(options.compression) && is.inArray(options.compression, ['none', 'jpeg', 'deflate', 'packbits', 'ccittfax4', 'lzw', 'webp', 'zstd', 'jp2k'])) {
this.options.tiffCompression = options.compression;
} else {
throw is.invalidParameterError('compression', 'one of: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k', options.compression);
}
}
if (is.defined(options.predictor)) {
if (is.string(options.predictor) && is.inArray(options.predictor, ['none', 'horizontal', 'float'])) {
this.options.tiffPredictor = options.predictor;
} else {
throw is.invalidParameterError('predictor', 'one of: none, horizontal, float', options.predictor);
}
}
if (is.defined(options.resolutionUnit)) {
if (is.string(options.resolutionUnit) && is.inArray(options.resolutionUnit, ['inch', 'cm'])) {
this.options.tiffResolutionUnit = options.resolutionUnit;
} else {
throw is.invalidParameterError('resolutionUnit', 'one of: inch, cm', options.resolutionUnit);
}
}
}
return this._updateFormatOut('tiff', options);
}
function avif (options) {
return this.heif({ ...options, compression: 'av1' });
}
function heif (options) {
if (is.object(options)) {
if (is.defined(options.quality)) {
if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
this.options.heifQuality = options.quality;
} else {
throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality);
}
}
if (is.defined(options.lossless)) {
if (is.bool(options.lossless)) {
this.options.heifLossless = options.lossless;
} else {
throw is.invalidParameterError('lossless', 'boolean', options.lossless);
}
}
if (is.defined(options.compression)) {
if (is.string(options.compression) && is.inArray(options.compression, ['av1', 'hevc'])) {
this.options.heifCompression = options.compression;
} else {
throw is.invalidParameterError('compression', 'one of: av1, hevc', options.compression);
}
}
if (is.defined(options.effort)) {
if (is.integer(options.effort) && is.inRange(options.effort, 0, 9)) {
this.options.heifEffort = options.effort;
} else {
throw is.invalidParameterError('effort', 'integer between 0 and 9', options.effort);
}
}
if (is.defined(options.chromaSubsampling)) {
if (is.string(options.chromaSubsampling) && is.inArray(options.chromaSubsampling, ['4:2:0', '4:4:4'])) {
this.options.heifChromaSubsampling = options.chromaSubsampling;
} else {
throw is.invalidParameterError('chromaSubsampling', 'one of: 4:2:0, 4:4:4', options.chromaSubsampling);
}
}
}
return this._updateFormatOut('heif', options);
}
function jxl (options) {
if (is.object(options)) {
if (is.defined(options.quality)) {
if (is.integer(options.quality) && is.inRange(options.quality, 1, 100)) {
this.options.jxlDistance = options.quality >= 30
? 0.1 + (100 - options.quality) * 0.09
: 53 / 3000 * options.quality * options.quality - 23 / 20 * options.quality + 25;
} else {
throw is.invalidParameterError('quality', 'integer between 1 and 100', options.quality);
}
} else if (is.defined(options.distance)) {
if (is.number(options.distance) && is.inRange(options.distance, 0, 15)) {
this.options.jxlDistance = options.distance;
} else {
throw is.invalidParameterError('distance', 'number between 0.0 and 15.0', options.distance);
}
}
if (is.defined(options.decodingTier)) {
if (is.integer(options.decodingTier) && is.inRange(options.decodingTier, 0, 4)) {
this.options.jxlDecodingTier = options.decodingTier;
} else {
throw is.invalidParameterError('decodingTier', 'integer between 0 and 4', options.decodingTier);
}
}
if (is.defined(options.lossless)) {
if (is.bool(options.lossless)) {
this.options.jxlLossless = options.lossless;
} else {
throw is.invalidParameterError('lossless', 'boolean', options.lossless);
}
}
if (is.defined(options.effort)) {
if (is.integer(options.effort) && is.inRange(options.effort, 3, 9)) {
this.options.jxlEffort = options.effort;
} else {
throw is.invalidParameterError('effort', 'integer between 3 and 9', options.effort);
}
}
}
return this._updateFormatOut('jxl', options);
}
function raw (options) {
if (is.object(options)) {
if (is.defined(options.depth)) {
if (is.string(options.depth) && is.inArray(options.depth,
['char', 'uchar', 'short', 'ushort', 'int', 'uint', 'float', 'complex', 'double', 'dpcomplex']
)) {
this.options.rawDepth = options.depth;
} else {
throw is.invalidParameterError('depth', 'one of: char, uchar, short, ushort, int, uint, float, complex, double, dpcomplex', options.depth);
}
}
}
return this._updateFormatOut('raw');
}
function tile (options) {
if (is.object(options)) {
if (is.defined(options.size)) {
if (is.integer(options.size) && is.inRange(options.size, 1, 8192)) {
this.options.tileSize = options.size;
} else {
throw is.invalidParameterError('size', 'integer between 1 and 8192', options.size);
}
}
if (is.defined(options.overlap)) {
if (is.integer(options.overlap) && is.inRange(options.overlap, 0, 8192)) {
if (options.overlap > this.options.tileSize) {
throw is.invalidParameterError('overlap', `<= size (${this.options.tileSize})`, options.overlap);
}
this.options.tileOverlap = options.overlap;
} else {
throw is.invalidParameterError('overlap', 'integer between 0 and 8192', options.overlap);
}
}
if (is.defined(options.container)) {
if (is.string(options.container) && is.inArray(options.container, ['fs', 'zip'])) {
this.options.tileContainer = options.container;
} else {
throw is.invalidParameterError('container', 'one of: fs, zip', options.container);
}
}
if (is.defined(options.layout)) {
if (is.string(options.layout) && is.inArray(options.layout, ['dz', 'google', 'iiif', 'iiif3', 'zoomify'])) {
this.options.tileLayout = options.layout;
} else {
throw is.invalidParameterError('layout', 'one of: dz, google, iiif, iiif3, zoomify', options.layout);
}
}
if (is.defined(options.angle)) {
if (is.integer(options.angle) && !(options.angle % 90)) {
this.options.tileAngle = options.angle;
} else {
throw is.invalidParameterError('angle', 'positive/negative multiple of 90', options.angle);
}
}
this._setBackgroundColourOption('tileBackground', options.background);
if (is.defined(options.depth)) {
if (is.string(options.depth) && is.inArray(options.depth, ['onepixel', 'onetile', 'one'])) {
this.options.tileDepth = options.depth;
} else {
throw is.invalidParameterError('depth', 'one of: onepixel, onetile, one', options.depth);
}
}
if (is.defined(options.skipBlanks)) {
if (is.integer(options.skipBlanks) && is.inRange(options.skipBlanks, -1, 65535)) {
this.options.tileSkipBlanks = options.skipBlanks;
} else {
throw is.invalidParameterError('skipBlanks', 'integer between -1 and 255/65535', options.skipBlanks);
}
} else if (is.defined(options.layout) && options.layout === 'google') {
this.options.tileSkipBlanks = 5;
}
const centre = is.bool(options.center) ? options.center : options.centre;
if (is.defined(centre)) {
this._setBooleanOption('tileCentre', centre);
}
if (is.defined(options.id)) {
if (is.string(options.id)) {
this.options.tileId = options.id;
} else {
throw is.invalidParameterError('id', 'string', options.id);
}
}
if (is.defined(options.basename)) {
if (is.string(options.basename)) {
this.options.tileBasename = options.basename;
} else {
throw is.invalidParameterError('basename', 'string', options.basename);
}
}
}
if (is.inArray(this.options.formatOut, ['jpeg', 'png', 'webp'])) {
this.options.tileFormat = this.options.formatOut;
} else if (this.options.formatOut !== 'input') {
throw is.invalidParameterError('format', 'one of: jpeg, png, webp', this.options.formatOut);
}
return this._updateFormatOut('dz');
}
function timeout (options) {
if (!is.plainObject(options)) {
throw is.invalidParameterError('options', 'object', options);
}
if (is.integer(options.seconds) && is.inRange(options.seconds, 0, 3600)) {
this.options.timeoutSeconds = options.seconds;
} else {
throw is.invalidParameterError('seconds', 'integer between 0 and 3600', options.seconds);
}
return this;
}
function _updateFormatOut (formatOut, options) {
if (!(is.object(options) && options.force === false)) {
this.options.formatOut = formatOut;
}
return this;
}
function _setBooleanOption (key, val) {
if (is.bool(val)) {
this.options[key] = val;
} else {
throw is.invalidParameterError(key, 'boolean', val);
}
}
function _read () {
if (!this.options.streamOut) {
this.options.streamOut = true;
this._pipeline();
}
}
function _pipeline (callback) {
if (typeof callback === 'function') {
if (this._isStreamInput()) {
this.on('finish', () => {
this._flattenBufferIn();
sharp.pipeline(this.options, callback);
});
} else {
sharp.pipeline(this.options, callback);
}
return this;
} else if (this.options.streamOut) {
if (this._isStreamInput()) {
this.once('finish', () => {
this._flattenBufferIn();
sharp.pipeline(this.options, (err, data, info) => {
if (err) {
this.emit('error', err);
} else {
this.emit('info', info);
this.push(data);
}
this.push(null);
this.on('end', () => this.emit('close'));
});
});
if (this.streamInFinished) {
this.emit('finish');
}
} else {
sharp.pipeline(this.options, (err, data, info) => {
if (err) {
this.emit('error', err);
} else {
this.emit('info', info);
this.push(data);
}
this.push(null);
this.on('end', () => this.emit('close'));
});
}
return this;
} else {
if (this._isStreamInput()) {
return new Promise((resolve, reject) => {
this.once('finish', () => {
this._flattenBufferIn();
sharp.pipeline(this.options, (err, data, info) => {
if (err) {
reject(err);
} else {
if (this.options.resolveWithObject) {
resolve({ data, info });
} else {
resolve(data);
}
}
});
});
});
} else {
return new Promise((resolve, reject) => {
sharp.pipeline(this.options, (err, data, info) => {
if (err) {
reject(err);
} else {
if (this.options.resolveWithObject) {
resolve({ data: data, info: info });
} else {
resolve(data);
}
}
});
});
}
}
}
module.exports = function (Sharp) {
Object.assign(Sharp.prototype, {
toFile,
toBuffer,
withMetadata,
toFormat,
jpeg,
jp2,
png,
webp,
tiff,
avif,
heif,
jxl,
gif,
raw,
tile,
timeout,
_updateFormatOut,
_setBooleanOption,
_read,
_pipeline
});
};