@basemaps/lambda-tiler 6.18.0 → 6.21.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.
Files changed (656) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/LICENSE +2 -2
  3. package/build/__test__/tile.set.cache.test.js +4 -10
  4. package/build/__test__/tile.style.json.test.d.ts +2 -0
  5. package/build/__test__/tile.style.json.test.d.ts.map +1 -0
  6. package/build/__test__/tile.style.json.test.js +33 -0
  7. package/build/__test__/xyz.test.js +27 -26
  8. package/build/cli/dump.js +2 -2
  9. package/build/cli/validate.js +2 -1
  10. package/build/index.d.ts.map +1 -1
  11. package/build/index.js +18 -1
  12. package/build/routes/__test__/attribution.test.js +3 -13
  13. package/build/routes/attribution.d.ts.map +1 -1
  14. package/build/routes/attribution.js +7 -20
  15. package/build/routes/esri/rest.d.ts +10 -0
  16. package/build/routes/esri/rest.d.ts.map +1 -0
  17. package/build/routes/esri/rest.js +87 -0
  18. package/build/routes/imagery.d.ts +10 -0
  19. package/build/routes/imagery.d.ts.map +1 -0
  20. package/build/routes/imagery.js +50 -0
  21. package/build/routes/response.d.ts +4 -0
  22. package/build/routes/response.d.ts.map +1 -0
  23. package/build/routes/response.js +3 -0
  24. package/build/routes/tile.d.ts +0 -20
  25. package/build/routes/tile.d.ts.map +1 -1
  26. package/build/routes/tile.js +11 -164
  27. package/build/routes/tile.json.d.ts +10 -0
  28. package/build/routes/tile.json.d.ts.map +1 -0
  29. package/build/routes/tile.json.js +31 -0
  30. package/build/routes/tile.style.json.d.ts +10 -0
  31. package/build/routes/tile.style.json.d.ts.map +1 -0
  32. package/build/routes/tile.style.json.js +74 -0
  33. package/build/routes/tile.wmts.d.ts +9 -0
  34. package/build/routes/tile.wmts.d.ts.map +1 -0
  35. package/build/routes/tile.wmts.js +57 -0
  36. package/build/routes/tile.xyz.d.ts +13 -0
  37. package/build/routes/tile.xyz.d.ts.map +1 -0
  38. package/build/routes/tile.xyz.js +28 -0
  39. package/build/source.tracer.d.ts +17 -0
  40. package/build/source.tracer.d.ts.map +1 -0
  41. package/build/source.tracer.js +22 -0
  42. package/build/tile.set.cache.js +3 -3
  43. package/build/tile.set.d.ts +0 -16
  44. package/build/tile.set.d.ts.map +1 -1
  45. package/build/tile.set.js +1 -20
  46. package/build/tile.set.raster.d.ts +9 -4
  47. package/build/tile.set.raster.d.ts.map +1 -1
  48. package/build/tile.set.raster.js +17 -6
  49. package/build/tile.set.vector.d.ts +10 -4
  50. package/build/tile.set.vector.d.ts.map +1 -1
  51. package/build/tile.set.vector.js +18 -8
  52. package/bundle.sh +2 -2
  53. package/package.json +14 -14
  54. package/scripts/create.deployment.package.mjs +34 -0
  55. package/src/__test__/tile.set.cache.test.ts +4 -12
  56. package/src/__test__/tile.style.json.test.ts +40 -0
  57. package/src/__test__/xyz.test.ts +35 -33
  58. package/src/cli/dump.ts +2 -2
  59. package/src/cli/validate.ts +2 -1
  60. package/src/index.ts +21 -1
  61. package/src/routes/__test__/attribution.test.ts +3 -13
  62. package/src/routes/attribution.ts +6 -17
  63. package/src/routes/esri/rest.ts +90 -0
  64. package/src/routes/imagery.ts +52 -0
  65. package/src/routes/response.ts +4 -0
  66. package/src/routes/tile.json.ts +44 -0
  67. package/src/routes/tile.style.json.ts +77 -0
  68. package/src/routes/tile.ts +11 -186
  69. package/src/routes/tile.wmts.ts +59 -0
  70. package/src/routes/tile.xyz.ts +30 -0
  71. package/src/source.tracer.ts +34 -0
  72. package/src/tile.set.cache.ts +3 -3
  73. package/src/tile.set.raster.ts +32 -7
  74. package/src/tile.set.ts +0 -40
  75. package/src/tile.set.vector.ts +26 -7
  76. package/tsconfig.tsbuildinfo +1 -1
  77. package/dist/index.js +0 -29695
  78. package/dist/node_modules/ansi-regex/index.js +0 -4
  79. package/dist/node_modules/ansi-regex/license +0 -21
  80. package/dist/node_modules/ansi-regex/package.json +0 -108
  81. package/dist/node_modules/ansi-regex/readme.md +0 -39
  82. package/dist/node_modules/aproba/LICENSE +0 -14
  83. package/dist/node_modules/aproba/README.md +0 -94
  84. package/dist/node_modules/aproba/index.js +0 -105
  85. package/dist/node_modules/aproba/package.json +0 -62
  86. package/dist/node_modules/are-we-there-yet/CHANGES.md +0 -37
  87. package/dist/node_modules/are-we-there-yet/LICENSE +0 -5
  88. package/dist/node_modules/are-we-there-yet/README.md +0 -195
  89. package/dist/node_modules/are-we-there-yet/index.js +0 -4
  90. package/dist/node_modules/are-we-there-yet/package.json +0 -63
  91. package/dist/node_modules/are-we-there-yet/tracker-base.js +0 -11
  92. package/dist/node_modules/are-we-there-yet/tracker-group.js +0 -107
  93. package/dist/node_modules/are-we-there-yet/tracker-stream.js +0 -36
  94. package/dist/node_modules/are-we-there-yet/tracker.js +0 -30
  95. package/dist/node_modules/base64-js/LICENSE +0 -21
  96. package/dist/node_modules/base64-js/README.md +0 -34
  97. package/dist/node_modules/base64-js/base64js.min.js +0 -1
  98. package/dist/node_modules/base64-js/index.d.ts +0 -3
  99. package/dist/node_modules/base64-js/index.js +0 -150
  100. package/dist/node_modules/base64-js/package.json +0 -75
  101. package/dist/node_modules/bl/.travis.yml +0 -17
  102. package/dist/node_modules/bl/BufferList.js +0 -396
  103. package/dist/node_modules/bl/LICENSE.md +0 -13
  104. package/dist/node_modules/bl/README.md +0 -247
  105. package/dist/node_modules/bl/bl.js +0 -84
  106. package/dist/node_modules/bl/node_modules/readable-stream/CONTRIBUTING.md +0 -38
  107. package/dist/node_modules/bl/node_modules/readable-stream/GOVERNANCE.md +0 -136
  108. package/dist/node_modules/bl/node_modules/readable-stream/LICENSE +0 -47
  109. package/dist/node_modules/bl/node_modules/readable-stream/README.md +0 -106
  110. package/dist/node_modules/bl/node_modules/readable-stream/errors-browser.js +0 -127
  111. package/dist/node_modules/bl/node_modules/readable-stream/errors.js +0 -116
  112. package/dist/node_modules/bl/node_modules/readable-stream/experimentalWarning.js +0 -17
  113. package/dist/node_modules/bl/node_modules/readable-stream/lib/_stream_duplex.js +0 -139
  114. package/dist/node_modules/bl/node_modules/readable-stream/lib/_stream_passthrough.js +0 -39
  115. package/dist/node_modules/bl/node_modules/readable-stream/lib/_stream_readable.js +0 -1124
  116. package/dist/node_modules/bl/node_modules/readable-stream/lib/_stream_transform.js +0 -201
  117. package/dist/node_modules/bl/node_modules/readable-stream/lib/_stream_writable.js +0 -697
  118. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/async_iterator.js +0 -207
  119. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/buffer_list.js +0 -210
  120. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -105
  121. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +0 -104
  122. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/from-browser.js +0 -3
  123. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/from.js +0 -64
  124. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/pipeline.js +0 -97
  125. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/state.js +0 -27
  126. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
  127. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
  128. package/dist/node_modules/bl/node_modules/readable-stream/package.json +0 -97
  129. package/dist/node_modules/bl/node_modules/readable-stream/readable-browser.js +0 -9
  130. package/dist/node_modules/bl/node_modules/readable-stream/readable.js +0 -16
  131. package/dist/node_modules/bl/package.json +0 -69
  132. package/dist/node_modules/bl/test/convert.js +0 -21
  133. package/dist/node_modules/bl/test/indexOf.js +0 -492
  134. package/dist/node_modules/bl/test/isBufferList.js +0 -32
  135. package/dist/node_modules/bl/test/test.js +0 -869
  136. package/dist/node_modules/buffer/AUTHORS.md +0 -70
  137. package/dist/node_modules/buffer/LICENSE +0 -21
  138. package/dist/node_modules/buffer/README.md +0 -410
  139. package/dist/node_modules/buffer/index.d.ts +0 -186
  140. package/dist/node_modules/buffer/index.js +0 -1817
  141. package/dist/node_modules/buffer/package.json +0 -127
  142. package/dist/node_modules/chownr/LICENSE +0 -15
  143. package/dist/node_modules/chownr/README.md +0 -3
  144. package/dist/node_modules/chownr/chownr.js +0 -167
  145. package/dist/node_modules/chownr/package.json +0 -62
  146. package/dist/node_modules/code-point-at/index.js +0 -32
  147. package/dist/node_modules/code-point-at/license +0 -21
  148. package/dist/node_modules/code-point-at/package.json +0 -70
  149. package/dist/node_modules/code-point-at/readme.md +0 -32
  150. package/dist/node_modules/color/LICENSE +0 -21
  151. package/dist/node_modules/color/README.md +0 -123
  152. package/dist/node_modules/color/index.js +0 -482
  153. package/dist/node_modules/color/package.json +0 -72
  154. package/dist/node_modules/color-convert/CHANGELOG.md +0 -54
  155. package/dist/node_modules/color-convert/LICENSE +0 -21
  156. package/dist/node_modules/color-convert/README.md +0 -68
  157. package/dist/node_modules/color-convert/conversions.js +0 -868
  158. package/dist/node_modules/color-convert/index.js +0 -78
  159. package/dist/node_modules/color-convert/package.json +0 -81
  160. package/dist/node_modules/color-convert/route.js +0 -97
  161. package/dist/node_modules/color-name/.eslintrc.json +0 -43
  162. package/dist/node_modules/color-name/LICENSE +0 -8
  163. package/dist/node_modules/color-name/README.md +0 -11
  164. package/dist/node_modules/color-name/index.js +0 -152
  165. package/dist/node_modules/color-name/package.json +0 -54
  166. package/dist/node_modules/color-name/test.js +0 -7
  167. package/dist/node_modules/color-string/LICENSE +0 -21
  168. package/dist/node_modules/color-string/README.md +0 -62
  169. package/dist/node_modules/color-string/index.js +0 -242
  170. package/dist/node_modules/color-string/package.json +0 -81
  171. package/dist/node_modules/console-control-strings/LICENSE +0 -13
  172. package/dist/node_modules/console-control-strings/README.md +0 -145
  173. package/dist/node_modules/console-control-strings/README.md~ +0 -140
  174. package/dist/node_modules/console-control-strings/index.js +0 -125
  175. package/dist/node_modules/console-control-strings/package.json +0 -61
  176. package/dist/node_modules/core-util-is/LICENSE +0 -19
  177. package/dist/node_modules/core-util-is/README.md +0 -3
  178. package/dist/node_modules/core-util-is/lib/util.js +0 -107
  179. package/dist/node_modules/core-util-is/package.json +0 -68
  180. package/dist/node_modules/decompress-response/index.d.ts +0 -29
  181. package/dist/node_modules/decompress-response/index.js +0 -40
  182. package/dist/node_modules/decompress-response/license +0 -9
  183. package/dist/node_modules/decompress-response/package.json +0 -82
  184. package/dist/node_modules/decompress-response/readme.md +0 -52
  185. package/dist/node_modules/deep-extend/CHANGELOG.md +0 -46
  186. package/dist/node_modules/deep-extend/LICENSE +0 -20
  187. package/dist/node_modules/deep-extend/README.md +0 -91
  188. package/dist/node_modules/deep-extend/index.js +0 -1
  189. package/dist/node_modules/deep-extend/lib/deep-extend.js +0 -150
  190. package/dist/node_modules/deep-extend/package.json +0 -92
  191. package/dist/node_modules/delegates/History.md +0 -22
  192. package/dist/node_modules/delegates/License +0 -20
  193. package/dist/node_modules/delegates/Makefile +0 -8
  194. package/dist/node_modules/delegates/Readme.md +0 -94
  195. package/dist/node_modules/delegates/index.js +0 -121
  196. package/dist/node_modules/delegates/package.json +0 -48
  197. package/dist/node_modules/delegates/test/index.js +0 -94
  198. package/dist/node_modules/detect-libc/LICENSE +0 -201
  199. package/dist/node_modules/detect-libc/README.md +0 -78
  200. package/dist/node_modules/detect-libc/bin/detect-libc.js +0 -18
  201. package/dist/node_modules/detect-libc/lib/detect-libc.js +0 -92
  202. package/dist/node_modules/detect-libc/package.json +0 -71
  203. package/dist/node_modules/end-of-stream/LICENSE +0 -21
  204. package/dist/node_modules/end-of-stream/README.md +0 -54
  205. package/dist/node_modules/end-of-stream/index.js +0 -94
  206. package/dist/node_modules/end-of-stream/package.json +0 -66
  207. package/dist/node_modules/expand-template/.travis.yml +0 -6
  208. package/dist/node_modules/expand-template/LICENSE +0 -21
  209. package/dist/node_modules/expand-template/README.md +0 -43
  210. package/dist/node_modules/expand-template/index.js +0 -26
  211. package/dist/node_modules/expand-template/package.json +0 -60
  212. package/dist/node_modules/expand-template/test.js +0 -67
  213. package/dist/node_modules/fs-constants/LICENSE +0 -21
  214. package/dist/node_modules/fs-constants/README.md +0 -26
  215. package/dist/node_modules/fs-constants/browser.js +0 -1
  216. package/dist/node_modules/fs-constants/index.js +0 -1
  217. package/dist/node_modules/fs-constants/package.json +0 -47
  218. package/dist/node_modules/gauge/CHANGELOG.md +0 -160
  219. package/dist/node_modules/gauge/LICENSE +0 -13
  220. package/dist/node_modules/gauge/README.md +0 -399
  221. package/dist/node_modules/gauge/base-theme.js +0 -14
  222. package/dist/node_modules/gauge/error.js +0 -24
  223. package/dist/node_modules/gauge/has-color.js +0 -12
  224. package/dist/node_modules/gauge/index.js +0 -233
  225. package/dist/node_modules/gauge/package.json +0 -91
  226. package/dist/node_modules/gauge/plumbing.js +0 -48
  227. package/dist/node_modules/gauge/process.js +0 -3
  228. package/dist/node_modules/gauge/progress-bar.js +0 -35
  229. package/dist/node_modules/gauge/render-template.js +0 -181
  230. package/dist/node_modules/gauge/set-immediate.js +0 -7
  231. package/dist/node_modules/gauge/set-interval.js +0 -3
  232. package/dist/node_modules/gauge/spin.js +0 -5
  233. package/dist/node_modules/gauge/template-item.js +0 -73
  234. package/dist/node_modules/gauge/theme-set.js +0 -115
  235. package/dist/node_modules/gauge/themes.js +0 -54
  236. package/dist/node_modules/gauge/wide-truncate.js +0 -25
  237. package/dist/node_modules/github-from-package/.travis.yml +0 -4
  238. package/dist/node_modules/github-from-package/LICENSE +0 -18
  239. package/dist/node_modules/github-from-package/example/package.json +0 -8
  240. package/dist/node_modules/github-from-package/example/url.js +0 -3
  241. package/dist/node_modules/github-from-package/index.js +0 -17
  242. package/dist/node_modules/github-from-package/package.json +0 -58
  243. package/dist/node_modules/github-from-package/readme.markdown +0 -53
  244. package/dist/node_modules/github-from-package/test/a.json +0 -8
  245. package/dist/node_modules/github-from-package/test/b.json +0 -5
  246. package/dist/node_modules/github-from-package/test/c.json +0 -5
  247. package/dist/node_modules/github-from-package/test/d.json +0 -7
  248. package/dist/node_modules/github-from-package/test/e.json +0 -5
  249. package/dist/node_modules/github-from-package/test/url.js +0 -19
  250. package/dist/node_modules/has-unicode/LICENSE +0 -14
  251. package/dist/node_modules/has-unicode/README.md +0 -43
  252. package/dist/node_modules/has-unicode/index.js +0 -16
  253. package/dist/node_modules/has-unicode/package.json +0 -58
  254. package/dist/node_modules/ieee754/LICENSE +0 -11
  255. package/dist/node_modules/ieee754/README.md +0 -51
  256. package/dist/node_modules/ieee754/index.d.ts +0 -10
  257. package/dist/node_modules/ieee754/index.js +0 -85
  258. package/dist/node_modules/ieee754/package.json +0 -84
  259. package/dist/node_modules/inherits/LICENSE +0 -16
  260. package/dist/node_modules/inherits/README.md +0 -42
  261. package/dist/node_modules/inherits/inherits.js +0 -9
  262. package/dist/node_modules/inherits/inherits_browser.js +0 -27
  263. package/dist/node_modules/inherits/package.json +0 -65
  264. package/dist/node_modules/ini/LICENSE +0 -15
  265. package/dist/node_modules/ini/README.md +0 -102
  266. package/dist/node_modules/ini/ini.js +0 -206
  267. package/dist/node_modules/ini/package.json +0 -66
  268. package/dist/node_modules/is-arrayish/LICENSE +0 -21
  269. package/dist/node_modules/is-arrayish/README.md +0 -16
  270. package/dist/node_modules/is-arrayish/index.js +0 -9
  271. package/dist/node_modules/is-arrayish/package.json +0 -77
  272. package/dist/node_modules/is-arrayish/yarn-error.log +0 -1443
  273. package/dist/node_modules/is-fullwidth-code-point/index.js +0 -46
  274. package/dist/node_modules/is-fullwidth-code-point/license +0 -21
  275. package/dist/node_modules/is-fullwidth-code-point/package.json +0 -77
  276. package/dist/node_modules/is-fullwidth-code-point/readme.md +0 -39
  277. package/dist/node_modules/isarray/.travis.yml +0 -4
  278. package/dist/node_modules/isarray/Makefile +0 -6
  279. package/dist/node_modules/isarray/README.md +0 -60
  280. package/dist/node_modules/isarray/component.json +0 -19
  281. package/dist/node_modules/isarray/index.js +0 -5
  282. package/dist/node_modules/isarray/package.json +0 -73
  283. package/dist/node_modules/isarray/test.js +0 -20
  284. package/dist/node_modules/lru-cache/LICENSE +0 -15
  285. package/dist/node_modules/lru-cache/README.md +0 -166
  286. package/dist/node_modules/lru-cache/index.js +0 -334
  287. package/dist/node_modules/lru-cache/package.json +0 -69
  288. package/dist/node_modules/mimic-response/index.d.ts +0 -17
  289. package/dist/node_modules/mimic-response/index.js +0 -38
  290. package/dist/node_modules/mimic-response/license +0 -9
  291. package/dist/node_modules/mimic-response/package.json +0 -74
  292. package/dist/node_modules/mimic-response/readme.md +0 -57
  293. package/dist/node_modules/minimist/.travis.yml +0 -8
  294. package/dist/node_modules/minimist/LICENSE +0 -18
  295. package/dist/node_modules/minimist/example/parse.js +0 -2
  296. package/dist/node_modules/minimist/index.js +0 -245
  297. package/dist/node_modules/minimist/package.json +0 -74
  298. package/dist/node_modules/minimist/readme.markdown +0 -95
  299. package/dist/node_modules/minimist/test/all_bool.js +0 -32
  300. package/dist/node_modules/minimist/test/bool.js +0 -178
  301. package/dist/node_modules/minimist/test/dash.js +0 -31
  302. package/dist/node_modules/minimist/test/default_bool.js +0 -35
  303. package/dist/node_modules/minimist/test/dotted.js +0 -22
  304. package/dist/node_modules/minimist/test/kv_short.js +0 -16
  305. package/dist/node_modules/minimist/test/long.js +0 -31
  306. package/dist/node_modules/minimist/test/num.js +0 -36
  307. package/dist/node_modules/minimist/test/parse.js +0 -197
  308. package/dist/node_modules/minimist/test/parse_modified.js +0 -9
  309. package/dist/node_modules/minimist/test/proto.js +0 -44
  310. package/dist/node_modules/minimist/test/short.js +0 -67
  311. package/dist/node_modules/minimist/test/stop_early.js +0 -15
  312. package/dist/node_modules/minimist/test/unknown.js +0 -102
  313. package/dist/node_modules/minimist/test/whitespace.js +0 -8
  314. package/dist/node_modules/mkdirp-classic/LICENSE +0 -21
  315. package/dist/node_modules/mkdirp-classic/README.md +0 -18
  316. package/dist/node_modules/mkdirp-classic/index.js +0 -98
  317. package/dist/node_modules/mkdirp-classic/package.json +0 -47
  318. package/dist/node_modules/napi-build-utils/LICENSE +0 -21
  319. package/dist/node_modules/napi-build-utils/README.md +0 -48
  320. package/dist/node_modules/napi-build-utils/index.js +0 -213
  321. package/dist/node_modules/napi-build-utils/index.md +0 -81
  322. package/dist/node_modules/napi-build-utils/package.json +0 -68
  323. package/dist/node_modules/node-abi/.github/workflows/update-abi.yml +0 -41
  324. package/dist/node_modules/node-abi/.travis.yml +0 -17
  325. package/dist/node_modules/node-abi/CODE_OF_CONDUCT.md +0 -73
  326. package/dist/node_modules/node-abi/CONTRIBUTING.md +0 -53
  327. package/dist/node_modules/node-abi/LICENSE +0 -21
  328. package/dist/node_modules/node-abi/README.md +0 -50
  329. package/dist/node_modules/node-abi/abi_registry.json +0 -144
  330. package/dist/node_modules/node-abi/index.js +0 -176
  331. package/dist/node_modules/node-abi/node_modules/semver/CHANGELOG.md +0 -39
  332. package/dist/node_modules/node-abi/node_modules/semver/LICENSE +0 -15
  333. package/dist/node_modules/node-abi/node_modules/semver/README.md +0 -412
  334. package/dist/node_modules/node-abi/node_modules/semver/bin/semver +0 -160
  335. package/dist/node_modules/node-abi/node_modules/semver/package.json +0 -60
  336. package/dist/node_modules/node-abi/node_modules/semver/range.bnf +0 -16
  337. package/dist/node_modules/node-abi/node_modules/semver/semver.js +0 -1483
  338. package/dist/node_modules/node-abi/package.json +0 -65
  339. package/dist/node_modules/node-abi/scripts/update-abi-registry.js +0 -119
  340. package/dist/node_modules/node-abi/test/index.js +0 -174
  341. package/dist/node_modules/node-addon-api/CHANGELOG.md +0 -722
  342. package/dist/node_modules/node-addon-api/LICENSE.md +0 -13
  343. package/dist/node_modules/node-addon-api/README.md +0 -293
  344. package/dist/node_modules/node-addon-api/common.gypi +0 -21
  345. package/dist/node_modules/node-addon-api/except.gypi +0 -16
  346. package/dist/node_modules/node-addon-api/index.js +0 -11
  347. package/dist/node_modules/node-addon-api/napi-inl.deprecated.h +0 -192
  348. package/dist/node_modules/node-addon-api/napi-inl.h +0 -5671
  349. package/dist/node_modules/node-addon-api/napi.h +0 -2727
  350. package/dist/node_modules/node-addon-api/node_api.gyp +0 -9
  351. package/dist/node_modules/node-addon-api/noexcept.gypi +0 -16
  352. package/dist/node_modules/node-addon-api/nothing.c +0 -0
  353. package/dist/node_modules/node-addon-api/package-support.json +0 -21
  354. package/dist/node_modules/node-addon-api/package.json +0 -393
  355. package/dist/node_modules/node-addon-api/tools/README.md +0 -73
  356. package/dist/node_modules/node-addon-api/tools/check-napi.js +0 -100
  357. package/dist/node_modules/node-addon-api/tools/clang-format.js +0 -67
  358. package/dist/node_modules/node-addon-api/tools/conversion.js +0 -309
  359. package/dist/node_modules/npmlog/CHANGELOG.md +0 -49
  360. package/dist/node_modules/npmlog/LICENSE +0 -15
  361. package/dist/node_modules/npmlog/README.md +0 -216
  362. package/dist/node_modules/npmlog/log.js +0 -309
  363. package/dist/node_modules/npmlog/package.json +0 -61
  364. package/dist/node_modules/number-is-nan/index.js +0 -4
  365. package/dist/node_modules/number-is-nan/license +0 -21
  366. package/dist/node_modules/number-is-nan/package.json +0 -67
  367. package/dist/node_modules/number-is-nan/readme.md +0 -28
  368. package/dist/node_modules/object-assign/index.js +0 -90
  369. package/dist/node_modules/object-assign/license +0 -21
  370. package/dist/node_modules/object-assign/package.json +0 -74
  371. package/dist/node_modules/object-assign/readme.md +0 -61
  372. package/dist/node_modules/once/LICENSE +0 -15
  373. package/dist/node_modules/once/README.md +0 -79
  374. package/dist/node_modules/once/once.js +0 -42
  375. package/dist/node_modules/once/package.json +0 -68
  376. package/dist/node_modules/prebuild-install/CHANGELOG.md +0 -81
  377. package/dist/node_modules/prebuild-install/CONTRIBUTING.md +0 -6
  378. package/dist/node_modules/prebuild-install/LICENSE +0 -21
  379. package/dist/node_modules/prebuild-install/README.md +0 -139
  380. package/dist/node_modules/prebuild-install/asset.js +0 -44
  381. package/dist/node_modules/prebuild-install/bin.js +0 -78
  382. package/dist/node_modules/prebuild-install/download.js +0 -142
  383. package/dist/node_modules/prebuild-install/error.js +0 -14
  384. package/dist/node_modules/prebuild-install/help.txt +0 -16
  385. package/dist/node_modules/prebuild-install/index.js +0 -1
  386. package/dist/node_modules/prebuild-install/log.js +0 -25
  387. package/dist/node_modules/prebuild-install/package.json +0 -127
  388. package/dist/node_modules/prebuild-install/proxy.js +0 -35
  389. package/dist/node_modules/prebuild-install/rc.js +0 -60
  390. package/dist/node_modules/prebuild-install/util.js +0 -143
  391. package/dist/node_modules/process-nextick-args/index.js +0 -45
  392. package/dist/node_modules/process-nextick-args/license.md +0 -19
  393. package/dist/node_modules/process-nextick-args/package.json +0 -50
  394. package/dist/node_modules/process-nextick-args/readme.md +0 -18
  395. package/dist/node_modules/pump/.travis.yml +0 -5
  396. package/dist/node_modules/pump/LICENSE +0 -21
  397. package/dist/node_modules/pump/README.md +0 -65
  398. package/dist/node_modules/pump/index.js +0 -82
  399. package/dist/node_modules/pump/package.json +0 -60
  400. package/dist/node_modules/pump/test-browser.js +0 -66
  401. package/dist/node_modules/pump/test-node.js +0 -53
  402. package/dist/node_modules/rc/LICENSE.APACHE2 +0 -15
  403. package/dist/node_modules/rc/LICENSE.BSD +0 -26
  404. package/dist/node_modules/rc/LICENSE.MIT +0 -24
  405. package/dist/node_modules/rc/README.md +0 -227
  406. package/dist/node_modules/rc/browser.js +0 -7
  407. package/dist/node_modules/rc/cli.js +0 -4
  408. package/dist/node_modules/rc/index.js +0 -53
  409. package/dist/node_modules/rc/lib/utils.js +0 -104
  410. package/dist/node_modules/rc/package.json +0 -64
  411. package/dist/node_modules/rc/test/ini.js +0 -16
  412. package/dist/node_modules/rc/test/nested-env-vars.js +0 -50
  413. package/dist/node_modules/rc/test/test.js +0 -59
  414. package/dist/node_modules/readable-stream/.travis.yml +0 -34
  415. package/dist/node_modules/readable-stream/CONTRIBUTING.md +0 -38
  416. package/dist/node_modules/readable-stream/GOVERNANCE.md +0 -136
  417. package/dist/node_modules/readable-stream/LICENSE +0 -47
  418. package/dist/node_modules/readable-stream/README.md +0 -58
  419. package/dist/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +0 -60
  420. package/dist/node_modules/readable-stream/duplex-browser.js +0 -1
  421. package/dist/node_modules/readable-stream/duplex.js +0 -1
  422. package/dist/node_modules/readable-stream/lib/_stream_duplex.js +0 -131
  423. package/dist/node_modules/readable-stream/lib/_stream_passthrough.js +0 -47
  424. package/dist/node_modules/readable-stream/lib/_stream_readable.js +0 -1019
  425. package/dist/node_modules/readable-stream/lib/_stream_transform.js +0 -214
  426. package/dist/node_modules/readable-stream/lib/_stream_writable.js +0 -687
  427. package/dist/node_modules/readable-stream/lib/internal/streams/BufferList.js +0 -79
  428. package/dist/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -74
  429. package/dist/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
  430. package/dist/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
  431. package/dist/node_modules/readable-stream/package.json +0 -81
  432. package/dist/node_modules/readable-stream/passthrough.js +0 -1
  433. package/dist/node_modules/readable-stream/readable-browser.js +0 -7
  434. package/dist/node_modules/readable-stream/readable.js +0 -19
  435. package/dist/node_modules/readable-stream/transform.js +0 -1
  436. package/dist/node_modules/readable-stream/writable-browser.js +0 -1
  437. package/dist/node_modules/readable-stream/writable.js +0 -8
  438. package/dist/node_modules/safe-buffer/LICENSE +0 -21
  439. package/dist/node_modules/safe-buffer/README.md +0 -584
  440. package/dist/node_modules/safe-buffer/index.d.ts +0 -187
  441. package/dist/node_modules/safe-buffer/index.js +0 -62
  442. package/dist/node_modules/safe-buffer/package.json +0 -64
  443. package/dist/node_modules/semver/CHANGELOG.md +0 -111
  444. package/dist/node_modules/semver/LICENSE +0 -15
  445. package/dist/node_modules/semver/README.md +0 -566
  446. package/dist/node_modules/semver/bin/semver.js +0 -173
  447. package/dist/node_modules/semver/classes/comparator.js +0 -135
  448. package/dist/node_modules/semver/classes/index.js +0 -5
  449. package/dist/node_modules/semver/classes/range.js +0 -510
  450. package/dist/node_modules/semver/classes/semver.js +0 -287
  451. package/dist/node_modules/semver/functions/clean.js +0 -6
  452. package/dist/node_modules/semver/functions/cmp.js +0 -48
  453. package/dist/node_modules/semver/functions/coerce.js +0 -51
  454. package/dist/node_modules/semver/functions/compare-build.js +0 -7
  455. package/dist/node_modules/semver/functions/compare-loose.js +0 -3
  456. package/dist/node_modules/semver/functions/compare.js +0 -5
  457. package/dist/node_modules/semver/functions/diff.js +0 -23
  458. package/dist/node_modules/semver/functions/eq.js +0 -3
  459. package/dist/node_modules/semver/functions/gt.js +0 -3
  460. package/dist/node_modules/semver/functions/gte.js +0 -3
  461. package/dist/node_modules/semver/functions/inc.js +0 -15
  462. package/dist/node_modules/semver/functions/lt.js +0 -3
  463. package/dist/node_modules/semver/functions/lte.js +0 -3
  464. package/dist/node_modules/semver/functions/major.js +0 -3
  465. package/dist/node_modules/semver/functions/minor.js +0 -3
  466. package/dist/node_modules/semver/functions/neq.js +0 -3
  467. package/dist/node_modules/semver/functions/parse.js +0 -33
  468. package/dist/node_modules/semver/functions/patch.js +0 -3
  469. package/dist/node_modules/semver/functions/prerelease.js +0 -6
  470. package/dist/node_modules/semver/functions/rcompare.js +0 -3
  471. package/dist/node_modules/semver/functions/rsort.js +0 -3
  472. package/dist/node_modules/semver/functions/satisfies.js +0 -10
  473. package/dist/node_modules/semver/functions/sort.js +0 -3
  474. package/dist/node_modules/semver/functions/valid.js +0 -6
  475. package/dist/node_modules/semver/index.js +0 -48
  476. package/dist/node_modules/semver/internal/constants.js +0 -17
  477. package/dist/node_modules/semver/internal/debug.js +0 -9
  478. package/dist/node_modules/semver/internal/identifiers.js +0 -23
  479. package/dist/node_modules/semver/internal/parse-options.js +0 -11
  480. package/dist/node_modules/semver/internal/re.js +0 -182
  481. package/dist/node_modules/semver/package.json +0 -73
  482. package/dist/node_modules/semver/preload.js +0 -2
  483. package/dist/node_modules/semver/range.bnf +0 -16
  484. package/dist/node_modules/semver/ranges/gtr.js +0 -4
  485. package/dist/node_modules/semver/ranges/intersects.js +0 -7
  486. package/dist/node_modules/semver/ranges/ltr.js +0 -4
  487. package/dist/node_modules/semver/ranges/max-satisfying.js +0 -25
  488. package/dist/node_modules/semver/ranges/min-satisfying.js +0 -24
  489. package/dist/node_modules/semver/ranges/min-version.js +0 -60
  490. package/dist/node_modules/semver/ranges/outside.js +0 -80
  491. package/dist/node_modules/semver/ranges/simplify.js +0 -44
  492. package/dist/node_modules/semver/ranges/subset.js +0 -222
  493. package/dist/node_modules/semver/ranges/to-comparators.js +0 -8
  494. package/dist/node_modules/semver/ranges/valid.js +0 -11
  495. package/dist/node_modules/set-blocking/CHANGELOG.md +0 -26
  496. package/dist/node_modules/set-blocking/LICENSE.txt +0 -14
  497. package/dist/node_modules/set-blocking/README.md +0 -31
  498. package/dist/node_modules/set-blocking/index.js +0 -7
  499. package/dist/node_modules/set-blocking/package.json +0 -70
  500. package/dist/node_modules/sharp/LICENSE +0 -191
  501. package/dist/node_modules/sharp/README.md +0 -117
  502. package/dist/node_modules/sharp/binding.gyp +0 -230
  503. package/dist/node_modules/sharp/build/Release/sharp.node +0 -0
  504. package/dist/node_modules/sharp/install/can-compile.js +0 -11
  505. package/dist/node_modules/sharp/install/dll-copy.js +0 -37
  506. package/dist/node_modules/sharp/install/libvips.js +0 -180
  507. package/dist/node_modules/sharp/lib/agent.js +0 -40
  508. package/dist/node_modules/sharp/lib/channel.js +0 -167
  509. package/dist/node_modules/sharp/lib/colour.js +0 -130
  510. package/dist/node_modules/sharp/lib/composite.js +0 -178
  511. package/dist/node_modules/sharp/lib/constructor.js +0 -392
  512. package/dist/node_modules/sharp/lib/index.js +0 -13
  513. package/dist/node_modules/sharp/lib/input.js +0 -429
  514. package/dist/node_modules/sharp/lib/is.js +0 -129
  515. package/dist/node_modules/sharp/lib/libvips.js +0 -123
  516. package/dist/node_modules/sharp/lib/operation.js +0 -648
  517. package/dist/node_modules/sharp/lib/output.js +0 -1035
  518. package/dist/node_modules/sharp/lib/platform.js +0 -25
  519. package/dist/node_modules/sharp/lib/resize.js +0 -454
  520. package/dist/node_modules/sharp/lib/utility.js +0 -179
  521. package/dist/node_modules/sharp/package.json +0 -427
  522. package/dist/node_modules/sharp/src/common.cc +0 -827
  523. package/dist/node_modules/sharp/src/common.h +0 -308
  524. package/dist/node_modules/sharp/src/libvips/cplusplus/VConnection.cpp +0 -178
  525. package/dist/node_modules/sharp/src/libvips/cplusplus/VError.cpp +0 -50
  526. package/dist/node_modules/sharp/src/libvips/cplusplus/VImage.cpp +0 -1467
  527. package/dist/node_modules/sharp/src/libvips/cplusplus/VInterpolate.cpp +0 -76
  528. package/dist/node_modules/sharp/src/libvips/cplusplus/vips-operators.cpp +0 -3526
  529. package/dist/node_modules/sharp/src/metadata.cc +0 -271
  530. package/dist/node_modules/sharp/src/metadata.h +0 -90
  531. package/dist/node_modules/sharp/src/operations.cc +0 -285
  532. package/dist/node_modules/sharp/src/operations.h +0 -102
  533. package/dist/node_modules/sharp/src/pipeline.cc +0 -1516
  534. package/dist/node_modules/sharp/src/pipeline.h +0 -325
  535. package/dist/node_modules/sharp/src/sharp.cc +0 -52
  536. package/dist/node_modules/sharp/src/stats.cc +0 -193
  537. package/dist/node_modules/sharp/src/stats.h +0 -70
  538. package/dist/node_modules/sharp/src/utilities.cc +0 -243
  539. package/dist/node_modules/sharp/src/utilities.h +0 -29
  540. package/dist/node_modules/sharp/vendor/8.10.6/THIRD-PARTY-NOTICES.md +0 -42
  541. package/dist/node_modules/sharp/vendor/8.10.6/lib/libvips-cpp.so.42 +0 -0
  542. package/dist/node_modules/sharp/vendor/8.10.6/platform.json +0 -1
  543. package/dist/node_modules/sharp/vendor/8.10.6/versions.json +0 -31
  544. package/dist/node_modules/signal-exit/LICENSE.txt +0 -16
  545. package/dist/node_modules/signal-exit/README.md +0 -39
  546. package/dist/node_modules/signal-exit/index.js +0 -200
  547. package/dist/node_modules/signal-exit/package.json +0 -66
  548. package/dist/node_modules/signal-exit/signals.js +0 -53
  549. package/dist/node_modules/simple-concat/.travis.yml +0 -3
  550. package/dist/node_modules/simple-concat/LICENSE +0 -20
  551. package/dist/node_modules/simple-concat/README.md +0 -44
  552. package/dist/node_modules/simple-concat/index.js +0 -15
  553. package/dist/node_modules/simple-concat/package.json +0 -72
  554. package/dist/node_modules/simple-concat/test/basic.js +0 -41
  555. package/dist/node_modules/simple-get/LICENSE +0 -20
  556. package/dist/node_modules/simple-get/README.md +0 -319
  557. package/dist/node_modules/simple-get/index.js +0 -99
  558. package/dist/node_modules/simple-get/package.json +0 -79
  559. package/dist/node_modules/simple-swizzle/LICENSE +0 -21
  560. package/dist/node_modules/simple-swizzle/README.md +0 -39
  561. package/dist/node_modules/simple-swizzle/index.js +0 -29
  562. package/dist/node_modules/simple-swizzle/package.json +0 -71
  563. package/dist/node_modules/string-width/index.js +0 -37
  564. package/dist/node_modules/string-width/license +0 -21
  565. package/dist/node_modules/string-width/package.json +0 -89
  566. package/dist/node_modules/string-width/readme.md +0 -42
  567. package/dist/node_modules/string_decoder/.travis.yml +0 -50
  568. package/dist/node_modules/string_decoder/LICENSE +0 -48
  569. package/dist/node_modules/string_decoder/README.md +0 -47
  570. package/dist/node_modules/string_decoder/lib/string_decoder.js +0 -296
  571. package/dist/node_modules/string_decoder/package.json +0 -61
  572. package/dist/node_modules/strip-ansi/index.js +0 -6
  573. package/dist/node_modules/strip-ansi/license +0 -21
  574. package/dist/node_modules/strip-ansi/package.json +0 -102
  575. package/dist/node_modules/strip-ansi/readme.md +0 -33
  576. package/dist/node_modules/strip-json-comments/index.js +0 -70
  577. package/dist/node_modules/strip-json-comments/license +0 -21
  578. package/dist/node_modules/strip-json-comments/package.json +0 -74
  579. package/dist/node_modules/strip-json-comments/readme.md +0 -64
  580. package/dist/node_modules/tar-fs/.travis.yml +0 -6
  581. package/dist/node_modules/tar-fs/LICENSE +0 -21
  582. package/dist/node_modules/tar-fs/README.md +0 -165
  583. package/dist/node_modules/tar-fs/index.js +0 -351
  584. package/dist/node_modules/tar-fs/package.json +0 -69
  585. package/dist/node_modules/tar-fs/test/fixtures/a/hello.txt +0 -1
  586. package/dist/node_modules/tar-fs/test/fixtures/b/a/test.txt +0 -1
  587. package/dist/node_modules/tar-fs/test/fixtures/d/file1 +0 -0
  588. package/dist/node_modules/tar-fs/test/fixtures/d/file2 +0 -0
  589. package/dist/node_modules/tar-fs/test/fixtures/d/sub-dir/file5 +0 -0
  590. package/dist/node_modules/tar-fs/test/fixtures/d/sub-files/file3 +0 -0
  591. package/dist/node_modules/tar-fs/test/fixtures/d/sub-files/file4 +0 -0
  592. package/dist/node_modules/tar-fs/test/fixtures/e/directory/.ignore +0 -0
  593. package/dist/node_modules/tar-fs/test/fixtures/e/file +0 -0
  594. package/dist/node_modules/tar-fs/test/fixtures/invalid.tar +0 -0
  595. package/dist/node_modules/tar-fs/test/index.js +0 -346
  596. package/dist/node_modules/tar-stream/LICENSE +0 -21
  597. package/dist/node_modules/tar-stream/README.md +0 -168
  598. package/dist/node_modules/tar-stream/extract.js +0 -257
  599. package/dist/node_modules/tar-stream/headers.js +0 -295
  600. package/dist/node_modules/tar-stream/index.js +0 -2
  601. package/dist/node_modules/tar-stream/node_modules/readable-stream/CONTRIBUTING.md +0 -38
  602. package/dist/node_modules/tar-stream/node_modules/readable-stream/GOVERNANCE.md +0 -136
  603. package/dist/node_modules/tar-stream/node_modules/readable-stream/LICENSE +0 -47
  604. package/dist/node_modules/tar-stream/node_modules/readable-stream/README.md +0 -106
  605. package/dist/node_modules/tar-stream/node_modules/readable-stream/errors-browser.js +0 -127
  606. package/dist/node_modules/tar-stream/node_modules/readable-stream/errors.js +0 -116
  607. package/dist/node_modules/tar-stream/node_modules/readable-stream/experimentalWarning.js +0 -17
  608. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/_stream_duplex.js +0 -139
  609. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/_stream_passthrough.js +0 -39
  610. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/_stream_readable.js +0 -1124
  611. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/_stream_transform.js +0 -201
  612. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/_stream_writable.js +0 -697
  613. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/async_iterator.js +0 -207
  614. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/buffer_list.js +0 -210
  615. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -105
  616. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +0 -104
  617. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/from-browser.js +0 -3
  618. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/from.js +0 -64
  619. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/pipeline.js +0 -97
  620. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/state.js +0 -27
  621. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
  622. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
  623. package/dist/node_modules/tar-stream/node_modules/readable-stream/package.json +0 -97
  624. package/dist/node_modules/tar-stream/node_modules/readable-stream/readable-browser.js +0 -9
  625. package/dist/node_modules/tar-stream/node_modules/readable-stream/readable.js +0 -16
  626. package/dist/node_modules/tar-stream/pack.js +0 -255
  627. package/dist/node_modules/tar-stream/package.json +0 -90
  628. package/dist/node_modules/tar-stream/sandbox.js +0 -11
  629. package/dist/node_modules/tunnel-agent/LICENSE +0 -55
  630. package/dist/node_modules/tunnel-agent/README.md +0 -4
  631. package/dist/node_modules/tunnel-agent/index.js +0 -244
  632. package/dist/node_modules/tunnel-agent/package.json +0 -56
  633. package/dist/node_modules/util-deprecate/History.md +0 -16
  634. package/dist/node_modules/util-deprecate/LICENSE +0 -24
  635. package/dist/node_modules/util-deprecate/README.md +0 -53
  636. package/dist/node_modules/util-deprecate/browser.js +0 -67
  637. package/dist/node_modules/util-deprecate/node.js +0 -6
  638. package/dist/node_modules/util-deprecate/package.json +0 -58
  639. package/dist/node_modules/wide-align/LICENSE +0 -14
  640. package/dist/node_modules/wide-align/README.md +0 -47
  641. package/dist/node_modules/wide-align/align.js +0 -65
  642. package/dist/node_modules/wide-align/package.json +0 -66
  643. package/dist/node_modules/wrappy/LICENSE +0 -15
  644. package/dist/node_modules/wrappy/README.md +0 -36
  645. package/dist/node_modules/wrappy/package.json +0 -58
  646. package/dist/node_modules/wrappy/wrappy.js +0 -33
  647. package/dist/node_modules/yallist/LICENSE +0 -15
  648. package/dist/node_modules/yallist/README.md +0 -204
  649. package/dist/node_modules/yallist/iterator.js +0 -8
  650. package/dist/node_modules/yallist/package.json +0 -62
  651. package/dist/node_modules/yallist/yallist.js +0 -426
  652. package/dist/package-lock.json +0 -507
  653. package/dist/package.json +0 -63
  654. package/dist/static/expected_tile_2193_153_255_z7.png +0 -0
  655. package/dist/static/expected_tile_NZTM2000Quad_30_33_z6.png +0 -0
  656. package/dist/static/expected_tile_WebMercatorQuad_252_156_z8.png +0 -0
