mirror of
https://github.com/lovell/sharp.git
synced 2025-07-09 10:30:15 +02:00
Add support for page selection with multi-page TIFF input (#1204)
This commit is contained in:
parent
8ef1532691
commit
b154cd0418
@ -57,6 +57,12 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
|
|||||||
throw new Error('Expected width, height and channels for raw pixel input');
|
throw new Error('Expected width, height and channels for raw pixel input');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Page input for multi-page TIFF
|
||||||
|
if (is.defined(inputOptions.page)) {
|
||||||
|
if (is.integer(inputOptions.page) && is.inRange(inputOptions.page, 0, 100000)) {
|
||||||
|
inputDescriptor.page = inputOptions.page;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Create new image
|
// Create new image
|
||||||
if (is.defined(inputOptions.create)) {
|
if (is.defined(inputOptions.create)) {
|
||||||
if (
|
if (
|
||||||
|
@ -47,7 +47,8 @@
|
|||||||
"Marcel Bretschneider <marcel.bretschneider@gmail.com>",
|
"Marcel Bretschneider <marcel.bretschneider@gmail.com>",
|
||||||
"Andrea Bianco <andrea.bianco@unibas.ch>",
|
"Andrea Bianco <andrea.bianco@unibas.ch>",
|
||||||
"Rik Heywood <rik@rik.org>",
|
"Rik Heywood <rik@rik.org>",
|
||||||
"Thomas Parisot <hi@oncletom.io>"
|
"Thomas Parisot <hi@oncletom.io>",
|
||||||
|
"Nathan Graves <nathanrgraves+github@gmail.com>"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)",
|
"install": "(node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)",
|
||||||
|
@ -63,6 +63,10 @@ namespace sharp {
|
|||||||
descriptor->rawWidth = AttrTo<uint32_t>(input, "rawWidth");
|
descriptor->rawWidth = AttrTo<uint32_t>(input, "rawWidth");
|
||||||
descriptor->rawHeight = AttrTo<uint32_t>(input, "rawHeight");
|
descriptor->rawHeight = AttrTo<uint32_t>(input, "rawHeight");
|
||||||
}
|
}
|
||||||
|
// Page input for multi-page TIFF
|
||||||
|
if (HasAttr(input, "page")) {
|
||||||
|
descriptor->page = AttrTo<uint32_t>(input, "page");
|
||||||
|
}
|
||||||
// Create new image
|
// Create new image
|
||||||
if (HasAttr(input, "createChannels")) {
|
if (HasAttr(input, "createChannels")) {
|
||||||
descriptor->createChannels = AttrTo<uint32_t>(input, "createChannels");
|
descriptor->createChannels = AttrTo<uint32_t>(input, "createChannels");
|
||||||
@ -229,6 +233,9 @@ namespace sharp {
|
|||||||
if (imageType == ImageType::MAGICK) {
|
if (imageType == ImageType::MAGICK) {
|
||||||
option->set("density", std::to_string(descriptor->density).data());
|
option->set("density", std::to_string(descriptor->density).data());
|
||||||
}
|
}
|
||||||
|
if (imageType == ImageType::TIFF) {
|
||||||
|
option->set("page", descriptor->page);
|
||||||
|
}
|
||||||
image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
|
image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
|
||||||
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
||||||
SetDensity(image, descriptor->density);
|
SetDensity(image, descriptor->density);
|
||||||
@ -268,6 +275,9 @@ namespace sharp {
|
|||||||
if (imageType == ImageType::MAGICK) {
|
if (imageType == ImageType::MAGICK) {
|
||||||
option->set("density", std::to_string(descriptor->density).data());
|
option->set("density", std::to_string(descriptor->density).data());
|
||||||
}
|
}
|
||||||
|
if (imageType == ImageType::TIFF) {
|
||||||
|
option->set("page", descriptor->page);
|
||||||
|
}
|
||||||
image = VImage::new_from_file(descriptor->file.data(), option);
|
image = VImage::new_from_file(descriptor->file.data(), option);
|
||||||
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
|
||||||
SetDensity(image, descriptor->density);
|
SetDensity(image, descriptor->density);
|
||||||
|
@ -53,6 +53,7 @@ namespace sharp {
|
|||||||
int rawChannels;
|
int rawChannels;
|
||||||
int rawWidth;
|
int rawWidth;
|
||||||
int rawHeight;
|
int rawHeight;
|
||||||
|
int page;
|
||||||
int createChannels;
|
int createChannels;
|
||||||
int createWidth;
|
int createWidth;
|
||||||
int createHeight;
|
int createHeight;
|
||||||
@ -66,6 +67,7 @@ namespace sharp {
|
|||||||
rawChannels(0),
|
rawChannels(0),
|
||||||
rawWidth(0),
|
rawWidth(0),
|
||||||
rawHeight(0),
|
rawHeight(0),
|
||||||
|
page(0),
|
||||||
createChannels(0),
|
createChannels(0),
|
||||||
createWidth(0),
|
createWidth(0),
|
||||||
createHeight(0) {
|
createHeight(0) {
|
||||||
|
BIN
test/fixtures/G31D_MULTI.TIF
vendored
Normal file
BIN
test/fixtures/G31D_MULTI.TIF
vendored
Normal file
Binary file not shown.
1
test/fixtures/index.js
vendored
1
test/fixtures/index.js
vendored
@ -94,6 +94,7 @@ module.exports = {
|
|||||||
inputWebP: getPath('4.webp'), // http://www.gstatic.com/webp/gallery/4.webp
|
inputWebP: getPath('4.webp'), // http://www.gstatic.com/webp/gallery/4.webp
|
||||||
inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp
|
inputWebPWithTransparency: getPath('5_webp_a.webp'), // http://www.gstatic.com/webp/gallery3/5_webp_a.webp
|
||||||
inputTiff: getPath('G31D.TIF'), // http://www.fileformat.info/format/tiff/sample/e6c9a6e5253348f4aef6d17b534360ab/index.htm
|
inputTiff: getPath('G31D.TIF'), // http://www.fileformat.info/format/tiff/sample/e6c9a6e5253348f4aef6d17b534360ab/index.htm
|
||||||
|
inputTiffMultipage: getPath('G31D_MULTI.TIF'), // gm convert G31D.TIF -resize 50% G31D_2.TIF ; tiffcp G31D.TIF G31D_2.TIF G31D_MULTI.TIF
|
||||||
inputTiffCielab: getPath('cielab-dagams.tiff'), // https://github.com/lovell/sharp/issues/646
|
inputTiffCielab: getPath('cielab-dagams.tiff'), // https://github.com/lovell/sharp/issues/646
|
||||||
inputTiffUncompressed: getPath('uncompressed_tiff.tiff'), // https://code.google.com/archive/p/imagetestsuite/wikis/TIFFTestSuite.wiki file: 0c84d07e1b22b76f24cccc70d8788e4a.tif
|
inputTiffUncompressed: getPath('uncompressed_tiff.tiff'), // https://code.google.com/archive/p/imagetestsuite/wikis/TIFFTestSuite.wiki file: 0c84d07e1b22b76f24cccc70d8788e4a.tif
|
||||||
inputTiff8BitDepth: getPath('8bit_depth.tiff'),
|
inputTiff8BitDepth: getPath('8bit_depth.tiff'),
|
||||||
|
@ -528,6 +528,22 @@ describe('Input/output', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('TIFF file input with invalid page fails gracefully', function (done) {
|
||||||
|
sharp(fixtures.inputTiffMultipage, { page: 2 })
|
||||||
|
.toBuffer(function (err) {
|
||||||
|
assert.strictEqual(true, !!err);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('TIFF buffer input with invalid page fails gracefully', function (done) {
|
||||||
|
sharp(fs.readFileSync(fixtures.inputTiffMultipage), { page: 2 })
|
||||||
|
.toBuffer(function (err) {
|
||||||
|
assert.strictEqual(true, !!err);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Output filename with unknown extension', function () {
|
describe('Output filename with unknown extension', function () {
|
||||||
it('Match JPEG input', function (done) {
|
it('Match JPEG input', function (done) {
|
||||||
sharp(fixtures.inputJpg)
|
sharp(fixtures.inputJpg)
|
||||||
@ -880,6 +896,53 @@ describe('Input/output', function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Load multi-page TIFF\'s from file', function (done) {
|
||||||
|
sharp(fixtures.inputTiffMultipage) // defaults to page 0
|
||||||
|
.jpeg()
|
||||||
|
.toBuffer(function (err, defaultData, defaultInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, defaultData.length > 0);
|
||||||
|
assert.strictEqual(defaultData.length, defaultInfo.size);
|
||||||
|
assert.strictEqual('jpeg', defaultInfo.format);
|
||||||
|
|
||||||
|
sharp(fixtures.inputTiffMultipage, { page: 1 }) // 50%-scale copy of page 0
|
||||||
|
.jpeg()
|
||||||
|
.toBuffer(function (err, scaledData, scaledInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, scaledData.length > 0);
|
||||||
|
assert.strictEqual(scaledData.length, scaledInfo.size);
|
||||||
|
assert.strictEqual('jpeg', scaledInfo.format);
|
||||||
|
assert.strictEqual(defaultInfo.width, scaledInfo.width * 2);
|
||||||
|
assert.strictEqual(defaultInfo.height, scaledInfo.height * 2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Load multi-page TIFF\'s from Buffer', function (done) {
|
||||||
|
const inputTiffBuffer = fs.readFileSync(fixtures.inputTiffMultipage);
|
||||||
|
sharp(inputTiffBuffer) // defaults to page 0
|
||||||
|
.jpeg()
|
||||||
|
.toBuffer(function (err, defaultData, defaultInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, defaultData.length > 0);
|
||||||
|
assert.strictEqual(defaultData.length, defaultInfo.size);
|
||||||
|
assert.strictEqual('jpeg', defaultInfo.format);
|
||||||
|
|
||||||
|
sharp(inputTiffBuffer, { page: 1 }) // 50%-scale copy of page 0
|
||||||
|
.jpeg()
|
||||||
|
.toBuffer(function (err, scaledData, scaledInfo) {
|
||||||
|
if (err) throw err;
|
||||||
|
assert.strictEqual(true, scaledData.length > 0);
|
||||||
|
assert.strictEqual(scaledData.length, scaledInfo.size);
|
||||||
|
assert.strictEqual('jpeg', scaledInfo.format);
|
||||||
|
assert.strictEqual(defaultInfo.width, scaledInfo.width * 2);
|
||||||
|
assert.strictEqual(defaultInfo.height, scaledInfo.height * 2);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('Save TIFF to Buffer', function (done) {
|
it('Save TIFF to Buffer', function (done) {
|
||||||
sharp(fixtures.inputTiff)
|
sharp(fixtures.inputTiff)
|
||||||
.resize(320, 240)
|
.resize(320, 240)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user