sharp 0.28.1 → 0.29.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/common.cc CHANGED
@@ -92,9 +92,13 @@ namespace sharp {
92
92
  }
93
93
  // Raw pixel input
94
94
  if (HasAttr(input, "rawChannels")) {
95
+ descriptor->rawDepth = static_cast<VipsBandFormat>(
96
+ vips_enum_from_nick(nullptr, VIPS_TYPE_BAND_FORMAT,
97
+ AttrAsStr(input, "rawDepth").data()));
95
98
  descriptor->rawChannels = AttrAsUint32(input, "rawChannels");
96
99
  descriptor->rawWidth = AttrAsUint32(input, "rawWidth");
97
100
  descriptor->rawHeight = AttrAsUint32(input, "rawHeight");
101
+ descriptor->rawPremultiplied = AttrAsBool(input, "rawPremultiplied");
98
102
  }
99
103
  // Multi-page input (GIF, TIFF, PDF)
100
104
  if (HasAttr(input, "pages")) {
@@ -153,6 +157,10 @@ namespace sharp {
153
157
  bool IsGif(std::string const &str) {
154
158
  return EndsWith(str, ".gif") || EndsWith(str, ".GIF");
155
159
  }
160
+ bool IsJp2(std::string const &str) {
161
+ return EndsWith(str, ".jp2") || EndsWith(str, ".jpx") || EndsWith(str, ".j2k") || EndsWith(str, ".j2c")
162
+ || EndsWith(str, ".JP2") || EndsWith(str, ".JPX") || EndsWith(str, ".J2K") || EndsWith(str, ".J2C");
163
+ }
156
164
  bool IsTiff(std::string const &str) {
157
165
  return EndsWith(str, ".tif") || EndsWith(str, ".tiff") || EndsWith(str, ".TIF") || EndsWith(str, ".TIFF");
158
166
  }
@@ -186,6 +194,7 @@ namespace sharp {
186
194
  case ImageType::WEBP: id = "webp"; break;
187
195
  case ImageType::TIFF: id = "tiff"; break;
188
196
  case ImageType::GIF: id = "gif"; break;
197
+ case ImageType::JP2: id = "jp2"; break;
189
198
  case ImageType::SVG: id = "svg"; break;
190
199
  case ImageType::HEIF: id = "heif"; break;
191
200
  case ImageType::PDF: id = "pdf"; break;
@@ -222,6 +231,8 @@ namespace sharp {
222
231
  { "VipsForeignLoadGifBuffer", ImageType::GIF },
223
232
  { "VipsForeignLoadNsgifFile", ImageType::GIF },
224
233
  { "VipsForeignLoadNsgifBuffer", ImageType::GIF },
234
+ { "VipsForeignLoadJp2kBuffer", ImageType::JP2 },
235
+ { "VipsForeignLoadJp2kFile", ImageType::JP2 },
225
236
  { "VipsForeignLoadSvgFile", ImageType::SVG },
226
237
  { "VipsForeignLoadSvgBuffer", ImageType::SVG },
227
238
  { "VipsForeignLoadHeifFile", ImageType::HEIF },
@@ -230,11 +241,14 @@ namespace sharp {
230
241
  { "VipsForeignLoadPdfBuffer", ImageType::PDF },
231
242
  { "VipsForeignLoadMagickFile", ImageType::MAGICK },
232
243
  { "VipsForeignLoadMagickBuffer", ImageType::MAGICK },
244
+ { "VipsForeignLoadMagick7File", ImageType::MAGICK },
245
+ { "VipsForeignLoadMagick7Buffer", ImageType::MAGICK },
233
246
  { "VipsForeignLoadOpenslide", ImageType::OPENSLIDE },
234
247
  { "VipsForeignLoadPpmFile", ImageType::PPM },
235
248
  { "VipsForeignLoadFits", ImageType::FITS },
236
249
  { "VipsForeignLoadOpenexr", ImageType::EXR },
237
250
  { "VipsForeignLoadVips", ImageType::VIPS },
251
+ { "VipsForeignLoadVipsFile", ImageType::VIPS },
238
252
  { "VipsForeignLoadRaw", ImageType::RAW }
239
253
  };
240
254
 
@@ -280,6 +294,7 @@ namespace sharp {
280
294
  imageType == ImageType::WEBP ||
281
295
  imageType == ImageType::MAGICK ||
282
296
  imageType == ImageType::GIF ||
297
+ imageType == ImageType::JP2 ||
283
298
  imageType == ImageType::TIFF ||
284
299
  imageType == ImageType::HEIF ||
285
300
  imageType == ImageType::PDF;
@@ -295,12 +310,15 @@ namespace sharp {
295
310
  if (descriptor->rawChannels > 0) {
296
311
  // Raw, uncompressed pixel data
297
312
  image = VImage::new_from_memory(descriptor->buffer, descriptor->bufferLength,
298
- descriptor->rawWidth, descriptor->rawHeight, descriptor->rawChannels, VIPS_FORMAT_UCHAR);
313
+ descriptor->rawWidth, descriptor->rawHeight, descriptor->rawChannels, descriptor->rawDepth);
299
314
  if (descriptor->rawChannels < 3) {
300
315
  image.get_image()->Type = VIPS_INTERPRETATION_B_W;
301
316
  } else {
302
317
  image.get_image()->Type = VIPS_INTERPRETATION_sRGB;
303
318
  }
319
+ if (descriptor->rawPremultiplied) {
320
+ image = image.unpremultiply();
321
+ }
304
322
  imageType = ImageType::RAW;
305
323
  } else {
306
324
  // Compressed data
@@ -500,6 +518,17 @@ namespace sharp {
500
518
  return copy;
501
519
  }
502
520
 
521
+ /*
522
+ Remove animation properties from image.
523
+ */
524
+ VImage RemoveAnimationProperties(VImage image) {
525
+ VImage copy = image.copy();
526
+ copy.remove(VIPS_META_PAGE_HEIGHT);
527
+ copy.remove("delay");
528
+ copy.remove("loop");
529
+ return copy;
530
+ }
531
+
503
532
  /*
504
533
  Does this image have a non-default density?
505
534
  */
@@ -520,9 +549,8 @@ namespace sharp {
520
549
  VImage SetDensity(VImage image, const double density) {
521
550
  const double pixelsPerMm = density / 25.4;
522
551
  VImage copy = image.copy();
523
- copy.set("Xres", pixelsPerMm);
524
- copy.set("Yres", pixelsPerMm);
525
- copy.set(VIPS_META_RESOLUTION_UNIT, "in");
552
+ copy.get_image()->Xres = pixelsPerMm;
553
+ copy.get_image()->Yres = pixelsPerMm;
526
554
  return copy;
527
555
  }
528
556
 
@@ -750,23 +778,27 @@ namespace sharp {
750
778
  /*
751
779
  Convert RGBA value to another colourspace
752
780
  */
753
- std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba, VipsInterpretation const interpretation) {
781
+ std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba,
782
+ VipsInterpretation const interpretation, bool premultiply) {
754
783
  int const bands = static_cast<int>(rgba.size());
755
- if (bands < 3 || interpretation == VIPS_INTERPRETATION_sRGB || interpretation == VIPS_INTERPRETATION_RGB) {
784
+ if (bands < 3) {
756
785
  return rgba;
757
- } else {
758
- VImage pixel = VImage::new_matrix(1, 1);
759
- pixel.set("bands", bands);
760
- pixel = pixel.new_from_image(rgba);
761
- pixel = pixel.colourspace(interpretation, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB));
762
- return pixel(0, 0);
763
786
  }
787
+ VImage pixel = VImage::new_matrix(1, 1);
788
+ pixel.set("bands", bands);
789
+ pixel = pixel
790
+ .new_from_image(rgba)
791
+ .colourspace(interpretation, VImage::option()->set("source_space", VIPS_INTERPRETATION_sRGB));
792
+ if (premultiply) {
793
+ pixel = pixel.premultiply();
794
+ }
795
+ return pixel(0, 0);
764
796
  }
765
797
 
766
798
  /*
767
799
  Apply the alpha channel to a given colour
768
800
  */
769
- std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour) {
801
+ std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour, bool premultiply) {
770
802
  // Scale up 8-bit values to match 16-bit input image
771
803
  double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;
772
804
  // Create alphaColour colour
@@ -790,7 +822,7 @@ namespace sharp {
790
822
  alphaColour.push_back(colour[3] * multiplier);
791
823
  }
792
824
  // Ensure alphaColour colour uses correct colourspace
793
- alphaColour = sharp::GetRgbaAsColourspace(alphaColour, image.interpretation());
825
+ alphaColour = sharp::GetRgbaAsColourspace(alphaColour, image.interpretation(), premultiply);
794
826
  // Add non-transparent alpha channel, if required
795
827
  if (colour[3] < 255.0 && !HasAlpha(image)) {
796
828
  image = image.bandjoin(
@@ -820,4 +852,5 @@ namespace sharp {
820
852
  }
821
853
  return image;
822
854
  }
855
+
823
856
  } // namespace sharp
package/src/common.h CHANGED
@@ -25,9 +25,9 @@
25
25
  // Verify platform and compiler compatibility
26
26
 
27
27
  #if (VIPS_MAJOR_VERSION < 8) || \
28
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 10) || \
29
- (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 10 && VIPS_MICRO_VERSION < 6)
30
- #error "libvips version 8.10.6+ is required - please see https://sharp.pixelplumbing.com/install"
28
+ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION < 11) || \
29
+ (VIPS_MAJOR_VERSION == 8 && VIPS_MINOR_VERSION == 11 && VIPS_MICRO_VERSION < 3)
30
+ #error "libvips version 8.11.3+ is required - please see https://sharp.pixelplumbing.com/install"
31
31
  #endif
32
32
 
33
33
  #if ((!defined(__clang__)) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6)))
@@ -54,9 +54,11 @@ namespace sharp {
54
54
  size_t bufferLength;
55
55
  bool isBuffer;
56
56
  double density;
57
+ VipsBandFormat rawDepth;
57
58
  int rawChannels;
58
59
  int rawWidth;
59
60
  int rawHeight;
61
+ bool rawPremultiplied;
60
62
  int pages;
61
63
  int page;
62
64
  int level;
@@ -77,9 +79,11 @@ namespace sharp {
77
79
  bufferLength(0),
78
80
  isBuffer(FALSE),
79
81
  density(72.0),
82
+ rawDepth(VIPS_FORMAT_UCHAR),
80
83
  rawChannels(0),
81
84
  rawWidth(0),
82
85
  rawHeight(0),
86
+ rawPremultiplied(false),
83
87
  pages(1),
84
88
  page(0),
85
89
  level(0),
@@ -112,6 +116,7 @@ namespace sharp {
112
116
  JPEG,
113
117
  PNG,
114
118
  WEBP,
119
+ JP2,
115
120
  TIFF,
116
121
  GIF,
117
122
  SVG,
@@ -138,6 +143,7 @@ namespace sharp {
138
143
  bool IsJpeg(std::string const &str);
139
144
  bool IsPng(std::string const &str);
140
145
  bool IsWebp(std::string const &str);
146
+ bool IsJp2(std::string const &str);
141
147
  bool IsGif(std::string const &str);
142
148
  bool IsTiff(std::string const &str);
143
149
  bool IsHeic(std::string const &str);
@@ -204,6 +210,11 @@ namespace sharp {
204
210
  */
205
211
  VImage SetAnimationProperties(VImage image, int pageHeight, std::vector<int> delay, int loop);
206
212
 
213
+ /*
214
+ Remove animation properties from image.
215
+ */
216
+ VImage RemoveAnimationProperties(VImage image);
217
+
207
218
  /*
208
219
  Does this image have a non-default density?
209
220
  */
@@ -284,12 +295,13 @@ namespace sharp {
284
295
  /*
285
296
  Convert RGBA value to another colourspace
286
297
  */
287
- std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba, VipsInterpretation const interpretation);
298
+ std::vector<double> GetRgbaAsColourspace(std::vector<double> const rgba,
299
+ VipsInterpretation const interpretation, bool premultiply);
288
300
 
289
301
  /*
290
302
  Apply the alpha channel to a given colour
291
303
  */
292
- std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour);
304
+ std::tuple<VImage, std::vector<double>> ApplyAlpha(VImage image, std::vector<double> colour, bool premultiply);
293
305
 
294
306
  /*
295
307
  Removes alpha channel, if any.
@@ -110,19 +110,6 @@ VSource::new_from_options( const char *options )
110
110
  return( out );
111
111
  }
112
112
 
113
- VOption *
114
- VOption::set( const char *name, const VSource value )
115
- {
116
- Pair *pair = new Pair( name );
117
-
118
- pair->input = true;
119
- g_value_init( &pair->value, VIPS_TYPE_SOURCE );
120
- g_value_set_object( &pair->value, value.get_source() );
121
- options.push_back( pair );
122
-
123
- return( this );
124
- }
125
-
126
113
  VTarget
127
114
  VTarget::new_to_descriptor( int descriptor )
128
115
  {
@@ -162,17 +149,4 @@ VTarget::new_to_memory()
162
149
  return( out );
163
150
  }
164
151
 
165
- VOption *
166
- VOption::set( const char *name, const VTarget value )
167
- {
168
- Pair *pair = new Pair( name );
169
-
170
- pair->input = true;
171
- g_value_init( &pair->value, VIPS_TYPE_TARGET );
172
- g_value_set_object( &pair->value, value.get_target() );
173
- options.push_back( pair );
174
-
175
- return( this );
176
- }
177
-
178
152
  VIPS_NAMESPACE_END
@@ -51,6 +51,12 @@
51
51
 
52
52
  VIPS_NAMESPACE_START
53
53
 
54
+ /**
55
+ * \namespace vips
56
+ *
57
+ * General docs for the vips namespace.
58
+ */
59
+
54
60
  std::vector<double>
55
61
  to_vectorv( int n, ... )
56
62
  {
@@ -140,6 +146,20 @@ VOption::set( const char *name, int value )
140
146
  return( this );
141
147
  }
142
148
 
149
+ // input guint64
150
+ VOption *
151
+ VOption::set( const char *name, guint64 value )
152
+ {
153
+ Pair *pair = new Pair( name );
154
+
155
+ pair->input = true;
156
+ g_value_init( &pair->value, G_TYPE_UINT64 );
157
+ g_value_set_uint64( &pair->value, value );
158
+ options.push_back( pair );
159
+
160
+ return( this );
161
+ }
162
+
143
163
  // input double
144
164
  VOption *
145
165
  VOption::set( const char *name, double value )
@@ -167,35 +187,37 @@ VOption::set( const char *name, const char *value )
167
187
  return( this );
168
188
  }
169
189
 
170
- // input image
190
+ // input vips object (image, source, target, etc. etc.)
171
191
  VOption *
172
- VOption::set( const char *name, const VImage value )
192
+ VOption::set( const char *name, const VObject value )
173
193
  {
174
194
  Pair *pair = new Pair( name );
195
+ VipsObject *object = value.get_object();
196
+ GType type = G_OBJECT_TYPE( object );
175
197
 
176
198
  pair->input = true;
177
- g_value_init( &pair->value, VIPS_TYPE_IMAGE );
178
- g_value_set_object( &pair->value, value.get_image() );
199
+ g_value_init( &pair->value, type );
200
+ g_value_set_object( &pair->value, object );
179
201
  options.push_back( pair );
180
202
 
181
203
  return( this );
182
204
  }
183
205
 
184
- // input double array
206
+ // input int array
185
207
  VOption *
186
- VOption::set( const char *name, std::vector<double> value )
208
+ VOption::set( const char *name, std::vector<int> value )
187
209
  {
188
210
  Pair *pair = new Pair( name );
189
211
 
190
- double *array;
212
+ int *array;
191
213
  unsigned int i;
192
214
 
193
215
  pair->input = true;
194
216
 
195
- g_value_init( &pair->value, VIPS_TYPE_ARRAY_DOUBLE );
196
- vips_value_set_array_double( &pair->value, NULL,
217
+ g_value_init( &pair->value, VIPS_TYPE_ARRAY_INT );
218
+ vips_value_set_array_int( &pair->value, NULL,
197
219
  static_cast< int >( value.size() ) );
198
- array = vips_value_get_array_double( &pair->value, NULL );
220
+ array = vips_value_get_array_int( &pair->value, NULL );
199
221
 
200
222
  for( i = 0; i < value.size(); i++ )
201
223
  array[i] = value[i];
@@ -205,21 +227,21 @@ VOption::set( const char *name, std::vector<double> value )
205
227
  return( this );
206
228
  }
207
229
 
208
- // input int array
230
+ // input double array
209
231
  VOption *
210
- VOption::set( const char *name, std::vector<int> value )
232
+ VOption::set( const char *name, std::vector<double> value )
211
233
  {
212
234
  Pair *pair = new Pair( name );
213
235
 
214
- int *array;
236
+ double *array;
215
237
  unsigned int i;
216
238
 
217
239
  pair->input = true;
218
240
 
219
- g_value_init( &pair->value, VIPS_TYPE_ARRAY_INT );
220
- vips_value_set_array_int( &pair->value, NULL,
241
+ g_value_init( &pair->value, VIPS_TYPE_ARRAY_DOUBLE );
242
+ vips_value_set_array_double( &pair->value, NULL,
221
243
  static_cast< int >( value.size() ) );
222
- array = vips_value_get_array_int( &pair->value, NULL );
244
+ array = vips_value_get_array_double( &pair->value, NULL );
223
245
 
224
246
  for( i = 0; i < value.size(); i++ )
225
247
  array[i] = value[i];
@@ -619,6 +641,22 @@ VImage::new_from_source( VSource source, const char *option_string,
619
641
  return( out );
620
642
  }
621
643
 
644
+ VImage
645
+ VImage::new_from_memory_steal( void *data, size_t size,
646
+ int width, int height, int bands, VipsBandFormat format )
647
+ {
648
+ VipsImage *image;
649
+
650
+ if( !(image = vips_image_new_from_memory( data, size,
651
+ width, height, bands, format )) )
652
+ throw( VError() );
653
+
654
+ g_signal_connect( image, "postclose",
655
+ G_CALLBACK( vips_image_free_buffer ), data);
656
+
657
+ return( VImage( image ) );
658
+ }
659
+
622
660
  VImage
623
661
  VImage::new_matrix( int width, int height )
624
662
  {
@@ -60,17 +60,4 @@ VInterpolate::new_from_name( const char *name, VOption *options )
60
60
  return( out );
61
61
  }
62
62
 
63
- VOption *
64
- VOption::set( const char *name, const VInterpolate value )
65
- {
66
- Pair *pair = new Pair( name );
67
-
68
- pair->input = true;
69
- g_value_init( &pair->value, VIPS_TYPE_INTERPOLATE );
70
- g_value_set_object( &pair->value, value.get_interpolate() );
71
- options.push_back( pair );
72
-
73
- return( this );
74
- }
75
-
76
63
  VIPS_NAMESPACE_END
@@ -1,5 +1,5 @@
1
1
  // bodies for vips operations
2
- // Sun 5 Jul 22:36:37 BST 2020
2
+ // Wed May 12 11:30:00 AM CEST 2021
3
3
  // this file is generated automatically, do not edit!
4
4
 
5
5
  VImage VImage::CMC2LCh( VOption *options ) const
@@ -1065,6 +1065,18 @@ VImage VImage::fitsload( const char *filename, VOption *options )
1065
1065
  return( out );
1066
1066
  }
1067
1067
 
1068
+ VImage VImage::fitsload_source( VSource source, VOption *options )
1069
+ {
1070
+ VImage out;
1071
+
1072
+ call( "fitsload_source",
1073
+ (options ? options : VImage::option())->
1074
+ set( "out", &out )->
1075
+ set( "source", source ) );
1076
+
1077
+ return( out );
1078
+ }
1079
+
1068
1080
  void VImage::fitssave( const char *filename, VOption *options ) const
1069
1081
  {
1070
1082
  call( "fitssave",
@@ -1656,6 +1668,70 @@ VImage VImage::join( VImage in2, VipsDirection direction, VOption *options ) con
1656
1668
  return( out );
1657
1669
  }
1658
1670
 
1671
+ VImage VImage::jp2kload( const char *filename, VOption *options )
1672
+ {
1673
+ VImage out;
1674
+
1675
+ call( "jp2kload",
1676
+ (options ? options : VImage::option())->
1677
+ set( "out", &out )->
1678
+ set( "filename", filename ) );
1679
+
1680
+ return( out );
1681
+ }
1682
+
1683
+ VImage VImage::jp2kload_buffer( VipsBlob *buffer, VOption *options )
1684
+ {
1685
+ VImage out;
1686
+
1687
+ call( "jp2kload_buffer",
1688
+ (options ? options : VImage::option())->
1689
+ set( "out", &out )->
1690
+ set( "buffer", buffer ) );
1691
+
1692
+ return( out );
1693
+ }
1694
+
1695
+ VImage VImage::jp2kload_source( VSource source, VOption *options )
1696
+ {
1697
+ VImage out;
1698
+
1699
+ call( "jp2kload_source",
1700
+ (options ? options : VImage::option())->
1701
+ set( "out", &out )->
1702
+ set( "source", source ) );
1703
+
1704
+ return( out );
1705
+ }
1706
+
1707
+ void VImage::jp2ksave( const char *filename, VOption *options ) const
1708
+ {
1709
+ call( "jp2ksave",
1710
+ (options ? options : VImage::option())->
1711
+ set( "in", *this )->
1712
+ set( "filename", filename ) );
1713
+ }
1714
+
1715
+ VipsBlob *VImage::jp2ksave_buffer( VOption *options ) const
1716
+ {
1717
+ VipsBlob *buffer;
1718
+
1719
+ call( "jp2ksave_buffer",
1720
+ (options ? options : VImage::option())->
1721
+ set( "in", *this )->
1722
+ set( "buffer", &buffer ) );
1723
+
1724
+ return( buffer );
1725
+ }
1726
+
1727
+ void VImage::jp2ksave_target( VTarget target, VOption *options ) const
1728
+ {
1729
+ call( "jp2ksave_target",
1730
+ (options ? options : VImage::option())->
1731
+ set( "in", *this )->
1732
+ set( "target", target ) );
1733
+ }
1734
+
1659
1735
  VImage VImage::jpegload( const char *filename, VOption *options )
1660
1736
  {
1661
1737
  VImage out;
@@ -1727,6 +1803,70 @@ void VImage::jpegsave_target( VTarget target, VOption *options ) const
1727
1803
  set( "target", target ) );
1728
1804
  }
1729
1805
 
1806
+ VImage VImage::jxlload( const char *filename, VOption *options )
1807
+ {
1808
+ VImage out;
1809
+
1810
+ call( "jxlload",
1811
+ (options ? options : VImage::option())->
1812
+ set( "out", &out )->
1813
+ set( "filename", filename ) );
1814
+
1815
+ return( out );
1816
+ }
1817
+
1818
+ VImage VImage::jxlload_buffer( VipsBlob *buffer, VOption *options )
1819
+ {
1820
+ VImage out;
1821
+
1822
+ call( "jxlload_buffer",
1823
+ (options ? options : VImage::option())->
1824
+ set( "out", &out )->
1825
+ set( "buffer", buffer ) );
1826
+
1827
+ return( out );
1828
+ }
1829
+
1830
+ VImage VImage::jxlload_source( VSource source, VOption *options )
1831
+ {
1832
+ VImage out;
1833
+
1834
+ call( "jxlload_source",
1835
+ (options ? options : VImage::option())->
1836
+ set( "out", &out )->
1837
+ set( "source", source ) );
1838
+
1839
+ return( out );
1840
+ }
1841
+
1842
+ void VImage::jxlsave( const char *filename, VOption *options ) const
1843
+ {
1844
+ call( "jxlsave",
1845
+ (options ? options : VImage::option())->
1846
+ set( "in", *this )->
1847
+ set( "filename", filename ) );
1848
+ }
1849
+
1850
+ VipsBlob *VImage::jxlsave_buffer( VOption *options ) const
1851
+ {
1852
+ VipsBlob *buffer;
1853
+
1854
+ call( "jxlsave_buffer",
1855
+ (options ? options : VImage::option())->
1856
+ set( "in", *this )->
1857
+ set( "buffer", &buffer ) );
1858
+
1859
+ return( buffer );
1860
+ }
1861
+
1862
+ void VImage::jxlsave_target( VTarget target, VOption *options ) const
1863
+ {
1864
+ call( "jxlsave_target",
1865
+ (options ? options : VImage::option())->
1866
+ set( "in", *this )->
1867
+ set( "target", target ) );
1868
+ }
1869
+
1730
1870
  VImage VImage::labelregions( VOption *options ) const
1731
1871
  {
1732
1872
  VImage mask;
@@ -2284,6 +2424,18 @@ VImage VImage::niftiload( const char *filename, VOption *options )
2284
2424
  return( out );
2285
2425
  }
2286
2426
 
2427
+ VImage VImage::niftiload_source( VSource source, VOption *options )
2428
+ {
2429
+ VImage out;
2430
+
2431
+ call( "niftiload_source",
2432
+ (options ? options : VImage::option())->
2433
+ set( "out", &out )->
2434
+ set( "source", source ) );
2435
+
2436
+ return( out );
2437
+ }
2438
+
2287
2439
  void VImage::niftisave( const char *filename, VOption *options ) const
2288
2440
  {
2289
2441
  call( "niftisave",
@@ -2316,6 +2468,18 @@ VImage VImage::openslideload( const char *filename, VOption *options )
2316
2468
  return( out );
2317
2469
  }
2318
2470
 
2471
+ VImage VImage::openslideload_source( VSource source, VOption *options )
2472
+ {
2473
+ VImage out;
2474
+
2475
+ call( "openslideload_source",
2476
+ (options ? options : VImage::option())->
2477
+ set( "out", &out )->
2478
+ set( "source", source ) );
2479
+
2480
+ return( out );
2481
+ }
2482
+
2319
2483
  VImage VImage::pdfload( const char *filename, VOption *options )
2320
2484
  {
2321
2485
  VImage out;
@@ -3388,6 +3552,18 @@ VImage VImage::vipsload( const char *filename, VOption *options )
3388
3552
  return( out );
3389
3553
  }
3390
3554
 
3555
+ VImage VImage::vipsload_source( VSource source, VOption *options )
3556
+ {
3557
+ VImage out;
3558
+
3559
+ call( "vipsload_source",
3560
+ (options ? options : VImage::option())->
3561
+ set( "out", &out )->
3562
+ set( "source", source ) );
3563
+
3564
+ return( out );
3565
+ }
3566
+
3391
3567
  void VImage::vipssave( const char *filename, VOption *options ) const
3392
3568
  {
3393
3569
  call( "vipssave",
@@ -3396,6 +3572,14 @@ void VImage::vipssave( const char *filename, VOption *options ) const
3396
3572
  set( "filename", filename ) );
3397
3573
  }
3398
3574
 
3575
+ void VImage::vipssave_target( VTarget target, VOption *options ) const
3576
+ {
3577
+ call( "vipssave_target",
3578
+ (options ? options : VImage::option())->
3579
+ set( "in", *this )->
3580
+ set( "target", target ) );
3581
+ }
3582
+
3399
3583
  VImage VImage::webpload( const char *filename, VOption *options )
3400
3584
  {
3401
3585
  VImage out;
package/src/metadata.cc CHANGED
@@ -90,6 +90,9 @@ class MetadataWorker : public Napi::AsyncWorker {
90
90
  baton->subifds = image.get_int(VIPS_META_N_SUBIFDS);
91
91
  }
92
92
  baton->hasProfile = sharp::HasProfile(image);
93
+ if (image.get_typeof("background") == VIPS_TYPE_ARRAY_DOUBLE) {
94
+ baton->background = image.get_array_double("background");
95
+ }
93
96
  // Derived attributes
94
97
  baton->hasAlpha = sharp::HasAlpha(image);
95
98
  baton->orientation = sharp::ExifOrientation(image);
@@ -209,6 +212,17 @@ class MetadataWorker : public Napi::AsyncWorker {
209
212
  if (baton->subifds > 0) {
210
213
  info.Set("subifds", baton->subifds);
211
214
  }
215
+ if (!baton->background.empty()) {
216
+ if (baton->background.size() == 3) {
217
+ Napi::Object background = Napi::Object::New(env);
218
+ background.Set("r", baton->background[0]);
219
+ background.Set("g", baton->background[1]);
220
+ background.Set("b", baton->background[2]);
221
+ info.Set("background", background);
222
+ } else {
223
+ info.Set("background", baton->background[0]);
224
+ }
225
+ }
212
226
  info.Set("hasProfile", baton->hasProfile);
213
227
  info.Set("hasAlpha", baton->hasAlpha);
214
228
  if (baton->orientation > 0) {
package/src/metadata.h CHANGED
@@ -42,6 +42,7 @@ struct MetadataBaton {
42
42
  std::string compression;
43
43
  std::vector<std::pair<int, int>> levels;
44
44
  int subifds;
45
+ std::vector<double> background;
45
46
  bool hasProfile;
46
47
  bool hasAlpha;
47
48
  int orientation;