sharp 0.32.6 → 0.33.0-alpha.11

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/pipeline.cc CHANGED
@@ -44,9 +44,9 @@ class PipelineWorker : public Napi::AsyncWorker {
44
44
  // libuv worker
45
45
  void Execute() {
46
46
  // Decrement queued task counter
47
- g_atomic_int_dec_and_test(&sharp::counterQueue);
47
+ sharp::counterQueue--;
48
48
  // Increment processing task counter
49
- g_atomic_int_inc(&sharp::counterProcess);
49
+ sharp::counterProcess++;
50
50
 
51
51
  try {
52
52
  // Open input
@@ -126,10 +126,10 @@ class PipelineWorker : public Napi::AsyncWorker {
126
126
  }
127
127
 
128
128
  // Trim
129
- if (baton->trimThreshold > 0.0) {
129
+ if (baton->trimThreshold >= 0.0) {
130
130
  MultiPageUnsupported(nPages, "Trim");
131
131
  image = sharp::StaySequential(image, access);
132
- image = sharp::Trim(image, baton->trimBackground, baton->trimThreshold);
132
+ image = sharp::Trim(image, baton->trimBackground, baton->trimThreshold, baton->trimLineArt);
133
133
  baton->trimOffsetLeft = image.xoffset();
134
134
  baton->trimOffsetTop = image.yoffset();
135
135
  }
@@ -182,7 +182,7 @@ class PipelineWorker : public Napi::AsyncWorker {
182
182
  // - trimming or pre-resize extract isn't required;
183
183
  // - input colourspace is not specified;
184
184
  bool const shouldPreShrink = (targetResizeWidth > 0 || targetResizeHeight > 0) &&
185
- baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold == 0.0 &&
185
+ baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold < 0.0 &&
186
186
  baton->colourspaceInput == VIPS_INTERPRETATION_LAST && !shouldRotateBefore;
187
187
 
188
188
  if (shouldPreShrink) {
@@ -485,9 +485,7 @@ class PipelineWorker : public Napi::AsyncWorker {
485
485
  image = sharp::StaySequential(image, access);
486
486
  image = image.smartcrop(baton->width, baton->height, VImage::option()
487
487
  ->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION)
488
- #if (VIPS_MAJOR_VERSION >= 8 && VIPS_MINOR_VERSION >= 15)
489
488
  ->set("premultiplied", shouldPremultiplyAlpha)
490
- #endif
491
489
  ->set("attention_x", &attention_x)
492
490
  ->set("attention_y", &attention_y));
493
491
  baton->hasCropOffset = true;
@@ -940,6 +938,7 @@ class PipelineWorker : public Napi::AsyncWorker {
940
938
  ->set("Q", baton->tiffQuality)
941
939
  ->set("bitdepth", baton->tiffBitdepth)
942
940
  ->set("compression", baton->tiffCompression)
941
+ ->set("miniswhite", baton->tiffMiniswhite)
943
942
  ->set("predictor", baton->tiffPredictor)
944
943
  ->set("pyramid", baton->tiffPyramid)
945
944
  ->set("tile", baton->tiffTile)
@@ -1136,6 +1135,7 @@ class PipelineWorker : public Napi::AsyncWorker {
1136
1135
  ->set("Q", baton->tiffQuality)
1137
1136
  ->set("bitdepth", baton->tiffBitdepth)
1138
1137
  ->set("compression", baton->tiffCompression)
1138
+ ->set("miniswhite", baton->tiffMiniswhite)
1139
1139
  ->set("predictor", baton->tiffPredictor)
1140
1140
  ->set("pyramid", baton->tiffPyramid)
1141
1141
  ->set("tile", baton->tiffTile)
@@ -1215,7 +1215,7 @@ class PipelineWorker : public Napi::AsyncWorker {
1215
1215
  // Handle warnings
1216
1216
  std::string warning = sharp::VipsWarningPop();
1217
1217
  while (!warning.empty()) {
1218
- debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
1218
+ debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) });
1219
1219
  warning = sharp::VipsWarningPop();
1220
1220
  }
1221
1221
 
@@ -1248,11 +1248,10 @@ class PipelineWorker : public Napi::AsyncWorker {
1248
1248
  info.Set("attentionX", static_cast<int32_t>(baton->attentionX));
1249
1249
  info.Set("attentionY", static_cast<int32_t>(baton->attentionY));
1250
1250
  }
1251
- if (baton->trimThreshold > 0.0) {
1251
+ if (baton->trimThreshold >= 0.0) {
1252
1252
  info.Set("trimOffsetLeft", static_cast<int32_t>(baton->trimOffsetLeft));
1253
1253
  info.Set("trimOffsetTop", static_cast<int32_t>(baton->trimOffsetTop));
1254
1254
  }
1255
-
1256
1255
  if (baton->input->textAutofitDpi) {
1257
1256
  info.Set("textAutofitDpi", static_cast<uint32_t>(baton->input->textAutofitDpi));
1258
1257
  }
@@ -1263,17 +1262,17 @@ class PipelineWorker : public Napi::AsyncWorker {
1263
1262
  // Pass ownership of output data to Buffer instance
1264
1263
  Napi::Buffer<char> data = Napi::Buffer<char>::NewOrCopy(env, static_cast<char*>(baton->bufferOut),
1265
1264
  baton->bufferOutLength, sharp::FreeCallback);
1266
- Callback().MakeCallback(Receiver().Value(), { env.Null(), data, info });
1265
+ Callback().Call(Receiver().Value(), { env.Null(), data, info });
1267
1266
  } else {
1268
1267
  // Add file size to info
1269
1268
  struct STAT64_STRUCT st;
1270
1269
  if (STAT64_FUNCTION(baton->fileOut.data(), &st) == 0) {
1271
1270
  info.Set("size", static_cast<uint32_t>(st.st_size));
1272
1271
  }
1273
- Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
1272
+ Callback().Call(Receiver().Value(), { env.Null(), info });
1274
1273
  }
1275
1274
  } else {
1276
- Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
1275
+ Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
1277
1276
  }
1278
1277
 
1279
1278
  // Delete baton
@@ -1289,9 +1288,9 @@ class PipelineWorker : public Napi::AsyncWorker {
1289
1288
  delete baton;
1290
1289
 
1291
1290
  // Decrement processing task counter
1292
- g_atomic_int_dec_and_test(&sharp::counterProcess);
1293
- Napi::Number queueLength = Napi::Number::New(env, static_cast<double>(sharp::counterQueue));
1294
- queueListener.MakeCallback(Receiver().Value(), { queueLength });
1291
+ sharp::counterProcess--;
1292
+ Napi::Number queueLength = Napi::Number::New(env, static_cast<int>(sharp::counterQueue));
1293
+ queueListener.Call(Receiver().Value(), { queueLength });
1295
1294
  }
1296
1295
 
1297
1296
  private:
@@ -1519,6 +1518,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1519
1518
  baton->thresholdGrayscale = sharp::AttrAsBool(options, "thresholdGrayscale");
1520
1519
  baton->trimBackground = sharp::AttrAsVectorOfDouble(options, "trimBackground");
1521
1520
  baton->trimThreshold = sharp::AttrAsDouble(options, "trimThreshold");
1521
+ baton->trimLineArt = sharp::AttrAsBool(options, "trimLineArt");
1522
1522
  baton->gamma = sharp::AttrAsDouble(options, "gamma");
1523
1523
  baton->gammaOut = sharp::AttrAsDouble(options, "gammaOut");
1524
1524
  baton->linearA = sharp::AttrAsVectorOfDouble(options, "linearA");
@@ -1647,6 +1647,7 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1647
1647
  baton->gifProgressive = sharp::AttrAsBool(options, "gifProgressive");
1648
1648
  baton->tiffQuality = sharp::AttrAsUint32(options, "tiffQuality");
1649
1649
  baton->tiffPyramid = sharp::AttrAsBool(options, "tiffPyramid");
1650
+ baton->tiffMiniswhite = sharp::AttrAsBool(options, "tiffMiniswhite");
1650
1651
  baton->tiffBitdepth = sharp::AttrAsUint32(options, "tiffBitdepth");
1651
1652
  baton->tiffTile = sharp::AttrAsBool(options, "tiffTile");
1652
1653
  baton->tiffTileWidth = sharp::AttrAsUint32(options, "tiffTileWidth");
@@ -1707,9 +1708,8 @@ Napi::Value pipeline(const Napi::CallbackInfo& info) {
1707
1708
  worker->Queue();
1708
1709
 
1709
1710
  // Increment queued task counter
1710
- g_atomic_int_inc(&sharp::counterQueue);
1711
- Napi::Number queueLength = Napi::Number::New(info.Env(), static_cast<double>(sharp::counterQueue));
1712
- queueListener.MakeCallback(info.This(), { queueLength });
1711
+ Napi::Number queueLength = Napi::Number::New(info.Env(), static_cast<int>(++sharp::counterQueue));
1712
+ queueListener.Call(info.This(), { queueLength });
1713
1713
 
1714
1714
  return info.Env().Undefined();
1715
1715
  }
package/src/pipeline.h CHANGED
@@ -92,6 +92,7 @@ struct PipelineBaton {
92
92
  bool thresholdGrayscale;
93
93
  std::vector<double> trimBackground;
94
94
  double trimThreshold;
95
+ bool trimLineArt;
95
96
  int trimOffsetLeft;
96
97
  int trimOffsetTop;
97
98
  std::vector<double> linearA;
@@ -169,6 +170,7 @@ struct PipelineBaton {
169
170
  VipsForeignTiffPredictor tiffPredictor;
170
171
  bool tiffPyramid;
171
172
  int tiffBitdepth;
173
+ bool tiffMiniswhite;
172
174
  bool tiffTile;
173
175
  int tiffTileHeight;
174
176
  int tiffTileWidth;
@@ -259,7 +261,8 @@ struct PipelineBaton {
259
261
  threshold(0),
260
262
  thresholdGrayscale(true),
261
263
  trimBackground{},
262
- trimThreshold(0.0),
264
+ trimThreshold(-1.0),
265
+ trimLineArt(false),
263
266
  trimOffsetLeft(0),
264
267
  trimOffsetTop(0),
265
268
  linearA{},
@@ -335,6 +338,7 @@ struct PipelineBaton {
335
338
  tiffPredictor(VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL),
336
339
  tiffPyramid(false),
337
340
  tiffBitdepth(8),
341
+ tiffMiniswhite(false),
338
342
  tiffTile(false),
339
343
  tiffTileHeight(256),
340
344
  tiffTileWidth(256),
package/src/sharp.cc CHANGED
@@ -1,6 +1,8 @@
1
1
  // Copyright 2013 Lovell Fuller and others.
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
 
4
+ #include <mutex> // NOLINT(build/c++11)
5
+
4
6
  #include <napi.h>
5
7
  #include <vips/vips8>
6
8
 
@@ -10,14 +12,11 @@
10
12
  #include "utilities.h"
11
13
  #include "stats.h"
12
14
 
13
- static void* sharp_vips_init(void*) {
14
- vips_init("sharp");
15
- return nullptr;
16
- }
17
-
18
15
  Napi::Object init(Napi::Env env, Napi::Object exports) {
19
- static GOnce sharp_vips_init_once = G_ONCE_INIT;
20
- g_once(&sharp_vips_init_once, static_cast<GThreadFunc>(sharp_vips_init), nullptr);
16
+ static std::once_flag sharp_vips_init_once;
17
+ std::call_once(sharp_vips_init_once, []() {
18
+ vips_init("sharp");
19
+ });
21
20
 
22
21
  g_log_set_handler("VIPS", static_cast<GLogLevelFlags>(G_LOG_LEVEL_WARNING),
23
22
  static_cast<GLogFunc>(sharp::VipsWarningCallback), nullptr);
package/src/stats.cc CHANGED
@@ -30,7 +30,7 @@ class StatsWorker : public Napi::AsyncWorker {
30
30
 
31
31
  void Execute() {
32
32
  // Decrement queued task counter
33
- g_atomic_int_dec_and_test(&sharp::counterQueue);
33
+ sharp::counterQueue--;
34
34
 
35
35
  vips::VImage image;
36
36
  sharp::ImageType imageType = sharp::ImageType::UNKNOWN;
@@ -106,7 +106,7 @@ class StatsWorker : public Napi::AsyncWorker {
106
106
  // Handle warnings
107
107
  std::string warning = sharp::VipsWarningPop();
108
108
  while (!warning.empty()) {
109
- debuglog.MakeCallback(Receiver().Value(), { Napi::String::New(env, warning) });
109
+ debuglog.Call(Receiver().Value(), { Napi::String::New(env, warning) });
110
110
  warning = sharp::VipsWarningPop();
111
111
  }
112
112
 
@@ -141,9 +141,9 @@ class StatsWorker : public Napi::AsyncWorker {
141
141
  dominant.Set("g", baton->dominantGreen);
142
142
  dominant.Set("b", baton->dominantBlue);
143
143
  info.Set("dominant", dominant);
144
- Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
144
+ Callback().Call(Receiver().Value(), { env.Null(), info });
145
145
  } else {
146
- Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
146
+ Callback().Call(Receiver().Value(), { Napi::Error::New(env, sharp::TrimEnd(baton->err)).Value() });
147
147
  }
148
148
 
149
149
  delete baton->input;
@@ -177,7 +177,7 @@ Napi::Value stats(const Napi::CallbackInfo& info) {
177
177
  worker->Queue();
178
178
 
179
179
  // Increment queued task counter
180
- g_atomic_int_inc(&sharp::counterQueue);
180
+ sharp::counterQueue++;
181
181
 
182
182
  return info.Env().Undefined();
183
183
  }
package/src/utilities.cc CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include <cmath>
5
5
  #include <string>
6
+ #include <cstdio>
6
7
 
7
8
  #include <napi.h>
8
9
  #include <vips/vips8>
@@ -70,8 +71,8 @@ Napi::Value concurrency(const Napi::CallbackInfo& info) {
70
71
  */
71
72
  Napi::Value counters(const Napi::CallbackInfo& info) {
72
73
  Napi::Object counters = Napi::Object::New(info.Env());
73
- counters.Set("queue", sharp::counterQueue);
74
- counters.Set("process", sharp::counterProcess);
74
+ counters.Set("queue", static_cast<int>(sharp::counterQueue));
75
+ counters.Set("process", static_cast<int>(sharp::counterProcess));
75
76
  return counters;
76
77
  }
77
78
 
@@ -91,9 +92,23 @@ Napi::Value simd(const Napi::CallbackInfo& info) {
91
92
  Get libvips version
92
93
  */
93
94
  Napi::Value libvipsVersion(const Napi::CallbackInfo& info) {
94
- char version[9];
95
- g_snprintf(version, sizeof(version), "%d.%d.%d", vips_version(0), vips_version(1), vips_version(2));
96
- return Napi::String::New(info.Env(), version);
95
+ Napi::Env env = info.Env();
96
+ Napi::Object version = Napi::Object::New(env);
97
+
98
+ char semver[9];
99
+ std::snprintf(semver, sizeof(semver), "%d.%d.%d", vips_version(0), vips_version(1), vips_version(2));
100
+ version.Set("semver", Napi::String::New(env, semver));
101
+ #ifdef SHARP_USE_GLOBAL_LIBVIPS
102
+ version.Set("isGlobal", Napi::Boolean::New(env, true));
103
+ #else
104
+ version.Set("isGlobal", Napi::Boolean::New(env, false));
105
+ #endif
106
+ #ifdef __EMSCRIPTEN__
107
+ version.Set("isWasm", Napi::Boolean::New(env, true));
108
+ #else
109
+ version.Set("isWasm", Napi::Boolean::New(env, false));
110
+ #endif
111
+ return version;
97
112
  }
98
113
 
99
114
  /*
@@ -1,14 +0,0 @@
1
- // Copyright 2013 Lovell Fuller and others.
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- 'use strict';
5
-
6
- const libvips = require('../lib/libvips');
7
-
8
- try {
9
- if (!(libvips.useGlobalLibvips() || libvips.hasVendoredLibvips())) {
10
- process.exitCode = 1;
11
- }
12
- } catch (err) {
13
- process.exitCode = 1;
14
- }
@@ -1,40 +0,0 @@
1
- // Copyright 2013 Lovell Fuller and others.
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- 'use strict';
5
-
6
- const fs = require('fs');
7
- const path = require('path');
8
-
9
- const libvips = require('../lib/libvips');
10
- const platform = require('../lib/platform');
11
-
12
- const minimumLibvipsVersion = libvips.minimumLibvipsVersion;
13
-
14
- const platformAndArch = platform();
15
-
16
- if (platformAndArch.startsWith('win32')) {
17
- const buildReleaseDir = path.join(__dirname, '..', 'build', 'Release');
18
- libvips.log(`Creating ${buildReleaseDir}`);
19
- try {
20
- libvips.mkdirSync(buildReleaseDir);
21
- } catch (err) {}
22
- const vendorLibDir = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion, platformAndArch, 'lib');
23
- libvips.log(`Copying DLLs from ${vendorLibDir} to ${buildReleaseDir}`);
24
- try {
25
- fs
26
- .readdirSync(vendorLibDir)
27
- .filter(function (filename) {
28
- return /\.dll$/.test(filename);
29
- })
30
- .forEach(function (filename) {
31
- fs.copyFileSync(
32
- path.join(vendorLibDir, filename),
33
- path.join(buildReleaseDir, filename)
34
- );
35
- });
36
- } catch (err) {
37
- libvips.log(err);
38
- process.exit(1);
39
- }
40
- }
@@ -1,222 +0,0 @@
1
- // Copyright 2013 Lovell Fuller and others.
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- 'use strict';
5
-
6
- const fs = require('fs');
7
- const os = require('os');
8
- const path = require('path');
9
- const stream = require('stream');
10
- const zlib = require('zlib');
11
- const { createHash } = require('crypto');
12
-
13
- const detectLibc = require('detect-libc');
14
- const semverCoerce = require('semver/functions/coerce');
15
- const semverLessThan = require('semver/functions/lt');
16
- const semverSatisfies = require('semver/functions/satisfies');
17
- const simpleGet = require('simple-get');
18
- const tarFs = require('tar-fs');
19
-
20
- const agent = require('../lib/agent');
21
- const libvips = require('../lib/libvips');
22
- const platform = require('../lib/platform');
23
-
24
- const minimumGlibcVersionByArch = {
25
- arm: '2.28',
26
- arm64: '2.17',
27
- x64: '2.17'
28
- };
29
-
30
- const hasSharpPrebuild = [
31
- 'darwin-x64',
32
- 'darwin-arm64',
33
- 'linux-arm64',
34
- 'linux-x64',
35
- 'linuxmusl-x64',
36
- 'linuxmusl-arm64',
37
- 'win32-ia32',
38
- 'win32-x64'
39
- ];
40
-
41
- const { minimumLibvipsVersion, minimumLibvipsVersionLabelled } = libvips;
42
- const localLibvipsDir = process.env.npm_config_sharp_libvips_local_prebuilds || '';
43
- const distHost = process.env.npm_config_sharp_libvips_binary_host || 'https://github.com/lovell/sharp-libvips/releases/download';
44
- const distBaseUrl = process.env.npm_config_sharp_dist_base_url || process.env.SHARP_DIST_BASE_URL || `${distHost}/v${minimumLibvipsVersionLabelled}/`;
45
- const installationForced = !!(process.env.npm_config_sharp_install_force || process.env.SHARP_INSTALL_FORCE);
46
-
47
- const fail = function (err) {
48
- libvips.log(err);
49
- if (err.code === 'EACCES') {
50
- libvips.log('Are you trying to install as a root or sudo user?');
51
- libvips.log('- For npm <= v6, try again with the "--unsafe-perm" flag');
52
- libvips.log('- For npm >= v8, the user must own the directory "npm install" is run in');
53
- }
54
- libvips.log('Please see https://sharp.pixelplumbing.com/install for required dependencies');
55
- process.exit(1);
56
- };
57
-
58
- const handleError = function (err) {
59
- if (installationForced) {
60
- libvips.log(`Installation warning: ${err.message}`);
61
- } else {
62
- throw err;
63
- }
64
- };
65
-
66
- const verifyIntegrity = function (platformAndArch) {
67
- const expected = libvips.integrity(platformAndArch);
68
- if (installationForced || !expected) {
69
- libvips.log(`Integrity check skipped for ${platformAndArch}`);
70
- return new stream.PassThrough();
71
- }
72
- const hash = createHash('sha512');
73
- return new stream.Transform({
74
- transform: function (chunk, _encoding, done) {
75
- hash.update(chunk);
76
- done(null, chunk);
77
- },
78
- flush: function (done) {
79
- const digest = `sha512-${hash.digest('base64')}`;
80
- if (expected !== digest) {
81
- try {
82
- libvips.removeVendoredLibvips();
83
- } catch (err) {
84
- libvips.log(err.message);
85
- }
86
- libvips.log(`Integrity expected: ${expected}`);
87
- libvips.log(`Integrity received: ${digest}`);
88
- done(new Error(`Integrity check failed for ${platformAndArch}`));
89
- } else {
90
- libvips.log(`Integrity check passed for ${platformAndArch}`);
91
- done();
92
- }
93
- }
94
- });
95
- };
96
-
97
- const extractTarball = function (tarPath, platformAndArch) {
98
- const versionedVendorPath = path.join(__dirname, '..', 'vendor', minimumLibvipsVersion, platformAndArch);
99
- libvips.mkdirSync(versionedVendorPath);
100
-
101
- const ignoreVendorInclude = hasSharpPrebuild.includes(platformAndArch) && !process.env.npm_config_build_from_source;
102
- const ignore = function (name) {
103
- return ignoreVendorInclude && name.includes('include/');
104
- };
105
-
106
- stream.pipeline(
107
- fs.createReadStream(tarPath),
108
- verifyIntegrity(platformAndArch),
109
- new zlib.BrotliDecompress(),
110
- tarFs.extract(versionedVendorPath, { ignore }),
111
- function (err) {
112
- if (err) {
113
- if (/unexpected end of file/.test(err.message)) {
114
- fail(new Error(`Please delete ${tarPath} as it is not a valid tarball`));
115
- }
116
- fail(err);
117
- }
118
- }
119
- );
120
- };
121
-
122
- try {
123
- const useGlobalLibvips = libvips.useGlobalLibvips();
124
-
125
- if (useGlobalLibvips) {
126
- const globalLibvipsVersion = libvips.globalLibvipsVersion();
127
- libvips.log(`Detected globally-installed libvips v${globalLibvipsVersion}`);
128
- libvips.log('Building from source via node-gyp');
129
- process.exit(1);
130
- } else if (libvips.hasVendoredLibvips()) {
131
- libvips.log(`Using existing vendored libvips v${minimumLibvipsVersion}`);
132
- } else {
133
- // Is this arch/platform supported?
134
- const arch = process.env.npm_config_arch || process.arch;
135
- const platformAndArch = platform();
136
- if (arch === 'ia32' && !platformAndArch.startsWith('win32')) {
137
- throw new Error(`Intel Architecture 32-bit systems require manual installation of libvips >= ${minimumLibvipsVersion}`);
138
- }
139
- if (platformAndArch === 'freebsd-x64' || platformAndArch === 'openbsd-x64' || platformAndArch === 'sunos-x64') {
140
- throw new Error(`BSD/SunOS systems require manual installation of libvips >= ${minimumLibvipsVersion}`);
141
- }
142
- // Linux libc version check
143
- const libcVersionRaw = detectLibc.versionSync();
144
- if (libcVersionRaw) {
145
- const libcFamily = detectLibc.familySync();
146
- const libcVersion = semverCoerce(libcVersionRaw).version;
147
- if (libcFamily === detectLibc.GLIBC && minimumGlibcVersionByArch[arch]) {
148
- if (semverLessThan(libcVersion, semverCoerce(minimumGlibcVersionByArch[arch]).version)) {
149
- handleError(new Error(`Use with glibc ${libcVersionRaw} requires manual installation of libvips >= ${minimumLibvipsVersion}`));
150
- }
151
- }
152
- if (libcFamily === detectLibc.MUSL) {
153
- if (semverLessThan(libcVersion, '1.1.24')) {
154
- handleError(new Error(`Use with musl ${libcVersionRaw} requires manual installation of libvips >= ${minimumLibvipsVersion}`));
155
- }
156
- }
157
- }
158
- // Node.js minimum version check
159
- const supportedNodeVersion = process.env.npm_package_engines_node || require('../package.json').engines.node;
160
- if (!semverSatisfies(process.versions.node, supportedNodeVersion)) {
161
- handleError(new Error(`Expected Node.js version ${supportedNodeVersion} but found ${process.versions.node}`));
162
- }
163
- // Download to per-process temporary file
164
- const tarFilename = ['libvips', minimumLibvipsVersionLabelled, platformAndArch].join('-') + '.tar.br';
165
- const tarPathCache = path.join(libvips.cachePath(), tarFilename);
166
- if (fs.existsSync(tarPathCache)) {
167
- libvips.log(`Using cached ${tarPathCache}`);
168
- extractTarball(tarPathCache, platformAndArch);
169
- } else if (localLibvipsDir) {
170
- // If localLibvipsDir is given try to use binaries from local directory
171
- const tarPathLocal = path.join(path.resolve(localLibvipsDir), `v${minimumLibvipsVersionLabelled}`, tarFilename);
172
- libvips.log(`Using local libvips from ${tarPathLocal}`);
173
- extractTarball(tarPathLocal, platformAndArch);
174
- } else {
175
- const url = distBaseUrl + tarFilename;
176
- libvips.log(`Downloading ${url}`);
177
- simpleGet({ url: url, agent: agent(libvips.log) }, function (err, response) {
178
- if (err) {
179
- fail(err);
180
- } else if (response.statusCode === 404) {
181
- fail(new Error(`Prebuilt libvips ${minimumLibvipsVersion} binaries are not yet available for ${platformAndArch}`));
182
- } else if (response.statusCode !== 200) {
183
- fail(new Error(`Status ${response.statusCode} ${response.statusMessage}`));
184
- } else {
185
- const tarPathTemp = path.join(os.tmpdir(), `${process.pid}-${tarFilename}`);
186
- const tmpFileStream = fs.createWriteStream(tarPathTemp);
187
- response
188
- .on('error', function (err) {
189
- tmpFileStream.destroy(err);
190
- })
191
- .on('close', function () {
192
- if (!response.complete) {
193
- tmpFileStream.destroy(new Error('Download incomplete (connection was terminated)'));
194
- }
195
- })
196
- .pipe(tmpFileStream);
197
- tmpFileStream
198
- .on('error', function (err) {
199
- // Clean up temporary file
200
- try {
201
- fs.unlinkSync(tarPathTemp);
202
- } catch (e) {}
203
- fail(err);
204
- })
205
- .on('close', function () {
206
- try {
207
- // Attempt to rename
208
- fs.renameSync(tarPathTemp, tarPathCache);
209
- } catch (err) {
210
- // Fall back to copy and unlink
211
- fs.copyFileSync(tarPathTemp, tarPathCache);
212
- fs.unlinkSync(tarPathTemp);
213
- }
214
- extractTarball(tarPathCache, platformAndArch);
215
- });
216
- }
217
- });
218
- }
219
- }
220
- } catch (err) {
221
- fail(err);
222
- }
package/lib/agent.js DELETED
@@ -1,44 +0,0 @@
1
- // Copyright 2013 Lovell Fuller and others.
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- 'use strict';
5
-
6
- const url = require('url');
7
- const tunnelAgent = require('tunnel-agent');
8
-
9
- const is = require('./is');
10
-
11
- const proxies = [
12
- 'HTTPS_PROXY',
13
- 'https_proxy',
14
- 'HTTP_PROXY',
15
- 'http_proxy',
16
- 'npm_config_https_proxy',
17
- 'npm_config_proxy'
18
- ];
19
-
20
- function env (key) {
21
- return process.env[key];
22
- }
23
-
24
- module.exports = function (log) {
25
- try {
26
- const proxy = new url.URL(proxies.map(env).find(is.string));
27
- const tunnel = proxy.protocol === 'https:'
28
- ? tunnelAgent.httpsOverHttps
29
- : tunnelAgent.httpsOverHttp;
30
- const proxyAuth = proxy.username && proxy.password
31
- ? `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`
32
- : null;
33
- log(`Via proxy ${proxy.protocol}//${proxy.hostname}:${proxy.port} ${proxyAuth ? 'with' : 'no'} credentials`);
34
- return tunnel({
35
- proxy: {
36
- port: Number(proxy.port),
37
- host: proxy.hostname,
38
- proxyAuth
39
- }
40
- });
41
- } catch (err) {
42
- return null;
43
- }
44
- };
package/lib/platform.js DELETED
@@ -1,30 +0,0 @@
1
- // Copyright 2013 Lovell Fuller and others.
2
- // SPDX-License-Identifier: Apache-2.0
3
-
4
- 'use strict';
5
-
6
- const detectLibc = require('detect-libc');
7
-
8
- const env = process.env;
9
-
10
- module.exports = function () {
11
- const arch = env.npm_config_arch || process.arch;
12
- const platform = env.npm_config_platform || process.platform;
13
- const libc = process.env.npm_config_libc ||
14
- /* istanbul ignore next */
15
- (detectLibc.isNonGlibcLinuxSync() ? detectLibc.familySync() : '');
16
- const libcId = platform !== 'linux' || libc === detectLibc.GLIBC ? '' : libc;
17
-
18
- const platformId = [`${platform}${libcId}`];
19
-
20
- if (arch === 'arm') {
21
- const fallback = process.versions.electron ? '7' : '6';
22
- platformId.push(`armv${env.npm_config_arm_version || process.config.variables.arm_version || fallback}`);
23
- } else if (arch === 'arm64') {
24
- platformId.push(`arm64v${env.npm_config_arm_version || '8'}`);
25
- } else {
26
- platformId.push(arch);
27
- }
28
-
29
- return platformId.join('-');
30
- };