Skip to content

Commit e2e46ae

Browse files
committed
Add support for libvips JPEG 2000 one-shot load option
1 parent 1533bf9 commit e2e46ae

File tree

9 files changed

+209
-125
lines changed

9 files changed

+209
-125
lines changed

docs/api-constructor.md

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ where the overall height is the `pageHeight` multiplied by the number of `pages`
4141
| [options.subifd] | <code>number</code> | <code>-1</code> | subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image. |
4242
| [options.level] | <code>number</code> | <code>0</code> | level to extract from a multi-level input (OpenSlide), zero based. |
4343
| [options.pdfBackground] | <code>string</code> \| <code>Object</code> | | Background colour to use when PDF is partially transparent. Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick. |
44+
| [options.jp2Oneshot] | <code>boolean</code> | <code>false</code> | Set to `true` to load JPEG 2000 images using [oneshot mode](https://github.com/libvips/libvips/issues/4205)|
4445
| [options.animated] | <code>boolean</code> | <code>false</code> | Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`. |
4546
| [options.raw] | <code>Object</code> | | describes raw pixel input image data. See `raw()` for pixel ordering. |
4647
| [options.raw.width] | <code>number</code> | | integral number of pixels wide. |

lib/constructor.js

+2
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ const debuglog = util.debuglog('sharp');
140140
* @param {number} [options.subifd=-1] - subIFD (Sub Image File Directory) to extract for OME-TIFF, defaults to main image.
141141
* @param {number} [options.level=0] - level to extract from a multi-level input (OpenSlide), zero based.
142142
* @param {string|Object} [options.pdfBackground] - Background colour to use when PDF is partially transparent. Parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick.
143+
* @param {boolean} [options.jp2Oneshot=false] - Set to `true` to load JPEG 2000 images using [oneshot mode](https://github.com/libvips/libvips/issues/4205)
143144
* @param {boolean} [options.animated=false] - Set to `true` to read all frames/pages of an animated image (GIF, WebP, TIFF), equivalent of setting `pages` to `-1`.
144145
* @param {Object} [options.raw] - describes raw pixel input image data. See `raw()` for pixel ordering.
145146
* @param {number} [options.raw.width] - integral number of pixels wide.
@@ -295,6 +296,7 @@ const Sharp = function (input, options) {
295296
jp2TileWidth: 512,
296297
jp2Lossless: false,
297298
jp2ChromaSubsampling: '4:4:4',
299+
jp2Oneshot: false,
298300
webpQuality: 80,
299301
webpAlphaQuality: 100,
300302
webpLossless: false,

lib/index.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,8 @@ declare namespace sharp {
938938
/** Background colour to use when PDF is partially transparent. Requires the use of a globally-installed libvips compiled with support for PDFium, Poppler, ImageMagick or GraphicsMagick. */
939939
pdfBackground?: Colour | Color | undefined;
940940
/** Set to `true` to read all frames/pages of an animated image (equivalent of setting `pages` to `-1`). (optional, default false) */
941+
jp2Oneshot?: boolean | undefined;
942+
/** Set to `true` to load JPEG 2000 images using [oneshot mode](https://github.com/libvips/libvips/issues/4205) **/
941943
animated?: boolean | undefined;
942944
/** Describes raw pixel input image data. See raw() for pixel ordering. */
943945
raw?: CreateRaw | undefined;

lib/input.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ const align = {
2424
* @private
2525
*/
2626
function _inputOptionsFromObject (obj) {
27-
const { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground } = obj;
28-
return [raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground].some(is.defined)
29-
? { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground }
27+
const { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground, jp2Oneshot } = obj;
28+
return [raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground, jp2Oneshot].some(is.defined)
29+
? { raw, density, limitInputPixels, ignoreIcc, unlimited, sequentialRead, failOn, failOnError, animated, page, pages, subifd, pdfBackground, jp2Oneshot }
3030
: undefined;
3131
}
3232

@@ -40,7 +40,8 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
4040
limitInputPixels: Math.pow(0x3FFF, 2),
4141
ignoreIcc: false,
4242
unlimited: false,
43-
sequentialRead: true
43+
sequentialRead: true,
44+
jp2Oneshot: false
4445
};
4546
if (is.string(input)) {
4647
// filesystem
@@ -226,6 +227,15 @@ function _createInputDescriptor (input, inputOptions, containerOptions) {
226227
if (is.defined(inputOptions.pdfBackground)) {
227228
this._setBackgroundColourOption('pdfBackground', inputOptions.pdfBackground);
228229
}
230+
231+
if (is.defined(inputOptions.jp2Oneshot)) {
232+
if (is.bool(inputOptions.jp2Oneshot)) {
233+
inputDescriptor.jp2Oneshot = inputOptions.jp2Oneshot;
234+
} else {
235+
throw is.invalidParameterError('jp2Oneshot', 'boolean', inputOptions.jp2Oneshot);
236+
}
237+
}
238+
229239
// Create new image
230240
if (is.defined(inputOptions.create)) {
231241
if (

src/common.cc

+11
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ namespace sharp {
113113
if (HasAttr(input, "pdfBackground")) {
114114
descriptor->pdfBackground = AttrAsVectorOfDouble(input, "pdfBackground");
115115
}
116+
// Use JPEG 2000 oneshot mode?
117+
if (HasAttr(input, "jp2Oneshot")) {
118+
descriptor->jp2Oneshot = AttrAsBool(input, "jp2Oneshot");
119+
}
120+
116121
// Create new image
117122
if (HasAttr(input, "createChannels")) {
118123
descriptor->createChannels = AttrAsUint32(input, "createChannels");
@@ -409,6 +414,9 @@ namespace sharp {
409414
if (imageType == ImageType::PDF) {
410415
option->set("background", descriptor->pdfBackground);
411416
}
417+
if (imageType == ImageType::JP2 && descriptor->jp2Oneshot) {
418+
option->set("oneshot", 1);
419+
}
412420
image = VImage::new_from_buffer(descriptor->buffer, descriptor->bufferLength, nullptr, option);
413421
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
414422
image = SetDensity(image, descriptor->density);
@@ -516,6 +524,9 @@ namespace sharp {
516524
if (imageType == ImageType::PDF) {
517525
option->set("background", descriptor->pdfBackground);
518526
}
527+
if (imageType == ImageType::JP2 && descriptor->jp2Oneshot) {
528+
option->set("oneshot", 1);
529+
}
519530
image = VImage::new_from_file(descriptor->file.data(), option);
520531
if (imageType == ImageType::SVG || imageType == ImageType::PDF || imageType == ImageType::MAGICK) {
521532
image = SetDensity(image, descriptor->density);

src/common.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ namespace sharp {
7575
VipsTextWrap textWrap;
7676
int textAutofitDpi;
7777
std::vector<double> pdfBackground;
78+
bool jp2Oneshot;
7879

7980
InputDescriptor():
8081
buffer(nullptr),
@@ -110,7 +111,8 @@ namespace sharp {
110111
textSpacing(0),
111112
textWrap(VIPS_TEXT_WRAP_WORD),
112113
textAutofitDpi(0),
113-
pdfBackground{ 255.0, 255.0, 255.0, 255.0 } {}
114+
pdfBackground{ 255.0, 255.0, 255.0, 255.0 },
115+
jp2Oneshot(false) {}
114116
};
115117

116118
// Convenience methods to access the attributes of a Napi::Object

0 commit comments

Comments
 (0)