@basemaps/lambda-tiler 6.20.0 → 6.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (618) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/build/__test__/tile.set.cache.test.js +4 -10
  3. package/build/cli/validate.js +2 -1
  4. package/build/index.d.ts.map +1 -1
  5. package/build/index.js +8 -1
  6. package/build/routes/__test__/attribution.test.js +3 -13
  7. package/build/routes/attribution.d.ts.map +1 -1
  8. package/build/routes/attribution.js +7 -20
  9. package/build/routes/tile.wmts.js +2 -2
  10. package/build/source.tracer.d.ts +17 -0
  11. package/build/source.tracer.d.ts.map +1 -0
  12. package/build/source.tracer.js +22 -0
  13. package/build/tile.set.cache.js +3 -3
  14. package/build/tile.set.d.ts +0 -16
  15. package/build/tile.set.d.ts.map +1 -1
  16. package/build/tile.set.js +1 -20
  17. package/build/tile.set.raster.d.ts +7 -4
  18. package/build/tile.set.raster.d.ts.map +1 -1
  19. package/build/tile.set.raster.js +14 -5
  20. package/build/tile.set.vector.d.ts +10 -4
  21. package/build/tile.set.vector.d.ts.map +1 -1
  22. package/build/tile.set.vector.js +17 -7
  23. package/bundle.sh +2 -2
  24. package/package.json +11 -11
  25. package/scripts/create.deployment.package.mjs +34 -0
  26. package/src/__test__/tile.set.cache.test.ts +4 -12
  27. package/src/cli/validate.ts +2 -1
  28. package/src/index.ts +11 -1
  29. package/src/routes/__test__/attribution.test.ts +3 -13
  30. package/src/routes/attribution.ts +6 -17
  31. package/src/routes/tile.wmts.ts +2 -2
  32. package/src/source.tracer.ts +34 -0
  33. package/src/tile.set.cache.ts +3 -3
  34. package/src/tile.set.raster.ts +28 -6
  35. package/src/tile.set.ts +0 -40
  36. package/src/tile.set.vector.ts +25 -6
  37. package/tsconfig.tsbuildinfo +1 -1
  38. package/dist/index.js +0 -30702
  39. package/dist/node_modules/ansi-regex/index.js +0 -4
  40. package/dist/node_modules/ansi-regex/license +0 -21
  41. package/dist/node_modules/ansi-regex/package.json +0 -108
  42. package/dist/node_modules/ansi-regex/readme.md +0 -39
  43. package/dist/node_modules/aproba/LICENSE +0 -14
  44. package/dist/node_modules/aproba/README.md +0 -94
  45. package/dist/node_modules/aproba/index.js +0 -105
  46. package/dist/node_modules/aproba/package.json +0 -62
  47. package/dist/node_modules/are-we-there-yet/CHANGES.md +0 -37
  48. package/dist/node_modules/are-we-there-yet/LICENSE +0 -5
  49. package/dist/node_modules/are-we-there-yet/README.md +0 -195
  50. package/dist/node_modules/are-we-there-yet/index.js +0 -4
  51. package/dist/node_modules/are-we-there-yet/package.json +0 -63
  52. package/dist/node_modules/are-we-there-yet/tracker-base.js +0 -11
  53. package/dist/node_modules/are-we-there-yet/tracker-group.js +0 -107
  54. package/dist/node_modules/are-we-there-yet/tracker-stream.js +0 -36
  55. package/dist/node_modules/are-we-there-yet/tracker.js +0 -30
  56. package/dist/node_modules/base64-js/LICENSE +0 -21
  57. package/dist/node_modules/base64-js/README.md +0 -34
  58. package/dist/node_modules/base64-js/base64js.min.js +0 -1
  59. package/dist/node_modules/base64-js/index.d.ts +0 -3
  60. package/dist/node_modules/base64-js/index.js +0 -150
  61. package/dist/node_modules/base64-js/package.json +0 -75
  62. package/dist/node_modules/bl/.travis.yml +0 -17
  63. package/dist/node_modules/bl/BufferList.js +0 -396
  64. package/dist/node_modules/bl/LICENSE.md +0 -13
  65. package/dist/node_modules/bl/README.md +0 -247
  66. package/dist/node_modules/bl/bl.js +0 -84
  67. package/dist/node_modules/bl/node_modules/readable-stream/CONTRIBUTING.md +0 -38
  68. package/dist/node_modules/bl/node_modules/readable-stream/GOVERNANCE.md +0 -136
  69. package/dist/node_modules/bl/node_modules/readable-stream/LICENSE +0 -47
  70. package/dist/node_modules/bl/node_modules/readable-stream/README.md +0 -106
  71. package/dist/node_modules/bl/node_modules/readable-stream/errors-browser.js +0 -127
  72. package/dist/node_modules/bl/node_modules/readable-stream/errors.js +0 -116
  73. package/dist/node_modules/bl/node_modules/readable-stream/experimentalWarning.js +0 -17
  74. package/dist/node_modules/bl/node_modules/readable-stream/lib/_stream_duplex.js +0 -139
  75. package/dist/node_modules/bl/node_modules/readable-stream/lib/_stream_passthrough.js +0 -39
  76. package/dist/node_modules/bl/node_modules/readable-stream/lib/_stream_readable.js +0 -1124
  77. package/dist/node_modules/bl/node_modules/readable-stream/lib/_stream_transform.js +0 -201
  78. package/dist/node_modules/bl/node_modules/readable-stream/lib/_stream_writable.js +0 -697
  79. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/async_iterator.js +0 -207
  80. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/buffer_list.js +0 -210
  81. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -105
  82. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +0 -104
  83. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/from-browser.js +0 -3
  84. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/from.js +0 -64
  85. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/pipeline.js +0 -97
  86. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/state.js +0 -27
  87. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
  88. package/dist/node_modules/bl/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
  89. package/dist/node_modules/bl/node_modules/readable-stream/package.json +0 -97
  90. package/dist/node_modules/bl/node_modules/readable-stream/readable-browser.js +0 -9
  91. package/dist/node_modules/bl/node_modules/readable-stream/readable.js +0 -16
  92. package/dist/node_modules/bl/package.json +0 -69
  93. package/dist/node_modules/bl/test/convert.js +0 -21
  94. package/dist/node_modules/bl/test/indexOf.js +0 -492
  95. package/dist/node_modules/bl/test/isBufferList.js +0 -32
  96. package/dist/node_modules/bl/test/test.js +0 -869
  97. package/dist/node_modules/buffer/AUTHORS.md +0 -70
  98. package/dist/node_modules/buffer/LICENSE +0 -21
  99. package/dist/node_modules/buffer/README.md +0 -410
  100. package/dist/node_modules/buffer/index.d.ts +0 -186
  101. package/dist/node_modules/buffer/index.js +0 -1817
  102. package/dist/node_modules/buffer/package.json +0 -127
  103. package/dist/node_modules/chownr/LICENSE +0 -15
  104. package/dist/node_modules/chownr/README.md +0 -3
  105. package/dist/node_modules/chownr/chownr.js +0 -167
  106. package/dist/node_modules/chownr/package.json +0 -62
  107. package/dist/node_modules/code-point-at/index.js +0 -32
  108. package/dist/node_modules/code-point-at/license +0 -21
  109. package/dist/node_modules/code-point-at/package.json +0 -70
  110. package/dist/node_modules/code-point-at/readme.md +0 -32
  111. package/dist/node_modules/color/LICENSE +0 -21
  112. package/dist/node_modules/color/README.md +0 -123
  113. package/dist/node_modules/color/index.js +0 -497
  114. package/dist/node_modules/color/package.json +0 -74
  115. package/dist/node_modules/color-convert/CHANGELOG.md +0 -54
  116. package/dist/node_modules/color-convert/LICENSE +0 -21
  117. package/dist/node_modules/color-convert/README.md +0 -68
  118. package/dist/node_modules/color-convert/conversions.js +0 -839
  119. package/dist/node_modules/color-convert/index.js +0 -81
  120. package/dist/node_modules/color-convert/package.json +0 -83
  121. package/dist/node_modules/color-convert/route.js +0 -97
  122. package/dist/node_modules/color-name/LICENSE +0 -8
  123. package/dist/node_modules/color-name/README.md +0 -11
  124. package/dist/node_modules/color-name/index.js +0 -152
  125. package/dist/node_modules/color-name/package.json +0 -57
  126. package/dist/node_modules/color-string/LICENSE +0 -21
  127. package/dist/node_modules/color-string/README.md +0 -62
  128. package/dist/node_modules/color-string/index.js +0 -242
  129. package/dist/node_modules/color-string/package.json +0 -81
  130. package/dist/node_modules/console-control-strings/LICENSE +0 -13
  131. package/dist/node_modules/console-control-strings/README.md +0 -145
  132. package/dist/node_modules/console-control-strings/README.md~ +0 -140
  133. package/dist/node_modules/console-control-strings/index.js +0 -125
  134. package/dist/node_modules/console-control-strings/package.json +0 -61
  135. package/dist/node_modules/core-util-is/LICENSE +0 -19
  136. package/dist/node_modules/core-util-is/README.md +0 -3
  137. package/dist/node_modules/core-util-is/lib/util.js +0 -107
  138. package/dist/node_modules/core-util-is/package.json +0 -68
  139. package/dist/node_modules/decompress-response/index.d.ts +0 -22
  140. package/dist/node_modules/decompress-response/index.js +0 -58
  141. package/dist/node_modules/decompress-response/license +0 -9
  142. package/dist/node_modules/decompress-response/package.json +0 -88
  143. package/dist/node_modules/decompress-response/readme.md +0 -48
  144. package/dist/node_modules/deep-extend/CHANGELOG.md +0 -46
  145. package/dist/node_modules/deep-extend/LICENSE +0 -20
  146. package/dist/node_modules/deep-extend/README.md +0 -91
  147. package/dist/node_modules/deep-extend/index.js +0 -1
  148. package/dist/node_modules/deep-extend/lib/deep-extend.js +0 -150
  149. package/dist/node_modules/deep-extend/package.json +0 -92
  150. package/dist/node_modules/delegates/History.md +0 -22
  151. package/dist/node_modules/delegates/License +0 -20
  152. package/dist/node_modules/delegates/Makefile +0 -8
  153. package/dist/node_modules/delegates/Readme.md +0 -94
  154. package/dist/node_modules/delegates/index.js +0 -121
  155. package/dist/node_modules/delegates/package.json +0 -48
  156. package/dist/node_modules/delegates/test/index.js +0 -94
  157. package/dist/node_modules/detect-libc/LICENSE +0 -201
  158. package/dist/node_modules/detect-libc/README.md +0 -78
  159. package/dist/node_modules/detect-libc/bin/detect-libc.js +0 -18
  160. package/dist/node_modules/detect-libc/lib/detect-libc.js +0 -92
  161. package/dist/node_modules/detect-libc/package.json +0 -70
  162. package/dist/node_modules/end-of-stream/LICENSE +0 -21
  163. package/dist/node_modules/end-of-stream/README.md +0 -54
  164. package/dist/node_modules/end-of-stream/index.js +0 -94
  165. package/dist/node_modules/end-of-stream/package.json +0 -66
  166. package/dist/node_modules/expand-template/.travis.yml +0 -6
  167. package/dist/node_modules/expand-template/LICENSE +0 -21
  168. package/dist/node_modules/expand-template/README.md +0 -43
  169. package/dist/node_modules/expand-template/index.js +0 -26
  170. package/dist/node_modules/expand-template/package.json +0 -60
  171. package/dist/node_modules/expand-template/test.js +0 -67
  172. package/dist/node_modules/fs-constants/LICENSE +0 -21
  173. package/dist/node_modules/fs-constants/README.md +0 -26
  174. package/dist/node_modules/fs-constants/browser.js +0 -1
  175. package/dist/node_modules/fs-constants/index.js +0 -1
  176. package/dist/node_modules/fs-constants/package.json +0 -47
  177. package/dist/node_modules/gauge/CHANGELOG.md +0 -160
  178. package/dist/node_modules/gauge/LICENSE +0 -13
  179. package/dist/node_modules/gauge/README.md +0 -399
  180. package/dist/node_modules/gauge/base-theme.js +0 -14
  181. package/dist/node_modules/gauge/error.js +0 -24
  182. package/dist/node_modules/gauge/has-color.js +0 -12
  183. package/dist/node_modules/gauge/index.js +0 -233
  184. package/dist/node_modules/gauge/package.json +0 -91
  185. package/dist/node_modules/gauge/plumbing.js +0 -48
  186. package/dist/node_modules/gauge/process.js +0 -3
  187. package/dist/node_modules/gauge/progress-bar.js +0 -35
  188. package/dist/node_modules/gauge/render-template.js +0 -181
  189. package/dist/node_modules/gauge/set-immediate.js +0 -7
  190. package/dist/node_modules/gauge/set-interval.js +0 -3
  191. package/dist/node_modules/gauge/spin.js +0 -5
  192. package/dist/node_modules/gauge/template-item.js +0 -73
  193. package/dist/node_modules/gauge/theme-set.js +0 -115
  194. package/dist/node_modules/gauge/themes.js +0 -54
  195. package/dist/node_modules/gauge/wide-truncate.js +0 -25
  196. package/dist/node_modules/github-from-package/.travis.yml +0 -4
  197. package/dist/node_modules/github-from-package/LICENSE +0 -18
  198. package/dist/node_modules/github-from-package/example/package.json +0 -8
  199. package/dist/node_modules/github-from-package/example/url.js +0 -3
  200. package/dist/node_modules/github-from-package/index.js +0 -17
  201. package/dist/node_modules/github-from-package/package.json +0 -58
  202. package/dist/node_modules/github-from-package/readme.markdown +0 -53
  203. package/dist/node_modules/github-from-package/test/a.json +0 -8
  204. package/dist/node_modules/github-from-package/test/b.json +0 -5
  205. package/dist/node_modules/github-from-package/test/c.json +0 -5
  206. package/dist/node_modules/github-from-package/test/d.json +0 -7
  207. package/dist/node_modules/github-from-package/test/e.json +0 -5
  208. package/dist/node_modules/github-from-package/test/url.js +0 -19
  209. package/dist/node_modules/has-unicode/LICENSE +0 -14
  210. package/dist/node_modules/has-unicode/README.md +0 -43
  211. package/dist/node_modules/has-unicode/index.js +0 -16
  212. package/dist/node_modules/has-unicode/package.json +0 -58
  213. package/dist/node_modules/ieee754/LICENSE +0 -11
  214. package/dist/node_modules/ieee754/README.md +0 -51
  215. package/dist/node_modules/ieee754/index.d.ts +0 -10
  216. package/dist/node_modules/ieee754/index.js +0 -85
  217. package/dist/node_modules/ieee754/package.json +0 -84
  218. package/dist/node_modules/inherits/LICENSE +0 -16
  219. package/dist/node_modules/inherits/README.md +0 -42
  220. package/dist/node_modules/inherits/inherits.js +0 -9
  221. package/dist/node_modules/inherits/inherits_browser.js +0 -27
  222. package/dist/node_modules/inherits/package.json +0 -65
  223. package/dist/node_modules/ini/LICENSE +0 -15
  224. package/dist/node_modules/ini/README.md +0 -102
  225. package/dist/node_modules/ini/ini.js +0 -206
  226. package/dist/node_modules/ini/package.json +0 -66
  227. package/dist/node_modules/is-arrayish/LICENSE +0 -21
  228. package/dist/node_modules/is-arrayish/README.md +0 -16
  229. package/dist/node_modules/is-arrayish/index.js +0 -9
  230. package/dist/node_modules/is-arrayish/package.json +0 -77
  231. package/dist/node_modules/is-arrayish/yarn-error.log +0 -1443
  232. package/dist/node_modules/is-fullwidth-code-point/index.js +0 -46
  233. package/dist/node_modules/is-fullwidth-code-point/license +0 -21
  234. package/dist/node_modules/is-fullwidth-code-point/package.json +0 -77
  235. package/dist/node_modules/is-fullwidth-code-point/readme.md +0 -39
  236. package/dist/node_modules/isarray/.travis.yml +0 -4
  237. package/dist/node_modules/isarray/Makefile +0 -6
  238. package/dist/node_modules/isarray/README.md +0 -60
  239. package/dist/node_modules/isarray/component.json +0 -19
  240. package/dist/node_modules/isarray/index.js +0 -5
  241. package/dist/node_modules/isarray/package.json +0 -73
  242. package/dist/node_modules/isarray/test.js +0 -20
  243. package/dist/node_modules/lru-cache/LICENSE +0 -15
  244. package/dist/node_modules/lru-cache/README.md +0 -166
  245. package/dist/node_modules/lru-cache/index.js +0 -334
  246. package/dist/node_modules/lru-cache/package.json +0 -69
  247. package/dist/node_modules/mimic-response/index.d.ts +0 -17
  248. package/dist/node_modules/mimic-response/index.js +0 -77
  249. package/dist/node_modules/mimic-response/license +0 -9
  250. package/dist/node_modules/mimic-response/package.json +0 -74
  251. package/dist/node_modules/mimic-response/readme.md +0 -78
  252. package/dist/node_modules/minimist/.travis.yml +0 -8
  253. package/dist/node_modules/minimist/LICENSE +0 -18
  254. package/dist/node_modules/minimist/example/parse.js +0 -2
  255. package/dist/node_modules/minimist/index.js +0 -245
  256. package/dist/node_modules/minimist/package.json +0 -74
  257. package/dist/node_modules/minimist/readme.markdown +0 -95
  258. package/dist/node_modules/minimist/test/all_bool.js +0 -32
  259. package/dist/node_modules/minimist/test/bool.js +0 -178
  260. package/dist/node_modules/minimist/test/dash.js +0 -31
  261. package/dist/node_modules/minimist/test/default_bool.js +0 -35
  262. package/dist/node_modules/minimist/test/dotted.js +0 -22
  263. package/dist/node_modules/minimist/test/kv_short.js +0 -16
  264. package/dist/node_modules/minimist/test/long.js +0 -31
  265. package/dist/node_modules/minimist/test/num.js +0 -36
  266. package/dist/node_modules/minimist/test/parse.js +0 -197
  267. package/dist/node_modules/minimist/test/parse_modified.js +0 -9
  268. package/dist/node_modules/minimist/test/proto.js +0 -44
  269. package/dist/node_modules/minimist/test/short.js +0 -67
  270. package/dist/node_modules/minimist/test/stop_early.js +0 -15
  271. package/dist/node_modules/minimist/test/unknown.js +0 -102
  272. package/dist/node_modules/minimist/test/whitespace.js +0 -8
  273. package/dist/node_modules/mkdirp-classic/LICENSE +0 -21
  274. package/dist/node_modules/mkdirp-classic/README.md +0 -18
  275. package/dist/node_modules/mkdirp-classic/index.js +0 -98
  276. package/dist/node_modules/mkdirp-classic/package.json +0 -47
  277. package/dist/node_modules/napi-build-utils/LICENSE +0 -21
  278. package/dist/node_modules/napi-build-utils/README.md +0 -48
  279. package/dist/node_modules/napi-build-utils/index.js +0 -213
  280. package/dist/node_modules/napi-build-utils/index.md +0 -81
  281. package/dist/node_modules/napi-build-utils/package.json +0 -68
  282. package/dist/node_modules/node-abi/.circleci/config.yml +0 -63
  283. package/dist/node_modules/node-abi/.github/workflows/update-abi.yml +0 -41
  284. package/dist/node_modules/node-abi/.releaserc.json +0 -9
  285. package/dist/node_modules/node-abi/CODE_OF_CONDUCT.md +0 -73
  286. package/dist/node_modules/node-abi/CONTRIBUTING.md +0 -53
  287. package/dist/node_modules/node-abi/LICENSE +0 -21
  288. package/dist/node_modules/node-abi/README.md +0 -50
  289. package/dist/node_modules/node-abi/abi_registry.json +0 -179
  290. package/dist/node_modules/node-abi/index.js +0 -179
  291. package/dist/node_modules/node-abi/package.json +0 -66
  292. package/dist/node_modules/node-abi/scripts/update-abi-registry.js +0 -119
  293. package/dist/node_modules/node-abi/test/index.js +0 -166
  294. package/dist/node_modules/node-addon-api/LICENSE.md +0 -13
  295. package/dist/node_modules/node-addon-api/README.md +0 -293
  296. package/dist/node_modules/node-addon-api/common.gypi +0 -21
  297. package/dist/node_modules/node-addon-api/except.gypi +0 -25
  298. package/dist/node_modules/node-addon-api/index.js +0 -11
  299. package/dist/node_modules/node-addon-api/napi-inl.deprecated.h +0 -192
  300. package/dist/node_modules/node-addon-api/napi-inl.h +0 -6209
  301. package/dist/node_modules/node-addon-api/napi.h +0 -2983
  302. package/dist/node_modules/node-addon-api/node_api.gyp +0 -9
  303. package/dist/node_modules/node-addon-api/noexcept.gypi +0 -26
  304. package/dist/node_modules/node-addon-api/nothing.c +0 -0
  305. package/dist/node_modules/node-addon-api/package-support.json +0 -21
  306. package/dist/node_modules/node-addon-api/package.json +0 -422
  307. package/dist/node_modules/node-addon-api/tools/README.md +0 -73
  308. package/dist/node_modules/node-addon-api/tools/check-napi.js +0 -100
  309. package/dist/node_modules/node-addon-api/tools/clang-format.js +0 -68
  310. package/dist/node_modules/node-addon-api/tools/conversion.js +0 -309
  311. package/dist/node_modules/node-addon-api/tools/eslint-format.js +0 -71
  312. package/dist/node_modules/npmlog/CHANGELOG.md +0 -49
  313. package/dist/node_modules/npmlog/LICENSE +0 -15
  314. package/dist/node_modules/npmlog/README.md +0 -216
  315. package/dist/node_modules/npmlog/log.js +0 -309
  316. package/dist/node_modules/npmlog/package.json +0 -61
  317. package/dist/node_modules/number-is-nan/index.js +0 -4
  318. package/dist/node_modules/number-is-nan/license +0 -21
  319. package/dist/node_modules/number-is-nan/package.json +0 -67
  320. package/dist/node_modules/number-is-nan/readme.md +0 -28
  321. package/dist/node_modules/object-assign/index.js +0 -90
  322. package/dist/node_modules/object-assign/license +0 -21
  323. package/dist/node_modules/object-assign/package.json +0 -74
  324. package/dist/node_modules/object-assign/readme.md +0 -61
  325. package/dist/node_modules/once/LICENSE +0 -15
  326. package/dist/node_modules/once/README.md +0 -79
  327. package/dist/node_modules/once/once.js +0 -42
  328. package/dist/node_modules/once/package.json +0 -68
  329. package/dist/node_modules/prebuild-install/CHANGELOG.md +0 -98
  330. package/dist/node_modules/prebuild-install/CONTRIBUTING.md +0 -6
  331. package/dist/node_modules/prebuild-install/LICENSE +0 -21
  332. package/dist/node_modules/prebuild-install/README.md +0 -159
  333. package/dist/node_modules/prebuild-install/asset.js +0 -44
  334. package/dist/node_modules/prebuild-install/bin.js +0 -78
  335. package/dist/node_modules/prebuild-install/download.js +0 -142
  336. package/dist/node_modules/prebuild-install/error.js +0 -14
  337. package/dist/node_modules/prebuild-install/help.txt +0 -16
  338. package/dist/node_modules/prebuild-install/index.js +0 -1
  339. package/dist/node_modules/prebuild-install/log.js +0 -25
  340. package/dist/node_modules/prebuild-install/node_modules/detect-libc/LICENSE +0 -201
  341. package/dist/node_modules/prebuild-install/node_modules/detect-libc/README.md +0 -160
  342. package/dist/node_modules/prebuild-install/node_modules/detect-libc/index.d.ts +0 -11
  343. package/dist/node_modules/prebuild-install/node_modules/detect-libc/lib/detect-libc.js +0 -178
  344. package/dist/node_modules/prebuild-install/node_modules/detect-libc/lib/process.js +0 -16
  345. package/dist/node_modules/prebuild-install/node_modules/detect-libc/package.json +0 -71
  346. package/dist/node_modules/prebuild-install/package.json +0 -126
  347. package/dist/node_modules/prebuild-install/proxy.js +0 -35
  348. package/dist/node_modules/prebuild-install/rc.js +0 -60
  349. package/dist/node_modules/prebuild-install/util.js +0 -143
  350. package/dist/node_modules/process-nextick-args/index.js +0 -45
  351. package/dist/node_modules/process-nextick-args/license.md +0 -19
  352. package/dist/node_modules/process-nextick-args/package.json +0 -50
  353. package/dist/node_modules/process-nextick-args/readme.md +0 -18
  354. package/dist/node_modules/pump/.travis.yml +0 -5
  355. package/dist/node_modules/pump/LICENSE +0 -21
  356. package/dist/node_modules/pump/README.md +0 -65
  357. package/dist/node_modules/pump/index.js +0 -82
  358. package/dist/node_modules/pump/package.json +0 -60
  359. package/dist/node_modules/pump/test-browser.js +0 -66
  360. package/dist/node_modules/pump/test-node.js +0 -53
  361. package/dist/node_modules/rc/LICENSE.APACHE2 +0 -15
  362. package/dist/node_modules/rc/LICENSE.BSD +0 -26
  363. package/dist/node_modules/rc/LICENSE.MIT +0 -24
  364. package/dist/node_modules/rc/README.md +0 -227
  365. package/dist/node_modules/rc/browser.js +0 -7
  366. package/dist/node_modules/rc/cli.js +0 -4
  367. package/dist/node_modules/rc/index.js +0 -53
  368. package/dist/node_modules/rc/lib/utils.js +0 -104
  369. package/dist/node_modules/rc/package.json +0 -64
  370. package/dist/node_modules/rc/test/ini.js +0 -16
  371. package/dist/node_modules/rc/test/nested-env-vars.js +0 -50
  372. package/dist/node_modules/rc/test/test.js +0 -59
  373. package/dist/node_modules/readable-stream/.travis.yml +0 -34
  374. package/dist/node_modules/readable-stream/CONTRIBUTING.md +0 -38
  375. package/dist/node_modules/readable-stream/GOVERNANCE.md +0 -136
  376. package/dist/node_modules/readable-stream/LICENSE +0 -47
  377. package/dist/node_modules/readable-stream/README.md +0 -58
  378. package/dist/node_modules/readable-stream/doc/wg-meetings/2015-01-30.md +0 -60
  379. package/dist/node_modules/readable-stream/duplex-browser.js +0 -1
  380. package/dist/node_modules/readable-stream/duplex.js +0 -1
  381. package/dist/node_modules/readable-stream/lib/_stream_duplex.js +0 -131
  382. package/dist/node_modules/readable-stream/lib/_stream_passthrough.js +0 -47
  383. package/dist/node_modules/readable-stream/lib/_stream_readable.js +0 -1019
  384. package/dist/node_modules/readable-stream/lib/_stream_transform.js +0 -214
  385. package/dist/node_modules/readable-stream/lib/_stream_writable.js +0 -687
  386. package/dist/node_modules/readable-stream/lib/internal/streams/BufferList.js +0 -79
  387. package/dist/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -74
  388. package/dist/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
  389. package/dist/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
  390. package/dist/node_modules/readable-stream/package.json +0 -81
  391. package/dist/node_modules/readable-stream/passthrough.js +0 -1
  392. package/dist/node_modules/readable-stream/readable-browser.js +0 -7
  393. package/dist/node_modules/readable-stream/readable.js +0 -19
  394. package/dist/node_modules/readable-stream/transform.js +0 -1
  395. package/dist/node_modules/readable-stream/writable-browser.js +0 -1
  396. package/dist/node_modules/readable-stream/writable.js +0 -8
  397. package/dist/node_modules/safe-buffer/LICENSE +0 -21
  398. package/dist/node_modules/safe-buffer/README.md +0 -584
  399. package/dist/node_modules/safe-buffer/index.d.ts +0 -187
  400. package/dist/node_modules/safe-buffer/index.js +0 -62
  401. package/dist/node_modules/safe-buffer/package.json +0 -64
  402. package/dist/node_modules/semver/CHANGELOG.md +0 -111
  403. package/dist/node_modules/semver/LICENSE +0 -15
  404. package/dist/node_modules/semver/README.md +0 -566
  405. package/dist/node_modules/semver/bin/semver.js +0 -173
  406. package/dist/node_modules/semver/classes/comparator.js +0 -135
  407. package/dist/node_modules/semver/classes/index.js +0 -5
  408. package/dist/node_modules/semver/classes/range.js +0 -510
  409. package/dist/node_modules/semver/classes/semver.js +0 -287
  410. package/dist/node_modules/semver/functions/clean.js +0 -6
  411. package/dist/node_modules/semver/functions/cmp.js +0 -48
  412. package/dist/node_modules/semver/functions/coerce.js +0 -51
  413. package/dist/node_modules/semver/functions/compare-build.js +0 -7
  414. package/dist/node_modules/semver/functions/compare-loose.js +0 -3
  415. package/dist/node_modules/semver/functions/compare.js +0 -5
  416. package/dist/node_modules/semver/functions/diff.js +0 -23
  417. package/dist/node_modules/semver/functions/eq.js +0 -3
  418. package/dist/node_modules/semver/functions/gt.js +0 -3
  419. package/dist/node_modules/semver/functions/gte.js +0 -3
  420. package/dist/node_modules/semver/functions/inc.js +0 -15
  421. package/dist/node_modules/semver/functions/lt.js +0 -3
  422. package/dist/node_modules/semver/functions/lte.js +0 -3
  423. package/dist/node_modules/semver/functions/major.js +0 -3
  424. package/dist/node_modules/semver/functions/minor.js +0 -3
  425. package/dist/node_modules/semver/functions/neq.js +0 -3
  426. package/dist/node_modules/semver/functions/parse.js +0 -33
  427. package/dist/node_modules/semver/functions/patch.js +0 -3
  428. package/dist/node_modules/semver/functions/prerelease.js +0 -6
  429. package/dist/node_modules/semver/functions/rcompare.js +0 -3
  430. package/dist/node_modules/semver/functions/rsort.js +0 -3
  431. package/dist/node_modules/semver/functions/satisfies.js +0 -10
  432. package/dist/node_modules/semver/functions/sort.js +0 -3
  433. package/dist/node_modules/semver/functions/valid.js +0 -6
  434. package/dist/node_modules/semver/index.js +0 -48
  435. package/dist/node_modules/semver/internal/constants.js +0 -17
  436. package/dist/node_modules/semver/internal/debug.js +0 -9
  437. package/dist/node_modules/semver/internal/identifiers.js +0 -23
  438. package/dist/node_modules/semver/internal/parse-options.js +0 -11
  439. package/dist/node_modules/semver/internal/re.js +0 -182
  440. package/dist/node_modules/semver/package.json +0 -74
  441. package/dist/node_modules/semver/preload.js +0 -2
  442. package/dist/node_modules/semver/range.bnf +0 -16
  443. package/dist/node_modules/semver/ranges/gtr.js +0 -4
  444. package/dist/node_modules/semver/ranges/intersects.js +0 -7
  445. package/dist/node_modules/semver/ranges/ltr.js +0 -4
  446. package/dist/node_modules/semver/ranges/max-satisfying.js +0 -25
  447. package/dist/node_modules/semver/ranges/min-satisfying.js +0 -24
  448. package/dist/node_modules/semver/ranges/min-version.js +0 -60
  449. package/dist/node_modules/semver/ranges/outside.js +0 -80
  450. package/dist/node_modules/semver/ranges/simplify.js +0 -44
  451. package/dist/node_modules/semver/ranges/subset.js +0 -222
  452. package/dist/node_modules/semver/ranges/to-comparators.js +0 -8
  453. package/dist/node_modules/semver/ranges/valid.js +0 -11
  454. package/dist/node_modules/set-blocking/CHANGELOG.md +0 -26
  455. package/dist/node_modules/set-blocking/LICENSE.txt +0 -14
  456. package/dist/node_modules/set-blocking/README.md +0 -31
  457. package/dist/node_modules/set-blocking/index.js +0 -7
  458. package/dist/node_modules/set-blocking/package.json +0 -70
  459. package/dist/node_modules/sharp/LICENSE +0 -191
  460. package/dist/node_modules/sharp/README.md +0 -117
  461. package/dist/node_modules/sharp/binding.gyp +0 -233
  462. package/dist/node_modules/sharp/build/Release/sharp-linux-x64.node +0 -0
  463. package/dist/node_modules/sharp/install/can-compile.js +0 -11
  464. package/dist/node_modules/sharp/install/dll-copy.js +0 -37
  465. package/dist/node_modules/sharp/install/libvips.js +0 -176
  466. package/dist/node_modules/sharp/lib/agent.js +0 -40
  467. package/dist/node_modules/sharp/lib/channel.js +0 -171
  468. package/dist/node_modules/sharp/lib/colour.js +0 -171
  469. package/dist/node_modules/sharp/lib/composite.js +0 -178
  470. package/dist/node_modules/sharp/lib/constructor.js +0 -379
  471. package/dist/node_modules/sharp/lib/index.js +0 -13
  472. package/dist/node_modules/sharp/lib/input.js +0 -471
  473. package/dist/node_modules/sharp/lib/is.js +0 -143
  474. package/dist/node_modules/sharp/lib/libvips.js +0 -108
  475. package/dist/node_modules/sharp/lib/operation.js +0 -671
  476. package/dist/node_modules/sharp/lib/output.js +0 -1166
  477. package/dist/node_modules/sharp/lib/platform.js +0 -25
  478. package/dist/node_modules/sharp/lib/resize.js +0 -454
  479. package/dist/node_modules/sharp/lib/sharp.js +0 -31
  480. package/dist/node_modules/sharp/lib/utility.js +0 -180
  481. package/dist/node_modules/sharp/package.json +0 -436
  482. package/dist/node_modules/sharp/src/common.cc +0 -883
  483. package/dist/node_modules/sharp/src/common.h +0 -328
  484. package/dist/node_modules/sharp/src/libvips/cplusplus/VConnection.cpp +0 -152
  485. package/dist/node_modules/sharp/src/libvips/cplusplus/VError.cpp +0 -50
  486. package/dist/node_modules/sharp/src/libvips/cplusplus/VImage.cpp +0 -1505
  487. package/dist/node_modules/sharp/src/libvips/cplusplus/VInterpolate.cpp +0 -63
  488. package/dist/node_modules/sharp/src/libvips/cplusplus/vips-operators.cpp +0 -3710
  489. package/dist/node_modules/sharp/src/metadata.cc +0 -285
  490. package/dist/node_modules/sharp/src/metadata.h +0 -91
  491. package/dist/node_modules/sharp/src/operations.cc +0 -311
  492. package/dist/node_modules/sharp/src/operations.h +0 -113
  493. package/dist/node_modules/sharp/src/pipeline.cc +0 -1584
  494. package/dist/node_modules/sharp/src/pipeline.h +0 -345
  495. package/dist/node_modules/sharp/src/sharp.cc +0 -52
  496. package/dist/node_modules/sharp/src/stats.cc +0 -193
  497. package/dist/node_modules/sharp/src/stats.h +0 -70
  498. package/dist/node_modules/sharp/src/utilities.cc +0 -243
  499. package/dist/node_modules/sharp/src/utilities.h +0 -29
  500. package/dist/node_modules/sharp/vendor/8.11.3/linux-x64/THIRD-PARTY-NOTICES.md +0 -41
  501. package/dist/node_modules/sharp/vendor/8.11.3/linux-x64/lib/libvips-cpp.so.42 +0 -0
  502. package/dist/node_modules/sharp/vendor/8.11.3/linux-x64/platform.json +0 -1
  503. package/dist/node_modules/sharp/vendor/8.11.3/linux-x64/versions.json +0 -30
  504. package/dist/node_modules/signal-exit/LICENSE.txt +0 -16
  505. package/dist/node_modules/signal-exit/README.md +0 -39
  506. package/dist/node_modules/signal-exit/index.js +0 -200
  507. package/dist/node_modules/signal-exit/package.json +0 -66
  508. package/dist/node_modules/signal-exit/signals.js +0 -53
  509. package/dist/node_modules/simple-concat/.travis.yml +0 -3
  510. package/dist/node_modules/simple-concat/LICENSE +0 -20
  511. package/dist/node_modules/simple-concat/README.md +0 -44
  512. package/dist/node_modules/simple-concat/index.js +0 -15
  513. package/dist/node_modules/simple-concat/package.json +0 -72
  514. package/dist/node_modules/simple-concat/test/basic.js +0 -41
  515. package/dist/node_modules/simple-get/.github/dependabot.yml +0 -15
  516. package/dist/node_modules/simple-get/.github/workflows/ci.yml +0 -23
  517. package/dist/node_modules/simple-get/LICENSE +0 -20
  518. package/dist/node_modules/simple-get/README.md +0 -333
  519. package/dist/node_modules/simple-get/index.js +0 -108
  520. package/dist/node_modules/simple-get/package.json +0 -93
  521. package/dist/node_modules/simple-swizzle/LICENSE +0 -21
  522. package/dist/node_modules/simple-swizzle/README.md +0 -39
  523. package/dist/node_modules/simple-swizzle/index.js +0 -29
  524. package/dist/node_modules/simple-swizzle/package.json +0 -71
  525. package/dist/node_modules/string-width/index.js +0 -37
  526. package/dist/node_modules/string-width/license +0 -21
  527. package/dist/node_modules/string-width/package.json +0 -89
  528. package/dist/node_modules/string-width/readme.md +0 -42
  529. package/dist/node_modules/string_decoder/.travis.yml +0 -50
  530. package/dist/node_modules/string_decoder/LICENSE +0 -48
  531. package/dist/node_modules/string_decoder/README.md +0 -47
  532. package/dist/node_modules/string_decoder/lib/string_decoder.js +0 -296
  533. package/dist/node_modules/string_decoder/package.json +0 -61
  534. package/dist/node_modules/strip-ansi/index.js +0 -6
  535. package/dist/node_modules/strip-ansi/license +0 -21
  536. package/dist/node_modules/strip-ansi/package.json +0 -102
  537. package/dist/node_modules/strip-ansi/readme.md +0 -33
  538. package/dist/node_modules/strip-json-comments/index.js +0 -70
  539. package/dist/node_modules/strip-json-comments/license +0 -21
  540. package/dist/node_modules/strip-json-comments/package.json +0 -74
  541. package/dist/node_modules/strip-json-comments/readme.md +0 -64
  542. package/dist/node_modules/tar-fs/.travis.yml +0 -6
  543. package/dist/node_modules/tar-fs/LICENSE +0 -21
  544. package/dist/node_modules/tar-fs/README.md +0 -165
  545. package/dist/node_modules/tar-fs/index.js +0 -351
  546. package/dist/node_modules/tar-fs/package.json +0 -69
  547. package/dist/node_modules/tar-fs/test/fixtures/a/hello.txt +0 -1
  548. package/dist/node_modules/tar-fs/test/fixtures/b/a/test.txt +0 -1
  549. package/dist/node_modules/tar-fs/test/fixtures/d/file1 +0 -0
  550. package/dist/node_modules/tar-fs/test/fixtures/d/file2 +0 -0
  551. package/dist/node_modules/tar-fs/test/fixtures/d/sub-dir/file5 +0 -0
  552. package/dist/node_modules/tar-fs/test/fixtures/d/sub-files/file3 +0 -0
  553. package/dist/node_modules/tar-fs/test/fixtures/d/sub-files/file4 +0 -0
  554. package/dist/node_modules/tar-fs/test/fixtures/e/directory/.ignore +0 -0
  555. package/dist/node_modules/tar-fs/test/fixtures/e/file +0 -0
  556. package/dist/node_modules/tar-fs/test/fixtures/invalid.tar +0 -0
  557. package/dist/node_modules/tar-fs/test/index.js +0 -346
  558. package/dist/node_modules/tar-stream/LICENSE +0 -21
  559. package/dist/node_modules/tar-stream/README.md +0 -168
  560. package/dist/node_modules/tar-stream/extract.js +0 -257
  561. package/dist/node_modules/tar-stream/headers.js +0 -295
  562. package/dist/node_modules/tar-stream/index.js +0 -2
  563. package/dist/node_modules/tar-stream/node_modules/readable-stream/CONTRIBUTING.md +0 -38
  564. package/dist/node_modules/tar-stream/node_modules/readable-stream/GOVERNANCE.md +0 -136
  565. package/dist/node_modules/tar-stream/node_modules/readable-stream/LICENSE +0 -47
  566. package/dist/node_modules/tar-stream/node_modules/readable-stream/README.md +0 -106
  567. package/dist/node_modules/tar-stream/node_modules/readable-stream/errors-browser.js +0 -127
  568. package/dist/node_modules/tar-stream/node_modules/readable-stream/errors.js +0 -116
  569. package/dist/node_modules/tar-stream/node_modules/readable-stream/experimentalWarning.js +0 -17
  570. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/_stream_duplex.js +0 -139
  571. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/_stream_passthrough.js +0 -39
  572. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/_stream_readable.js +0 -1124
  573. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/_stream_transform.js +0 -201
  574. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/_stream_writable.js +0 -697
  575. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/async_iterator.js +0 -207
  576. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/buffer_list.js +0 -210
  577. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/destroy.js +0 -105
  578. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/end-of-stream.js +0 -104
  579. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/from-browser.js +0 -3
  580. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/from.js +0 -64
  581. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/pipeline.js +0 -97
  582. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/state.js +0 -27
  583. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/stream-browser.js +0 -1
  584. package/dist/node_modules/tar-stream/node_modules/readable-stream/lib/internal/streams/stream.js +0 -1
  585. package/dist/node_modules/tar-stream/node_modules/readable-stream/package.json +0 -97
  586. package/dist/node_modules/tar-stream/node_modules/readable-stream/readable-browser.js +0 -9
  587. package/dist/node_modules/tar-stream/node_modules/readable-stream/readable.js +0 -16
  588. package/dist/node_modules/tar-stream/pack.js +0 -255
  589. package/dist/node_modules/tar-stream/package.json +0 -90
  590. package/dist/node_modules/tar-stream/sandbox.js +0 -11
  591. package/dist/node_modules/tunnel-agent/LICENSE +0 -55
  592. package/dist/node_modules/tunnel-agent/README.md +0 -4
  593. package/dist/node_modules/tunnel-agent/index.js +0 -244
  594. package/dist/node_modules/tunnel-agent/package.json +0 -56
  595. package/dist/node_modules/util-deprecate/History.md +0 -16
  596. package/dist/node_modules/util-deprecate/LICENSE +0 -24
  597. package/dist/node_modules/util-deprecate/README.md +0 -53
  598. package/dist/node_modules/util-deprecate/browser.js +0 -67
  599. package/dist/node_modules/util-deprecate/node.js +0 -6
  600. package/dist/node_modules/util-deprecate/package.json +0 -58
  601. package/dist/node_modules/wide-align/LICENSE +0 -14
  602. package/dist/node_modules/wide-align/README.md +0 -47
  603. package/dist/node_modules/wide-align/align.js +0 -65
  604. package/dist/node_modules/wide-align/package.json +0 -66
  605. package/dist/node_modules/wrappy/LICENSE +0 -15
  606. package/dist/node_modules/wrappy/README.md +0 -36
  607. package/dist/node_modules/wrappy/package.json +0 -58
  608. package/dist/node_modules/wrappy/wrappy.js +0 -33
  609. package/dist/node_modules/yallist/LICENSE +0 -15
  610. package/dist/node_modules/yallist/README.md +0 -204
  611. package/dist/node_modules/yallist/iterator.js +0 -8
  612. package/dist/node_modules/yallist/package.json +0 -62
  613. package/dist/node_modules/yallist/yallist.js +0 -426
  614. package/dist/package-lock.json +0 -507
  615. package/dist/package.json +0 -63
  616. package/dist/static/expected_tile_2193_153_255_z7.png +0 -0
  617. package/dist/static/expected_tile_NZTM2000Quad_30_33_z6.png +0 -0
  618. package/dist/static/expected_tile_WebMercatorQuad_252_156_z8.png +0 -0
@@ -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
- }