mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 02:30:12 +02:00
Non-animated GIF output defaults to no-loop #3394
This commit is contained in:
parent
3fd818c4b5
commit
3e41f8b65e
@ -14,6 +14,9 @@ Requires libvips v8.16.1
|
||||
* Breaking: Ensure `removeAlpha` removes all alpha channels.
|
||||
[#2266](https://github.com/lovell/sharp/issues/2266)
|
||||
|
||||
* Breaking: Non-animated GIF output defaults to no-loop instead of loop-forever.
|
||||
[#3394](https://github.com/lovell/sharp/issues/3394)
|
||||
|
||||
* Breaking: Support `info.size` on wide-character systems via upgrade to C++17.
|
||||
[#3943](https://github.com/lovell/sharp/issues/3943)
|
||||
|
||||
|
@ -296,6 +296,8 @@ const Sharp = function (input, options) {
|
||||
withExif: {},
|
||||
withExifMerge: true,
|
||||
resolveWithObject: false,
|
||||
loop: 1,
|
||||
delay: [],
|
||||
// output format
|
||||
jpegQuality: 80,
|
||||
jpegProgressive: false,
|
||||
|
@ -1705,6 +1705,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
||||
}
|
||||
baton->withExifMerge = sharp::AttrAsBool(options, "withExifMerge");
|
||||
baton->timeoutSeconds = sharp::AttrAsUint32(options, "timeoutSeconds");
|
||||
baton->loop = sharp::AttrAsUint32(options, "loop");
|
||||
baton->delay = sharp::AttrAsInt32Vector(options, "delay");
|
||||
// Format-specific
|
||||
baton->jpegQuality = sharp::AttrAsUint32(options, "jpegQuality");
|
||||
baton->jpegProgressive = sharp::AttrAsBool(options, "jpegProgressive");
|
||||
@ -1774,13 +1776,6 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
|
||||
baton->jxlEffort = sharp::AttrAsUint32(options, "jxlEffort");
|
||||
baton->jxlLossless = sharp::AttrAsBool(options, "jxlLossless");
|
||||
baton->rawDepth = sharp::AttrAsEnum<VipsBandFormat>(options, "rawDepth", VIPS_TYPE_BAND_FORMAT);
|
||||
// Animated output properties
|
||||
if (sharp::HasAttr(options, "loop")) {
|
||||
baton->loop = sharp::AttrAsUint32(options, "loop");
|
||||
}
|
||||
if (sharp::HasAttr(options, "delay")) {
|
||||
baton->delay = sharp::AttrAsInt32Vector(options, "delay");
|
||||
}
|
||||
baton->tileSize = sharp::AttrAsUint32(options, "tileSize");
|
||||
baton->tileOverlap = sharp::AttrAsUint32(options, "tileOverlap");
|
||||
baton->tileAngle = sharp::AttrAsInt32(options, "tileAngle");
|
||||
|
@ -380,7 +380,7 @@ struct PipelineBaton {
|
||||
ensureAlpha(-1.0),
|
||||
colourspacePipeline(VIPS_INTERPRETATION_LAST),
|
||||
colourspace(VIPS_INTERPRETATION_LAST),
|
||||
loop(-1),
|
||||
loop(1),
|
||||
tileSize(256),
|
||||
tileOverlap(0),
|
||||
tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),
|
||||
|
@ -224,4 +224,18 @@ describe('GIF input', () => {
|
||||
const after = await input.gif({ interPaletteMaxError: 100 }).toBuffer();
|
||||
assert.strict(before.length > after.length);
|
||||
});
|
||||
|
||||
it('non-animated input defaults to no-loop', async () => {
|
||||
for (const input of [fixtures.inputGif, fixtures.inputPng]) {
|
||||
const data = await sharp(input)
|
||||
.resize(8)
|
||||
.gif({ effort: 1 })
|
||||
.toBuffer();
|
||||
|
||||
const { format, pages, loop } = await sharp(data).metadata();
|
||||
assert.strictEqual('gif', format);
|
||||
assert.strictEqual(1, pages);
|
||||
assert.strictEqual(1, loop);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user