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