Add support for BigTIFF output (#4459)

This commit is contained in:
throwbi 2025-09-30 10:41:02 +02:00 committed by GitHub
parent 54722dd582
commit 6b922b30d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 26 additions and 0 deletions

View File

@ -646,6 +646,7 @@ instead of providing `xres` and `yres` in pixels/mm.
| [options.quality] | <code>number</code> | <code>80</code> | quality, integer 1-100 |
| [options.force] | <code>boolean</code> | <code>true</code> | force TIFF output, otherwise attempt to use input format |
| [options.compression] | <code>string</code> | <code>&quot;&#x27;jpeg&#x27;&quot;</code> | compression options: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k |
| [options.bigtiff] | <code>boolean</code> | <code>false</code> | use BigTIFF variant (has no effect when compression is none) |
| [options.predictor] | <code>string</code> | <code>&quot;&#x27;horizontal&#x27;&quot;</code> | compression predictor options: none, horizontal, float |
| [options.pyramid] | <code>boolean</code> | <code>false</code> | write an image pyramid |
| [options.tile] | <code>boolean</code> | <code>false</code> | write a tiled tiff |

View File

@ -352,6 +352,7 @@ const Sharp = function (input, options) {
gifProgressive: false,
tiffQuality: 80,
tiffCompression: 'jpeg',
tiffBigtiff: false,
tiffPredictor: 'horizontal',
tiffPyramid: false,
tiffMiniswhite: false,

2
lib/index.d.ts vendored
View File

@ -1460,6 +1460,8 @@ declare namespace sharp {
quality?: number | undefined;
/** Compression options: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k (optional, default 'jpeg') */
compression?: string | undefined;
/** Use BigTIFF variant (has no effect when compression is none) (optional, default false) */
bigtiff?: boolean | undefined;
/** Compression predictor options: none, horizontal, float (optional, default 'horizontal') */
predictor?: string | undefined;
/** Write an image pyramid (optional, default false) */

View File

@ -974,6 +974,7 @@ function trySetAnimationOptions (source, target) {
* @param {number} [options.quality=80] - quality, integer 1-100
* @param {boolean} [options.force=true] - force TIFF output, otherwise attempt to use input format
* @param {string} [options.compression='jpeg'] - compression options: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k
* @param {boolean} [options.bigtiff=false] - use BigTIFF variant (has no effect when compression is none)
* @param {string} [options.predictor='horizontal'] - compression predictor options: none, horizontal, float
* @param {boolean} [options.pyramid=false] - write an image pyramid
* @param {boolean} [options.tile=false] - write a tiled tiff
@ -1052,6 +1053,10 @@ function tiff (options) {
throw is.invalidParameterError('compression', 'one of: none, jpeg, deflate, packbits, ccittfax4, lzw, webp, zstd, jp2k', options.compression);
}
}
// bigtiff
if (is.defined(options.bigtiff)) {
this._setBooleanOption('tiffBigtiff', options.bigtiff);
}
// predictor
if (is.defined(options.predictor)) {
if (is.string(options.predictor) && is.inArray(options.predictor, ['none', 'horizontal', 'float'])) {

View File

@ -1009,6 +1009,7 @@ class PipelineWorker : public Napi::AsyncWorker {
->set("Q", baton->tiffQuality)
->set("bitdepth", baton->tiffBitdepth)
->set("compression", baton->tiffCompression)
->set("bigtiff", baton->tiffBigtiff)
->set("miniswhite", baton->tiffMiniswhite)
->set("predictor", baton->tiffPredictor)
->set("pyramid", baton->tiffPyramid)
@ -1211,6 +1212,7 @@ class PipelineWorker : public Napi::AsyncWorker {
->set("Q", baton->tiffQuality)
->set("bitdepth", baton->tiffBitdepth)
->set("compression", baton->tiffCompression)
->set("bigtiff", baton->tiffBigtiff)
->set("miniswhite", baton->tiffMiniswhite)
->set("predictor", baton->tiffPredictor)
->set("pyramid", baton->tiffPyramid)
@ -1750,6 +1752,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
baton->gifReuse = sharp::AttrAsBool(options, "gifReuse");
baton->gifProgressive = sharp::AttrAsBool(options, "gifProgressive");
baton->tiffQuality = sharp::AttrAsUint32(options, "tiffQuality");
baton->tiffBigtiff = sharp::AttrAsBool(options, "tiffBigtiff");
baton->tiffPyramid = sharp::AttrAsBool(options, "tiffPyramid");
baton->tiffMiniswhite = sharp::AttrAsBool(options, "tiffMiniswhite");
baton->tiffBitdepth = sharp::AttrAsUint32(options, "tiffBitdepth");

View File

@ -175,6 +175,7 @@ struct PipelineBaton {
bool gifProgressive;
int tiffQuality;
VipsForeignTiffCompression tiffCompression;
bool tiffBigtiff;
VipsForeignTiffPredictor tiffPredictor;
bool tiffPyramid;
int tiffBitdepth;
@ -350,6 +351,7 @@ struct PipelineBaton {
gifProgressive(false),
tiffQuality(80),
tiffCompression(VIPS_FOREIGN_TIFF_COMPRESSION_JPEG),
tiffBigtiff(false),
tiffPredictor(VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL),
tiffPyramid(false),
tiffBitdepth(8),

View File

@ -401,6 +401,18 @@ describe('TIFF', function () {
});
});
it('TIFF bigtiff true value does not throw error', function () {
assert.doesNotThrow(function () {
sharp().tiff({ bigtiff: true });
});
});
it('Invalid TIFF bigtiff value throws error', function () {
assert.throws(function () {
sharp().tiff({ bigtiff: 'true' });
});
});
it('TIFF invalid predictor option throws', function () {
assert.throws(function () {
sharp().tiff({ predictor: 'a' });