@@ -1,1516 +0,0 @@
1
- // Copyright 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Lovell Fuller and contributors.
2
- //
3
- // Licensed under the Apache License, Version 2.0 (the "License");
4
- // you may not use this file except in compliance with the License.
5
- // You may obtain a copy of the License at
6
- //
7
- // http://www.apache.org/licenses/LICENSE-2.0
8
- //
9
- // Unless required by applicable law or agreed to in writing, software
10
- // distributed under the License is distributed on an "AS IS" BASIS,
11
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- // See the License for the specific language governing permissions and
13
- // limitations under the License.
14
-
15
- #include <algorithm>
16
- #include <cmath>
17
- #include <map>
18
- #include <memory>
19
- #include <numeric>
20
- #include <string>
21
- #include <tuple>
22
- #include <utility>
23
- #include <vector>
24
- #include <sys/types.h>
25
- #include <sys/stat.h>
26
-
27
- #include <vips/vips8>
28
- #include <napi.h>
29
-
30
- #include "common.h"
31
- #include "operations.h"
32
- #include "pipeline.h"
33
-
34
- #if defined(WIN32)
35
- #define STAT64_STRUCT __stat64
36
- #define STAT64_FUNCTION _stat64
37
- #elif defined(__APPLE__)
38
- #define STAT64_STRUCT stat
39
- #define STAT64_FUNCTION stat
40
- #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
41
- #define STAT64_STRUCT stat
42
- #define STAT64_FUNCTION stat
43
- #else
44
- #define STAT64_STRUCT stat64
45
- #define STAT64_FUNCTION stat64
46
- #endif
47
-
48
- class PipelineWorker : public Napi::AsyncWorker {
49
- public:
50
- PipelineWorker(Napi::Function callback, PipelineBaton *baton,
51
- Napi::Function debuglog, Napi::Function queueListener) :
52
- Napi::AsyncWorker(callback),
53
- baton(baton),
54
- debuglog(Napi::Persistent(debuglog)),
55
- queueListener(Napi::Persistent(queueListener)) {}
56
- ~PipelineWorker() {}
57
-
58
- // libuv worker
59
- void Execute() {
60
- // Decrement queued task counter
61
- g_atomic_int_dec_and_test(&sharp::counterQueue);
62
- // Increment processing task counter
63
- g_atomic_int_inc(&sharp::counterProcess);
64
-
65
- try {
66
- // Open input
67
- vips::VImage image;
68
- sharp::ImageType inputImageType;
69
- std::tie(image, inputImageType) = sharp::OpenInput(baton->input);
70
-
71
- // Calculate angle of rotation
72
- VipsAngle rotation;
73
- if (baton->useExifOrientation) {
74
- // Rotate and flip image according to Exif orientation
75
- bool flip;
76
- bool flop;
77
- std::tie(rotation, flip, flop) = CalculateExifRotationAndFlip(sharp::ExifOrientation(image));
78
- baton->flip = baton->flip || flip;
79
- baton->flop = baton->flop || flop;
80
- } else {
81
- rotation = CalculateAngleRotation(baton->angle);
82
- }
83
-
84
- // Rotate pre-extract
85
- if (baton->rotateBeforePreExtract) {
86
- if (rotation != VIPS_ANGLE_D0) {
87
- image = image.rot(rotation);
88
- image = sharp::RemoveExifOrientation(image);
89
- }
90
- if (baton->rotationAngle != 0.0) {
91
- std::vector<double> background;
92
- std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground);
93
- image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background));
94
- }
95
- }
96
-
97
- // Trim
98
- if (baton->trimThreshold > 0.0) {
99
- image = sharp::Trim(image, baton->trimThreshold);
100
- baton->trimOffsetLeft = image.xoffset();
101
- baton->trimOffsetTop = image.yoffset();
102
- }
103
-
104
- // Pre extraction
105
- if (baton->topOffsetPre != -1) {
106
- image = image.extract_area(baton->leftOffsetPre, baton->topOffsetPre, baton->widthPre, baton->heightPre);
107
- }
108
-
109
- // Get pre-resize image width and height
110
- int inputWidth = image.width();
111
- int inputHeight = image.height();
112
- if (!baton->rotateBeforePreExtract &&
113
- (rotation == VIPS_ANGLE_D90 || rotation == VIPS_ANGLE_D270)) {
114
- // Swap input output width and height when rotating by 90 or 270 degrees
115
- std::swap(inputWidth, inputHeight);
116
- }
117
-
118
- // If withoutEnlargement is specified,
119
- // Override target width and height if exceeds respective value from input file
120
- if (baton->withoutEnlargement) {
121
- if (baton->width > inputWidth) {
122
- baton->width = inputWidth;
123
- }
124
- if (baton->height > inputHeight) {
125
- baton->height = inputHeight;
126
- }
127
- }
128
-
129
- // Scaling calculations
130
- double xfactor = 1.0;
131
- double yfactor = 1.0;
132
- int targetResizeWidth = baton->width;
133
- int targetResizeHeight = baton->height;
134
- if (baton->width > 0 && baton->height > 0) {
135
- // Fixed width and height
136
- xfactor = static_cast<double>(inputWidth) / static_cast<double>(baton->width);
137
- yfactor = static_cast<double>(inputHeight) / static_cast<double>(baton->height);
138
- switch (baton->canvas) {
139
- case Canvas::CROP:
140
- if (xfactor < yfactor) {
141
- targetResizeHeight = static_cast<int>(round(static_cast<double>(inputHeight) / xfactor));
142
- yfactor = xfactor;
143
- } else {
144
- targetResizeWidth = static_cast<int>(round(static_cast<double>(inputWidth) / yfactor));
145
- xfactor = yfactor;
146
- }
147
- break;
148
- case Canvas::EMBED:
149
- if (xfactor > yfactor) {
150
- targetResizeHeight = static_cast<int>(round(static_cast<double>(inputHeight) / xfactor));
151
- yfactor = xfactor;
152
- } else {
153
- targetResizeWidth = static_cast<int>(round(static_cast<double>(inputWidth) / yfactor));
154
- xfactor = yfactor;
155
- }
156
- break;
157
- case Canvas::MAX:
158
- if (xfactor > yfactor) {
159
- targetResizeHeight = baton->height = static_cast<int>(round(static_cast<double>(inputHeight) / xfactor));
160
- yfactor = xfactor;
161
- } else {
162
- targetResizeWidth = baton->width = static_cast<int>(round(static_cast<double>(inputWidth) / yfactor));
163
- xfactor = yfactor;
164
- }
165
- break;
166
- case Canvas::MIN:
167
- if (xfactor < yfactor) {
168
- targetResizeHeight = baton->height = static_cast<int>(round(static_cast<double>(inputHeight) / xfactor));
169
- yfactor = xfactor;
170
- } else {
171
- targetResizeWidth = baton->width = static_cast<int>(round(static_cast<double>(inputWidth) / yfactor));
172
- xfactor = yfactor;
173
- }
174
- break;
175
- case Canvas::IGNORE_ASPECT:
176
- if (!baton->rotateBeforePreExtract &&
177
- (rotation == VIPS_ANGLE_D90 || rotation == VIPS_ANGLE_D270)) {
178
- std::swap(xfactor, yfactor);
179
- }
180
- break;
181
- }
182
- } else if (baton->width > 0) {
183
- // Fixed width
184
- xfactor = static_cast<double>(inputWidth) / static_cast<double>(baton->width);
185
- if (baton->canvas == Canvas::IGNORE_ASPECT) {
186
- targetResizeHeight = baton->height = inputHeight;
187
- } else {
188
- // Auto height
189
- yfactor = xfactor;
190
- targetResizeHeight = baton->height = static_cast<int>(round(static_cast<double>(inputHeight) / yfactor));
191
- }
192
- } else if (baton->height > 0) {
193
- // Fixed height
194
- yfactor = static_cast<double>(inputHeight) / static_cast<double>(baton->height);
195
- if (baton->canvas == Canvas::IGNORE_ASPECT) {
196
- targetResizeWidth = baton->width = inputWidth;
197
- } else {
198
- // Auto width
199
- xfactor = yfactor;
200
- targetResizeWidth = baton->width = static_cast<int>(round(static_cast<double>(inputWidth) / xfactor));
201
- }
202
- } else {
203
- // Identity transform
204
- baton->width = inputWidth;
205
- baton->height = inputHeight;
206
- }
207
-
208
- // Calculate integral box shrink
209
- int xshrink = std::max(1, static_cast<int>(floor(xfactor)));
210
- int yshrink = std::max(1, static_cast<int>(floor(yfactor)));
211
-
212
- // Calculate residual float affine transformation
213
- double xresidual = static_cast<double>(xshrink) / xfactor;
214
- double yresidual = static_cast<double>(yshrink) / yfactor;
215
-
216
- // If integral x and y shrink are equal, try to use shrink-on-load for JPEG and WebP,
217
- // but not when applying gamma correction, pre-resize extract or trim
218
- int shrink_on_load = 1;
219
-
220
- int shrink_on_load_factor = 1;
221
- // Leave at least a factor of two for the final resize step, when fastShrinkOnLoad: false
222
- // for more consistent results and avoid occasional small image shifting
223
- if (!baton->fastShrinkOnLoad) {
224
- shrink_on_load_factor = 2;
225
- }
226
- if (
227
- xshrink == yshrink && xshrink >= 2 * shrink_on_load_factor &&
228
- (inputImageType == sharp::ImageType::JPEG || inputImageType == sharp::ImageType::WEBP) &&
229
- baton->gamma == 0 && baton->topOffsetPre == -1 && baton->trimThreshold == 0.0 &&
230
- image.width() > 3 && image.height() > 3 && baton->input->pages == 1
231
- ) {
232
- if (xshrink >= 8 * shrink_on_load_factor) {
233
- xfactor = xfactor / 8;
234
- yfactor = yfactor / 8;
235
- shrink_on_load = 8;
236
- } else if (xshrink >= 4 * shrink_on_load_factor) {
237
- xfactor = xfactor / 4;
238
- yfactor = yfactor / 4;
239
- shrink_on_load = 4;
240
- } else if (xshrink >= 2 * shrink_on_load_factor) {
241
- xfactor = xfactor / 2;
242
- yfactor = yfactor / 2;
243
- shrink_on_load = 2;
244
- }
245
- }
246
- // Help ensure a final kernel-based reduction to prevent shrink aliasing
247
- if (shrink_on_load > 1 && (xresidual == 1.0 || yresidual == 1.0)) {
248
- shrink_on_load = shrink_on_load / 2;
249
- xfactor = xfactor * 2;
250
- yfactor = yfactor * 2;
251
- }
252
- if (shrink_on_load > 1) {
253
- // Reload input using shrink-on-load
254
- vips::VOption *option = VImage::option()
255
- ->set("access", baton->input->access)
256
- ->set("shrink", shrink_on_load)
257
- ->set("fail", baton->input->failOnError);
258
- if (baton->input->buffer != nullptr) {
259
- VipsBlob *blob = vips_blob_new(nullptr, baton->input->buffer, baton->input->bufferLength);
260
- if (inputImageType == sharp::ImageType::JPEG) {
261
- // Reload JPEG buffer
262
- image = VImage::jpegload_buffer(blob, option);
263
- } else {
264
- // Reload WebP buffer
265
- image = VImage::webpload_buffer(blob, option);
266
- }
267
- vips_area_unref(reinterpret_cast<VipsArea*>(blob));
268
- } else {
269
- if (inputImageType == sharp::ImageType::JPEG) {
270
- // Reload JPEG file
271
- image = VImage::jpegload(const_cast<char*>(baton->input->file.data()), option);
272
- } else {
273
- // Reload WebP file
274
- image = VImage::webpload(const_cast<char*>(baton->input->file.data()), option);
275
- }
276
- }
277
- // Recalculate integral shrink and double residual
278
- int const shrunkOnLoadWidth = image.width();
279
- int const shrunkOnLoadHeight = image.height();
280
- if (!baton->rotateBeforePreExtract &&
281
- (rotation == VIPS_ANGLE_D90 || rotation == VIPS_ANGLE_D270)) {
282
- // Swap when rotating by 90 or 270 degrees
283
- xfactor = static_cast<double>(shrunkOnLoadWidth) / static_cast<double>(targetResizeHeight);
284
- yfactor = static_cast<double>(shrunkOnLoadHeight) / static_cast<double>(targetResizeWidth);
285
- } else {
286
- xfactor = static_cast<double>(shrunkOnLoadWidth) / static_cast<double>(targetResizeWidth);
287
- yfactor = static_cast<double>(shrunkOnLoadHeight) / static_cast<double>(targetResizeHeight);
288
- }
289
- }
290
-
291
- // Ensure we're using a device-independent colour space
292
- if (
293
- sharp::HasProfile(image) &&
294
- image.interpretation() != VIPS_INTERPRETATION_LABS &&
295
- image.interpretation() != VIPS_INTERPRETATION_GREY16
296
- ) {
297
- // Convert to sRGB using embedded profile
298
- try {
299
- image = image.icc_transform("srgb", VImage::option()
300
- ->set("embedded", TRUE)
301
- ->set("depth", image.interpretation() == VIPS_INTERPRETATION_RGB16 ? 16 : 8)
302
- ->set("intent", VIPS_INTENT_PERCEPTUAL));
303
- } catch(...) {
304
- // Ignore failure of embedded profile
305
- }
306
- } else if (image.interpretation() == VIPS_INTERPRETATION_CMYK) {
307
- image = image.icc_transform("srgb", VImage::option()
308
- ->set("input_profile", "cmyk")
309
- ->set("intent", VIPS_INTENT_PERCEPTUAL));
310
- }
311
-
312
- // Flatten image to remove alpha channel
313
- if (baton->flatten && sharp::HasAlpha(image)) {
314
- // Scale up 8-bit values to match 16-bit input image
315
- double const multiplier = sharp::Is16Bit(image.interpretation()) ? 256.0 : 1.0;
316
- // Background colour
317
- std::vector<double> background {
318
- baton->flattenBackground[0] * multiplier,
319
- baton->flattenBackground[1] * multiplier,
320
- baton->flattenBackground[2] * multiplier
321
- };
322
- image = image.flatten(VImage::option()
323
- ->set("background", background));
324
- }
325
-
326
- // Negate the colours in the image
327
- if (baton->negate) {
328
- image = image.invert();
329
- }
330
-
331
- // Gamma encoding (darken)
332
- if (baton->gamma >= 1 && baton->gamma <= 3) {
333
- image = sharp::Gamma(image, 1.0 / baton->gamma);
334
- }
335
-
336
- // Convert to greyscale (linear, therefore after gamma encoding, if any)
337
- if (baton->greyscale) {
338
- image = image.colourspace(VIPS_INTERPRETATION_B_W);
339
- }
340
-
341
- bool const shouldResize = xfactor != 1.0 || yfactor != 1.0;
342
- bool const shouldBlur = baton->blurSigma != 0.0;
343
- bool const shouldConv = baton->convKernelWidth * baton->convKernelHeight > 0;
344
- bool const shouldSharpen = baton->sharpenSigma != 0.0;
345
- bool const shouldApplyMedian = baton->medianSize > 0;
346
- bool const shouldComposite = !baton->composite.empty();
347
- bool const shouldModulate = baton->brightness != 1.0 || baton->saturation != 1.0 || baton->hue != 0.0;
348
- bool const shouldApplyClahe = baton->claheWidth != 0 && baton->claheHeight != 0;
349
-
350
- if (shouldComposite && !sharp::HasAlpha(image)) {
351
- image = sharp::EnsureAlpha(image, 1);
352
- }
353
-
354
- bool const shouldPremultiplyAlpha = sharp::HasAlpha(image) &&
355
- (shouldResize || shouldBlur || shouldConv || shouldSharpen || shouldComposite);
356
-
357
- // Premultiply image alpha channel before all transformations to avoid
358
- // dark fringing around bright pixels
359
- // See: http://entropymine.com/imageworsener/resizealpha/
360
- if (shouldPremultiplyAlpha) {
361
- image = image.premultiply();
362
- }
363
-
364
- // Resize
365
- if (shouldResize) {
366
- VipsKernel kernel = static_cast<VipsKernel>(
367
- vips_enum_from_nick(nullptr, VIPS_TYPE_KERNEL, baton->kernel.data()));
368
- if (
369
- kernel != VIPS_KERNEL_NEAREST && kernel != VIPS_KERNEL_CUBIC && kernel != VIPS_KERNEL_LANCZOS2 &&
370
- kernel != VIPS_KERNEL_LANCZOS3 && kernel != VIPS_KERNEL_MITCHELL
371
- ) {
372
- throw vips::VError("Unknown kernel");
373
- }
374
- // Ensure shortest edge is at least 1 pixel
375
- if (image.width() / xfactor < 0.5) {
376
- xfactor = 2 * image.width();
377
- baton->width = 1;
378
- }
379
- if (image.height() / yfactor < 0.5) {
380
- yfactor = 2 * image.height();
381
- baton->height = 1;
382
- }
383
- image = image.resize(1.0 / xfactor, VImage::option()
384
- ->set("vscale", 1.0 / yfactor)
385
- ->set("kernel", kernel));
386
- }
387
-
388
- // Rotate post-extract 90-angle
389
- if (!baton->rotateBeforePreExtract && rotation != VIPS_ANGLE_D0) {
390
- image = image.rot(rotation);
391
- image = sharp::RemoveExifOrientation(image);
392
- }
393
-
394
-
395
- // Flip (mirror about Y axis)
396
- if (baton->flip) {
397
- image = image.flip(VIPS_DIRECTION_VERTICAL);
398
- image = sharp::RemoveExifOrientation(image);
399
- }
400
-
401
- // Flop (mirror about X axis)
402
- if (baton->flop) {
403
- image = image.flip(VIPS_DIRECTION_HORIZONTAL);
404
- image = sharp::RemoveExifOrientation(image);
405
- }
406
-
407
- // Join additional color channels to the image
408
- if (baton->joinChannelIn.size() > 0) {
409
- VImage joinImage;
410
- sharp::ImageType joinImageType = sharp::ImageType::UNKNOWN;
411
-
412
- for (unsigned int i = 0; i < baton->joinChannelIn.size(); i++) {
413
- std::tie(joinImage, joinImageType) = sharp::OpenInput(baton->joinChannelIn[i]);
414
- image = image.bandjoin(joinImage);
415
- }
416
- image = image.copy(VImage::option()->set("interpretation", baton->colourspace));
417
- }
418
-
419
- // Crop/embed
420
- if (image.width() != baton->width || image.height() != baton->height) {
421
- if (baton->canvas == Canvas::EMBED) {
422
- std::vector<double> background;
423
- std::tie(image, background) = sharp::ApplyAlpha(image, baton->resizeBackground);
424
-
425
- // Embed
426
-
427
- // Calculate where to position the embeded image if gravity specified, else center.
428
- int left;
429
- int top;
430
-
431
- left = static_cast<int>(round((baton->width - image.width()) / 2));
432
- top = static_cast<int>(round((baton->height - image.height()) / 2));
433
-
434
- int width = std::max(image.width(), baton->width);
435
- int height = std::max(image.height(), baton->height);
436
- std::tie(left, top) = sharp::CalculateEmbedPosition(
437
- image.width(), image.height(), baton->width, baton->height, baton->position);
438
-
439
- image = image.embed(left, top, width, height, VImage::option()
440
- ->set("extend", VIPS_EXTEND_BACKGROUND)
441
- ->set("background", background));
442
-
443
- } else if (
444
- baton->canvas != Canvas::IGNORE_ASPECT &&
445
- (image.width() > baton->width || image.height() > baton->height)
446
- ) {
447
- // Crop/max/min
448
- if (baton->position < 9) {
449
- // Gravity-based crop
450
- int left;
451
- int top;
452
- std::tie(left, top) = sharp::CalculateCrop(
453
- image.width(), image.height(), baton->width, baton->height, baton->position);
454
- int width = std::min(image.width(), baton->width);
455
- int height = std::min(image.height(), baton->height);
456
- image = image.extract_area(left, top, width, height);
457
- } else {
458
- // Attention-based or Entropy-based crop
459
- if (baton->width > image.width()) {
460
- baton->width = image.width();
461
- }
462
- if (baton->height > image.height()) {
463
- baton->height = image.height();
464
- }
465
- image = image.tilecache(VImage::option()
466
- ->set("access", VIPS_ACCESS_RANDOM)
467
- ->set("threaded", TRUE));
468
- image = image.smartcrop(baton->width, baton->height, VImage::option()
469
- ->set("interesting", baton->position == 16 ? VIPS_INTERESTING_ENTROPY : VIPS_INTERESTING_ATTENTION));
470
- baton->hasCropOffset = true;
471
- baton->cropOffsetLeft = static_cast<int>(image.xoffset());
472
- baton->cropOffsetTop = static_cast<int>(image.yoffset());
473
- }
474
- }
475
- }
476
-
477
- // Rotate post-extract non-90 angle
478
- if (!baton->rotateBeforePreExtract && baton->rotationAngle != 0.0) {
479
- std::vector<double> background;
480
- std::tie(image, background) = sharp::ApplyAlpha(image, baton->rotationBackground);
481
- image = image.rotate(baton->rotationAngle, VImage::option()->set("background", background));
482
- }
483
-
484
- // Post extraction
485
- if (baton->topOffsetPost != -1) {
486
- image = image.extract_area(
487
- baton->leftOffsetPost, baton->topOffsetPost, baton->widthPost, baton->heightPost);
488
- }
489
-
490
- // Affine transform
491
- if (baton->affineMatrix.size() > 0) {
492
- std::vector<double> background;
493
- std::tie(image, background) = sharp::ApplyAlpha(image, baton->affineBackground);
494
- image = image.affine(baton->affineMatrix, VImage::option()->set("background", background)
495
- ->set("idx", baton->affineIdx)
496
- ->set("idy", baton->affineIdy)
497
- ->set("odx", baton->affineOdx)
498
- ->set("ody", baton->affineOdy)
499
- ->set("interpolate", baton->affineInterpolator));
500
- }
501
-
502
- // Extend edges
503
- if (baton->extendTop > 0 || baton->extendBottom > 0 || baton->extendLeft > 0 || baton->extendRight > 0) {
504
- std::vector<double> background;
505
- std::tie(image, background) = sharp::ApplyAlpha(image, baton->extendBackground);
506
-
507
- // Embed
508
- baton->width = image.width() + baton->extendLeft + baton->extendRight;
509
- baton->height = image.height() + baton->extendTop + baton->extendBottom;
510
-
511
- image = image.embed(baton->extendLeft, baton->extendTop, baton->width, baton->height,
512
- VImage::option()->set("extend", VIPS_EXTEND_BACKGROUND)->set("background", background));
513
- }
514
- // Median - must happen before blurring, due to the utility of blurring after thresholding
515
- if (shouldApplyMedian) {
516
- image = image.median(baton->medianSize);
517
- }
518
- // Threshold - must happen before blurring, due to the utility of blurring after thresholding
519
- if (baton->threshold != 0) {
520
- image = sharp::Threshold(image, baton->threshold, baton->thresholdGrayscale);
521
- }
522
-
523
- // Blur
524
- if (shouldBlur) {
525
- image = sharp::Blur(image, baton->blurSigma);
526
- }
527
-
528
- // Convolve
529
- if (shouldConv) {
530
- image = sharp::Convolve(image,
531
- baton->convKernelWidth, baton->convKernelHeight,
532
- baton->convKernelScale, baton->convKernelOffset,
533
- baton->convKernel);
534
- }
535
-
536
- // Recomb
537
- if (baton->recombMatrix != NULL) {
538
- image = sharp::Recomb(image, baton->recombMatrix);
539
- }
540
-
541
- if (shouldModulate) {
542
- image = sharp::Modulate(image, baton->brightness, baton->saturation, baton->hue);
543
- }
544
-
545
- // Sharpen
546
- if (shouldSharpen) {
547
- image = sharp::Sharpen(image, baton->sharpenSigma, baton->sharpenFlat, baton->sharpenJagged);
548
- }
549
-
550
- // Composite
551
- if (shouldComposite) {
552
- for (Composite *composite : baton->composite) {
553
- VImage compositeImage;
554
- sharp::ImageType compositeImageType = sharp::ImageType::UNKNOWN;
555
- std::tie(compositeImage, compositeImageType) = OpenInput(composite->input);
556
- // Verify within current dimensions
557
- if (compositeImage.width() > image.width() || compositeImage.height() > image.height()) {
558
- throw vips::VError("Image to composite must have same dimensions or smaller");
559
- }
560
- // Check if overlay is tiled
561
- if (composite->tile) {
562
- int across = 0;
563
- int down = 0;
564
- // Use gravity in overlay
565
- if (compositeImage.width() <= baton->width) {
566
- across = static_cast<int>(ceil(static_cast<double>(image.width()) / compositeImage.width()));
567
- // Ensure odd number of tiles across when gravity is centre, north or south
568
- if (composite->gravity == 0 || composite->gravity == 1 || composite->gravity == 3) {
569
- across |= 1;
570
- }
571
- }
572
- if (compositeImage.height() <= baton->height) {
573
- down = static_cast<int>(ceil(static_cast<double>(image.height()) / compositeImage.height()));
574
- // Ensure odd number of tiles down when gravity is centre, east or west
575
- if (composite->gravity == 0 || composite->gravity == 2 || composite->gravity == 4) {
576
- down |= 1;
577
- }
578
- }
579
- if (across != 0 || down != 0) {
580
- int left;
581
- int top;
582
- compositeImage = compositeImage.replicate(across, down);
583
- if (composite->hasOffset) {
584
- std::tie(left, top) = sharp::CalculateCrop(
585
- compositeImage.width(), compositeImage.height(), image.width(), image.height(),
586
- composite->left, composite->top);
587
- } else {
588
- std::tie(left, top) = sharp::CalculateCrop(
589
- compositeImage.width(), compositeImage.height(), image.width(), image.height(), composite->gravity);
590
- }
591
- compositeImage = compositeImage.extract_area(left, top, image.width(), image.height());
592
- }
593
- // gravity was used for extract_area, set it back to its default value of 0
594
- composite->gravity = 0;
595
- }
596
- // Ensure image to composite is sRGB with premultiplied alpha
597
- compositeImage = compositeImage.colourspace(VIPS_INTERPRETATION_sRGB);
598
- if (!sharp::HasAlpha(compositeImage)) {
599
- compositeImage = sharp::EnsureAlpha(compositeImage, 1);
600
- }
601
- if (!composite->premultiplied) compositeImage = compositeImage.premultiply();
602
- // Calculate position
603
- int left;
604
- int top;
605
- if (composite->hasOffset) {
606
- // Composite image at given offsets
607
- if (composite->tile) {
608
- std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(),
609
- compositeImage.width(), compositeImage.height(), composite->left, composite->top);
610
- } else {
611
- left = composite->left;
612
- top = composite->top;
613
- }
614
- } else {
615
- // Composite image with given gravity
616
- std::tie(left, top) = sharp::CalculateCrop(image.width(), image.height(),
617
- compositeImage.width(), compositeImage.height(), composite->gravity);
618
- }
619
- // Composite
620
- image = image.composite2(compositeImage, composite->mode, VImage::option()
621
- ->set("premultiplied", TRUE)
622
- ->set("x", left)
623
- ->set("y", top));
624
- }
625
- }
626
-
627
- // Reverse premultiplication after all transformations:
628
- if (shouldPremultiplyAlpha) {
629
- image = image.unpremultiply();
630
- // Cast pixel values to integer
631
- if (sharp::Is16Bit(image.interpretation())) {
632
- image = image.cast(VIPS_FORMAT_USHORT);
633
- } else {
634
- image = image.cast(VIPS_FORMAT_UCHAR);
635
- }
636
- }
637
- baton->premultiplied = shouldPremultiplyAlpha;
638
-
639
- // Gamma decoding (brighten)
640
- if (baton->gammaOut >= 1 && baton->gammaOut <= 3) {
641
- image = sharp::Gamma(image, baton->gammaOut);
642
- }
643
-
644
- // Linear adjustment (a * in + b)
645
- if (baton->linearA != 1.0 || baton->linearB != 0.0) {
646
- image = sharp::Linear(image, baton->linearA, baton->linearB);
647
- }
648
-
649
- // Apply normalisation - stretch luminance to cover full dynamic range
650
- if (baton->normalise) {
651
- image = sharp::Normalise(image);
652
- }
653
-
654
- // Apply contrast limiting adaptive histogram equalization (CLAHE)
655
- if (shouldApplyClahe) {
656
- image = sharp::Clahe(image, baton->claheWidth, baton->claheHeight, baton->claheMaxSlope);
657
- }
658
-
659
- // Apply bitwise boolean operation between images
660
- if (baton->boolean != nullptr) {
661
- VImage booleanImage;
662
- sharp::ImageType booleanImageType = sharp::ImageType::UNKNOWN;
663
- std::tie(booleanImage, booleanImageType) = sharp::OpenInput(baton->boolean);
664
- image = sharp::Boolean(image, booleanImage, baton->booleanOp);
665
- }
666
-
667
- // Apply per-channel Bandbool bitwise operations after all other operations
668
- if (baton->bandBoolOp >= VIPS_OPERATION_BOOLEAN_AND && baton->bandBoolOp < VIPS_OPERATION_BOOLEAN_LAST) {
669
- image = sharp::Bandbool(image, baton->bandBoolOp);
670
- }
671
-
672
- // Tint the image
673
- if (baton->tintA < 128.0 || baton->tintB < 128.0) {
674
- image = sharp::Tint(image, baton->tintA, baton->tintB);
675
- }
676
-
677
- // Extract an image channel (aka vips band)
678
- if (baton->extractChannel > -1) {
679
- if (baton->extractChannel >= image.bands()) {
680
- if (baton->extractChannel == 3 && sharp::HasAlpha(image)) {
681
- baton->extractChannel = image.bands() - 1;
682
- } else {
683
- (baton->err).append("Cannot extract channel from image. Too few channels in image.");
684
- return Error();
685
- }
686
- }
687
- VipsInterpretation const interpretation = sharp::Is16Bit(image.interpretation())
688
- ? VIPS_INTERPRETATION_GREY16
689
- : VIPS_INTERPRETATION_B_W;
690
- image = image
691
- .extract_band(baton->extractChannel)
692
- .copy(VImage::option()->set("interpretation", interpretation));
693
- }
694
-
695
- // Remove alpha channel, if any
696
- if (baton->removeAlpha) {
697
- image = sharp::RemoveAlpha(image);
698
- }
699
-
700
- // Ensure alpha channel, if missing
701
- if (baton->ensureAlpha != -1) {
702
- image = sharp::EnsureAlpha(image, baton->ensureAlpha);
703
- }
704
-
705
- // Convert image to sRGB, if not already
706
- if (sharp::Is16Bit(image.interpretation())) {
707
- image = image.cast(VIPS_FORMAT_USHORT);
708
- }
709
- if (image.interpretation() != baton->colourspace) {
710
- // Convert colourspace, pass the current known interpretation so libvips doesn't have to guess
711
- image = image.colourspace(baton->colourspace, VImage::option()->set("source_space", image.interpretation()));
712
- // Transform colours from embedded profile to output profile
713
- if (baton->withMetadata && sharp::HasProfile(image)) {
714
- image = image.icc_transform(vips_enum_nick(VIPS_TYPE_INTERPRETATION, baton->colourspace),
715
- VImage::option()->set("embedded", TRUE));
716
- }
717
- }
718
-
719
- // Apply output ICC profile
720
- if (!baton->withMetadataIcc.empty()) {
721
- image = image.icc_transform(
722
- const_cast<char*>(baton->withMetadataIcc.data()),
723
- VImage::option()
724
- ->set("input_profile", "srgb")
725
- ->set("intent", VIPS_INTENT_PERCEPTUAL));
726
- }
727
- // Override EXIF Orientation tag
728
- if (baton->withMetadata && baton->withMetadataOrientation != -1) {
729
- image = sharp::SetExifOrientation(image, baton->withMetadataOrientation);
730
- }
731
- // Override pixel density
732
- if (baton->withMetadataDensity > 0) {
733
- image = sharp::SetDensity(image, baton->withMetadataDensity);
734
- }
735
- // Metadata key/value pairs, e.g. EXIF
736
- if (!baton->withMetadataStrs.empty()) {
737
- image = image.copy();
738
- for (const auto& s : baton->withMetadataStrs) {
739
- image.set(s.first.data(), s.second.data());
740
- }
741
- }
742
-
743
- // Number of channels used in output image
744
- baton->channels = image.bands();
745
- baton->width = image.width();
746
- baton->height = image.height();
747
-
748
- bool const supportsGifOutput = vips_type_find("VipsOperation", "magicksave") != 0 &&
749
- vips_type_find("VipsOperation", "magicksave_buffer") != 0;
750
-
751
- image = sharp::SetAnimationProperties(
752
- image,
753
- baton->pageHeight,
754
- baton->delay,
755
- baton->loop);
756
-
757
- // Output
758
- if (baton->fileOut.empty()) {
759
- // Buffer output
760
- if (baton->formatOut == "jpeg" || (baton->formatOut == "input" && inputImageType == sharp::ImageType::JPEG)) {
761
- // Write JPEG to buffer
762
- sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG);
763
- VipsArea *area = reinterpret_cast<VipsArea*>(image.jpegsave_buffer(VImage::option()
764
- ->set("strip", !baton->withMetadata)
765
- ->set("Q", baton->jpegQuality)
766
- ->set("interlace", baton->jpegProgressive)
767
- ->set("subsample_mode", baton->jpegChromaSubsampling == "4:4:4"
768
- ? VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF
769
- : VIPS_FOREIGN_JPEG_SUBSAMPLE_ON)
770
- ->set("trellis_quant", baton->jpegTrellisQuantisation)
771
- ->set("quant_table", baton->jpegQuantisationTable)
772
- ->set("overshoot_deringing", baton->jpegOvershootDeringing)
773
- ->set("optimize_scans", baton->jpegOptimiseScans)
774
- ->set("optimize_coding", baton->jpegOptimiseCoding)));
775
- baton->bufferOut = static_cast<char*>(area->data);
776
- baton->bufferOutLength = area->length;
777
- area->free_fn = nullptr;
778
- vips_area_unref(area);
779
- baton->formatOut = "jpeg";
780
- if (baton->colourspace == VIPS_INTERPRETATION_CMYK) {
781
- baton->channels = std::min(baton->channels, 4);
782
- } else {
783
- baton->channels = std::min(baton->channels, 3);
784
- }
785
- } else if (baton->formatOut == "png" || (baton->formatOut == "input" &&
786
- (inputImageType == sharp::ImageType::PNG || (inputImageType == sharp::ImageType::GIF && !supportsGifOutput) ||
787
- inputImageType == sharp::ImageType::SVG))) {
788
- // Write PNG to buffer
789
- sharp::AssertImageTypeDimensions(image, sharp::ImageType::PNG);
790
- VipsArea *area = reinterpret_cast<VipsArea*>(image.pngsave_buffer(VImage::option()
791
- ->set("strip", !baton->withMetadata)
792
- ->set("interlace", baton->pngProgressive)
793
- ->set("compression", baton->pngCompressionLevel)
794
- ->set("filter", baton->pngAdaptiveFiltering ? VIPS_FOREIGN_PNG_FILTER_ALL : VIPS_FOREIGN_PNG_FILTER_NONE)
795
- ->set("palette", baton->pngPalette)
796
- ->set("Q", baton->pngQuality)
797
- ->set("colours", baton->pngColours)
798
- ->set("dither", baton->pngDither)));
799
- baton->bufferOut = static_cast<char*>(area->data);
800
- baton->bufferOutLength = area->length;
801
- area->free_fn = nullptr;
802
- vips_area_unref(area);
803
- baton->formatOut = "png";
804
- } else if (baton->formatOut == "webp" ||
805
- (baton->formatOut == "input" && inputImageType == sharp::ImageType::WEBP)) {
806
- // Write WEBP to buffer
807
- sharp::AssertImageTypeDimensions(image, sharp::ImageType::WEBP);
808
- VipsArea *area = reinterpret_cast<VipsArea*>(image.webpsave_buffer(VImage::option()
809
- ->set("strip", !baton->withMetadata)
810
- ->set("Q", baton->webpQuality)
811
- ->set("lossless", baton->webpLossless)
812
- ->set("near_lossless", baton->webpNearLossless)
813
- ->set("smart_subsample", baton->webpSmartSubsample)
814
- ->set("reduction_effort", baton->webpReductionEffort)
815
- ->set("alpha_q", baton->webpAlphaQuality)));
816
- baton->bufferOut = static_cast<char*>(area->data);
817
- baton->bufferOutLength = area->length;
818
- area->free_fn = nullptr;
819
- vips_area_unref(area);
820
- baton->formatOut = "webp";
821
- } else if (baton->formatOut == "gif" ||
822
- (baton->formatOut == "input" && inputImageType == sharp::ImageType::GIF && supportsGifOutput)) {
823
- // Write GIF to buffer
824
- sharp::AssertImageTypeDimensions(image, sharp::ImageType::GIF);
825
- VipsArea *area = reinterpret_cast<VipsArea*>(image.magicksave_buffer(VImage::option()
826
- ->set("strip", !baton->withMetadata)
827
- ->set("optimize_gif_frames", TRUE)
828
- ->set("optimize_gif_transparency", TRUE)
829
- ->set("format", "gif")));
830
- baton->bufferOut = static_cast<char*>(area->data);
831
- baton->bufferOutLength = area->length;
832
- area->free_fn = nullptr;
833
- vips_area_unref(area);
834
- baton->formatOut = "gif";
835
- } else if (baton->formatOut == "tiff" ||
836
- (baton->formatOut == "input" && inputImageType == sharp::ImageType::TIFF)) {
837
- // Write TIFF to buffer
838
- if (baton->tiffCompression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) {
839
- sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG);
840
- baton->channels = std::min(baton->channels, 3);
841
- }
842
- // Cast pixel values to float, if required
843
- if (baton->tiffPredictor == VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT) {
844
- image = image.cast(VIPS_FORMAT_FLOAT);
845
- }
846
- VipsArea *area = reinterpret_cast<VipsArea*>(image.tiffsave_buffer(VImage::option()
847
- ->set("strip", !baton->withMetadata)
848
- ->set("Q", baton->tiffQuality)
849
- ->set("bitdepth", baton->tiffBitdepth)
850
- ->set("compression", baton->tiffCompression)
851
- ->set("predictor", baton->tiffPredictor)
852
- ->set("pyramid", baton->tiffPyramid)
853
- ->set("tile", baton->tiffTile)
854
- ->set("tile_height", baton->tiffTileHeight)
855
- ->set("tile_width", baton->tiffTileWidth)
856
- ->set("xres", baton->tiffXres)
857
- ->set("yres", baton->tiffYres)));
858
- baton->bufferOut = static_cast<char*>(area->data);
859
- baton->bufferOutLength = area->length;
860
- area->free_fn = nullptr;
861
- vips_area_unref(area);
862
- baton->formatOut = "tiff";
863
- } else if (baton->formatOut == "heif" ||
864
- (baton->formatOut == "input" && inputImageType == sharp::ImageType::HEIF)) {
865
- // Write HEIF to buffer
866
- VipsArea *area = reinterpret_cast<VipsArea*>(image.heifsave_buffer(VImage::option()
867
- ->set("strip", !baton->withMetadata)
868
- ->set("compression", baton->heifCompression)
869
- ->set("Q", baton->heifQuality)
870
- ->set("speed", baton->heifSpeed)
871
- #if defined(VIPS_TYPE_FOREIGN_SUBSAMPLE)
872
- ->set("subsample_mode", baton->heifChromaSubsampling == "4:4:4"
873
- ? VIPS_FOREIGN_SUBSAMPLE_OFF : VIPS_FOREIGN_SUBSAMPLE_ON)
874
- #endif
875
- ->set("lossless", baton->heifLossless)));
876
- baton->bufferOut = static_cast<char*>(area->data);
877
- baton->bufferOutLength = area->length;
878
- area->free_fn = nullptr;
879
- vips_area_unref(area);
880
- baton->formatOut = "heif";
881
- } else if (baton->formatOut == "raw" ||
882
- (baton->formatOut == "input" && inputImageType == sharp::ImageType::RAW)) {
883
- // Write raw, uncompressed image data to buffer
884
- if (baton->greyscale || image.interpretation() == VIPS_INTERPRETATION_B_W) {
885
- // Extract first band for greyscale image
886
- image = image[0];
887
- baton->channels = 1;
888
- }
889
- if (image.format() != VIPS_FORMAT_UCHAR) {
890
- // Cast pixels to uint8 (unsigned char)
891
- image = image.cast(VIPS_FORMAT_UCHAR);
892
- }
893
- // Get raw image data
894
- baton->bufferOut = static_cast<char*>(image.write_to_memory(&baton->bufferOutLength));
895
- if (baton->bufferOut == nullptr) {
896
- (baton->err).append("Could not allocate enough memory for raw output");
897
- return Error();
898
- }
899
- baton->formatOut = "raw";
900
- } else {
901
- // Unsupported output format
902
- (baton->err).append("Unsupported output format ");
903
- if (baton->formatOut == "input") {
904
- (baton->err).append(ImageTypeId(inputImageType));
905
- } else {
906
- (baton->err).append(baton->formatOut);
907
- }
908
- return Error();
909
- }
910
- } else {
911
- // File output
912
- bool const isJpeg = sharp::IsJpeg(baton->fileOut);
913
- bool const isPng = sharp::IsPng(baton->fileOut);
914
- bool const isWebp = sharp::IsWebp(baton->fileOut);
915
- bool const isGif = sharp::IsGif(baton->fileOut);
916
- bool const isTiff = sharp::IsTiff(baton->fileOut);
917
- bool const isHeif = sharp::IsHeif(baton->fileOut);
918
- bool const isDz = sharp::IsDz(baton->fileOut);
919
- bool const isDzZip = sharp::IsDzZip(baton->fileOut);
920
- bool const isV = sharp::IsV(baton->fileOut);
921
- bool const mightMatchInput = baton->formatOut == "input";
922
- bool const willMatchInput = mightMatchInput &&
923
- !(isJpeg || isPng || isWebp || isGif || isTiff || isHeif || isDz || isDzZip || isV);
924
-
925
- if (baton->formatOut == "jpeg" || (mightMatchInput && isJpeg) ||
926
- (willMatchInput && inputImageType == sharp::ImageType::JPEG)) {
927
- // Write JPEG to file
928
- sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG);
929
- image.jpegsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
930
- ->set("strip", !baton->withMetadata)
931
- ->set("Q", baton->jpegQuality)
932
- ->set("interlace", baton->jpegProgressive)
933
- ->set("subsample_mode", baton->jpegChromaSubsampling == "4:4:4"
934
- ? VIPS_FOREIGN_JPEG_SUBSAMPLE_OFF
935
- : VIPS_FOREIGN_JPEG_SUBSAMPLE_ON)
936
- ->set("trellis_quant", baton->jpegTrellisQuantisation)
937
- ->set("quant_table", baton->jpegQuantisationTable)
938
- ->set("overshoot_deringing", baton->jpegOvershootDeringing)
939
- ->set("optimize_scans", baton->jpegOptimiseScans)
940
- ->set("optimize_coding", baton->jpegOptimiseCoding));
941
- baton->formatOut = "jpeg";
942
- baton->channels = std::min(baton->channels, 3);
943
- } else if (baton->formatOut == "png" || (mightMatchInput && isPng) || (willMatchInput &&
944
- (inputImageType == sharp::ImageType::PNG || (inputImageType == sharp::ImageType::GIF && !supportsGifOutput) ||
945
- inputImageType == sharp::ImageType::SVG))) {
946
- // Write PNG to file
947
- sharp::AssertImageTypeDimensions(image, sharp::ImageType::PNG);
948
- image.pngsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
949
- ->set("strip", !baton->withMetadata)
950
- ->set("interlace", baton->pngProgressive)
951
- ->set("compression", baton->pngCompressionLevel)
952
- ->set("filter", baton->pngAdaptiveFiltering ? VIPS_FOREIGN_PNG_FILTER_ALL : VIPS_FOREIGN_PNG_FILTER_NONE)
953
- ->set("palette", baton->pngPalette)
954
- ->set("Q", baton->pngQuality)
955
- ->set("colours", baton->pngColours)
956
- ->set("dither", baton->pngDither));
957
- baton->formatOut = "png";
958
- } else if (baton->formatOut == "webp" || (mightMatchInput && isWebp) ||
959
- (willMatchInput && inputImageType == sharp::ImageType::WEBP)) {
960
- // Write WEBP to file
961
- sharp::AssertImageTypeDimensions(image, sharp::ImageType::WEBP);
962
- image.webpsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
963
- ->set("strip", !baton->withMetadata)
964
- ->set("Q", baton->webpQuality)
965
- ->set("lossless", baton->webpLossless)
966
- ->set("near_lossless", baton->webpNearLossless)
967
- ->set("smart_subsample", baton->webpSmartSubsample)
968
- ->set("reduction_effort", baton->webpReductionEffort)
969
- ->set("alpha_q", baton->webpAlphaQuality));
970
- baton->formatOut = "webp";
971
- } else if (baton->formatOut == "gif" || (mightMatchInput && isGif) ||
972
- (willMatchInput && inputImageType == sharp::ImageType::GIF && supportsGifOutput)) {
973
- // Write GIF to file
974
- sharp::AssertImageTypeDimensions(image, sharp::ImageType::GIF);
975
- image.magicksave(const_cast<char*>(baton->fileOut.data()), VImage::option()
976
- ->set("strip", !baton->withMetadata)
977
- ->set("optimize_gif_frames", TRUE)
978
- ->set("optimize_gif_transparency", TRUE)
979
- ->set("format", "gif"));
980
- baton->formatOut = "gif";
981
- } else if (baton->formatOut == "tiff" || (mightMatchInput && isTiff) ||
982
- (willMatchInput && inputImageType == sharp::ImageType::TIFF)) {
983
- // Write TIFF to file
984
- if (baton->tiffCompression == VIPS_FOREIGN_TIFF_COMPRESSION_JPEG) {
985
- sharp::AssertImageTypeDimensions(image, sharp::ImageType::JPEG);
986
- baton->channels = std::min(baton->channels, 3);
987
- }
988
- // Cast pixel values to float, if required
989
- if (baton->tiffPredictor == VIPS_FOREIGN_TIFF_PREDICTOR_FLOAT) {
990
- image = image.cast(VIPS_FORMAT_FLOAT);
991
- }
992
- image.tiffsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
993
- ->set("strip", !baton->withMetadata)
994
- ->set("Q", baton->tiffQuality)
995
- ->set("bitdepth", baton->tiffBitdepth)
996
- ->set("compression", baton->tiffCompression)
997
- ->set("predictor", baton->tiffPredictor)
998
- ->set("pyramid", baton->tiffPyramid)
999
- ->set("tile", baton->tiffTile)
1000
- ->set("tile_height", baton->tiffTileHeight)
1001
- ->set("tile_width", baton->tiffTileWidth)
1002
- ->set("xres", baton->tiffXres)
1003
- ->set("yres", baton->tiffYres));
1004
- baton->formatOut = "tiff";
1005
- } else if (baton->formatOut == "heif" || (mightMatchInput && isHeif) ||
1006
- (willMatchInput && inputImageType == sharp::ImageType::HEIF)) {
1007
- // Write HEIF to file
1008
- image.heifsave(const_cast<char*>(baton->fileOut.data()), VImage::option()
1009
- ->set("strip", !baton->withMetadata)
1010
- ->set("Q", baton->heifQuality)
1011
- ->set("compression", baton->heifCompression)
1012
- ->set("speed", baton->heifSpeed)
1013
- #if defined(VIPS_TYPE_FOREIGN_SUBSAMPLE)
1014
- ->set("subsample_mode", baton->heifChromaSubsampling == "4:4:4"
1015
- ? VIPS_FOREIGN_SUBSAMPLE_OFF : VIPS_FOREIGN_SUBSAMPLE_ON)
1016
- #endif
1017
- ->set("lossless", baton->heifLossless));
1018
- baton->formatOut = "heif";
1019
- } else if (baton->formatOut == "dz" || isDz || isDzZip) {
1020
- if (isDzZip) {
1021
- baton->tileContainer = VIPS_FOREIGN_DZ_CONTAINER_ZIP;
1022
- }
1023
- // Forward format options through suffix
1024
- std::string suffix;
1025
- if (baton->tileFormat == "png") {
1026
- std::vector<std::pair<std::string, std::string>> options {
1027
- {"interlace", baton->pngProgressive ? "TRUE" : "FALSE"},
1028
- {"compression", std::to_string(baton->pngCompressionLevel)},
1029
- {"filter", baton->pngAdaptiveFiltering ? "all" : "none"}
1030
- };
1031
- suffix = AssembleSuffixString(".png", options);
1032
- } else if (baton->tileFormat == "webp") {
1033
- std::vector<std::pair<std::string, std::string>> options {
1034
- {"Q", std::to_string(baton->webpQuality)},
1035
- {"alpha_q", std::to_string(baton->webpAlphaQuality)},
1036
- {"lossless", baton->webpLossless ? "TRUE" : "FALSE"},
1037
- {"near_lossless", baton->webpNearLossless ? "TRUE" : "FALSE"},
1038
- {"smart_subsample", baton->webpSmartSubsample ? "TRUE" : "FALSE"},
1039
- {"reduction_effort", std::to_string(baton->webpReductionEffort)}
1040
- };
1041
- suffix = AssembleSuffixString(".webp", options);
1042
- } else {
1043
- std::vector<std::pair<std::string, std::string>> options {
1044
- {"Q", std::to_string(baton->jpegQuality)},
1045
- {"interlace", baton->jpegProgressive ? "TRUE" : "FALSE"},
1046
- {"subsample_mode", baton->jpegChromaSubsampling == "4:4:4" ? "off" : "on"},
1047
- {"trellis_quant", baton->jpegTrellisQuantisation ? "TRUE" : "FALSE"},
1048
- {"quant_table", std::to_string(baton->jpegQuantisationTable)},
1049
- {"overshoot_deringing", baton->jpegOvershootDeringing ? "TRUE": "FALSE"},
1050
- {"optimize_scans", baton->jpegOptimiseScans ? "TRUE": "FALSE"},
1051
- {"optimize_coding", baton->jpegOptimiseCoding ? "TRUE": "FALSE"}
1052
- };
1053
- std::string extname = baton->tileLayout == VIPS_FOREIGN_DZ_LAYOUT_DZ ? ".jpeg" : ".jpg";
1054
- suffix = AssembleSuffixString(extname, options);
1055
- }
1056
- // Remove alpha channel from tile background if image does not contain an alpha channel
1057
- if (!sharp::HasAlpha(image)) {
1058
- baton->tileBackground.pop_back();
1059
- }
1060
- // Write DZ to file
1061
- vips::VOption *options = VImage::option()
1062
- ->set("strip", !baton->withMetadata)
1063
- ->set("tile_size", baton->tileSize)
1064
- ->set("overlap", baton->tileOverlap)
1065
- ->set("container", baton->tileContainer)
1066
- ->set("layout", baton->tileLayout)
1067
- ->set("suffix", const_cast<char*>(suffix.data()))
1068
- ->set("angle", CalculateAngleRotation(baton->tileAngle))
1069
- ->set("background", baton->tileBackground)
1070
- ->set("centre", baton->tileCentre)
1071
- ->set("id", const_cast<char*>(baton->tileId.data()))
1072
- ->set("skip_blanks", baton->tileSkipBlanks);
1073
- // libvips chooses a default depth based on layout. Instead of replicating that logic here by
1074
- // not passing anything - libvips will handle choice
1075
- if (baton->tileDepth < VIPS_FOREIGN_DZ_DEPTH_LAST) {
1076
- options->set("depth", baton->tileDepth);
1077
- }
1078
- image.dzsave(const_cast<char*>(baton->fileOut.data()), options);
1079
- baton->formatOut = "dz";
1080
- } else if (baton->formatOut == "v" || (mightMatchInput && isV) ||
1081
- (willMatchInput && inputImageType == sharp::ImageType::VIPS)) {
1082
- // Write V to file
1083
- image.vipssave(const_cast<char*>(baton->fileOut.data()), VImage::option()
1084
- ->set("strip", !baton->withMetadata));
1085
- baton->formatOut = "v";
1086
- } else {
1087
- // Unsupported output format
1088
- (baton->err).append("Unsupported output format " + baton->fileOut);
1089
- return Error();
1090
- }
1091
- }
1092
- } catch (vips::VError const &err) {
1093
- char const *what = err.what();
1094
- if (what && what[0]) {
1095
- (baton->err).append(what);
1096
- } else {
1097
- (baton->err).append("Unknown error");
1098
- }
1099
- }
1100
- // Clean up libvips' per-request data and threads
1101
- vips_error_clear();
1102
- vips_thread_shutdown();
1103
- }
1104
-
1105
- void OnOK() {
1106
- Napi::Env env = Env();
1107
- Napi::HandleScope scope(env);
1108
-
1109
- // Handle warnings
1110
- std::string warning = sharp::VipsWarningPop();
1111
- while (!warning.empty()) {
1112
- debuglog.Call({ Napi::String::New(env, warning) });
1113
- warning = sharp::VipsWarningPop();
1114
- }
1115
-
1116
- if (baton->err.empty()) {
1117
- int width = baton->width;
1118
- int height = baton->height;
1119
- if (baton->topOffsetPre != -1 && (baton->width == -1 || baton->height == -1)) {
1120
- width = baton->widthPre;
1121
- height = baton->heightPre;
1122
- }
1123
- if (baton->topOffsetPost != -1) {
1124
- width = baton->widthPost;
1125
- height = baton->heightPost;
1126
- }
1127
- // Info Object
1128
- Napi::Object info = Napi::Object::New(env);
1129
- info.Set("format", baton->formatOut);
1130
- info.Set("width", static_cast<uint32_t>(width));
1131
- info.Set("height", static_cast<uint32_t>(height));
1132
- info.Set("channels", static_cast<uint32_t>(baton->channels));
1133
- info.Set("premultiplied", baton->premultiplied);
1134
- if (baton->hasCropOffset) {
1135
- info.Set("cropOffsetLeft", static_cast<int32_t>(baton->cropOffsetLeft));
1136
- info.Set("cropOffsetTop", static_cast<int32_t>(baton->cropOffsetTop));
1137
- }
1138
- if (baton->trimThreshold > 0.0) {
1139
- info.Set("trimOffsetLeft", static_cast<int32_t>(baton->trimOffsetLeft));
1140
- info.Set("trimOffsetTop", static_cast<int32_t>(baton->trimOffsetTop));
1141
- }
1142
-
1143
- if (baton->bufferOutLength > 0) {
1144
- // Add buffer size to info
1145
- info.Set("size", static_cast<uint32_t>(baton->bufferOutLength));
1146
- // Pass ownership of output data to Buffer instance
1147
- Napi::Buffer<char> data = Napi::Buffer<char>::New(env, static_cast<char*>(baton->bufferOut),
1148
- baton->bufferOutLength, sharp::FreeCallback);
1149
- Callback().MakeCallback(Receiver().Value(), { env.Null(), data, info });
1150
- } else {
1151
- // Add file size to info
1152
- struct STAT64_STRUCT st;
1153
- if (STAT64_FUNCTION(baton->fileOut.data(), &st) == 0) {
1154
- info.Set("size", static_cast<uint32_t>(st.st_size));
1155
- }
1156
- Callback().MakeCallback(Receiver().Value(), { env.Null(), info });
1157
- }
1158
- } else {
1159
- Callback().MakeCallback(Receiver().Value(), { Napi::Error::New(env, baton->err).Value() });
1160
- }
1161
-
1162
- // Delete baton
1163
- delete baton->input;
1164
- delete baton->boolean;
1165
- for (Composite *composite : baton->composite) {
1166
- delete composite->input;
1167
- delete composite;
1168
- }
1169
- for (sharp::InputDescriptor *input : baton->joinChannelIn) {
1170
- delete input;
1171
- }
1172
- delete baton;
1173
-
1174
- // Decrement processing task counter
1175
- g_atomic_int_dec_and_test(&sharp::counterProcess);
1176
- Napi::Number queueLength = Napi::Number::New(env, static_cast<double>(sharp::counterQueue));
1177
- queueListener.Call(Receiver().Value(), { queueLength });
1178
- }
1179
-
1180
- private:
1181
- PipelineBaton *baton;
1182
- Napi::FunctionReference debuglog;
1183
- Napi::FunctionReference queueListener;
1184
-
1185
- /*
1186
- Calculate the angle of rotation and need-to-flip for the given Exif orientation
1187
- By default, returns zero, i.e. no rotation.
1188
- */
1189
- std::tuple<VipsAngle, bool, bool>
1190
- CalculateExifRotationAndFlip(int const exifOrientation) {
1191
- VipsAngle rotate = VIPS_ANGLE_D0;
1192
- bool flip = FALSE;
1193
- bool flop = FALSE;
1194
- switch (exifOrientation) {
1195
- case 6: rotate = VIPS_ANGLE_D90; break;
1196
- case 3: rotate = VIPS_ANGLE_D180; break;
1197
- case 8: rotate = VIPS_ANGLE_D270; break;
1198
- case 2: flop = TRUE; break; // flop 1
1199
- case 7: flip = TRUE; rotate = VIPS_ANGLE_D90; break; // flip 6
1200
- case 4: flop = TRUE; rotate = VIPS_ANGLE_D180; break; // flop 3
1201
- case 5: flip = TRUE; rotate = VIPS_ANGLE_D270; break; // flip 8
1202
- }
1203
- return std::make_tuple(rotate, flip, flop);
1204
- }
1205
-
1206
- /*
1207
- Calculate the rotation for the given angle.
1208
- Supports any positive or negative angle that is a multiple of 90.
1209
- */
1210
- VipsAngle
1211
- CalculateAngleRotation(int angle) {
1212
- angle = angle % 360;
1213
- if (angle < 0)
1214
- angle = 360 + angle;
1215
- switch (angle) {
1216
- case 90: return VIPS_ANGLE_D90;
1217
- case 180: return VIPS_ANGLE_D180;
1218
- case 270: return VIPS_ANGLE_D270;
1219
- }
1220
- return VIPS_ANGLE_D0;
1221
- }
1222
-
1223
- /*
1224
- Assemble the suffix argument to dzsave, which is the format (by extname)
1225
- alongisde comma-separated arguments to the corresponding `formatsave` vips
1226
- action.
1227
- */
1228
- std::string
1229
- AssembleSuffixString(std::string extname, std::vector<std::pair<std::string, std::string>> options) {
1230
- std::string argument;
1231
- for (auto const &option : options) {
1232
- if (!argument.empty()) {
1233
- argument += ",";
1234
- }
1235
- argument += option.first + "=" + option.second;
1236
- }
1237
- return extname + "[" + argument + "]";
1238
- }
1239
-
1240
- /*
1241
- Clear all thread-local data.
1242
- */
1243
- void Error() {
1244
- // Clean up libvips' per-request data and threads
1245
- vips_error_clear();
1246
- vips_thread_shutdown();
1247
- }
1248
- };
1249
-
1250
- /*
1251
- pipeline(options, output, callback)
1252
- */
1253
- Napi::Value pipeline(const Napi::CallbackInfo& info) {
1254
- // V8 objects are converted to non-V8 types held in the baton struct
1255
- PipelineBaton *baton = new PipelineBaton;
1256
- Napi::Object options = info[0].As<Napi::Object>();
1257
-
1258
- // Input
1259
- baton->input = sharp::CreateInputDescriptor(options.Get("input").As<Napi::Object>());
1260
- // Extract image options
1261
- baton->topOffsetPre = sharp::AttrAsInt32(options, "topOffsetPre");
1262
- baton->leftOffsetPre = sharp::AttrAsInt32(options, "leftOffsetPre");
1263
- baton->widthPre = sharp::AttrAsInt32(options, "widthPre");
1264
- baton->heightPre = sharp::AttrAsInt32(options, "heightPre");
1265
- baton->topOffsetPost = sharp::AttrAsInt32(options, "topOffsetPost");
1266
- baton->leftOffsetPost = sharp::AttrAsInt32(options, "leftOffsetPost");
1267
- baton->widthPost = sharp::AttrAsInt32(options, "widthPost");
1268
- baton->heightPost = sharp::AttrAsInt32(options, "heightPost");
1269
- // Output image dimensions
1270
- baton->width = sharp::AttrAsInt32(options, "width");
1271
- baton->height = sharp::AttrAsInt32(options, "height");
1272
- // Canvas option
1273
- std::string canvas = sharp::AttrAsStr(options, "canvas");
1274
- if (canvas == "crop") {
1275
- baton->canvas = Canvas::CROP;
1276
- } else if (canvas == "embed") {
1277
- baton->canvas = Canvas::EMBED;
1278
- } else if (canvas == "max") {
1279
- baton->canvas = Canvas::MAX;
1280
- } else if (canvas == "min") {
1281
- baton->canvas = Canvas::MIN;
1282
- } else if (canvas == "ignore_aspect") {
1283
- baton->canvas = Canvas::IGNORE_ASPECT;
1284
- }
1285
- // Tint chroma
1286
- baton->tintA = sharp::AttrAsDouble(options, "tintA");
1287
- baton->tintB = sharp::AttrAsDouble(options, "tintB");
1288
- // Composite
1289
- Napi::Array compositeArray = options.Get("composite").As<Napi::Array>();
1290
- for (unsigned int i = 0; i < compositeArray.Length(); i++) {
1291
- Napi::Object compositeObject = compositeArray.Get(i).As<Napi::Object>();
1292
- Composite *composite = new Composite;
1293
- composite->input = sharp::CreateInputDescriptor(compositeObject.Get("input").As<Napi::Object>());
1294
- composite->mode = static_cast<VipsBlendMode>(
1295
- vips_enum_from_nick(nullptr, VIPS_TYPE_BLEND_MODE, sharp::AttrAsStr(compositeObject, "blend").data()));
1296
- composite->gravity = sharp::AttrAsUint32(compositeObject, "gravity");
1297
- composite->left = sharp::AttrAsInt32(compositeObject, "left");
1298
- composite->top = sharp::AttrAsInt32(compositeObject, "top");
1299
- composite->hasOffset = sharp::AttrAsBool(compositeObject, "hasOffset");
1300
- composite->tile = sharp::AttrAsBool(compositeObject, "tile");
1301
- composite->premultiplied = sharp::AttrAsBool(compositeObject, "premultiplied");
1302
- baton->composite.push_back(composite);
1303
- }
1304
- // Resize options
1305
- baton->withoutEnlargement = sharp::AttrAsBool(options, "withoutEnlargement");
1306
- baton->position = sharp::AttrAsInt32(options, "position");
1307
- baton->resizeBackground = sharp::AttrAsVectorOfDouble(options, "resizeBackground");
1308
- baton->kernel = sharp::AttrAsStr(options, "kernel");
1309
- baton->fastShrinkOnLoad = sharp::AttrAsBool(options, "fastShrinkOnLoad");
1310
- // Join Channel Options
1311
- if (options.Has("joinChannelIn")) {
1312
- Napi::Array joinChannelArray = options.Get("joinChannelIn").As<Napi::Array>();
1313
- for (unsigned int i = 0; i < joinChannelArray.Length(); i++) {
1314
- baton->joinChannelIn.push_back(
1315
- sharp::CreateInputDescriptor(joinChannelArray.Get(i).As<Napi::Object>()));
1316
- }
1317
- }
1318
- // Operators
1319
- baton->flatten = sharp::AttrAsBool(options, "flatten");
1320
- baton->flattenBackground = sharp::AttrAsVectorOfDouble(options, "flattenBackground");
1321
- baton->negate = sharp::AttrAsBool(options, "negate");
1322
- baton->blurSigma = sharp::AttrAsDouble(options, "blurSigma");
1323
- baton->brightness = sharp::AttrAsDouble(options, "brightness");
1324
- baton->saturation = sharp::AttrAsDouble(options, "saturation");
1325
- baton->hue = sharp::AttrAsInt32(options, "hue");
1326
- baton->medianSize = sharp::AttrAsUint32(options, "medianSize");
1327
- baton->sharpenSigma = sharp::AttrAsDouble(options, "sharpenSigma");
1328
- baton->sharpenFlat = sharp::AttrAsDouble(options, "sharpenFlat");
1329
- baton->sharpenJagged = sharp::AttrAsDouble(options, "sharpenJagged");
1330
- baton->threshold = sharp::AttrAsInt32(options, "threshold");
1331
- baton->thresholdGrayscale = sharp::AttrAsBool(options, "thresholdGrayscale");
1332
- baton->trimThreshold = sharp::AttrAsDouble(options, "trimThreshold");
1333
- baton->gamma = sharp::AttrAsDouble(options, "gamma");
1334
- baton->gammaOut = sharp::AttrAsDouble(options, "gammaOut");
1335
- baton->linearA = sharp::AttrAsDouble(options, "linearA");
1336
- baton->linearB = sharp::AttrAsDouble(options, "linearB");
1337
- baton->greyscale = sharp::AttrAsBool(options, "greyscale");
1338
- baton->normalise = sharp::AttrAsBool(options, "normalise");
1339
- baton->claheWidth = sharp::AttrAsUint32(options, "claheWidth");
1340
- baton->claheHeight = sharp::AttrAsUint32(options, "claheHeight");
1341
- baton->claheMaxSlope = sharp::AttrAsUint32(options, "claheMaxSlope");
1342
- baton->useExifOrientation = sharp::AttrAsBool(options, "useExifOrientation");
1343
- baton->angle = sharp::AttrAsInt32(options, "angle");
1344
- baton->rotationAngle = sharp::AttrAsDouble(options, "rotationAngle");
1345
- baton->rotationBackground = sharp::AttrAsVectorOfDouble(options, "rotationBackground");
1346
- baton->rotateBeforePreExtract = sharp::AttrAsBool(options, "rotateBeforePreExtract");
1347
- baton->flip = sharp::AttrAsBool(options, "flip");
1348
- baton->flop = sharp::AttrAsBool(options, "flop");
1349
- baton->extendTop = sharp::AttrAsInt32(options, "extendTop");
1350
- baton->extendBottom = sharp::AttrAsInt32(options, "extendBottom");
1351
- baton->extendLeft = sharp::AttrAsInt32(options, "extendLeft");
1352
- baton->extendRight = sharp::AttrAsInt32(options, "extendRight");
1353
- baton->extendBackground = sharp::AttrAsVectorOfDouble(options, "extendBackground");
1354
- baton->extractChannel = sharp::AttrAsInt32(options, "extractChannel");
1355
- baton->affineMatrix = sharp::AttrAsVectorOfDouble(options, "affineMatrix");
1356
- baton->affineBackground = sharp::AttrAsVectorOfDouble(options, "affineBackground");
1357
- baton->affineIdx = sharp::AttrAsDouble(options, "affineIdx");
1358
- baton->affineIdy = sharp::AttrAsDouble(options, "affineIdy");
1359
- baton->affineOdx = sharp::AttrAsDouble(options, "affineOdx");
1360
- baton->affineOdy = sharp::AttrAsDouble(options, "affineOdy");
1361
- baton->affineInterpolator = vips::VInterpolate::new_from_name(sharp::AttrAsStr(options, "affineInterpolator").data());
1362
-
1363
- baton->removeAlpha = sharp::AttrAsBool(options, "removeAlpha");
1364
- baton->ensureAlpha = sharp::AttrAsDouble(options, "ensureAlpha");
1365
- if (options.Has("boolean")) {
1366
- baton->boolean = sharp::CreateInputDescriptor(options.Get("boolean").As<Napi::Object>());
1367
- baton->booleanOp = sharp::GetBooleanOperation(sharp::AttrAsStr(options, "booleanOp"));
1368
- }
1369
- if (options.Has("bandBoolOp")) {
1370
- baton->bandBoolOp = sharp::GetBooleanOperation(sharp::AttrAsStr(options, "bandBoolOp"));
1371
- }
1372
- if (options.Has("convKernel")) {
1373
- Napi::Object kernel = options.Get("convKernel").As<Napi::Object>();
1374
- baton->convKernelWidth = sharp::AttrAsUint32(kernel, "width");
1375
- baton->convKernelHeight = sharp::AttrAsUint32(kernel, "height");
1376
- baton->convKernelScale = sharp::AttrAsDouble(kernel, "scale");
1377
- baton->convKernelOffset = sharp::AttrAsDouble(kernel, "offset");
1378
- size_t const kernelSize = static_cast<size_t>(baton->convKernelWidth * baton->convKernelHeight);
1379
- baton->convKernel = std::unique_ptr<double[]>(new double[kernelSize]);
1380
- Napi::Array kdata = kernel.Get("kernel").As<Napi::Array>();
1381
- for (unsigned int i = 0; i < kernelSize; i++) {
1382
- baton->convKernel[i] = sharp::AttrAsDouble(kdata, i);
1383
- }
1384
- }
1385
- if (options.Has("recombMatrix")) {
1386
- baton->recombMatrix = std::unique_ptr<double[]>(new double[9]);
1387
- Napi::Array recombMatrix = options.Get("recombMatrix").As<Napi::Array>();
1388
- for (unsigned int i = 0; i < 9; i++) {
1389
- baton->recombMatrix[i] = sharp::AttrAsDouble(recombMatrix, i);
1390
- }
1391
- }
1392
- baton->colourspace = sharp::GetInterpretation(sharp::AttrAsStr(options, "colourspace"));
1393
- if (baton->colourspace == VIPS_INTERPRETATION_ERROR) {
1394
- baton->colourspace = VIPS_INTERPRETATION_sRGB;
1395
- }
1396
- // Output
1397
- baton->formatOut = sharp::AttrAsStr(options, "formatOut");
1398
- baton->fileOut = sharp::AttrAsStr(options, "fileOut");
1399
- baton->withMetadata = sharp::AttrAsBool(options, "withMetadata");
1400
- baton->withMetadataOrientation = sharp::AttrAsUint32(options, "withMetadataOrientation");
1401
- baton->withMetadataDensity = sharp::AttrAsDouble(options, "withMetadataDensity");
1402
- baton->withMetadataIcc = sharp::AttrAsStr(options, "withMetadataIcc");
1403
- Napi::Object mdStrs = options.Get("withMetadataStrs").As<Napi::Object>();
1404
- Napi::Array mdStrKeys = mdStrs.GetPropertyNames();
1405
- for (unsigned int i = 0; i < mdStrKeys.Length(); i++) {
1406
- std::string k = sharp::AttrAsStr(mdStrKeys, i);
1407
- baton->withMetadataStrs.insert(std::make_pair(k, sharp::AttrAsStr(mdStrs, k)));
1408
- }
1409
- // Format-specific
1410
- baton->jpegQuality = sharp::AttrAsUint32(options, "jpegQuality");
1411
- baton->jpegProgressive = sharp::AttrAsBool(options, "jpegProgressive");
1412
- baton->jpegChromaSubsampling = sharp::AttrAsStr(options, "jpegChromaSubsampling");
1413
- baton->jpegTrellisQuantisation = sharp::AttrAsBool(options, "jpegTrellisQuantisation");
1414
- baton->jpegQuantisationTable = sharp::AttrAsUint32(options, "jpegQuantisationTable");
1415
- baton->jpegOvershootDeringing = sharp::AttrAsBool(options, "jpegOvershootDeringing");
1416
- baton->jpegOptimiseScans = sharp::AttrAsBool(options, "jpegOptimiseScans");
1417
- baton->jpegOptimiseCoding = sharp::AttrAsBool(options, "jpegOptimiseCoding");
1418
- baton->pngProgressive = sharp::AttrAsBool(options, "pngProgressive");
1419
- baton->pngCompressionLevel = sharp::AttrAsUint32(options, "pngCompressionLevel");
1420
- baton->pngAdaptiveFiltering = sharp::AttrAsBool(options, "pngAdaptiveFiltering");
1421
- baton->pngPalette = sharp::AttrAsBool(options, "pngPalette");
1422
- baton->pngQuality = sharp::AttrAsUint32(options, "pngQuality");
1423
- baton->pngColours = sharp::AttrAsUint32(options, "pngColours");
1424
- baton->pngDither = sharp::AttrAsDouble(options, "pngDither");
1425
- baton->webpQuality = sharp::AttrAsUint32(options, "webpQuality");
1426
- baton->webpAlphaQuality = sharp::AttrAsUint32(options, "webpAlphaQuality");
1427
- baton->webpLossless = sharp::AttrAsBool(options, "webpLossless");
1428
- baton->webpNearLossless = sharp::AttrAsBool(options, "webpNearLossless");
1429
- baton->webpSmartSubsample = sharp::AttrAsBool(options, "webpSmartSubsample");
1430
- baton->webpReductionEffort = sharp::AttrAsUint32(options, "webpReductionEffort");
1431
- baton->tiffQuality = sharp::AttrAsUint32(options, "tiffQuality");
1432
- baton->tiffPyramid = sharp::AttrAsBool(options, "tiffPyramid");
1433
- baton->tiffBitdepth = sharp::AttrAsUint32(options, "tiffBitdepth");
1434
- baton->tiffTile = sharp::AttrAsBool(options, "tiffTile");
1435
- baton->tiffTileWidth = sharp::AttrAsUint32(options, "tiffTileWidth");
1436
- baton->tiffTileHeight = sharp::AttrAsUint32(options, "tiffTileHeight");
1437
- baton->tiffXres = sharp::AttrAsDouble(options, "tiffXres");
1438
- baton->tiffYres = sharp::AttrAsDouble(options, "tiffYres");
1439
- // tiff compression options
1440
- baton->tiffCompression = static_cast<VipsForeignTiffCompression>(
1441
- vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_TIFF_COMPRESSION,
1442
- sharp::AttrAsStr(options, "tiffCompression").data()));
1443
- baton->tiffPredictor = static_cast<VipsForeignTiffPredictor>(
1444
- vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_TIFF_PREDICTOR,
1445
- sharp::AttrAsStr(options, "tiffPredictor").data()));
1446
- baton->heifQuality = sharp::AttrAsUint32(options, "heifQuality");
1447
- baton->heifLossless = sharp::AttrAsBool(options, "heifLossless");
1448
- baton->heifCompression = static_cast<VipsForeignHeifCompression>(
1449
- vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_HEIF_COMPRESSION,
1450
- sharp::AttrAsStr(options, "heifCompression").data()));
1451
- baton->heifSpeed = sharp::AttrAsUint32(options, "heifSpeed");
1452
- baton->heifChromaSubsampling = sharp::AttrAsStr(options, "heifChromaSubsampling");
1453
-
1454
- // Animated output
1455
- if (sharp::HasAttr(options, "pageHeight")) {
1456
- baton->pageHeight = sharp::AttrAsUint32(options, "pageHeight");
1457
- }
1458
- if (sharp::HasAttr(options, "loop")) {
1459
- baton->loop = sharp::AttrAsUint32(options, "loop");
1460
- }
1461
- if (sharp::HasAttr(options, "delay")) {
1462
- baton->delay = sharp::AttrAsInt32Vector(options, "delay");
1463
- }
1464
-
1465
- // Tile output
1466
- baton->tileSize = sharp::AttrAsUint32(options, "tileSize");
1467
- baton->tileOverlap = sharp::AttrAsUint32(options, "tileOverlap");
1468
- baton->tileAngle = sharp::AttrAsInt32(options, "tileAngle");
1469
- baton->tileBackground = sharp::AttrAsVectorOfDouble(options, "tileBackground");
1470
- baton->tileSkipBlanks = sharp::AttrAsInt32(options, "tileSkipBlanks");
1471
- baton->tileContainer = static_cast<VipsForeignDzContainer>(
1472
- vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_DZ_CONTAINER,
1473
- sharp::AttrAsStr(options, "tileContainer").data()));
1474
- baton->tileLayout = static_cast<VipsForeignDzLayout>(
1475
- vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_DZ_LAYOUT,
1476
- sharp::AttrAsStr(options, "tileLayout").data()));
1477
- baton->tileFormat = sharp::AttrAsStr(options, "tileFormat");
1478
- baton->tileDepth = static_cast<VipsForeignDzDepth>(
1479
- vips_enum_from_nick(nullptr, VIPS_TYPE_FOREIGN_DZ_DEPTH,
1480
- sharp::AttrAsStr(options, "tileDepth").data()));
1481
- baton->tileCentre = sharp::AttrAsBool(options, "tileCentre");
1482
- baton->tileId = sharp::AttrAsStr(options, "tileId");
1483
-
1484
- // Force random access for certain operations
1485
- if (baton->input->access == VIPS_ACCESS_SEQUENTIAL) {
1486
- if (
1487
- baton->trimThreshold > 0.0 ||
1488
- baton->normalise ||
1489
- baton->position == 16 || baton->position == 17 ||
1490
- baton->angle % 360 != 0 ||
1491
- fmod(baton->rotationAngle, 360.0) != 0.0 ||
1492
- baton->useExifOrientation
1493
- ) {
1494
- baton->input->access = VIPS_ACCESS_RANDOM;
1495
- }
1496
- }
1497
-
1498
- // Function to notify of libvips warnings
1499
- Napi::Function debuglog = options.Get("debuglog").As<Napi::Function>();
1500
-
1501
- // Function to notify of queue length changes
1502
- Napi::Function queueListener = options.Get("queueListener").As<Napi::Function>();
1503
-
1504
- // Join queue for worker thread
1505
- Napi::Function callback = info[1].As<Napi::Function>();
1506
- PipelineWorker *worker = new PipelineWorker(callback, baton, debuglog, queueListener);
1507
- worker->Receiver().Set("options", options);
1508
- worker->Queue();
1509
-
1510
- // Increment queued task counter
1511
- g_atomic_int_inc(&sharp::counterQueue);
1512
- Napi::Number queueLength = Napi::Number::New(info.Env(), static_cast<double>(sharp::counterQueue));
1513
- queueListener.Call(info.This(), { queueLength });
1514
-
1515
- return info.Env().Undefined();
1516
- }