sharp 0.20.8 → 0.21.0

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/metadata.cc CHANGED
@@ -62,6 +62,12 @@ class MetadataWorker : public Nan::AsyncWorker {
62
62
  if (sharp::HasDensity(image)) {
63
63
  baton->density = sharp::GetDensity(image);
64
64
  }
65
+ if (image.get_typeof("jpeg-chroma-subsample") == VIPS_TYPE_REF_STRING) {
66
+ baton->chromaSubsampling = image.get_string("jpeg-chroma-subsample");
67
+ }
68
+ if (image.get_typeof("interlaced") == G_TYPE_INT) {
69
+ baton->isProgressive = image.get_int("interlaced") == 1;
70
+ }
65
71
  baton->hasProfile = sharp::HasProfile(image);
66
72
  // Derived attributes
67
73
  baton->hasAlpha = sharp::HasAlpha(image);
@@ -117,6 +123,9 @@ class MetadataWorker : public Nan::AsyncWorker {
117
123
  // Metadata Object
118
124
  v8::Local<v8::Object> info = New<v8::Object>();
119
125
  Set(info, New("format").ToLocalChecked(), New<v8::String>(baton->format).ToLocalChecked());
126
+ if (baton->input->bufferLength > 0) {
127
+ Set(info, New("size").ToLocalChecked(), New<v8::Uint32>(static_cast<uint32_t>(baton->input->bufferLength)));
128
+ }
120
129
  Set(info, New("width").ToLocalChecked(), New<v8::Uint32>(baton->width));
121
130
  Set(info, New("height").ToLocalChecked(), New<v8::Uint32>(baton->height));
122
131
  Set(info, New("space").ToLocalChecked(), New<v8::String>(baton->space).ToLocalChecked());
@@ -125,6 +134,12 @@ class MetadataWorker : public Nan::AsyncWorker {
125
134
  if (baton->density > 0) {
126
135
  Set(info, New("density").ToLocalChecked(), New<v8::Uint32>(baton->density));
127
136
  }
137
+ if (!baton->chromaSubsampling.empty()) {
138
+ Set(info,
139
+ New("chromaSubsampling").ToLocalChecked(),
140
+ New<v8::String>(baton->chromaSubsampling).ToLocalChecked());
141
+ }
142
+ Set(info, New("isProgressive").ToLocalChecked(), New<v8::Boolean>(baton->isProgressive));
128
143
  Set(info, New("hasProfile").ToLocalChecked(), New<v8::Boolean>(baton->hasProfile));
129
144
  Set(info, New("hasAlpha").ToLocalChecked(), New<v8::Boolean>(baton->hasAlpha));
130
145
  if (baton->orientation > 0) {
package/src/metadata.h CHANGED
@@ -31,6 +31,8 @@ struct MetadataBaton {
31
31
  int channels;
32
32
  std::string depth;
33
33
  int density;
34
+ std::string chromaSubsampling;
35
+ bool isProgressive;
34
36
  bool hasProfile;
35
37
  bool hasAlpha;
36
38
  int orientation;
@@ -50,6 +52,7 @@ struct MetadataBaton {
50
52
  height(0),
51
53
  channels(0),
52
54
  density(0),
55
+ isProgressive(false),
53
56
  hasProfile(false),
54
57
  hasAlpha(false),
55
58
  orientation(0),
package/src/operations.cc CHANGED
@@ -78,7 +78,7 @@ namespace sharp {
78
78
  //
79
79
  // References:
80
80
  // - http://en.wikipedia.org/wiki/Alpha_compositing#Alpha_blending
81
- // - https://github.com/jcupitt/ruby-vips/issues/28#issuecomment-9014826
81
+ // - https://github.com/libvips/ruby-vips/issues/28#issuecomment-9014826
82
82
  //
83
83
  // out_a = src_a + dst_a * (1 - src_a)
84
84
  // ^^^^^^^^^^^
@@ -324,55 +324,22 @@ namespace sharp {
324
324
  return image.boolean(imageR, boolean);
325
325
  }
326
326
 
327
- VImage Trim(VImage image, int const tolerance) {
328
- using sharp::MaximumImageAlpha;
329
- // An equivalent of ImageMagick's -trim in C++ ... automatically remove
330
- // "boring" image edges.
331
-
332
- // We use .project to sum the rows and columns of a 0/255 mask image, the first
333
- // non-zero row or column is the object edge. We make the mask image with an
334
- // amount-different-from-background image plus a threshold.
335
-
336
- // find the value of the pixel at (0, 0) ... we will search for all pixels
337
- // significantly different from this
338
- std::vector<double> background = image(0, 0);
339
-
340
- double const max = MaximumImageAlpha(image.interpretation());
341
-
342
- // we need to smooth the image, subtract the background from every pixel, take
343
- // the absolute value of the difference, then threshold
344
- VImage mask = (image.median(3) - background).abs() > (max * tolerance / 100);
345
-
346
- // sum mask rows and columns, then search for the first non-zero sum in each
347
- // direction
348
- VImage rows;
349
- VImage columns = mask.project(&rows);
350
-
351
- VImage profileLeftV;
352
- VImage profileLeftH = columns.profile(&profileLeftV);
353
-
354
- VImage profileRightV;
355
- VImage profileRightH = columns.fliphor().profile(&profileRightV);
356
-
357
- VImage profileTopV;
358
- VImage profileTopH = rows.profile(&profileTopV);
359
-
360
- VImage profileBottomV;
361
- VImage profileBottomH = rows.flipver().profile(&profileBottomV);
362
-
363
- int left = static_cast<int>(floor(profileLeftV.min()));
364
- int right = columns.width() - static_cast<int>(floor(profileRightV.min()));
365
- int top = static_cast<int>(floor(profileTopH.min()));
366
- int bottom = rows.height() - static_cast<int>(floor(profileBottomH.min()));
367
-
368
- int width = right - left;
369
- int height = bottom - top;
370
-
371
- if (width <= 0 || height <= 0) {
327
+ /*
328
+ Trim an image
329
+ */
330
+ VImage Trim(VImage image, double const threshold) {
331
+ // Top-left pixel provides the background colour
332
+ VImage background = image.extract_area(0, 0, 1, 1);
333
+ if (HasAlpha(background)) {
334
+ background = background.flatten();
335
+ }
336
+ int top, width, height;
337
+ int const left = image.find_trim(&top, &width, &height, VImage::option()
338
+ ->set("background", background(0, 0))
339
+ ->set("threshold", threshold));
340
+ if (width == 0 || height == 0) {
372
341
  throw VError("Unexpected error while trimming. Try to lower the tolerance");
373
342
  }
374
-
375
- // and now crop the original image
376
343
  return image.extract_area(left, top, width, height);
377
344
  }
378
345
 
package/src/operations.h CHANGED
@@ -100,7 +100,7 @@ namespace sharp {
100
100
  /*
101
101
  Trim an image
102
102
  */
103
- VImage Trim(VImage image, int const tolerance);
103
+ VImage Trim(VImage image, double const threshold);
104
104
 
105
105
  /*
106
106
  * Linear adjustment (a * in + b)
package/src/pipeline.cc CHANGED
@@ -100,8 +100,10 @@ class PipelineWorker : public Nan::AsyncWorker {
100
100
  }
101
101
 
102
102
  // Trim
103
- if (baton->trimTolerance != 0) {
104
- image = sharp::Trim(image, baton->trimTolerance);
103
+ if (baton->trimThreshold > 0.0) {
104
+ image = sharp::Trim(image, baton->trimThreshold);
105
+ baton->trimOffsetLeft = image.xoffset();
106
+ baton->trimOffsetTop = image.yoffset();
105
107
  }
106
108
 
107
109
  // Pre extraction
@@ -233,7 +235,7 @@ class PipelineWorker : public Nan::AsyncWorker {
233
235
  if (
234
236
  xshrink == yshrink && xshrink >= 2 * shrink_on_load_factor &&
235
237
  (inputImageType == ImageType::JPEG || inputImageType == ImageType::WEBP) &&
236
- baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimTolerance == 0
238
+ baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold == 0.0
237
239
  ) {
238
240
  if (xshrink >= 8 * shrink_on_load_factor) {
239
241
  xfactor = xfactor / 8;
@@ -318,9 +320,9 @@ class PipelineWorker : public Nan::AsyncWorker {
318
320
  double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;
319
321
  // Background colour
320
322
  std::vector<double> background {
321
- baton->background[0] * multiplier,
322
- baton->background[1] * multiplier,
323
- baton->background[2] * multiplier
323
+ baton->flattenBackground[0] * multiplier,
324
+ baton->flattenBackground[1] * multiplier,
325
+ baton->flattenBackground[2] * multiplier
324
326
  };
325
327
  image = image.flatten(VImage::option()
326
328
  ->set("background", background));
@@ -421,35 +423,8 @@ class PipelineWorker : public Nan::AsyncWorker {
421
423
  // Crop/embed
422
424
  if (image.width() != baton->width || image.height() != baton->height) {
423
425
  if (baton->canvas == Canvas::EMBED) {
424
- // Scale up 8-bit values to match 16-bit input image
425
- double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;
426
- // Create background colour
427
426
  std::vector<double> background;
428
- if (image.bands() > 2) {
429
- background = {
430
- multiplier * baton->background[0],
431
- multiplier * baton->background[1],
432
- multiplier * baton->background[2]
433
- };
434
- } else {
435
- // Convert sRGB to greyscale
436
- background = { multiplier * (
437
- 0.2126 * baton->background[0] +
438
- 0.7152 * baton->background[1] +
439
- 0.0722 * baton->background[2])
440
- };
441
- }
442
- // Add alpha channel to background colour
443
- if (baton->background[3] < 255.0 || HasAlpha(image)) {
444
- background.push_back(baton->background[3] * multiplier);
445
- }
446
- // Ensure background colour uses correct colourspace
447
- background = sharp::GetRgbaAsColourspace(background, image.interpretation());
448
- // Add non-transparent alpha channel, if required
449
- if (baton->background[3] < 255.0 && !HasAlpha(image)) {
450
- image = image.bandjoin(
451
- VImage::new_matrix(image.width(), image.height()).new_from_image(255 * multiplier));
452
- }
427
+ std::tie(image, background) = sharp::ApplyAlpha(image, baton->resizeBackground);
453
428
 
454
429
  // Embed
455
430
 
@@ -463,7 +438,7 @@ class PipelineWorker : public Nan::AsyncWorker {
463
438
  int width = std::max(image.width(), baton->width);
464
439
  int height = std::max(image.height(), baton->height);
465
440
  std::tie(left, top) = sharp::CalculateEmbedPosition(
466
- image.width(), image.height(), baton->width, baton->height, baton->embed);
441
+ image.width(), image.height(), baton->width, baton->height, baton->position);
467
442
 
468
443
  image = image.embed(left, top, width, height, VImage::option()
469
444
  ->set("extend", VIPS_EXTEND_BACKGROUND)
@@ -474,12 +449,12 @@ class PipelineWorker : public Nan::AsyncWorker {
474
449
  (image.width() > baton->width || image.height() > baton->height)
475
450
  ) {
476
451
  // Crop/max/min
477
- if (baton->crop < 9) {
452
+ if (baton->position < 9) {
478
453
  // Gravity-based crop
479
454
  int left;
480
455
  int top;
481
456
  std::tie(left, top) = sharp::CalculateCrop(
482
- image.width(), image.height(), baton->width, baton->height, baton->crop);
457
+ image.width(), image.height(), baton->width, baton->height, baton->position);
483
458
  int width = std::min(image.width(), baton->width);
484
459
  int height = std::min(image.height(), baton->height);
485
460
  image = image.extract_area(left, top, width, height);
@@ -495,7 +470,7 @@ class PipelineWorker : public Nan::AsyncWorker {
495
470
  ->set("access", baton->accessMethod)
496
471
  ->set("threaded", TRUE));
497
472
  image = image.smartcrop(baton->width, baton->height, VImage::option()
498
- ->set("interesting", baton->crop == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION));
473
+ ->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION));
499
474
  baton->hasCropOffset = true;
500
475
  baton->cropOffsetLeft = static_cast<int>(image.xoffset());
501
476
  baton->cropOffsetTop = static_cast<int>(image.yoffset());
@@ -503,6 +478,13 @@ class PipelineWorker : public Nan::AsyncWorker {
503
478
  }
504
479
  }
505
480
 
481
+ // Rotate by degree
482
+ if (baton->rotationAngle != 0.0) {
483
+ std::vector<double> background;
484
+ std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground);
485
+ image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background));
486
+ }
487
+
506
488
  // Post extraction
507
489
  if (baton->topOffsetPost != -1) {
508
490
  image = image.extract_area(
@@ -511,35 +493,9 @@ class PipelineWorker : public Nan::AsyncWorker {
511
493
 
512
494
  // Extend edges
513
495
  if (baton->extendTop > 0 || baton->extendBottom > 0 || baton->extendLeft > 0 || baton->extendRight > 0) {
514
- // Scale up 8-bit values to match 16-bit input image
515
- double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;
516
- // Create background colour
517
496
  std::vector<double> background;
518
- if (image.bands() > 2) {
519
- background = {
520
- multiplier * baton->background[0],
521
- multiplier * baton->background[1],
522
- multiplier * baton->background[2]
523
- };
524
- } else {
525
- // Convert sRGB to greyscale
526
- background = { multiplier * (
527
- 0.2126 * baton->background[0] +
528
- 0.7152 * baton->background[1] +
529
- 0.0722 * baton->background[2])
530
- };
531
- }
532
- // Add alpha channel to background colour
533
- if (baton->background[3] < 255.0 || HasAlpha(image)) {
534
- background.push_back(baton->background[3] * multiplier);
535
- }
536
- // Ensure background colour uses correct colourspace
537
- background = sharp::GetRgbaAsColourspace(background, image.interpretation());
538
- // Add non-transparent alpha channel, if required
539
- if (baton->background[3] < 255.0 && !HasAlpha(image)) {
540
- image = image.bandjoin(
541
- VImage::new_matrix(image.width(), image.height()).new_from_image(255 * multiplier));
542
- }
497
+ std::tie(image, background) = sharp::ApplyAlpha(image, baton->extendBackground);
498
+
543
499
  // Embed
544
500
  baton->width = image.width() + baton->extendLeft + baton->extendRight;
545
501
  baton->height = image.height() + baton->extendTop + baton->extendBottom;
@@ -894,10 +850,6 @@ class PipelineWorker : public Nan::AsyncWorker {
894
850
  if (baton->tiffCompression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) {
895
851
  sharp::AssertImageTypeDimensions(image, ImageType::JPEG);
896
852
  }
897
- // Cast pixel values to float, if required
898
- if (baton->tiffPredictor == VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT) {
899
- image = image.cast(VIPS_FORMAT_FLOAT);
900
- }
901
853
  image.tiffsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
902
854
  ->set("strip", !baton->withMetadata)
903
855
  ->set("Q", baton->tiffQuality)
@@ -1016,6 +968,12 @@ class PipelineWorker : public Nan::AsyncWorker {
1016
968
  Set(info, New("cropOffsetTop").ToLocalChecked(),
1017
969
  New<v8::Int32>(static_cast<int32_t>(baton->cropOffsetTop)));
1018
970
  }
971
+ if (baton->trimThreshold > 0.0) {
972
+ Set(info, New("trimOffsetLeft").ToLocalChecked(),
973
+ New<v8::Int32>(static_cast<int32_t>(baton->trimOffsetLeft)));
974
+ Set(info, New("trimOffsetTop").ToLocalChecked(),
975
+ New<v8::Int32>(static_cast<int32_t>(baton->trimOffsetTop)));
976
+ }
1019
977
 
1020
978
  if (baton->bufferOutLength > 0) {
1021
979
  // Pass ownership of output data to Buffer instance
@@ -1147,6 +1105,7 @@ NAN_METHOD(pipeline) {
1147
1105
  using sharp::AttrTo;
1148
1106
  using sharp::AttrAs;
1149
1107
  using sharp::AttrAsStr;
1108
+ using sharp::AttrAsRgba;
1150
1109
  using sharp::CreateInputDescriptor;
1151
1110
 
1152
1111
  // Input Buffers must not undergo GC compaction during processing
@@ -1190,11 +1149,6 @@ NAN_METHOD(pipeline) {
1190
1149
  } else if (canvas == "ignore_aspect") {
1191
1150
  baton->canvas = Canvas::IGNORE_ASPECT;
1192
1151
  }
1193
- // Background colour
1194
- v8::Local<v8::Object> background = AttrAs<v8::Object>(options, "background");
1195
- for (unsigned int i = 0; i < 4; i++) {
1196
- baton->background[i] = AttrTo<double>(background, i);
1197
- }
1198
1152
  // Tint chroma
1199
1153
  baton->tintA = AttrTo<double>(options, "tintA");
1200
1154
  baton->tintB = AttrTo<double>(options, "tintB");
@@ -1209,8 +1163,8 @@ NAN_METHOD(pipeline) {
1209
1163
  }
1210
1164
  // Resize options
1211
1165
  baton->withoutEnlargement = AttrTo<bool>(options, "withoutEnlargement");
1212
- baton->crop = AttrTo<int32_t>(options, "crop");
1213
- baton->embed = AttrTo<int32_t>(options, "embed");
1166
+ baton->position = AttrTo<int32_t>(options, "position");
1167
+ baton->resizeBackground = AttrAsRgba(options, "resizeBackground");
1214
1168
  baton->kernel = AttrAsStr(options, "kernel");
1215
1169
  baton->fastShrinkOnLoad = AttrTo<bool>(options, "fastShrinkOnLoad");
1216
1170
  // Join Channel Options
@@ -1228,6 +1182,7 @@ NAN_METHOD(pipeline) {
1228
1182
  }
1229
1183
  // Operators
1230
1184
  baton->flatten = AttrTo<bool>(options, "flatten");
1185
+ baton->flattenBackground = AttrAsRgba(options, "flattenBackground");
1231
1186
  baton->negate = AttrTo<bool>(options, "negate");
1232
1187
  baton->blurSigma = AttrTo<double>(options, "blurSigma");
1233
1188
  baton->medianSize = AttrTo<uint32_t>(options, "medianSize");
@@ -1236,7 +1191,7 @@ NAN_METHOD(pipeline) {
1236
1191
  baton->sharpenJagged = AttrTo<double>(options, "sharpenJagged");
1237
1192
  baton->threshold = AttrTo<int32_t>(options, "threshold");
1238
1193
  baton->thresholdGrayscale = AttrTo<bool>(options, "thresholdGrayscale");
1239
- baton->trimTolerance = AttrTo<int32_t>(options, "trimTolerance");
1194
+ baton->trimThreshold = AttrTo<double>(options, "trimThreshold");
1240
1195
  baton->gamma = AttrTo<double>(options, "gamma");
1241
1196
  baton->linearA = AttrTo<double>(options, "linearA");
1242
1197
  baton->linearB = AttrTo<double>(options, "linearB");
@@ -1244,6 +1199,8 @@ NAN_METHOD(pipeline) {
1244
1199
  baton->normalise = AttrTo<bool>(options, "normalise");
1245
1200
  baton->useExifOrientation = AttrTo<bool>(options, "useExifOrientation");
1246
1201
  baton->angle = AttrTo<int32_t>(options, "angle");
1202
+ baton->rotationAngle = AttrTo<double>(options, "rotationAngle");
1203
+ baton->rotationBackground = AttrAsRgba(options, "rotationBackground");
1247
1204
  baton->rotateBeforePreExtract = AttrTo<bool>(options, "rotateBeforePreExtract");
1248
1205
  baton->flip = AttrTo<bool>(options, "flip");
1249
1206
  baton->flop = AttrTo<bool>(options, "flop");
@@ -1251,7 +1208,9 @@ NAN_METHOD(pipeline) {
1251
1208
  baton->extendBottom = AttrTo<int32_t>(options, "extendBottom");
1252
1209
  baton->extendLeft = AttrTo<int32_t>(options, "extendLeft");
1253
1210
  baton->extendRight = AttrTo<int32_t>(options, "extendRight");
1211
+ baton->extendBackground = AttrAsRgba(options, "extendBackground");
1254
1212
  baton->extractChannel = AttrTo<int32_t>(options, "extractChannel");
1213
+
1255
1214
  baton->removeAlpha = AttrTo<bool>(options, "removeAlpha");
1256
1215
  if (HasAttr(options, "boolean")) {
1257
1216
  baton->boolean = CreateInputDescriptor(AttrAs<v8::Object>(options, "boolean"), buffersToPersist);
@@ -1342,8 +1301,8 @@ NAN_METHOD(pipeline) {
1342
1301
  }
1343
1302
  // Force random access for certain operations
1344
1303
  if (baton->accessMethod == VIPS_ACCESS_SEQUENTIAL && (
1345
- baton->trimTolerance != 0 || baton->normalise ||
1346
- baton->crop == 16 || baton->crop == 17)) {
1304
+ baton->trimThreshold > 0.0 || baton->normalise ||
1305
+ baton->position == 16 || baton->position == 17)) {
1347
1306
  baton->accessMethod = VIPS_ACCESS_RANDOM;
1348
1307
  }
1349
1308
 
package/src/pipeline.h CHANGED
@@ -61,18 +61,18 @@ struct PipelineBaton {
61
61
  int height;
62
62
  int channels;
63
63
  Canvas canvas;
64
- int crop;
65
- int embed;
64
+ int position;
65
+ std::vector<double> resizeBackground;
66
66
  bool hasCropOffset;
67
67
  int cropOffsetLeft;
68
68
  int cropOffsetTop;
69
69
  bool premultiplied;
70
70
  std::string kernel;
71
71
  bool fastShrinkOnLoad;
72
- double background[4];
73
72
  double tintA;
74
73
  double tintB;
75
74
  bool flatten;
75
+ std::vector<double> flattenBackground;
76
76
  bool negate;
77
77
  double blurSigma;
78
78
  int medianSize;
@@ -81,7 +81,9 @@ struct PipelineBaton {
81
81
  double sharpenJagged;
82
82
  int threshold;
83
83
  bool thresholdGrayscale;
84
- int trimTolerance;
84
+ double trimThreshold;
85
+ int trimOffsetLeft;
86
+ int trimOffsetTop;
85
87
  double linearA;
86
88
  double linearB;
87
89
  double gamma;
@@ -89,6 +91,8 @@ struct PipelineBaton {
89
91
  bool normalise;
90
92
  bool useExifOrientation;
91
93
  int angle;
94
+ double rotationAngle;
95
+ std::vector<double> rotationBackground;
92
96
  bool rotateBeforePreExtract;
93
97
  bool flip;
94
98
  bool flop;
@@ -96,6 +100,7 @@ struct PipelineBaton {
96
100
  int extendBottom;
97
101
  int extendLeft;
98
102
  int extendRight;
103
+ std::vector<double> extendBackground;
99
104
  bool withoutEnlargement;
100
105
  VipsAccess accessMethod;
101
106
  int jpegQuality;
@@ -155,8 +160,8 @@ struct PipelineBaton {
155
160
  topOffsetPost(-1),
156
161
  channels(0),
157
162
  canvas(Canvas::CROP),
158
- crop(0),
159
- embed(0),
163
+ position(0),
164
+ resizeBackground{ 0.0, 0.0, 0.0, 255.0 },
160
165
  hasCropOffset(false),
161
166
  cropOffsetLeft(0),
162
167
  cropOffsetTop(0),
@@ -164,6 +169,7 @@ struct PipelineBaton {
164
169
  tintA(128.0),
165
170
  tintB(128.0),
166
171
  flatten(false),
172
+ flattenBackground{ 0.0, 0.0, 0.0 },
167
173
  negate(false),
168
174
  blurSigma(0.0),
169
175
  medianSize(0),
@@ -172,7 +178,9 @@ struct PipelineBaton {
172
178
  sharpenJagged(2.0),
173
179
  threshold(0),
174
180
  thresholdGrayscale(true),
175
- trimTolerance(0),
181
+ trimThreshold(0.0),
182
+ trimOffsetLeft(0),
183
+ trimOffsetTop(0),
176
184
  linearA(1.0),
177
185
  linearB(0.0),
178
186
  gamma(0.0),
@@ -180,12 +188,15 @@ struct PipelineBaton {
180
188
  normalise(false),
181
189
  useExifOrientation(false),
182
190
  angle(0),
191
+ rotationAngle(0.0),
192
+ rotationBackground{ 0.0, 0.0, 0.0, 255.0 },
183
193
  flip(false),
184
194
  flop(false),
185
195
  extendTop(0),
186
196
  extendBottom(0),
187
197
  extendLeft(0),
188
198
  extendRight(0),
199
+ extendBackground{ 0.0, 0.0, 0.0, 255.0 },
189
200
  withoutEnlargement(false),
190
201
  jpegQuality(80),
191
202
  jpegProgressive(false),
@@ -222,12 +233,7 @@ struct PipelineBaton {
222
233
  tileContainer(VIPS_FOREIGN_DZ_CONTAINER_FS),
223
234
  tileLayout(VIPS_FOREIGN_DZ_LAYOUT_DZ),
224
235
  tileAngle(0),
225
- tileDepth(VIPS_FOREIGN_DZ_DEPTH_LAST){
226
- background[0] = 0.0;
227
- background[1] = 0.0;
228
- background[2] = 0.0;
229
- background[3] = 255.0;
230
- }
236
+ tileDepth(VIPS_FOREIGN_DZ_DEPTH_LAST) {}
231
237
  };
232
238
 
233
239
  #endif // SRC_PIPELINE_H_
package/src/utilities.cc CHANGED
@@ -259,7 +259,7 @@ NAN_METHOD(_maxColourDistance) {
259
259
  }
260
260
  // Calculate colour distance
261
261
  maxColourDistance = image1.dE00(image2).max();
262
- } catch (VError err) {
262
+ } catch (VError const &err) {
263
263
  return ThrowError(err.what());
264
264
  }
265
265