mirror of
https://github.com/lovell/sharp.git
synced 2026-02-04 21:56:18 +01:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4aff57b071 | ||
|
|
1df8d82fe0 | ||
|
|
98e90784f4 | ||
|
|
87ea54cc66 | ||
|
|
d5e98bc8ad | ||
|
|
fa69ff773a | ||
|
|
a183bb1cac | ||
|
|
cf62372cab |
@@ -41,8 +41,8 @@ Any change that modifies the existing public API should be added to the relevant
|
||||
|
||||
| Release | WIP branch |
|
||||
| ------: | :--------- |
|
||||
| v0.21.0 | teeth |
|
||||
| v0.22.0 | uptake |
|
||||
| v0.23.0 | vision |
|
||||
|
||||
Please squash your changes into a single commit using a command like `git rebase -i upstream/<wip-branch>`.
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ If the overlay image contains an alpha channel then composition with premultipli
|
||||
|
||||
### Parameters
|
||||
|
||||
- `overlay` **([Buffer][1] \| [String][2])** Buffer containing image data or String containing the path to an image file.
|
||||
- `overlay` **([Buffer][1] \| [String][2])?** Buffer containing image data or String containing the path to an image file.
|
||||
- `options` **[Object][3]?**
|
||||
- `options.gravity` **[String][2]** gravity at which to place the overlay. (optional, default `'centre'`)
|
||||
- `options.top` **[Number][4]?** the pixel offset from the top edge.
|
||||
|
||||
@@ -9,9 +9,8 @@
|
||||
a String containing the path to an JPEG, PNG, WebP, GIF, SVG or TIFF image file.
|
||||
JPEG, PNG, WebP, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
|
||||
- `options` **[Object][3]?** if present, is an Object with optional attributes.
|
||||
- `options.failOnError` **[Boolean][4]** by default apply a "best effort"
|
||||
to decode images, even if the data is corrupt or invalid. Set this flag to true
|
||||
if you'd rather halt processing and raise an error when loading invalid images. (optional, default `false`)
|
||||
- `options.failOnError` **[Boolean][4]** by default halt processing and raise an error when loading invalid images.
|
||||
Set this flag to `false` if you'd rather apply a "best effort" to decode images, even if the data is corrupt or invalid. (optional, default `true`)
|
||||
- `options.density` **[Number][5]** number representing the DPI for vector images. (optional, default `72`)
|
||||
- `options.page` **[Number][5]** page number to extract for multi-page input (GIF, TIFF) (optional, default `0`)
|
||||
- `options.raw` **[Object][3]?** describes raw pixel input image data. See `raw()` for pixel ordering.
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
|
||||
Requires libvips v8.7.0.
|
||||
|
||||
#### v0.21.3 - 19<sup>th</sup> January 2019
|
||||
|
||||
* Input image decoding now fails fast, set `failOnError` to change this behaviour.
|
||||
|
||||
* Failed filesystem-based input now separates missing file and invalid format errors.
|
||||
[#1542](https://github.com/lovell/sharp/issues/1542)
|
||||
|
||||
#### v0.21.2 - 13<sup>th</sup> January 2019
|
||||
|
||||
* Ensure all metadata is removed from PNG output unless `withMetadata` used.
|
||||
|
||||
@@ -20,7 +20,8 @@ const distBaseUrl = process.env.npm_config_sharp_dist_base_url || process.env.SH
|
||||
|
||||
const fail = function (err) {
|
||||
npmLog.error('sharp', err.message);
|
||||
npmLog.error('sharp', 'Please see http://sharp.pixelplumbing.com/page/install');
|
||||
npmLog.info('sharp', 'Attempting to build from source via node-gyp but this may fail due to the above error');
|
||||
npmLog.info('sharp', 'Please see https://sharp.pixelplumbing.com/page/install for required dependencies');
|
||||
process.exit(1);
|
||||
};
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ const is = require('./is');
|
||||
* // sharpened, with metadata, 90% quality WebP image data. Phew!
|
||||
* });
|
||||
*
|
||||
* @param {(Buffer|String)} overlay - Buffer containing image data or String containing the path to an image file.
|
||||
* @param {(Buffer|String)} [overlay] - Buffer containing image data or String containing the path to an image file.
|
||||
* @param {Object} [options]
|
||||
* @param {String} [options.gravity='centre'] - gravity at which to place the overlay.
|
||||
* @param {Number} [options.top] - the pixel offset from the top edge.
|
||||
|
||||
@@ -61,9 +61,8 @@ const debuglog = util.debuglog('sharp');
|
||||
* a String containing the path to an JPEG, PNG, WebP, GIF, SVG or TIFF image file.
|
||||
* JPEG, PNG, WebP, GIF, SVG, TIFF or raw pixel image data can be streamed into the object when not present.
|
||||
* @param {Object} [options] - if present, is an Object with optional attributes.
|
||||
* @param {Boolean} [options.failOnError=false] - by default apply a "best effort"
|
||||
* to decode images, even if the data is corrupt or invalid. Set this flag to true
|
||||
* if you'd rather halt processing and raise an error when loading invalid images.
|
||||
* @param {Boolean} [options.failOnError=true] - by default halt processing and raise an error when loading invalid images.
|
||||
* Set this flag to `false` if you'd rather apply a "best effort" to decode images, even if the data is corrupt or invalid.
|
||||
* @param {Number} [options.density=72] - number representing the DPI for vector images.
|
||||
* @param {Number} [options.page=0] - page number to extract for multi-page input (GIF, TIFF)
|
||||
* @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering.
|
||||
|
||||
@@ -9,7 +9,7 @@ const sharp = require('../build/Release/sharp.node');
|
||||
* @private
|
||||
*/
|
||||
function _createInputDescriptor (input, inputOptions, containerOptions) {
|
||||
const inputDescriptor = { failOnError: false };
|
||||
const inputDescriptor = { failOnError: true };
|
||||
if (is.string(input)) {
|
||||
// filesystem
|
||||
inputDescriptor.file = input;
|
||||
|
||||
@@ -32,7 +32,7 @@ const sharp = require('../build/Release/sharp.node');
|
||||
*/
|
||||
function toFile (fileOut, callback) {
|
||||
if (!fileOut || fileOut.length === 0) {
|
||||
const errOutputInvalid = new Error('Invalid output');
|
||||
const errOutputInvalid = new Error('Missing output file path');
|
||||
if (is.fn(callback)) {
|
||||
callback(errOutputInvalid);
|
||||
} else {
|
||||
|
||||
@@ -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.21.2",
|
||||
"version": "0.21.3",
|
||||
"author": "Lovell Fuller <npm@lovell.info>",
|
||||
"homepage": "https://github.com/lovell/sharp",
|
||||
"contributors": [
|
||||
@@ -108,7 +108,7 @@
|
||||
"devDependencies": {
|
||||
"async": "^2.6.1",
|
||||
"cc": "^1.0.2",
|
||||
"decompress-zip": "^0.3.1",
|
||||
"decompress-zip": "^0.3.2",
|
||||
"documentation": "^9.1.1",
|
||||
"exif-reader": "^1.0.2",
|
||||
"icc": "^1.0.0",
|
||||
|
||||
@@ -137,6 +137,7 @@ namespace sharp {
|
||||
case ImageType::VIPS: id = "v"; break;
|
||||
case ImageType::RAW: id = "raw"; break;
|
||||
case ImageType::UNKNOWN: id = "unknown"; break;
|
||||
case ImageType::MISSING: id = "missing"; break;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
@@ -203,6 +204,10 @@ namespace sharp {
|
||||
} else if (EndsWith(loader, "Magick") || EndsWith(loader, "MagickFile")) {
|
||||
imageType = ImageType::MAGICK;
|
||||
}
|
||||
} else {
|
||||
if (EndsWith(vips::VError().what(), " not found\n")) {
|
||||
imageType = ImageType::MISSING;
|
||||
}
|
||||
}
|
||||
return imageType;
|
||||
}
|
||||
@@ -269,6 +274,9 @@ namespace sharp {
|
||||
} else {
|
||||
// From filesystem
|
||||
imageType = DetermineImageType(descriptor->file.data());
|
||||
if (imageType == ImageType::MISSING) {
|
||||
throw vips::VError("Input file is missing");
|
||||
}
|
||||
if (imageType != ImageType::UNKNOWN) {
|
||||
try {
|
||||
vips::VOption *option = VImage::option()
|
||||
@@ -291,7 +299,7 @@ namespace sharp {
|
||||
throw vips::VError(std::string("Input file has corrupt header: ") + err.what());
|
||||
}
|
||||
} else {
|
||||
throw vips::VError("Input file is missing or of an unsupported image format");
|
||||
throw vips::VError("Input file contains unsupported image format");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace sharp {
|
||||
|
||||
InputDescriptor():
|
||||
buffer(nullptr),
|
||||
failOnError(FALSE),
|
||||
failOnError(TRUE),
|
||||
bufferLength(0),
|
||||
density(72.0),
|
||||
rawChannels(0),
|
||||
@@ -106,7 +106,8 @@ namespace sharp {
|
||||
FITS,
|
||||
VIPS,
|
||||
RAW,
|
||||
UNKNOWN
|
||||
UNKNOWN,
|
||||
MISSING
|
||||
};
|
||||
|
||||
// How many tasks are in the queue?
|
||||
|
||||
@@ -147,6 +147,47 @@
|
||||
...
|
||||
fun:WebPDecode
|
||||
}
|
||||
{
|
||||
cond_libwebp_generic
|
||||
Memcheck:Cond
|
||||
obj:/usr/lib/x86_64-linux-gnu/libwebp.so.6.0.2
|
||||
}
|
||||
|
||||
# tiff
|
||||
{
|
||||
param_tiff_write_encoded_tile
|
||||
Memcheck:Param
|
||||
write(buf)
|
||||
fun:write
|
||||
...
|
||||
fun:TIFFWriteEncodedTile
|
||||
}
|
||||
|
||||
# gsf
|
||||
{
|
||||
param_gsf_output_write
|
||||
Memcheck:Param
|
||||
write(buf)
|
||||
fun:write
|
||||
...
|
||||
fun:gsf_output_write
|
||||
}
|
||||
{
|
||||
value_gsf_output_write_crc32_little
|
||||
Memcheck:Value8
|
||||
fun:crc32_little
|
||||
...
|
||||
fun:gsf_output_write
|
||||
}
|
||||
|
||||
# fontconfig
|
||||
{
|
||||
leak_fontconfig_FcConfigSubstituteWithPat
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: definite,indirect
|
||||
...
|
||||
fun:FcConfigSubstituteWithPat
|
||||
}
|
||||
|
||||
# libvips
|
||||
{
|
||||
@@ -197,6 +238,11 @@
|
||||
...
|
||||
fun:vips_region_prepare_to
|
||||
}
|
||||
{
|
||||
cond_libvips_vips_stats_scan
|
||||
Memcheck:Cond
|
||||
fun:vips_stats_scan
|
||||
}
|
||||
{
|
||||
value_libvips_vips_region_fill
|
||||
Memcheck:Value8
|
||||
@@ -204,6 +250,17 @@
|
||||
fun:vips_region_fill
|
||||
fun:vips_region_prepare
|
||||
}
|
||||
{
|
||||
value_libvips_vips_hist_find_uchar_scan
|
||||
Memcheck:Value8
|
||||
fun:vips_hist_find_uchar_scan
|
||||
}
|
||||
{
|
||||
value_libvips_write_webp_image
|
||||
Memcheck:Value8
|
||||
...
|
||||
fun:write_webp_image
|
||||
}
|
||||
{
|
||||
leak_libvips_init
|
||||
Memcheck:Leak
|
||||
@@ -377,6 +434,56 @@
|
||||
...
|
||||
fun:_ZN4node12NodePlatformC1EiPN2v817TracingControllerE
|
||||
}
|
||||
{
|
||||
param_nodejs_delayed_task_scheduler
|
||||
Memcheck:Param
|
||||
epoll_ctl(event)
|
||||
fun:epoll_ctl
|
||||
fun:uv__io_poll
|
||||
fun:uv_run
|
||||
fun:_ZZN4node20BackgroundTaskRunner20DelayedTaskScheduler5StartEvENUlPvE_4_FUNES2_
|
||||
}
|
||||
{
|
||||
param_nodejs_isolate_data
|
||||
Memcheck:Param
|
||||
epoll_ctl(event)
|
||||
fun:epoll_ctl
|
||||
fun:uv__io_poll
|
||||
fun:uv_run
|
||||
fun:_ZN4node5StartEPN2v87IsolateEPNS_11IsolateDataERKSt6vectorISsSaISsEES9_
|
||||
}
|
||||
{
|
||||
param_nodejs_try_init_and_run_loop
|
||||
Memcheck:Param
|
||||
epoll_ctl(event)
|
||||
fun:epoll_ctl
|
||||
fun:uv__io_poll
|
||||
fun:uv_run
|
||||
fun:_ZN4node17SyncProcessRunner23TryInitializeAndRunLoopEN2v85LocalINS1_5ValueEEE
|
||||
}
|
||||
{
|
||||
param_nodejs_run_exit_handlers
|
||||
Memcheck:Param
|
||||
epoll_ctl(event)
|
||||
fun:epoll_ctl
|
||||
fun:uv__io_poll
|
||||
fun:uv_run
|
||||
fun:_ZN4node7tracing5AgentD1Ev
|
||||
fun:_ZN4node5._215D1Ev
|
||||
fun:__run_exit_handlers
|
||||
}
|
||||
{
|
||||
leak_nodejs_crypto_entropy_source
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN4node6crypto13EntropySourceEPhm
|
||||
}
|
||||
{
|
||||
leak_nodejs_debug_options
|
||||
Memcheck:Leak
|
||||
...
|
||||
fun:_ZN4node9inspector5Agent5StartERKSsSt10shared_ptrINS_12DebugOptionsEEb
|
||||
}
|
||||
{
|
||||
leak_nan_FunctionCallbackInfo
|
||||
Memcheck:Leak
|
||||
|
||||
@@ -6,10 +6,9 @@ const sharp = require('../../');
|
||||
const fixtures = require('../fixtures');
|
||||
|
||||
describe('failOnError', function () {
|
||||
it('handles truncated JPEG by default', function (done) {
|
||||
sharp(fixtures.inputJpgTruncated)
|
||||
it('handles truncated JPEG', function (done) {
|
||||
sharp(fixtures.inputJpgTruncated, { failOnError: false })
|
||||
.resize(320, 240)
|
||||
// .toFile(fixtures.expected('truncated.jpg'), done);
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('jpeg', info.format);
|
||||
@@ -19,10 +18,9 @@ describe('failOnError', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('handles truncated PNG by default', function (done) {
|
||||
sharp(fixtures.inputPngTruncated)
|
||||
it('handles truncated PNG', function (done) {
|
||||
sharp(fixtures.inputPngTruncated, { failOnError: false })
|
||||
.resize(320, 240)
|
||||
// .toFile(fixtures.expected('truncated.png'), done);
|
||||
.toBuffer(function (err, data, info) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual('png', info.format);
|
||||
@@ -46,8 +44,8 @@ describe('failOnError', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns errors to callback for truncated JPEG when failOnError is set', function (done) {
|
||||
sharp(fixtures.inputJpgTruncated, { failOnError: true }).toBuffer(function (err, data, info) {
|
||||
it('returns errors to callback for truncated JPEG', function (done) {
|
||||
sharp(fixtures.inputJpgTruncated).toBuffer(function (err, data, info) {
|
||||
assert.ok(err.message.includes('VipsJpeg: Premature end of JPEG file'), err);
|
||||
assert.strictEqual(data, null);
|
||||
assert.strictEqual(info, null);
|
||||
@@ -55,8 +53,8 @@ describe('failOnError', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('returns errors to callback for truncated PNG when failOnError is set', function (done) {
|
||||
sharp(fixtures.inputPngTruncated, { failOnError: true }).toBuffer(function (err, data, info) {
|
||||
it('returns errors to callback for truncated PNG', function (done) {
|
||||
sharp(fixtures.inputPngTruncated).toBuffer(function (err, data, info) {
|
||||
assert.ok(err.message.includes('vipspng: libpng read error'), err);
|
||||
assert.strictEqual(data, null);
|
||||
assert.strictEqual(info, null);
|
||||
@@ -64,8 +62,8 @@ describe('failOnError', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects promises for truncated JPEG when failOnError is set', function (done) {
|
||||
sharp(fixtures.inputJpgTruncated, { failOnError: true })
|
||||
it('rejects promises for truncated JPEG', function (done) {
|
||||
sharp(fixtures.inputJpgTruncated)
|
||||
.toBuffer()
|
||||
.then(() => {
|
||||
throw new Error('Expected rejection');
|
||||
|
||||
@@ -263,7 +263,8 @@ describe('Input/output', function () {
|
||||
|
||||
it('Fail when output File is input File', function (done) {
|
||||
sharp(fixtures.inputJpg).toFile(fixtures.inputJpg, function (err) {
|
||||
assert(!!err);
|
||||
assert(err instanceof Error);
|
||||
assert.strictEqual('Cannot use same file for input and output', err.message);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -273,14 +274,16 @@ describe('Input/output', function () {
|
||||
assert(false);
|
||||
done();
|
||||
}).catch(function (err) {
|
||||
assert(!!err);
|
||||
assert(err instanceof Error);
|
||||
assert.strictEqual('Cannot use same file for input and output', err.message);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Fail when output File is empty', function (done) {
|
||||
sharp(fixtures.inputJpg).toFile('', function (err) {
|
||||
assert(!!err);
|
||||
assert(err instanceof Error);
|
||||
assert.strictEqual('Missing output file path', err.message);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -290,7 +293,8 @@ describe('Input/output', function () {
|
||||
assert(false);
|
||||
done();
|
||||
}).catch(function (err) {
|
||||
assert(!!err);
|
||||
assert(err instanceof Error);
|
||||
assert.strictEqual('Missing output file path', err.message);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -301,6 +305,7 @@ describe('Input/output', function () {
|
||||
done();
|
||||
}).catch(function (err) {
|
||||
assert(err instanceof Error);
|
||||
assert.strictEqual('Input buffer contains unsupported image format', err.message);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -311,6 +316,18 @@ describe('Input/output', function () {
|
||||
done();
|
||||
}).catch(function (err) {
|
||||
assert(err instanceof Error);
|
||||
assert.strictEqual('Input buffer contains unsupported image format', err.message);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('Fail when input file path is missing', function (done) {
|
||||
sharp('does-not-exist').toBuffer().then(function () {
|
||||
assert(false);
|
||||
done();
|
||||
}).catch(function (err) {
|
||||
assert(err instanceof Error);
|
||||
assert.strictEqual('Input file is missing', err.message);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user