librawspeed-full 1.0.129

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 (541) hide show
  1. package/CHANGELOG.md +1138 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1414 -0
  4. package/binding.gyp +55 -0
  5. package/deps/LibRaw-Source/LibRaw-0.21.4/.clang-format +4 -0
  6. package/deps/LibRaw-Source/LibRaw-0.21.4/COPYRIGHT +27 -0
  7. package/deps/LibRaw-Source/LibRaw-0.21.4/Changelog.txt +2802 -0
  8. package/deps/LibRaw-Source/LibRaw-0.21.4/DEVELOPER-NOTES +20 -0
  9. package/deps/LibRaw-Source/LibRaw-0.21.4/GoPro/dng-sdk-1_4-allow-VC5-validate.diff +21 -0
  10. package/deps/LibRaw-Source/LibRaw-0.21.4/GoPro/dng-sdk-1_6-hide-ccVc5-definitiion.diff +15 -0
  11. package/deps/LibRaw-Source/LibRaw-0.21.4/GoPro/dng-sdk-allow-VC5-validate.diff +21 -0
  12. package/deps/LibRaw-Source/LibRaw-0.21.4/GoPro/gpr_read_image.cpp.diff +29 -0
  13. package/deps/LibRaw-Source/LibRaw-0.21.4/GoPro/gpr_read_image.h.diff +12 -0
  14. package/deps/LibRaw-Source/LibRaw-0.21.4/INSTALL +51 -0
  15. package/deps/LibRaw-Source/LibRaw-0.21.4/LICENSE.CDDL +340 -0
  16. package/deps/LibRaw-Source/LibRaw-0.21.4/LICENSE.LGPL +458 -0
  17. package/deps/LibRaw-Source/LibRaw-0.21.4/LibRaw.pro +19 -0
  18. package/deps/LibRaw-Source/LibRaw-0.21.4/LibRaw.sln +123 -0
  19. package/deps/LibRaw-Source/LibRaw-0.21.4/Makefile +2135 -0
  20. package/deps/LibRaw-Source/LibRaw-0.21.4/Makefile.am +140 -0
  21. package/deps/LibRaw-Source/LibRaw-0.21.4/Makefile.devel.nopp +230 -0
  22. package/deps/LibRaw-Source/LibRaw-0.21.4/Makefile.devel.noppr2i +227 -0
  23. package/deps/LibRaw-Source/LibRaw-0.21.4/Makefile.dist +501 -0
  24. package/deps/LibRaw-Source/LibRaw-0.21.4/Makefile.in +2135 -0
  25. package/deps/LibRaw-Source/LibRaw-0.21.4/Makefile.mingw +297 -0
  26. package/deps/LibRaw-Source/LibRaw-0.21.4/Makefile.msvc +628 -0
  27. package/deps/LibRaw-Source/LibRaw-0.21.4/README.DNGSDK.txt +43 -0
  28. package/deps/LibRaw-Source/LibRaw-0.21.4/README.GoPro.txt +112 -0
  29. package/deps/LibRaw-Source/LibRaw-0.21.4/README.RawSpeed.txt +62 -0
  30. package/deps/LibRaw-Source/LibRaw-0.21.4/README.cmake +9 -0
  31. package/deps/LibRaw-Source/LibRaw-0.21.4/README.demosaic-packs +17 -0
  32. package/deps/LibRaw-Source/LibRaw-0.21.4/README.md +106 -0
  33. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed/rawspeed.cpucount-unix.patch +15 -0
  34. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed/rawspeed.qmake-pro-files.patch +84 -0
  35. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed/rawspeed.samsung-decoder.patch +39 -0
  36. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed/rawspeed.uncompressed-color-dng.patch +13 -0
  37. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed/rawspeed.win32-dll.patch +186 -0
  38. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed/rawspeed_xmldata.cpp +4115 -0
  39. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed3/README.md +69 -0
  40. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed3/patches/01.CameraMeta-extensibility.patch +13 -0
  41. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed3/patches/02.Makernotes-processing.patch +36 -0
  42. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed3/patches/03.remove-limits-and-logging.patch +245 -0
  43. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed3/patches/04.clang-cl-compatibility.patch +37 -0
  44. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.cpp +251 -0
  45. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed3/rawspeed3_c_api/rawspeed3_capi.h +83 -0
  46. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed3/rawspeed3_c_api/rawspeed3_capi_test.cpp +71 -0
  47. package/deps/LibRaw-Source/LibRaw-0.21.4/RawSpeed3/rawspeed3_c_api/rsxml2c.sh +5 -0
  48. package/deps/LibRaw-Source/LibRaw-0.21.4/aclocal.m4 +1674 -0
  49. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/.dirstamp +0 -0
  50. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/.keep_me +2 -0
  51. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/4channels +0 -0
  52. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/dcraw_emu +0 -0
  53. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/mem_image +0 -0
  54. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/multirender_test +0 -0
  55. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/postprocessing_benchmark +0 -0
  56. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/raw-identify +0 -0
  57. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/rawtextdump +0 -0
  58. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/simple_dcraw +0 -0
  59. package/deps/LibRaw-Source/LibRaw-0.21.4/bin/unprocessed_raw +0 -0
  60. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/include/libraw/libraw.h +534 -0
  61. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/include/libraw/libraw_alloc.h +148 -0
  62. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/include/libraw/libraw_const.h +814 -0
  63. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/include/libraw/libraw_datastream.h +410 -0
  64. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/include/libraw/libraw_internal.h +341 -0
  65. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/include/libraw/libraw_types.h +1175 -0
  66. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/include/libraw/libraw_version.h +63 -0
  67. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/lib/libraw.a +0 -0
  68. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/lib/libraw.la +41 -0
  69. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/lib/libraw_r.a +0 -0
  70. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/lib/libraw_r.la +41 -0
  71. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/lib/pkgconfig/libraw.pc +12 -0
  72. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/lib/pkgconfig/libraw_r.pc +12 -0
  73. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/share/doc/libraw/COPYRIGHT +27 -0
  74. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/share/doc/libraw/Changelog.txt +2802 -0
  75. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/share/doc/libraw/LICENSE.CDDL +340 -0
  76. package/deps/LibRaw-Source/LibRaw-0.21.4/build/darwin-arm64/share/doc/libraw/LICENSE.LGPL +458 -0
  77. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/4channels.pro +5 -0
  78. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/4channels.vcxproj +145 -0
  79. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/4channels.vcxproj.filters +18 -0
  80. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/dcraw_emu.pro +6 -0
  81. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/dcraw_emu.vcxproj +145 -0
  82. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/dcraw_emu.vcxproj.filters +18 -0
  83. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/dcraw_half.pro +6 -0
  84. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/dcraw_half.vcxproj +145 -0
  85. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/dcraw_half.vcxproj.filters +18 -0
  86. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/half_mt.pro +10 -0
  87. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/libraw-common-lib.pro +28 -0
  88. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/libraw-common.pro +8 -0
  89. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/libraw.pro +70 -0
  90. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/libraw.vcxproj +234 -0
  91. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/libraw.vcxproj.filters +295 -0
  92. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/mem_image.pro +6 -0
  93. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/mem_image.vcxproj +145 -0
  94. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/mem_image.vcxproj.filters +18 -0
  95. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/multirender_test.pro +6 -0
  96. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/multirender_test.vcxproj +145 -0
  97. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/multirender_test.vcxproj.filters +18 -0
  98. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/openbayer_sample.pro +6 -0
  99. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/openbayer_sample.vcxproj +145 -0
  100. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/openbayer_sample.vcxproj.filters +18 -0
  101. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/postprocessing_benchmark.pro +4 -0
  102. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/postprocessing_benchmark.vcxproj +145 -0
  103. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/postprocessing_benchmark.vcxproj.filters +18 -0
  104. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/raw-identify.pro +6 -0
  105. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/raw-identify.vcxproj +145 -0
  106. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/raw-identify.vcxproj.filters +18 -0
  107. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/rawtextdump.pro +6 -0
  108. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/rawtextdump.vcxproj +145 -0
  109. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/rawtextdump.vcxproj.filters +18 -0
  110. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/simple_dcraw.pro +6 -0
  111. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/simple_dcraw.vcxproj +145 -0
  112. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/simple_dcraw.vcxproj.filters +18 -0
  113. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/unprocessed_raw.pro +6 -0
  114. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/unprocessed_raw.vcxproj +145 -0
  115. package/deps/LibRaw-Source/LibRaw-0.21.4/buildfiles/unprocessed_raw.vcxproj.filters +18 -0
  116. package/deps/LibRaw-Source/LibRaw-0.21.4/compile +347 -0
  117. package/deps/LibRaw-Source/LibRaw-0.21.4/config.guess +1433 -0
  118. package/deps/LibRaw-Source/LibRaw-0.21.4/config.log +930 -0
  119. package/deps/LibRaw-Source/LibRaw-0.21.4/config.status +2090 -0
  120. package/deps/LibRaw-Source/LibRaw-0.21.4/config.sub +1804 -0
  121. package/deps/LibRaw-Source/LibRaw-0.21.4/configure +22084 -0
  122. package/deps/LibRaw-Source/LibRaw-0.21.4/configure.ac +153 -0
  123. package/deps/LibRaw-Source/LibRaw-0.21.4/depcomp +791 -0
  124. package/deps/LibRaw-Source/LibRaw-0.21.4/doc/API-C.html +187 -0
  125. package/deps/LibRaw-Source/LibRaw-0.21.4/doc/API-CXX.html +881 -0
  126. package/deps/LibRaw-Source/LibRaw-0.21.4/doc/API-datastruct.html +1341 -0
  127. package/deps/LibRaw-Source/LibRaw-0.21.4/doc/API-notes.html +305 -0
  128. package/deps/LibRaw-Source/LibRaw-0.21.4/doc/API-overview.html +66 -0
  129. package/deps/LibRaw-Source/LibRaw-0.21.4/doc/Install-LibRaw.html +124 -0
  130. package/deps/LibRaw-Source/LibRaw-0.21.4/doc/Samples-LibRaw.html +213 -0
  131. package/deps/LibRaw-Source/LibRaw-0.21.4/doc/Why-LibRaw.html +65 -0
  132. package/deps/LibRaw-Source/LibRaw-0.21.4/doc/index.html +38 -0
  133. package/deps/LibRaw-Source/LibRaw-0.21.4/install-sh +501 -0
  134. package/deps/LibRaw-Source/LibRaw-0.21.4/internal/dcraw_defs.h +66 -0
  135. package/deps/LibRaw-Source/LibRaw-0.21.4/internal/dcraw_fileio_defs.h +25 -0
  136. package/deps/LibRaw-Source/LibRaw-0.21.4/internal/defines.h +193 -0
  137. package/deps/LibRaw-Source/LibRaw-0.21.4/internal/dmp_include.h +27 -0
  138. package/deps/LibRaw-Source/LibRaw-0.21.4/internal/libraw_cameraids.h +320 -0
  139. package/deps/LibRaw-Source/LibRaw-0.21.4/internal/libraw_cxx_defs.h +133 -0
  140. package/deps/LibRaw-Source/LibRaw-0.21.4/internal/libraw_internal_funcs.h +412 -0
  141. package/deps/LibRaw-Source/LibRaw-0.21.4/internal/var_defines.h +215 -0
  142. package/deps/LibRaw-Source/LibRaw-0.21.4/internal/x3f_tools.h +539 -0
  143. package/deps/LibRaw-Source/LibRaw-0.21.4/lib/.dirstamp +0 -0
  144. package/deps/LibRaw-Source/LibRaw-0.21.4/lib/.libs/libraw.a +0 -0
  145. package/deps/LibRaw-Source/LibRaw-0.21.4/lib/.libs/libraw.lai +41 -0
  146. package/deps/LibRaw-Source/LibRaw-0.21.4/lib/.libs/libraw_r.a +0 -0
  147. package/deps/LibRaw-Source/LibRaw-0.21.4/lib/.libs/libraw_r.lai +41 -0
  148. package/deps/LibRaw-Source/LibRaw-0.21.4/lib/libraw.la +41 -0
  149. package/deps/LibRaw-Source/LibRaw-0.21.4/lib/libraw_r.la +41 -0
  150. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw/libraw.h +534 -0
  151. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw/libraw_alloc.h +148 -0
  152. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw/libraw_const.h +814 -0
  153. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw/libraw_datastream.h +410 -0
  154. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw/libraw_internal.h +341 -0
  155. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw/libraw_types.h +1175 -0
  156. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw/libraw_version.h +63 -0
  157. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw.pc +12 -0
  158. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw.pc.in +12 -0
  159. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw_r.pc +12 -0
  160. package/deps/LibRaw-Source/LibRaw-0.21.4/libraw_r.pc.in +12 -0
  161. package/deps/LibRaw-Source/LibRaw-0.21.4/libtool +12190 -0
  162. package/deps/LibRaw-Source/LibRaw-0.21.4/ltmain.sh +11524 -0
  163. package/deps/LibRaw-Source/LibRaw-0.21.4/m4/ax_openmp.m4 +99 -0
  164. package/deps/LibRaw-Source/LibRaw-0.21.4/m4/libtool.m4 +8488 -0
  165. package/deps/LibRaw-Source/LibRaw-0.21.4/m4/ltoptions.m4 +467 -0
  166. package/deps/LibRaw-Source/LibRaw-0.21.4/m4/ltsugar.m4 +124 -0
  167. package/deps/LibRaw-Source/LibRaw-0.21.4/m4/ltversion.m4 +24 -0
  168. package/deps/LibRaw-Source/LibRaw-0.21.4/m4/lt~obsolete.m4 +99 -0
  169. package/deps/LibRaw-Source/LibRaw-0.21.4/missing +215 -0
  170. package/deps/LibRaw-Source/LibRaw-0.21.4/object/.keep_me +0 -0
  171. package/deps/LibRaw-Source/LibRaw-0.21.4/rsxml2c.sh +6 -0
  172. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_4channels-4channels.Po +0 -0
  173. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_dcraw_emu-dcraw_emu.Po +0 -0
  174. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_dcraw_half-dcraw_half.Po +0 -0
  175. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_half_mt-half_mt.Po +0 -0
  176. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_mem_image-mem_image_sample.Po +0 -0
  177. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_multirender_test-multirender_test.Po +0 -0
  178. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_postprocessing_benchmark-postprocessing_benchmark.Po +0 -0
  179. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_raw_identify-raw-identify.Po +0 -0
  180. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_rawtextdump-rawtextdump.Po +0 -0
  181. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_simple_dcraw-simple_dcraw.Po +0 -0
  182. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.deps/bin_unprocessed_raw-unprocessed_raw.Po +0 -0
  183. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/.dirstamp +0 -0
  184. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/4channels.cpp +174 -0
  185. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/Makefile +2 -0
  186. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/dcraw_emu.cpp +670 -0
  187. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/dcraw_half.c +78 -0
  188. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/half_mt.c +178 -0
  189. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/half_mt_win32.c +212 -0
  190. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/mem_image_sample.cpp +282 -0
  191. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/multirender_test.cpp +107 -0
  192. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/openbayer_sample.cpp +65 -0
  193. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/postprocessing_benchmark.cpp +223 -0
  194. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/raw-identify.cpp +743 -0
  195. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/rawtextdump.cpp +144 -0
  196. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/simple_dcraw.cpp +217 -0
  197. package/deps/LibRaw-Source/LibRaw-0.21.4/samples/unprocessed_raw.cpp +319 -0
  198. package/deps/LibRaw-Source/LibRaw-0.21.4/shlib-version.sh +11 -0
  199. package/deps/LibRaw-Source/LibRaw-0.21.4/src/.deps/.dirstamp +0 -0
  200. package/deps/LibRaw-Source/LibRaw-0.21.4/src/.deps/libraw_c_api.Plo +1597 -0
  201. package/deps/LibRaw-Source/LibRaw-0.21.4/src/.deps/libraw_datastream.Plo +1604 -0
  202. package/deps/LibRaw-Source/LibRaw-0.21.4/src/.dirstamp +0 -0
  203. package/deps/LibRaw-Source/LibRaw-0.21.4/src/Makefile +2 -0
  204. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/.dirstamp +0 -0
  205. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/canon_600.Plo +1656 -0
  206. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/crx.Plo +1659 -0
  207. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/decoders_dcraw.Plo +1657 -0
  208. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/decoders_libraw.Plo +1659 -0
  209. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/decoders_libraw_dcrdefs.Plo +1657 -0
  210. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/dng.Plo +1656 -0
  211. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/fp_dng.Plo +1659 -0
  212. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/fuji_compressed.Plo +1659 -0
  213. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/generic.Plo +1656 -0
  214. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/kodak_decoders.Plo +1656 -0
  215. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/load_mfbacks.Plo +1656 -0
  216. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/smal.Plo +1656 -0
  217. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/unpack.Plo +1661 -0
  218. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.deps/unpack_thumb.Plo +1659 -0
  219. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/.dirstamp +0 -0
  220. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/canon_600.cpp +225 -0
  221. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/canon_600.lo +12 -0
  222. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/canon_600.o +0 -0
  223. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/crx.cpp +2781 -0
  224. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/crx.lo +12 -0
  225. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/crx.o +0 -0
  226. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/decoders_dcraw.cpp +1816 -0
  227. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/decoders_dcraw.lo +12 -0
  228. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/decoders_dcraw.o +0 -0
  229. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/decoders_libraw.cpp +873 -0
  230. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/decoders_libraw.lo +12 -0
  231. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/decoders_libraw.o +0 -0
  232. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/decoders_libraw_dcrdefs.cpp +411 -0
  233. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/decoders_libraw_dcrdefs.lo +12 -0
  234. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/decoders_libraw_dcrdefs.o +0 -0
  235. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/dng.cpp +284 -0
  236. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/dng.lo +12 -0
  237. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/dng.o +0 -0
  238. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/fp_dng.cpp +689 -0
  239. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/fp_dng.lo +12 -0
  240. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/fp_dng.o +0 -0
  241. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/fuji_compressed.cpp +1210 -0
  242. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/fuji_compressed.lo +12 -0
  243. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/fuji_compressed.o +0 -0
  244. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/generic.cpp +101 -0
  245. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/generic.lo +12 -0
  246. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/generic.o +0 -0
  247. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/kodak_decoders.cpp +524 -0
  248. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/kodak_decoders.lo +12 -0
  249. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/kodak_decoders.o +0 -0
  250. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/load_mfbacks.cpp +936 -0
  251. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/load_mfbacks.lo +12 -0
  252. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/load_mfbacks.o +0 -0
  253. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/smal.cpp +181 -0
  254. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/smal.lo +12 -0
  255. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/smal.o +0 -0
  256. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/unpack.cpp +508 -0
  257. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/unpack.lo +12 -0
  258. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/unpack.o +0 -0
  259. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/unpack_thumb.cpp +405 -0
  260. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/unpack_thumb.lo +12 -0
  261. package/deps/LibRaw-Source/LibRaw-0.21.4/src/decoders/unpack_thumb.o +0 -0
  262. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/.deps/.dirstamp +0 -0
  263. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/.deps/aahd_demosaic.Plo +1653 -0
  264. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/.deps/ahd_demosaic.Plo +1656 -0
  265. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/.deps/dcb_demosaic.Plo +1656 -0
  266. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/.deps/dht_demosaic.Plo +1653 -0
  267. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/.deps/misc_demosaic.Plo +1656 -0
  268. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/.deps/xtrans_demosaic.Plo +1656 -0
  269. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/.dirstamp +0 -0
  270. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/aahd_demosaic.cpp +781 -0
  271. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/aahd_demosaic.lo +12 -0
  272. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/aahd_demosaic.o +0 -0
  273. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/ahd_demosaic.cpp +355 -0
  274. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/ahd_demosaic.lo +12 -0
  275. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/ahd_demosaic.o +0 -0
  276. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/dcb_demosaic.cpp +900 -0
  277. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/dcb_demosaic.lo +12 -0
  278. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/dcb_demosaic.o +0 -0
  279. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/dht_demosaic.cpp +1033 -0
  280. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/dht_demosaic.lo +12 -0
  281. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/dht_demosaic.o +0 -0
  282. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/misc_demosaic.cpp +420 -0
  283. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/misc_demosaic.lo +12 -0
  284. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/misc_demosaic.o +0 -0
  285. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/xtrans_demosaic.cpp +434 -0
  286. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/xtrans_demosaic.lo +12 -0
  287. package/deps/LibRaw-Source/LibRaw-0.21.4/src/demosaic/xtrans_demosaic.o +0 -0
  288. package/deps/LibRaw-Source/LibRaw-0.21.4/src/integration/.deps/.dirstamp +0 -0
  289. package/deps/LibRaw-Source/LibRaw-0.21.4/src/integration/.deps/dngsdk_glue.Plo +1659 -0
  290. package/deps/LibRaw-Source/LibRaw-0.21.4/src/integration/.deps/rawspeed_glue.Plo +1659 -0
  291. package/deps/LibRaw-Source/LibRaw-0.21.4/src/integration/.dirstamp +0 -0
  292. package/deps/LibRaw-Source/LibRaw-0.21.4/src/integration/dngsdk_glue.cpp +416 -0
  293. package/deps/LibRaw-Source/LibRaw-0.21.4/src/integration/dngsdk_glue.lo +12 -0
  294. package/deps/LibRaw-Source/LibRaw-0.21.4/src/integration/dngsdk_glue.o +0 -0
  295. package/deps/LibRaw-Source/LibRaw-0.21.4/src/integration/rawspeed_glue.cpp +286 -0
  296. package/deps/LibRaw-Source/LibRaw-0.21.4/src/integration/rawspeed_glue.lo +12 -0
  297. package/deps/LibRaw-Source/LibRaw-0.21.4/src/integration/rawspeed_glue.o +0 -0
  298. package/deps/LibRaw-Source/LibRaw-0.21.4/src/libraw_c_api.cpp +457 -0
  299. package/deps/LibRaw-Source/LibRaw-0.21.4/src/libraw_c_api.lo +12 -0
  300. package/deps/LibRaw-Source/LibRaw-0.21.4/src/libraw_c_api.o +0 -0
  301. package/deps/LibRaw-Source/LibRaw-0.21.4/src/libraw_datastream.cpp +1046 -0
  302. package/deps/LibRaw-Source/LibRaw-0.21.4/src/libraw_datastream.lo +12 -0
  303. package/deps/LibRaw-Source/LibRaw-0.21.4/src/libraw_datastream.o +0 -0
  304. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/.dirstamp +0 -0
  305. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/adobepano.Plo +1656 -0
  306. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/canon.Plo +1657 -0
  307. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/ciff.Plo +1656 -0
  308. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/cr3_parser.Plo +1656 -0
  309. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/epson.Plo +1656 -0
  310. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/exif_gps.Plo +1657 -0
  311. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/fuji.Plo +1656 -0
  312. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/hasselblad_model.Plo +1657 -0
  313. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/identify.Plo +1657 -0
  314. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/identify_tools.Plo +1656 -0
  315. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/kodak.Plo +1656 -0
  316. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/leica.Plo +1656 -0
  317. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/makernotes.Plo +1656 -0
  318. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/mediumformat.Plo +1656 -0
  319. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/minolta.Plo +1656 -0
  320. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/misc_parsers.Plo +1656 -0
  321. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/nikon.Plo +1656 -0
  322. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/normalize_model.Plo +1657 -0
  323. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/olympus.Plo +1657 -0
  324. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/p1.Plo +1656 -0
  325. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/pentax.Plo +1657 -0
  326. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/samsung.Plo +1656 -0
  327. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/sony.Plo +1657 -0
  328. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.deps/tiff.Plo +1657 -0
  329. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/.dirstamp +0 -0
  330. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/adobepano.cpp +154 -0
  331. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/adobepano.lo +12 -0
  332. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/adobepano.o +0 -0
  333. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/canon.cpp +1335 -0
  334. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/canon.lo +12 -0
  335. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/canon.o +0 -0
  336. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/ciff.cpp +411 -0
  337. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/ciff.lo +12 -0
  338. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/ciff.o +0 -0
  339. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/cr3_parser.cpp +896 -0
  340. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/cr3_parser.lo +12 -0
  341. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/cr3_parser.o +0 -0
  342. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/epson.cpp +96 -0
  343. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/epson.lo +12 -0
  344. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/epson.o +0 -0
  345. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/exif_gps.cpp +430 -0
  346. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/exif_gps.lo +12 -0
  347. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/exif_gps.o +0 -0
  348. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/fuji.cpp +1427 -0
  349. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/fuji.lo +12 -0
  350. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/fuji.o +0 -0
  351. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/hasselblad_model.cpp +538 -0
  352. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/hasselblad_model.lo +12 -0
  353. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/hasselblad_model.o +0 -0
  354. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/identify.cpp +3167 -0
  355. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/identify.lo +12 -0
  356. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/identify.o +0 -0
  357. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/identify_tools.cpp +140 -0
  358. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/identify_tools.lo +12 -0
  359. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/identify_tools.o +0 -0
  360. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/kodak.cpp +363 -0
  361. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/kodak.lo +12 -0
  362. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/kodak.o +0 -0
  363. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/leica.cpp +375 -0
  364. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/leica.lo +12 -0
  365. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/leica.o +0 -0
  366. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/makernotes.cpp +786 -0
  367. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/makernotes.lo +12 -0
  368. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/makernotes.o +0 -0
  369. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/mediumformat.cpp +521 -0
  370. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/mediumformat.lo +12 -0
  371. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/mediumformat.o +0 -0
  372. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/minolta.cpp +110 -0
  373. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/minolta.lo +12 -0
  374. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/minolta.o +0 -0
  375. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/misc_parsers.cpp +694 -0
  376. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/misc_parsers.lo +12 -0
  377. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/misc_parsers.o +0 -0
  378. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/nikon.cpp +1051 -0
  379. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/nikon.lo +12 -0
  380. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/nikon.o +0 -0
  381. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/normalize_model.cpp +1451 -0
  382. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/normalize_model.lo +12 -0
  383. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/normalize_model.o +0 -0
  384. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/olympus.cpp +685 -0
  385. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/olympus.lo +12 -0
  386. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/olympus.o +0 -0
  387. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/p1.cpp +192 -0
  388. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/p1.lo +12 -0
  389. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/p1.o +0 -0
  390. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/pentax.cpp +675 -0
  391. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/pentax.lo +12 -0
  392. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/pentax.o +0 -0
  393. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/samsung.cpp +182 -0
  394. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/samsung.lo +12 -0
  395. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/samsung.o +0 -0
  396. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/sony.cpp +2320 -0
  397. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/sony.lo +12 -0
  398. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/sony.o +0 -0
  399. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/tiff.cpp +2198 -0
  400. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/tiff.lo +12 -0
  401. package/deps/LibRaw-Source/LibRaw-0.21.4/src/metadata/tiff.o +0 -0
  402. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/.deps/.dirstamp +0 -0
  403. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/.deps/aspect_ratio.Plo +1656 -0
  404. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/.deps/dcraw_process.Plo +1659 -0
  405. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/.deps/mem_image.Plo +1659 -0
  406. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/.deps/postprocessing_aux.Plo +1657 -0
  407. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/.deps/postprocessing_utils.Plo +1660 -0
  408. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/.deps/postprocessing_utils_dcrdefs.Plo +1657 -0
  409. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/.dirstamp +0 -0
  410. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/aspect_ratio.cpp +113 -0
  411. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/aspect_ratio.lo +12 -0
  412. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/aspect_ratio.o +0 -0
  413. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/dcraw_process.cpp +259 -0
  414. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/dcraw_process.lo +12 -0
  415. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/dcraw_process.o +0 -0
  416. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/mem_image.cpp +292 -0
  417. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/mem_image.lo +12 -0
  418. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/mem_image.o +0 -0
  419. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/postprocessing_aux.cpp +413 -0
  420. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/postprocessing_aux.lo +12 -0
  421. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/postprocessing_aux.o +0 -0
  422. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/postprocessing_ph.cpp +31 -0
  423. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/postprocessing_utils.cpp +190 -0
  424. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/postprocessing_utils.lo +12 -0
  425. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/postprocessing_utils.o +0 -0
  426. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/postprocessing_utils_dcrdefs.cpp +308 -0
  427. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/postprocessing_utils_dcrdefs.lo +12 -0
  428. package/deps/LibRaw-Source/LibRaw-0.21.4/src/postprocessing/postprocessing_utils_dcrdefs.o +0 -0
  429. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/.deps/.dirstamp +0 -0
  430. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/.deps/ext_preprocess.Plo +1656 -0
  431. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/.deps/raw2image.Plo +1659 -0
  432. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/.deps/subtract_black.Plo +1659 -0
  433. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/.dirstamp +0 -0
  434. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/ext_preprocess.cpp +127 -0
  435. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/ext_preprocess.lo +12 -0
  436. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/ext_preprocess.o +0 -0
  437. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/preprocessing_ph.cpp +24 -0
  438. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/raw2image.cpp +560 -0
  439. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/raw2image.lo +12 -0
  440. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/raw2image.o +0 -0
  441. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/subtract_black.cpp +91 -0
  442. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/subtract_black.lo +12 -0
  443. package/deps/LibRaw-Source/LibRaw-0.21.4/src/preprocessing/subtract_black.o +0 -0
  444. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/.deps/.dirstamp +0 -0
  445. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/.deps/cameralist.Plo +1659 -0
  446. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/.deps/colorconst.Plo +1659 -0
  447. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/.deps/colordata.Plo +1656 -0
  448. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/.deps/wblists.Plo +1656 -0
  449. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/.dirstamp +0 -0
  450. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/cameralist.cpp +1268 -0
  451. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/cameralist.lo +12 -0
  452. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/cameralist.o +0 -0
  453. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/colorconst.cpp +57 -0
  454. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/colorconst.lo +12 -0
  455. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/colorconst.o +0 -0
  456. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/colordata.cpp +1841 -0
  457. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/colordata.lo +12 -0
  458. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/colordata.o +0 -0
  459. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/wblists.cpp +217 -0
  460. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/wblists.lo +12 -0
  461. package/deps/LibRaw-Source/LibRaw-0.21.4/src/tables/wblists.o +0 -0
  462. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.deps/.dirstamp +0 -0
  463. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.deps/curves.Plo +1656 -0
  464. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.deps/decoder_info.Plo +1659 -0
  465. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.deps/init_close_utils.Plo +1659 -0
  466. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.deps/open.Plo +1661 -0
  467. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.deps/phaseone_processing.Plo +1659 -0
  468. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.deps/read_utils.Plo +1656 -0
  469. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.deps/thumb_utils.Plo +1659 -0
  470. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.deps/utils_dcraw.Plo +1656 -0
  471. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.deps/utils_libraw.Plo +1659 -0
  472. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/.dirstamp +0 -0
  473. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/curves.cpp +154 -0
  474. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/curves.lo +12 -0
  475. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/curves.o +0 -0
  476. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/decoder_info.cpp +413 -0
  477. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/decoder_info.lo +12 -0
  478. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/decoder_info.o +0 -0
  479. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/init_close_utils.cpp +340 -0
  480. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/init_close_utils.lo +12 -0
  481. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/init_close_utils.o +0 -0
  482. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/open.cpp +1269 -0
  483. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/open.lo +12 -0
  484. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/open.o +0 -0
  485. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/phaseone_processing.cpp +101 -0
  486. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/phaseone_processing.lo +12 -0
  487. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/phaseone_processing.o +0 -0
  488. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/read_utils.cpp +176 -0
  489. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/read_utils.lo +12 -0
  490. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/read_utils.o +0 -0
  491. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/thumb_utils.cpp +338 -0
  492. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/thumb_utils.lo +12 -0
  493. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/thumb_utils.o +0 -0
  494. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/utils_dcraw.cpp +330 -0
  495. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/utils_dcraw.lo +12 -0
  496. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/utils_dcraw.o +0 -0
  497. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/utils_libraw.cpp +673 -0
  498. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/utils_libraw.lo +12 -0
  499. package/deps/LibRaw-Source/LibRaw-0.21.4/src/utils/utils_libraw.o +0 -0
  500. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/.deps/.dirstamp +0 -0
  501. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/.deps/apply_profile.Plo +1656 -0
  502. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/.deps/file_write.Plo +1656 -0
  503. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/.deps/tiff_writer.Plo +1659 -0
  504. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/.dirstamp +0 -0
  505. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/apply_profile.cpp +76 -0
  506. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/apply_profile.lo +12 -0
  507. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/apply_profile.o +0 -0
  508. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/file_write.cpp +338 -0
  509. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/file_write.lo +12 -0
  510. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/file_write.o +0 -0
  511. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/tiff_writer.cpp +73 -0
  512. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/tiff_writer.lo +12 -0
  513. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/tiff_writer.o +0 -0
  514. package/deps/LibRaw-Source/LibRaw-0.21.4/src/write/write_ph.cpp +39 -0
  515. package/deps/LibRaw-Source/LibRaw-0.21.4/src/x3f/.deps/.dirstamp +0 -0
  516. package/deps/LibRaw-Source/LibRaw-0.21.4/src/x3f/.deps/x3f_parse_process.Plo +1 -0
  517. package/deps/LibRaw-Source/LibRaw-0.21.4/src/x3f/.deps/x3f_utils_patched.Plo +1 -0
  518. package/deps/LibRaw-Source/LibRaw-0.21.4/src/x3f/.dirstamp +0 -0
  519. package/deps/LibRaw-Source/LibRaw-0.21.4/src/x3f/x3f_parse_process.cpp +708 -0
  520. package/deps/LibRaw-Source/LibRaw-0.21.4/src/x3f/x3f_parse_process.lo +12 -0
  521. package/deps/LibRaw-Source/LibRaw-0.21.4/src/x3f/x3f_parse_process.o +0 -0
  522. package/deps/LibRaw-Source/LibRaw-0.21.4/src/x3f/x3f_utils_patched.cpp +2119 -0
  523. package/deps/LibRaw-Source/LibRaw-0.21.4/src/x3f/x3f_utils_patched.lo +12 -0
  524. package/deps/LibRaw-Source/LibRaw-0.21.4/src/x3f/x3f_utils_patched.o +0 -0
  525. package/deps/LibRaw-Source/LibRaw-0.21.4/version.sh +16 -0
  526. package/lib/index.d.ts +671 -0
  527. package/lib/index.js +2292 -0
  528. package/package.json +134 -0
  529. package/prebuilds/darwin-arm64/librawspeed-full.node +0 -0
  530. package/scripts/build-libraw.sh +303 -0
  531. package/scripts/download-dependencies.sh +31 -0
  532. package/scripts/download-libraw.sh +30 -0
  533. package/scripts/generate-docs.js +590 -0
  534. package/scripts/merge-prebuilds.sh +40 -0
  535. package/scripts/prepare-libraw.js +132 -0
  536. package/scripts/publish.sh +84 -0
  537. package/scripts/setup-dev-env.sh +112 -0
  538. package/src/addon.cpp +8 -0
  539. package/src/libraw_wrapper.cpp +1370 -0
  540. package/src/libraw_wrapper.h +114 -0
  541. package/types/index.d.ts +152 -0
package/lib/index.js ADDED
@@ -0,0 +1,2292 @@
1
+ const path = require("path");
2
+ const sharp = require("sharp");
3
+
4
+ let librawAddon;
5
+ try {
6
+ // 使用 node-gyp-build 从包根目录加载预构建文件或回退到源码编译
7
+ const packageRoot = path.resolve(__dirname, '..');
8
+ librawAddon = require('node-gyp-build')(packageRoot);
9
+ } catch (err) {
10
+ try {
11
+ // 回退到传统方式(Release)
12
+ librawAddon = require("../build/Release/raw_addon.node");
13
+ } catch (err2) {
14
+ try {
15
+ // 回退到 Debug
16
+ librawAddon = require("../build/Debug/raw_addon.node");
17
+ } catch (err3) {
18
+ const details = [err, err2, err3]
19
+ .filter(Boolean)
20
+ .map((error) => error && error.message)
21
+ .join(" | ");
22
+ throw new Error(
23
+ `LibRaw 插件未构建。请先运行 "npm run build"。加载详情: ${details}`
24
+ );
25
+ }
26
+ }
27
+ }
28
+
29
+ class LibRaw {
30
+ constructor() {
31
+ this._wrapper = new librawAddon.LibRawWrapper();
32
+ this._isProcessed = false; // 跟踪是否已调用 processImage()
33
+ this._processedImageData = null; // 缓存处理后的图像数据
34
+ }
35
+
36
+ // ============== FILE OPERATIONS ==============
37
+
38
+ /**
39
+ * 从文件系统加载 RAW 文件
40
+ * @param {string} filename - RAW 文件路径
41
+ * @returns {Promise<boolean>} - 成功状态
42
+ */
43
+ async loadFile(filename) {
44
+ return new Promise((resolve, reject) => {
45
+ try {
46
+ const result = this._wrapper.loadFile(filename);
47
+ this._isProcessed = false; // 为新文件重置处理状态
48
+ this._processedImageData = null; // 清除缓存数据
49
+ resolve(result);
50
+ } catch (error) {
51
+ reject(error);
52
+ }
53
+ });
54
+ }
55
+
56
+ /**
57
+ * 从内存缓冲区加载 RAW 文件
58
+ * @param {Buffer} buffer - 包含 RAW 数据的缓冲区
59
+ * @returns {Promise<boolean>} - 成功状态
60
+ */
61
+ async loadBuffer(buffer) {
62
+ return new Promise((resolve, reject) => {
63
+ try {
64
+ const result = this._wrapper.loadBuffer(buffer);
65
+ resolve(result);
66
+ } catch (error) {
67
+ reject(error);
68
+ }
69
+ });
70
+ }
71
+
72
+ /**
73
+ * 关闭并清理资源
74
+ * @returns {Promise<boolean>} - 成功状态
75
+ */
76
+ async close() {
77
+ return new Promise((resolve, reject) => {
78
+ try {
79
+ const result = this._wrapper.close();
80
+ resolve(result);
81
+ } catch (error) {
82
+ reject(error);
83
+ }
84
+ });
85
+ }
86
+
87
+ // ============== ERROR HANDLING ==============
88
+
89
+ /**
90
+ * 获取最后的错误消息
91
+ * @returns {string} - 最后的错误消息
92
+ */
93
+ getLastError() {
94
+ return this._wrapper.getLastError();
95
+ }
96
+
97
+ /**
98
+ * 将错误代码转换为字符串
99
+ * @param {number} errorCode - 错误代码
100
+ * @returns {string} - 错误消息
101
+ */
102
+ strerror(errorCode) {
103
+ return this._wrapper.strerror(errorCode);
104
+ }
105
+
106
+ // ============== METADATA & INFORMATION ==============
107
+
108
+ /**
109
+ * 从加载的 RAW 文件获取基本元数据
110
+ * @returns {Promise<Object>} - 元数据对象
111
+ */
112
+ async getMetadata() {
113
+ return new Promise((resolve, reject) => {
114
+ try {
115
+ const metadata = this._wrapper.getMetadata();
116
+ resolve(metadata);
117
+ } catch (error) {
118
+ reject(error);
119
+ }
120
+ });
121
+ }
122
+
123
+ /**
124
+ * 获取图像尺寸和大小信息
125
+ * @returns {Promise<Object>} - 包含宽度/高度详情的尺寸对象
126
+ */
127
+ async getImageSize() {
128
+ return new Promise((resolve, reject) => {
129
+ try {
130
+ const size = this._wrapper.getImageSize();
131
+ resolve(size);
132
+ } catch (error) {
133
+ reject(error);
134
+ }
135
+ });
136
+ }
137
+
138
+ /**
139
+ * 获取高级元数据,包括色彩矩阵和校准数据
140
+ * @returns {Promise<Object>} - 高级元数据对象
141
+ */
142
+ async getAdvancedMetadata() {
143
+ return new Promise((resolve, reject) => {
144
+ try {
145
+ const metadata = this._wrapper.getAdvancedMetadata();
146
+ resolve(metadata);
147
+ } catch (error) {
148
+ reject(error);
149
+ }
150
+ });
151
+ }
152
+
153
+ /**
154
+ * 获取镜头信息
155
+ * @returns {Promise<Object>} - 镜头元数据对象
156
+ */
157
+ async getLensInfo() {
158
+ return new Promise((resolve, reject) => {
159
+ try {
160
+ const lensInfo = this._wrapper.getLensInfo();
161
+ resolve(lensInfo);
162
+ } catch (error) {
163
+ reject(error);
164
+ }
165
+ });
166
+ }
167
+
168
+ /**
169
+ * 获取色彩信息,包括白平衡和色彩矩阵
170
+ * @returns {Promise<Object>} - 色彩信息对象
171
+ */
172
+ async getColorInfo() {
173
+ return new Promise((resolve, reject) => {
174
+ try {
175
+ const colorInfo = this._wrapper.getColorInfo();
176
+ resolve(colorInfo);
177
+ } catch (error) {
178
+ reject(error);
179
+ }
180
+ });
181
+ }
182
+
183
+ // ============== IMAGE PROCESSING ==============
184
+
185
+ /**
186
+ * 解包缩略图数据
187
+ * @returns {Promise<boolean>} - 成功状态
188
+ */
189
+ async unpackThumbnail() {
190
+ return new Promise((resolve, reject) => {
191
+ try {
192
+ const result = this._wrapper.unpackThumbnail();
193
+ resolve(result);
194
+ } catch (error) {
195
+ reject(error);
196
+ }
197
+ });
198
+ }
199
+
200
+ /**
201
+ * 使用当前设置处理 RAW 图像
202
+ * @returns {Promise<boolean>} - 成功状态
203
+ */
204
+ async processImage() {
205
+ return new Promise((resolve, reject) => {
206
+ try {
207
+ const result = this._wrapper.processImage();
208
+ this._isProcessed = true; // 标记为已处理
209
+ resolve(result);
210
+ } catch (error) {
211
+ reject(error);
212
+ }
213
+ });
214
+ }
215
+
216
+ /**
217
+ * 从 RAW 数据中减去黑电平
218
+ * @returns {Promise<boolean>} - 成功状态
219
+ */
220
+ async subtractBlack() {
221
+ return new Promise((resolve, reject) => {
222
+ try {
223
+ const result = this._wrapper.subtractBlack();
224
+ resolve(result);
225
+ } catch (error) {
226
+ reject(error);
227
+ }
228
+ });
229
+ }
230
+
231
+ /**
232
+ * 将 RAW 数据转换为图像格式
233
+ * @returns {Promise<boolean>} - 成功状态
234
+ */
235
+ async raw2Image() {
236
+ return new Promise((resolve, reject) => {
237
+ try {
238
+ const result = this._wrapper.raw2Image();
239
+ resolve(result);
240
+ } catch (error) {
241
+ reject(error);
242
+ }
243
+ });
244
+ }
245
+
246
+ /**
247
+ * 调整图像中的最大值
248
+ * @returns {Promise<boolean>} - 成功状态
249
+ */
250
+ async adjustMaximum() {
251
+ return new Promise((resolve, reject) => {
252
+ try {
253
+ const result = this._wrapper.adjustMaximum();
254
+ resolve(result);
255
+ } catch (error) {
256
+ reject(error);
257
+ }
258
+ });
259
+ }
260
+
261
+ // ============== MEMORY IMAGE CREATION ==============
262
+
263
+ /**
264
+ * 在内存中创建处理后的图像
265
+ * @returns {Promise<Object>} - 包含缓冲区的图像数据对象
266
+ */
267
+ async createMemoryImage() {
268
+ return new Promise((resolve, reject) => {
269
+ try {
270
+ // 如果可用则返回缓存数据
271
+ if (this._processedImageData) {
272
+ resolve(this._processedImageData);
273
+ return;
274
+ }
275
+
276
+ const imageData = this._wrapper.createMemoryImage();
277
+
278
+ // 如果图像已处理则缓存结果
279
+ if (this._isProcessed) {
280
+ this._processedImageData = imageData;
281
+ }
282
+
283
+ resolve(imageData);
284
+ } catch (error) {
285
+ reject(error);
286
+ }
287
+ });
288
+ }
289
+
290
+ /**
291
+ * 在内存中创建缩略图
292
+ * @returns {Promise<Object>} - 包含缓冲区的缩略图数据对象
293
+ */
294
+ async createMemoryThumbnail() {
295
+ return new Promise((resolve, reject) => {
296
+ try {
297
+ const thumbData = this._wrapper.createMemoryThumbnail();
298
+ resolve(thumbData);
299
+ } catch (error) {
300
+ reject(error);
301
+ }
302
+ });
303
+ }
304
+
305
+ // ============== FILE WRITERS ==============
306
+
307
+ /**
308
+ * 将处理后的图像写入 PPM 文件
309
+ * @param {string} filename - 输出文件名
310
+ * @returns {Promise<boolean>} - 成功状态
311
+ */
312
+ async writePPM(filename) {
313
+ return new Promise((resolve, reject) => {
314
+ try {
315
+ const result = this._wrapper.writePPM(filename);
316
+ resolve(result);
317
+ } catch (error) {
318
+ reject(error);
319
+ }
320
+ });
321
+ }
322
+
323
+ /**
324
+ * 将处理后的图像写入 TIFF 文件
325
+ * @param {string} filename - 输出文件名
326
+ * @returns {Promise<boolean>} - 成功状态
327
+ */
328
+ async writeTIFF(filename) {
329
+ return new Promise((resolve, reject) => {
330
+ try {
331
+ const result = this._wrapper.writeTIFF(filename);
332
+ resolve(result);
333
+ } catch (error) {
334
+ reject(error);
335
+ }
336
+ });
337
+ }
338
+
339
+ /**
340
+ * 将缩略图写入文件
341
+ * @param {string} filename - 输出文件名
342
+ * @returns {Promise<boolean>} - 成功状态
343
+ */
344
+ async writeThumbnail(filename) {
345
+ return new Promise((resolve, reject) => {
346
+ try {
347
+ const result = this._wrapper.writeThumbnail(filename);
348
+ resolve(result);
349
+ } catch (error) {
350
+ reject(error);
351
+ }
352
+ });
353
+ }
354
+
355
+ // ============== CONFIGURATION & SETTINGS ==============
356
+
357
+ /**
358
+ * 设置处理输出参数
359
+ * @param {Object} params - 参数对象
360
+ * @returns {Promise<boolean>} - 成功状态
361
+ */
362
+ async setOutputParams(params) {
363
+ return new Promise((resolve, reject) => {
364
+ try {
365
+ const result = this._wrapper.setOutputParams(params);
366
+ resolve(result);
367
+ } catch (error) {
368
+ reject(error);
369
+ }
370
+ });
371
+ }
372
+
373
+ /**
374
+ * 获取当前输出参数
375
+ * @returns {Promise<Object>} - 当前参数
376
+ */
377
+ async getOutputParams() {
378
+ return new Promise((resolve, reject) => {
379
+ try {
380
+ const params = this._wrapper.getOutputParams();
381
+ resolve(params);
382
+ } catch (error) {
383
+ reject(error);
384
+ }
385
+ });
386
+ }
387
+
388
+ // ============== UTILITY FUNCTIONS ==============
389
+
390
+ /**
391
+ * 检查图像是否使用浮点数据
392
+ * @returns {Promise<boolean>} - 浮点状态
393
+ */
394
+ async isFloatingPoint() {
395
+ return new Promise((resolve, reject) => {
396
+ try {
397
+ const result = this._wrapper.isFloatingPoint();
398
+ resolve(result);
399
+ } catch (error) {
400
+ reject(error);
401
+ }
402
+ });
403
+ }
404
+
405
+ /**
406
+ * 检查图像是否为富士旋转
407
+ * @returns {Promise<boolean>} - 富士旋转状态
408
+ */
409
+ async isFujiRotated() {
410
+ return new Promise((resolve, reject) => {
411
+ try {
412
+ const result = this._wrapper.isFujiRotated();
413
+ resolve(result);
414
+ } catch (error) {
415
+ reject(error);
416
+ }
417
+ });
418
+ }
419
+
420
+ /**
421
+ * 检查图像是否为 sRAW 格式
422
+ * @returns {Promise<boolean>} - sRAW 状态
423
+ */
424
+ async isSRAW() {
425
+ return new Promise((resolve, reject) => {
426
+ try {
427
+ const result = this._wrapper.isSRAW();
428
+ resolve(result);
429
+ } catch (error) {
430
+ reject(error);
431
+ }
432
+ });
433
+ }
434
+
435
+ /**
436
+ * 检查缩略图是否为 JPEG 格式
437
+ * @returns {Promise<boolean>} - JPEG 缩略图状态
438
+ */
439
+ async isJPEGThumb() {
440
+ return new Promise((resolve, reject) => {
441
+ try {
442
+ const result = this._wrapper.isJPEGThumb();
443
+ resolve(result);
444
+ } catch (error) {
445
+ reject(error);
446
+ }
447
+ });
448
+ }
449
+
450
+ /**
451
+ * 获取处理过程中的错误计数
452
+ * @returns {Promise<number>} - 错误数量
453
+ */
454
+ async errorCount() {
455
+ return new Promise((resolve, reject) => {
456
+ try {
457
+ const count = this._wrapper.errorCount();
458
+ resolve(count);
459
+ } catch (error) {
460
+ reject(error);
461
+ }
462
+ });
463
+ }
464
+
465
+ // ============== EXTENDED UTILITY FUNCTIONS ==============
466
+
467
+ /**
468
+ * 检查图像是否为尼康 sRAW 格式
469
+ * @returns {Promise<boolean>} - 如果是尼康 sRAW 则为 true
470
+ */
471
+ async isNikonSRAW() {
472
+ return new Promise((resolve, reject) => {
473
+ try {
474
+ const result = this._wrapper.isNikonSRAW();
475
+ resolve(result);
476
+ } catch (error) {
477
+ reject(error);
478
+ }
479
+ });
480
+ }
481
+
482
+ /**
483
+ * 检查图像是否为 Coolscan NEF 格式
484
+ * @returns {Promise<boolean>} - 如果是 Coolscan NEF 则为 true
485
+ */
486
+ async isCoolscanNEF() {
487
+ return new Promise((resolve, reject) => {
488
+ try {
489
+ const result = this._wrapper.isCoolscanNEF();
490
+ resolve(result);
491
+ } catch (error) {
492
+ reject(error);
493
+ }
494
+ });
495
+ }
496
+
497
+ /**
498
+ * 检查图像是否有浮点数据
499
+ * @returns {Promise<boolean>} - 如果有浮点数据则为 true
500
+ */
501
+ async haveFPData() {
502
+ return new Promise((resolve, reject) => {
503
+ try {
504
+ const result = this._wrapper.haveFPData();
505
+ resolve(result);
506
+ } catch (error) {
507
+ reject(error);
508
+ }
509
+ });
510
+ }
511
+
512
+ /**
513
+ * 获取 sRAW 中点值
514
+ * @returns {Promise<number>} - sRAW 中点
515
+ */
516
+ async srawMidpoint() {
517
+ return new Promise((resolve, reject) => {
518
+ try {
519
+ const result = this._wrapper.srawMidpoint();
520
+ resolve(result);
521
+ } catch (error) {
522
+ reject(error);
523
+ }
524
+ });
525
+ }
526
+
527
+ /**
528
+ * 检查缩略图是否正常
529
+ * @param {number} [maxSize=-1] - 最大尺寸限制
530
+ * @returns {Promise<number>} - 缩略图状态
531
+ */
532
+ async thumbOK(maxSize = -1) {
533
+ return new Promise((resolve, reject) => {
534
+ try {
535
+ const result = this._wrapper.thumbOK(maxSize);
536
+ resolve(result);
537
+ } catch (error) {
538
+ reject(error);
539
+ }
540
+ });
541
+ }
542
+
543
+ /**
544
+ * 获取解包器函数名称
545
+ * @returns {Promise<string>} - 解包器函数名称
546
+ */
547
+ async unpackFunctionName() {
548
+ return new Promise((resolve, reject) => {
549
+ try {
550
+ const result = this._wrapper.unpackFunctionName();
551
+ resolve(result);
552
+ } catch (error) {
553
+ reject(error);
554
+ }
555
+ });
556
+ }
557
+
558
+ /**
559
+ * 获取解码器信息
560
+ * @returns {Promise<Object>} - 包含名称和标志的解码器信息
561
+ */
562
+ async getDecoderInfo() {
563
+ return new Promise((resolve, reject) => {
564
+ try {
565
+ const result = this._wrapper.getDecoderInfo();
566
+ resolve(result);
567
+ } catch (error) {
568
+ reject(error);
569
+ }
570
+ });
571
+ }
572
+
573
+ // ============== ADVANCED PROCESSING ==============
574
+
575
+ /**
576
+ * 解包 RAW 数据(低级操作)
577
+ * @returns {Promise<boolean>} - 成功状态
578
+ */
579
+ async unpack() {
580
+ return new Promise((resolve, reject) => {
581
+ try {
582
+ const result = this._wrapper.unpack();
583
+ resolve(result);
584
+ } catch (error) {
585
+ reject(error);
586
+ }
587
+ });
588
+ }
589
+
590
+ /**
591
+ * 使用扩展选项将 RAW 转换为图像
592
+ * @param {boolean} [subtractBlack=true] - 是否减去黑电平
593
+ * @returns {Promise<boolean>} - 成功状态
594
+ */
595
+ async raw2ImageEx(subtractBlack = true) {
596
+ return new Promise((resolve, reject) => {
597
+ try {
598
+ const result = this._wrapper.raw2ImageEx(subtractBlack);
599
+ resolve(result);
600
+ } catch (error) {
601
+ reject(error);
602
+ }
603
+ });
604
+ }
605
+
606
+ /**
607
+ * 仅调整信息尺寸(不处理)
608
+ * @returns {Promise<boolean>} - 成功状态
609
+ */
610
+ async adjustSizesInfoOnly() {
611
+ return new Promise((resolve, reject) => {
612
+ try {
613
+ const result = this._wrapper.adjustSizesInfoOnly();
614
+ resolve(result);
615
+ } catch (error) {
616
+ reject(error);
617
+ }
618
+ });
619
+ }
620
+
621
+ /**
622
+ * 释放处理后的图像数据
623
+ * @returns {Promise<boolean>} - 成功状态
624
+ */
625
+ async freeImage() {
626
+ return new Promise((resolve, reject) => {
627
+ try {
628
+ const result = this._wrapper.freeImage();
629
+ resolve(result);
630
+ } catch (error) {
631
+ reject(error);
632
+ }
633
+ });
634
+ }
635
+
636
+ /**
637
+ * 将浮点数据转换为整数数据
638
+ * @param {number} [dmin=4096] - 最小数据值
639
+ * @param {number} [dmax=32767] - 最大数据值
640
+ * @param {number} [dtarget=16383] - 目标值
641
+ * @returns {Promise<boolean>} - 成功状态
642
+ */
643
+ async convertFloatToInt(dmin = 4096, dmax = 32767, dtarget = 16383) {
644
+ return new Promise((resolve, reject) => {
645
+ try {
646
+ const result = this._wrapper.convertFloatToInt(dmin, dmax, dtarget);
647
+ resolve(result);
648
+ } catch (error) {
649
+ reject(error);
650
+ }
651
+ });
652
+ }
653
+
654
+ // ============== MEMORY OPERATIONS EXTENDED ==============
655
+
656
+ /**
657
+ * 获取内存图像格式信息
658
+ * @returns {Promise<Object>} - 包含宽度、高度、颜色、位深度的格式信息
659
+ */
660
+ async getMemImageFormat() {
661
+ return new Promise((resolve, reject) => {
662
+ try {
663
+ const result = this._wrapper.getMemImageFormat();
664
+ resolve(result);
665
+ } catch (error) {
666
+ reject(error);
667
+ }
668
+ });
669
+ }
670
+
671
+ /**
672
+ * 将内存图像复制到缓冲区
673
+ * @param {Buffer} buffer - 目标缓冲区
674
+ * @param {number} stride - 行步长(字节)
675
+ * @param {boolean} bgr - 是否使用 BGR 顺序
676
+ * @returns {Promise<boolean>} - 成功状态
677
+ */
678
+ async copyMemImage(buffer, stride, bgr = false) {
679
+ return new Promise((resolve, reject) => {
680
+ try {
681
+ const result = this._wrapper.copyMemImage(buffer, stride, bgr);
682
+ resolve(result);
683
+ } catch (error) {
684
+ reject(error);
685
+ }
686
+ });
687
+ }
688
+
689
+ // ============== COLOR OPERATIONS ==============
690
+
691
+ /**
692
+ * 获取特定位置的颜色滤镜
693
+ * @param {number} row - 行位置
694
+ * @param {number} col - 列位置
695
+ * @returns {Promise<number>} - 颜色值
696
+ */
697
+ async getColorAt(row, col) {
698
+ return new Promise((resolve, reject) => {
699
+ try {
700
+ const result = this._wrapper.getColorAt(row, col);
701
+ resolve(result);
702
+ } catch (error) {
703
+ reject(error);
704
+ }
705
+ });
706
+ }
707
+
708
+ /**
709
+ * 获取物理白点(基于 cam_mul+cam_xyz 的 xy、Kelvin、Duv)
710
+ * @returns {Promise<{xy:{x:number,y:number}, kelvin:number, duv:number}>}
711
+ */
712
+ async getWhitepointPhysics() {
713
+ return new Promise((resolve, reject) => {
714
+ try {
715
+ const result = this._wrapper.getWhitepointPhysics();
716
+ resolve(result);
717
+ } catch (error) {
718
+ reject(error);
719
+ }
720
+ });
721
+ }
722
+
723
+ // ============== MEMORY STREAM OPERATIONS (NEW FEATURE) ==============
724
+
725
+ /**
726
+ * 在内存中创建处理后的图像作为 JPEG 缓冲区
727
+ * @param {Object} options - JPEG 转换选项
728
+ * @param {number} [options.quality=85] - JPEG 质量 (1-100)
729
+ * @param {number} [options.width] - 目标宽度(如果未指定高度则保持宽高比)
730
+ * @param {number} [options.height] - 目标高度(如果未指定宽度则保持宽高比)
731
+ * @param {boolean} [options.progressive=false] - 使用渐进式 JPEG
732
+ * @param {boolean} [options.mozjpeg=true] - 使用 mozjpeg 编码器获得更好的压缩
733
+ * @param {number} [options.chromaSubsampling='4:2:0'] - 色度子采样 ('4:4:4', '4:2:2', '4:2:0')
734
+ * @param {boolean} [options.trellisQuantisation=false] - 启用网格量化
735
+ * @param {boolean} [options.optimizeScans=false] - 优化扫描顺序
736
+ * @param {number} [options.overshootDeringing=false] - 过冲去振铃
737
+ * @param {boolean} [options.optimizeCoding=true] - 优化霍夫曼编码
738
+ * @param {string} [options.colorSpace='srgb'] - 输出色彩空间 ('srgb', 'rec2020', 'p3', 'cmyk')
739
+ * @returns {Promise<Object>} - 包含元数据的 JPEG 缓冲区
740
+ */
741
+ async createJPEGBuffer(options = {}) {
742
+ return new Promise(async (resolve, reject) => {
743
+ try {
744
+ // 设置具有性能优化值的默认选项
745
+ const opts = {
746
+ quality: options.quality || 85,
747
+ progressive: options.progressive || false,
748
+ mozjpeg: options.mozjpeg !== false, // 默认为 true 以获得更好的压缩
749
+ chromaSubsampling: options.chromaSubsampling || "4:2:0",
750
+ trellisQuantisation: options.trellisQuantisation || false,
751
+ optimizeScans: options.optimizeScans || false,
752
+ overshootDeringing: options.overshootDeringing || false,
753
+ optimizeCoding: options.optimizeCoding !== false, // 默认为 true
754
+ colorSpace: options.colorSpace || "srgb",
755
+ ...options,
756
+ };
757
+
758
+ const startTime = process.hrtime.bigint();
759
+
760
+ // 智能处理:仅在未处理时处理
761
+ if (!this._isProcessed) {
762
+ await this.processImage();
763
+ }
764
+
765
+ // 在内存中创建处理后的图像(如果可用则使用缓存)
766
+ const imageData = await this.createMemoryImage();
767
+
768
+ if (!imageData || !imageData.data) {
769
+ throw new Error("从 RAW 数据创建内存图像失败");
770
+ }
771
+
772
+ // 将 LibRaw RGB 数据转换为 Sharp 兼容缓冲区
773
+ let sharpInstance;
774
+
775
+ // 确定这是否为大图像以进行性能优化
776
+ const isLargeImage = imageData.width * imageData.height > 20_000_000; // > 20MP
777
+ const fastMode = opts.fastMode !== false; // 默认为快速模式
778
+
779
+ // 优化的 Sharp 配置
780
+ const sharpConfig = {
781
+ raw: {
782
+ width: imageData.width,
783
+ height: imageData.height,
784
+ channels: imageData.colors,
785
+ premultiplied: false,
786
+ },
787
+ // 性能优化
788
+ sequentialRead: true,
789
+ limitInputPixels: false,
790
+ density: fastMode ? 72 : 300, // 降低 DPI 以提高速度
791
+ };
792
+
793
+ if (imageData.bits === 16) {
794
+ sharpConfig.raw.depth = "ushort";
795
+ }
796
+
797
+ sharpInstance = sharp(imageData.data, sharpConfig);
798
+
799
+ // 如果指定则应用调整大小并进行性能优化
800
+ if (opts.width || opts.height) {
801
+ const resizeOptions = {
802
+ withoutEnlargement: true,
803
+ // 对大图像或启用快速模式时使用更快的核
804
+ kernel:
805
+ isLargeImage || fastMode
806
+ ? sharp.kernel.cubic
807
+ : sharp.kernel.lanczos3,
808
+ fit: "inside",
809
+ fastShrinkOnLoad: true, // 启用快速加载时缩小优化
810
+ };
811
+
812
+ if (opts.width && opts.height) {
813
+ sharpInstance = sharpInstance.resize(
814
+ opts.width,
815
+ opts.height,
816
+ resizeOptions
817
+ );
818
+ } else if (opts.width) {
819
+ sharpInstance = sharpInstance.resize(
820
+ opts.width,
821
+ null,
822
+ resizeOptions
823
+ );
824
+ } else {
825
+ sharpInstance = sharpInstance.resize(
826
+ null,
827
+ opts.height,
828
+ resizeOptions
829
+ );
830
+ }
831
+ }
832
+
833
+ // 配置色彩空间
834
+ switch (opts.colorSpace.toLowerCase()) {
835
+ case "rec2020":
836
+ sharpInstance = sharpInstance.toColorspace("rec2020");
837
+ break;
838
+ case "p3":
839
+ sharpInstance = sharpInstance.toColorspace("p3");
840
+ break;
841
+ case "cmyk":
842
+ sharpInstance = sharpInstance.toColorspace("cmyk");
843
+ break;
844
+ case "srgb":
845
+ default:
846
+ sharpInstance = sharpInstance.toColorspace("srgb");
847
+ break;
848
+ }
849
+
850
+ // 配置 JPEG 选项并进行性能优化
851
+ const jpegOptions = {
852
+ quality: Math.max(1, Math.min(100, opts.quality)),
853
+ progressive: fastMode ? false : opts.progressive, // 为速度禁用渐进式
854
+ mozjpeg: fastMode ? false : opts.mozjpeg, // 为速度禁用 mozjpeg
855
+ trellisQuantisation: fastMode ? false : opts.trellisQuantisation,
856
+ optimizeScans: fastMode ? false : opts.optimizeScans,
857
+ overshootDeringing: false, // 总是为速度禁用
858
+ optimizeCoding: fastMode ? false : opts.optimizeCoding,
859
+ // 为 JPEG 编码添加努力控制
860
+ effort: fastMode ? 1 : Math.min(opts.effort || 4, 6),
861
+ };
862
+
863
+ // 设置色度子采样
864
+ switch (opts.chromaSubsampling) {
865
+ case "4:4:4":
866
+ jpegOptions.chromaSubsampling = "4:4:4";
867
+ break;
868
+ case "4:2:2":
869
+ jpegOptions.chromaSubsampling = "4:4:4"; // Sharp 不支持 4:2:2,改用 4:4:4
870
+ break;
871
+ case "4:2:0":
872
+ default:
873
+ jpegOptions.chromaSubsampling = "4:2:0";
874
+ break;
875
+ }
876
+
877
+ // 转换为 JPEG 并获取缓冲区
878
+ const jpegBuffer = await sharpInstance
879
+ .jpeg(jpegOptions)
880
+ .toBuffer({ resolveWithObject: true });
881
+
882
+ const endTime = process.hrtime.bigint();
883
+ const processingTime = Number(endTime - startTime) / 1000000; // 转换为毫秒
884
+
885
+ // 计算压缩比
886
+ const originalSize = imageData.dataSize;
887
+ const compressedSize = jpegBuffer.data.length;
888
+ const compressionRatio = originalSize / compressedSize;
889
+
890
+ const result = {
891
+ success: true,
892
+ buffer: jpegBuffer.data,
893
+ metadata: {
894
+ originalDimensions: {
895
+ width: imageData.width,
896
+ height: imageData.height,
897
+ },
898
+ outputDimensions: {
899
+ width: jpegBuffer.info.width,
900
+ height: jpegBuffer.info.height,
901
+ },
902
+ fileSize: {
903
+ original: originalSize,
904
+ compressed: compressedSize,
905
+ compressionRatio: compressionRatio.toFixed(2),
906
+ },
907
+ processing: {
908
+ timeMs: processingTime.toFixed(2),
909
+ throughputMBps: (
910
+ originalSize /
911
+ 1024 /
912
+ 1024 /
913
+ (processingTime / 1000)
914
+ ).toFixed(2),
915
+ },
916
+ jpegOptions: jpegOptions,
917
+ },
918
+ };
919
+
920
+ resolve(result);
921
+ } catch (error) {
922
+ reject(new Error(`JPEG buffer creation failed: ${error.message}`));
923
+ }
924
+ });
925
+ }
926
+
927
+ /**
928
+ * 在内存中创建处理后的图像作为 PNG 缓冲区
929
+ * @param {Object} options - PNG 转换选项
930
+ * @param {number} [options.width] - 目标宽度
931
+ * @param {number} [options.height] - 目标高度
932
+ * @param {number} [options.compressionLevel=6] - PNG 压缩级别 (0-9)
933
+ * @param {boolean} [options.progressive=false] - 使用渐进式 PNG
934
+ * @param {string} [options.colorSpace='srgb'] - 输出色彩空间
935
+ * @returns {Promise<Object>} - 包含元数据的 PNG 缓冲区
936
+ */
937
+ async createPNGBuffer(options = {}) {
938
+ return new Promise(async (resolve, reject) => {
939
+ try {
940
+ const startTime = process.hrtime.bigint();
941
+
942
+ // 智能处理:仅在未处理时处理
943
+ if (!this._isProcessed) {
944
+ await this.processImage();
945
+ }
946
+
947
+ // 在内存中创建处理后的图像(如果可用则使用缓存)
948
+ const imageData = await this.createMemoryImage();
949
+
950
+ if (!imageData || !imageData.data) {
951
+ throw new Error("从 RAW 数据创建内存图像失败");
952
+ }
953
+
954
+ // 设置 Sharp 配置
955
+ const sharpConfig = {
956
+ raw: {
957
+ width: imageData.width,
958
+ height: imageData.height,
959
+ channels: imageData.colors,
960
+ premultiplied: false,
961
+ },
962
+ sequentialRead: true,
963
+ limitInputPixels: false,
964
+ };
965
+
966
+ if (imageData.bits === 16) {
967
+ sharpConfig.raw.depth = "ushort";
968
+ }
969
+
970
+ let sharpInstance = sharp(imageData.data, sharpConfig);
971
+
972
+ // 如果指定则应用调整大小
973
+ if (options.width || options.height) {
974
+ const resizeOptions = {
975
+ withoutEnlargement: true,
976
+ kernel: sharp.kernel.lanczos3,
977
+ fit: "inside",
978
+ fastShrinkOnLoad: true,
979
+ };
980
+
981
+ if (options.width && options.height) {
982
+ sharpInstance = sharpInstance.resize(
983
+ options.width,
984
+ options.height,
985
+ resizeOptions
986
+ );
987
+ } else if (options.width) {
988
+ sharpInstance = sharpInstance.resize(
989
+ options.width,
990
+ null,
991
+ resizeOptions
992
+ );
993
+ } else {
994
+ sharpInstance = sharpInstance.resize(
995
+ null,
996
+ options.height,
997
+ resizeOptions
998
+ );
999
+ }
1000
+ }
1001
+
1002
+ // 配置色彩空间
1003
+ switch ((options.colorSpace || "srgb").toLowerCase()) {
1004
+ case "rec2020":
1005
+ sharpInstance = sharpInstance.toColorspace("rec2020");
1006
+ break;
1007
+ case "p3":
1008
+ sharpInstance = sharpInstance.toColorspace("p3");
1009
+ break;
1010
+ case "srgb":
1011
+ default:
1012
+ sharpInstance = sharpInstance.toColorspace("srgb");
1013
+ break;
1014
+ }
1015
+
1016
+ // 配置 PNG 选项
1017
+ const pngOptions = {
1018
+ compressionLevel: Math.max(
1019
+ 0,
1020
+ Math.min(9, options.compressionLevel || 6)
1021
+ ),
1022
+ progressive: options.progressive || false,
1023
+ quality: 100, // PNG 是无损的
1024
+ };
1025
+
1026
+ // 转换为 PNG 并获取缓冲区
1027
+ const pngBuffer = await sharpInstance
1028
+ .png(pngOptions)
1029
+ .toBuffer({ resolveWithObject: true });
1030
+
1031
+ const endTime = process.hrtime.bigint();
1032
+ const processingTime = Number(endTime - startTime) / 1000000;
1033
+
1034
+ const result = {
1035
+ success: true,
1036
+ buffer: pngBuffer.data,
1037
+ metadata: {
1038
+ originalDimensions: {
1039
+ width: imageData.width,
1040
+ height: imageData.height,
1041
+ },
1042
+ outputDimensions: {
1043
+ width: pngBuffer.info.width,
1044
+ height: pngBuffer.info.height,
1045
+ },
1046
+ fileSize: {
1047
+ original: imageData.dataSize,
1048
+ compressed: pngBuffer.data.length,
1049
+ compressionRatio: (
1050
+ imageData.dataSize / pngBuffer.data.length
1051
+ ).toFixed(2),
1052
+ },
1053
+ processing: {
1054
+ timeMs: processingTime.toFixed(2),
1055
+ throughputMBps: (
1056
+ imageData.dataSize /
1057
+ 1024 /
1058
+ 1024 /
1059
+ (processingTime / 1000)
1060
+ ).toFixed(2),
1061
+ },
1062
+ pngOptions: pngOptions,
1063
+ },
1064
+ };
1065
+
1066
+ resolve(result);
1067
+ } catch (error) {
1068
+ reject(new Error(`PNG buffer creation failed: ${error.message}`));
1069
+ }
1070
+ });
1071
+ }
1072
+
1073
+ /**
1074
+ * Create processed image as TIFF buffer in memory
1075
+ * @param {Object} options - TIFF conversion options
1076
+ * @param {number} [options.width] - Target width
1077
+ * @param {number} [options.height] - Target height
1078
+ * @param {string} [options.compression='lzw'] - TIFF compression ('none', 'lzw', 'jpeg', 'zip')
1079
+ * @param {number} [options.quality=90] - JPEG quality when using JPEG compression
1080
+ * @param {boolean} [options.pyramid=false] - Create pyramidal TIFF
1081
+ * @param {string} [options.colorSpace='srgb'] - Output color space
1082
+ * @returns {Promise<Object>} - TIFF buffer with metadata
1083
+ */
1084
+ async createTIFFBuffer(options = {}) {
1085
+ return new Promise(async (resolve, reject) => {
1086
+ try {
1087
+ const startTime = process.hrtime.bigint();
1088
+
1089
+ // 智能处理:仅在未处理时处理
1090
+ if (!this._isProcessed) {
1091
+ await this.processImage();
1092
+ }
1093
+
1094
+ // 在内存中创建处理后的图像(如果可用则使用缓存)
1095
+ const imageData = await this.createMemoryImage();
1096
+
1097
+ if (!imageData || !imageData.data) {
1098
+ throw new Error("从 RAW 数据创建内存图像失败");
1099
+ }
1100
+
1101
+ // 设置 Sharp 配置
1102
+ const sharpConfig = {
1103
+ raw: {
1104
+ width: imageData.width,
1105
+ height: imageData.height,
1106
+ channels: imageData.colors,
1107
+ premultiplied: false,
1108
+ },
1109
+ sequentialRead: true,
1110
+ limitInputPixels: false,
1111
+ };
1112
+
1113
+ if (imageData.bits === 16) {
1114
+ sharpConfig.raw.depth = "ushort";
1115
+ }
1116
+
1117
+ let sharpInstance = sharp(imageData.data, sharpConfig);
1118
+
1119
+ // 如果指定则应用调整大小
1120
+ if (options.width || options.height) {
1121
+ const resizeOptions = {
1122
+ withoutEnlargement: true,
1123
+ kernel: sharp.kernel.lanczos3,
1124
+ fit: "inside",
1125
+ fastShrinkOnLoad: true,
1126
+ };
1127
+
1128
+ if (options.width && options.height) {
1129
+ sharpInstance = sharpInstance.resize(
1130
+ options.width,
1131
+ options.height,
1132
+ resizeOptions
1133
+ );
1134
+ } else if (options.width) {
1135
+ sharpInstance = sharpInstance.resize(
1136
+ options.width,
1137
+ null,
1138
+ resizeOptions
1139
+ );
1140
+ } else {
1141
+ sharpInstance = sharpInstance.resize(
1142
+ null,
1143
+ options.height,
1144
+ resizeOptions
1145
+ );
1146
+ }
1147
+ }
1148
+
1149
+ // 配置色彩空间
1150
+ switch ((options.colorSpace || "srgb").toLowerCase()) {
1151
+ case "rec2020":
1152
+ sharpInstance = sharpInstance.toColorspace("rec2020");
1153
+ break;
1154
+ case "p3":
1155
+ sharpInstance = sharpInstance.toColorspace("p3");
1156
+ break;
1157
+ case "srgb":
1158
+ default:
1159
+ sharpInstance = sharpInstance.toColorspace("srgb");
1160
+ break;
1161
+ }
1162
+
1163
+ // 配置 TIFF 选项
1164
+ const tiffOptions = {
1165
+ compression: options.compression || "lzw",
1166
+ pyramid: options.pyramid || false,
1167
+ quality: options.quality || 90,
1168
+ };
1169
+
1170
+ // 转换为 TIFF 并获取缓冲区
1171
+ const tiffBuffer = await sharpInstance
1172
+ .tiff(tiffOptions)
1173
+ .toBuffer({ resolveWithObject: true });
1174
+
1175
+ const endTime = process.hrtime.bigint();
1176
+ const processingTime = Number(endTime - startTime) / 1000000;
1177
+
1178
+ const result = {
1179
+ success: true,
1180
+ buffer: tiffBuffer.data,
1181
+ metadata: {
1182
+ originalDimensions: {
1183
+ width: imageData.width,
1184
+ height: imageData.height,
1185
+ },
1186
+ outputDimensions: {
1187
+ width: tiffBuffer.info.width,
1188
+ height: tiffBuffer.info.height,
1189
+ },
1190
+ fileSize: {
1191
+ original: imageData.dataSize,
1192
+ compressed: tiffBuffer.data.length,
1193
+ compressionRatio: (
1194
+ imageData.dataSize / tiffBuffer.data.length
1195
+ ).toFixed(2),
1196
+ },
1197
+ processing: {
1198
+ timeMs: processingTime.toFixed(2),
1199
+ throughputMBps: (
1200
+ imageData.dataSize /
1201
+ 1024 /
1202
+ 1024 /
1203
+ (processingTime / 1000)
1204
+ ).toFixed(2),
1205
+ },
1206
+ tiffOptions: tiffOptions,
1207
+ },
1208
+ };
1209
+
1210
+ resolve(result);
1211
+ } catch (error) {
1212
+ reject(new Error(`TIFF buffer creation failed: ${error.message}`));
1213
+ }
1214
+ });
1215
+ }
1216
+
1217
+ /**
1218
+ * Create processed image as WebP buffer in memory
1219
+ * @param {Object} options - WebP conversion options
1220
+ * @param {number} [options.width] - Target width
1221
+ * @param {number} [options.height] - Target height
1222
+ * @param {number} [options.quality=80] - WebP quality (1-100)
1223
+ * @param {boolean} [options.lossless=false] - Use lossless WebP
1224
+ * @param {number} [options.effort=4] - Encoding effort (0-6)
1225
+ * @param {string} [options.colorSpace='srgb'] - Output color space
1226
+ * @returns {Promise<Object>} - WebP buffer with metadata
1227
+ */
1228
+ async createWebPBuffer(options = {}) {
1229
+ return new Promise(async (resolve, reject) => {
1230
+ try {
1231
+ const startTime = process.hrtime.bigint();
1232
+
1233
+ // 智能处理:仅在未处理时处理
1234
+ if (!this._isProcessed) {
1235
+ await this.processImage();
1236
+ }
1237
+
1238
+ // 在内存中创建处理后的图像(如果可用则使用缓存)
1239
+ const imageData = await this.createMemoryImage();
1240
+
1241
+ if (!imageData || !imageData.data) {
1242
+ throw new Error("从 RAW 数据创建内存图像失败");
1243
+ }
1244
+
1245
+ // 设置 Sharp 配置
1246
+ const sharpConfig = {
1247
+ raw: {
1248
+ width: imageData.width,
1249
+ height: imageData.height,
1250
+ channels: imageData.colors,
1251
+ premultiplied: false,
1252
+ },
1253
+ sequentialRead: true,
1254
+ limitInputPixels: false,
1255
+ };
1256
+
1257
+ if (imageData.bits === 16) {
1258
+ sharpConfig.raw.depth = "ushort";
1259
+ }
1260
+
1261
+ let sharpInstance = sharp(imageData.data, sharpConfig);
1262
+
1263
+ // 如果指定则应用调整大小
1264
+ if (options.width || options.height) {
1265
+ const resizeOptions = {
1266
+ withoutEnlargement: true,
1267
+ kernel: sharp.kernel.lanczos3,
1268
+ fit: "inside",
1269
+ fastShrinkOnLoad: true,
1270
+ };
1271
+
1272
+ if (options.width && options.height) {
1273
+ sharpInstance = sharpInstance.resize(
1274
+ options.width,
1275
+ options.height,
1276
+ resizeOptions
1277
+ );
1278
+ } else if (options.width) {
1279
+ sharpInstance = sharpInstance.resize(
1280
+ options.width,
1281
+ null,
1282
+ resizeOptions
1283
+ );
1284
+ } else {
1285
+ sharpInstance = sharpInstance.resize(
1286
+ null,
1287
+ options.height,
1288
+ resizeOptions
1289
+ );
1290
+ }
1291
+ }
1292
+
1293
+ // 配置色彩空间
1294
+ switch ((options.colorSpace || "srgb").toLowerCase()) {
1295
+ case "rec2020":
1296
+ sharpInstance = sharpInstance.toColorspace("rec2020");
1297
+ break;
1298
+ case "p3":
1299
+ sharpInstance = sharpInstance.toColorspace("p3");
1300
+ break;
1301
+ case "srgb":
1302
+ default:
1303
+ sharpInstance = sharpInstance.toColorspace("srgb");
1304
+ break;
1305
+ }
1306
+
1307
+ // 配置 WebP 选项
1308
+ const webpOptions = {
1309
+ quality: Math.max(1, Math.min(100, options.quality || 80)),
1310
+ lossless: options.lossless || false,
1311
+ effort: Math.max(0, Math.min(6, options.effort || 4)),
1312
+ };
1313
+
1314
+ // 转换为 WebP 并获取缓冲区
1315
+ const webpBuffer = await sharpInstance
1316
+ .webp(webpOptions)
1317
+ .toBuffer({ resolveWithObject: true });
1318
+
1319
+ const endTime = process.hrtime.bigint();
1320
+ const processingTime = Number(endTime - startTime) / 1000000;
1321
+
1322
+ const result = {
1323
+ success: true,
1324
+ buffer: webpBuffer.data,
1325
+ metadata: {
1326
+ originalDimensions: {
1327
+ width: imageData.width,
1328
+ height: imageData.height,
1329
+ },
1330
+ outputDimensions: {
1331
+ width: webpBuffer.info.width,
1332
+ height: webpBuffer.info.height,
1333
+ },
1334
+ fileSize: {
1335
+ original: imageData.dataSize,
1336
+ compressed: webpBuffer.data.length,
1337
+ compressionRatio: (
1338
+ imageData.dataSize / webpBuffer.data.length
1339
+ ).toFixed(2),
1340
+ },
1341
+ processing: {
1342
+ timeMs: processingTime.toFixed(2),
1343
+ throughputMBps: (
1344
+ imageData.dataSize /
1345
+ 1024 /
1346
+ 1024 /
1347
+ (processingTime / 1000)
1348
+ ).toFixed(2),
1349
+ },
1350
+ webpOptions: webpOptions,
1351
+ },
1352
+ };
1353
+
1354
+ resolve(result);
1355
+ } catch (error) {
1356
+ reject(new Error(`WebP buffer creation failed: ${error.message}`));
1357
+ }
1358
+ });
1359
+ }
1360
+
1361
+ /**
1362
+ * Create processed image as AVIF buffer in memory
1363
+ * @param {Object} options - AVIF conversion options
1364
+ * @param {number} [options.width] - Target width
1365
+ * @param {number} [options.height] - Target height
1366
+ * @param {number} [options.quality=50] - AVIF quality (1-100)
1367
+ * @param {boolean} [options.lossless=false] - Use lossless AVIF
1368
+ * @param {number} [options.effort=4] - Encoding effort (0-9)
1369
+ * @param {string} [options.colorSpace='srgb'] - Output color space
1370
+ * @returns {Promise<Object>} - AVIF buffer with metadata
1371
+ */
1372
+ async createAVIFBuffer(options = {}) {
1373
+ return new Promise(async (resolve, reject) => {
1374
+ try {
1375
+ const startTime = process.hrtime.bigint();
1376
+
1377
+ // 智能处理:仅在未处理时处理
1378
+ if (!this._isProcessed) {
1379
+ await this.processImage();
1380
+ }
1381
+
1382
+ // 在内存中创建处理后的图像(如果可用则使用缓存)
1383
+ const imageData = await this.createMemoryImage();
1384
+
1385
+ if (!imageData || !imageData.data) {
1386
+ throw new Error("从 RAW 数据创建内存图像失败");
1387
+ }
1388
+
1389
+ // 设置 Sharp 配置
1390
+ const sharpConfig = {
1391
+ raw: {
1392
+ width: imageData.width,
1393
+ height: imageData.height,
1394
+ channels: imageData.colors,
1395
+ premultiplied: false,
1396
+ },
1397
+ sequentialRead: true,
1398
+ limitInputPixels: false,
1399
+ };
1400
+
1401
+ if (imageData.bits === 16) {
1402
+ sharpConfig.raw.depth = "ushort";
1403
+ }
1404
+
1405
+ let sharpInstance = sharp(imageData.data, sharpConfig);
1406
+
1407
+ // 如果指定则应用调整大小
1408
+ if (options.width || options.height) {
1409
+ const resizeOptions = {
1410
+ withoutEnlargement: true,
1411
+ kernel: sharp.kernel.lanczos3,
1412
+ fit: "inside",
1413
+ fastShrinkOnLoad: true,
1414
+ };
1415
+
1416
+ if (options.width && options.height) {
1417
+ sharpInstance = sharpInstance.resize(
1418
+ options.width,
1419
+ options.height,
1420
+ resizeOptions
1421
+ );
1422
+ } else if (options.width) {
1423
+ sharpInstance = sharpInstance.resize(
1424
+ options.width,
1425
+ null,
1426
+ resizeOptions
1427
+ );
1428
+ } else {
1429
+ sharpInstance = sharpInstance.resize(
1430
+ null,
1431
+ options.height,
1432
+ resizeOptions
1433
+ );
1434
+ }
1435
+ }
1436
+
1437
+ // 配置色彩空间
1438
+ switch ((options.colorSpace || "srgb").toLowerCase()) {
1439
+ case "rec2020":
1440
+ sharpInstance = sharpInstance.toColorspace("rec2020");
1441
+ break;
1442
+ case "p3":
1443
+ sharpInstance = sharpInstance.toColorspace("p3");
1444
+ break;
1445
+ case "srgb":
1446
+ default:
1447
+ sharpInstance = sharpInstance.toColorspace("srgb");
1448
+ break;
1449
+ }
1450
+
1451
+ // 配置 AVIF 选项
1452
+ const avifOptions = {
1453
+ quality: Math.max(1, Math.min(100, options.quality || 50)),
1454
+ lossless: options.lossless || false,
1455
+ effort: Math.max(0, Math.min(9, options.effort || 4)),
1456
+ };
1457
+
1458
+ // 转换为 AVIF 并获取缓冲区
1459
+ const avifBuffer = await sharpInstance
1460
+ .avif(avifOptions)
1461
+ .toBuffer({ resolveWithObject: true });
1462
+
1463
+ const endTime = process.hrtime.bigint();
1464
+ const processingTime = Number(endTime - startTime) / 1000000;
1465
+
1466
+ const result = {
1467
+ success: true,
1468
+ buffer: avifBuffer.data,
1469
+ metadata: {
1470
+ originalDimensions: {
1471
+ width: imageData.width,
1472
+ height: imageData.height,
1473
+ },
1474
+ outputDimensions: {
1475
+ width: avifBuffer.info.width,
1476
+ height: avifBuffer.info.height,
1477
+ },
1478
+ fileSize: {
1479
+ original: imageData.dataSize,
1480
+ compressed: avifBuffer.data.length,
1481
+ compressionRatio: (
1482
+ imageData.dataSize / avifBuffer.data.length
1483
+ ).toFixed(2),
1484
+ },
1485
+ processing: {
1486
+ timeMs: processingTime.toFixed(2),
1487
+ throughputMBps: (
1488
+ imageData.dataSize /
1489
+ 1024 /
1490
+ 1024 /
1491
+ (processingTime / 1000)
1492
+ ).toFixed(2),
1493
+ },
1494
+ avifOptions: avifOptions,
1495
+ },
1496
+ };
1497
+
1498
+ resolve(result);
1499
+ } catch (error) {
1500
+ reject(new Error(`AVIF buffer creation failed: ${error.message}`));
1501
+ }
1502
+ });
1503
+ }
1504
+
1505
+ /**
1506
+ * Create raw PPM buffer from processed image data
1507
+ * @returns {Promise<Object>} - PPM buffer with metadata
1508
+ */
1509
+ async createPPMBuffer() {
1510
+ return new Promise(async (resolve, reject) => {
1511
+ try {
1512
+ const startTime = process.hrtime.bigint();
1513
+
1514
+ // 智能处理:仅在未处理时处理
1515
+ if (!this._isProcessed) {
1516
+ await this.processImage();
1517
+ }
1518
+
1519
+ // 在内存中创建处理后的图像(如果可用则使用缓存)
1520
+ const imageData = await this.createMemoryImage();
1521
+
1522
+ if (!imageData || !imageData.data) {
1523
+ throw new Error("从 RAW 数据创建内存图像失败");
1524
+ }
1525
+
1526
+ // 创建 PPM 头部
1527
+ const header = `P6\n${imageData.width} ${imageData.height}\n255\n`;
1528
+ const headerBuffer = Buffer.from(header, "ascii");
1529
+
1530
+ // 如果需要,将图像数据转换为 8 位 RGB
1531
+ let rgbData;
1532
+ if (imageData.bits === 16) {
1533
+ // 将 16 位转换为 8 位
1534
+ const pixels = imageData.width * imageData.height;
1535
+ const channels = imageData.colors;
1536
+ rgbData = Buffer.alloc(pixels * 3); // PPM 总是 RGB
1537
+
1538
+ for (let i = 0; i < pixels; i++) {
1539
+ const srcOffset = i * channels * 2; // 16 位数据
1540
+ const dstOffset = i * 3;
1541
+
1542
+ // 读取 16 位值并转换为 8 位
1543
+ rgbData[dstOffset] = Math.min(
1544
+ 255,
1545
+ Math.floor((imageData.data.readUInt16LE(srcOffset) / 65535) * 255)
1546
+ ); // R
1547
+ rgbData[dstOffset + 1] = Math.min(
1548
+ 255,
1549
+ Math.floor(
1550
+ (imageData.data.readUInt16LE(srcOffset + 2) / 65535) * 255
1551
+ )
1552
+ ); // G
1553
+ rgbData[dstOffset + 2] = Math.min(
1554
+ 255,
1555
+ Math.floor(
1556
+ (imageData.data.readUInt16LE(srcOffset + 4) / 65535) * 255
1557
+ )
1558
+ ); // B
1559
+ }
1560
+ } else {
1561
+ // Already 8-bit, just copy RGB channels
1562
+ const pixels = imageData.width * imageData.height;
1563
+ const channels = imageData.colors;
1564
+ rgbData = Buffer.alloc(pixels * 3);
1565
+
1566
+ for (let i = 0; i < pixels; i++) {
1567
+ const srcOffset = i * channels;
1568
+ const dstOffset = i * 3;
1569
+
1570
+ rgbData[dstOffset] = imageData.data[srcOffset]; // R
1571
+ rgbData[dstOffset + 1] = imageData.data[srcOffset + 1]; // G
1572
+ rgbData[dstOffset + 2] = imageData.data[srcOffset + 2]; // B
1573
+ }
1574
+ }
1575
+
1576
+ // Combine header and data
1577
+ const ppmBuffer = Buffer.concat([headerBuffer, rgbData]);
1578
+
1579
+ const endTime = process.hrtime.bigint();
1580
+ const processingTime = Number(endTime - startTime) / 1000000;
1581
+
1582
+ const result = {
1583
+ success: true,
1584
+ buffer: ppmBuffer,
1585
+ metadata: {
1586
+ format: "PPM",
1587
+ dimensions: {
1588
+ width: imageData.width,
1589
+ height: imageData.height,
1590
+ },
1591
+ fileSize: {
1592
+ original: imageData.dataSize,
1593
+ compressed: ppmBuffer.length,
1594
+ compressionRatio: (imageData.dataSize / ppmBuffer.length).toFixed(
1595
+ 2
1596
+ ),
1597
+ },
1598
+ processing: {
1599
+ timeMs: processingTime.toFixed(2),
1600
+ throughputMBps: (
1601
+ imageData.dataSize /
1602
+ 1024 /
1603
+ 1024 /
1604
+ (processingTime / 1000)
1605
+ ).toFixed(2),
1606
+ },
1607
+ },
1608
+ };
1609
+
1610
+ resolve(result);
1611
+ } catch (error) {
1612
+ reject(new Error(`PPM buffer creation failed: ${error.message}`));
1613
+ }
1614
+ });
1615
+ }
1616
+
1617
+ /**
1618
+ * Create thumbnail as JPEG buffer in memory
1619
+ * @param {Object} options - JPEG options for thumbnail
1620
+ * @param {number} [options.quality=85] - JPEG quality
1621
+ * @param {number} [options.maxSize] - Maximum dimension size
1622
+ * @returns {Promise<Object>} - Thumbnail JPEG buffer with metadata
1623
+ */
1624
+ async createThumbnailJPEGBuffer(options = {}) {
1625
+ return new Promise(async (resolve, reject) => {
1626
+ try {
1627
+ const startTime = process.hrtime.bigint();
1628
+
1629
+ // Unpack thumbnail if needed
1630
+ await this.unpackThumbnail();
1631
+
1632
+ // Create thumbnail in memory
1633
+ const thumbData = await this.createMemoryThumbnail();
1634
+
1635
+ if (!thumbData || !thumbData.data) {
1636
+ throw new Error("Failed to create memory thumbnail");
1637
+ }
1638
+
1639
+ let sharpInstance;
1640
+
1641
+ // Check if thumbnail is already JPEG
1642
+ if (await this.isJPEGThumb()) {
1643
+ // Thumbnail is already JPEG, return directly or reprocess if options specified
1644
+ if (!options.quality && !options.maxSize) {
1645
+ const result = {
1646
+ success: true,
1647
+ buffer: thumbData.data,
1648
+ metadata: {
1649
+ format: "JPEG",
1650
+ dimensions: {
1651
+ width: thumbData.width,
1652
+ height: thumbData.height,
1653
+ },
1654
+ fileSize: {
1655
+ compressed: thumbData.data.length,
1656
+ },
1657
+ processing: {
1658
+ timeMs: "0.00",
1659
+ fromCache: true,
1660
+ },
1661
+ },
1662
+ };
1663
+ resolve(result);
1664
+ return;
1665
+ } else {
1666
+ // Reprocess existing JPEG with new options
1667
+ sharpInstance = sharp(thumbData.data);
1668
+ }
1669
+ } else {
1670
+ // Convert RAW thumbnail data
1671
+ const sharpConfig = {
1672
+ raw: {
1673
+ width: thumbData.width,
1674
+ height: thumbData.height,
1675
+ channels: thumbData.colors || 3,
1676
+ premultiplied: false,
1677
+ },
1678
+ };
1679
+
1680
+ if (thumbData.bits === 16) {
1681
+ sharpConfig.raw.depth = "ushort";
1682
+ }
1683
+
1684
+ sharpInstance = sharp(thumbData.data, sharpConfig);
1685
+ }
1686
+
1687
+ // Apply max size constraint if specified
1688
+ if (options.maxSize) {
1689
+ sharpInstance = sharpInstance.resize(
1690
+ options.maxSize,
1691
+ options.maxSize,
1692
+ {
1693
+ fit: "inside",
1694
+ withoutEnlargement: true,
1695
+ }
1696
+ );
1697
+ }
1698
+
1699
+ // Configure JPEG options
1700
+ const jpegOptions = {
1701
+ quality: Math.max(1, Math.min(100, options.quality || 85)),
1702
+ progressive: false, // Thumbnails typically don't need progressive
1703
+ mozjpeg: false, // Keep simple for speed
1704
+ };
1705
+
1706
+ // Convert to JPEG buffer
1707
+ const jpegBuffer = await sharpInstance
1708
+ .jpeg(jpegOptions)
1709
+ .toBuffer({ resolveWithObject: true });
1710
+
1711
+ const endTime = process.hrtime.bigint();
1712
+ const processingTime = Number(endTime - startTime) / 1000000;
1713
+
1714
+ const result = {
1715
+ success: true,
1716
+ buffer: jpegBuffer.data,
1717
+ metadata: {
1718
+ format: "JPEG",
1719
+ originalDimensions: {
1720
+ width: thumbData.width,
1721
+ height: thumbData.height,
1722
+ },
1723
+ outputDimensions: {
1724
+ width: jpegBuffer.info.width,
1725
+ height: jpegBuffer.info.height,
1726
+ },
1727
+ fileSize: {
1728
+ original: thumbData.dataSize || thumbData.data.length,
1729
+ compressed: jpegBuffer.data.length,
1730
+ compressionRatio: (
1731
+ (thumbData.dataSize || thumbData.data.length) /
1732
+ jpegBuffer.data.length
1733
+ ).toFixed(2),
1734
+ },
1735
+ processing: {
1736
+ timeMs: processingTime.toFixed(2),
1737
+ },
1738
+ jpegOptions: jpegOptions,
1739
+ },
1740
+ };
1741
+
1742
+ resolve(result);
1743
+ } catch (error) {
1744
+ reject(
1745
+ new Error(`Thumbnail JPEG buffer creation failed: ${error.message}`)
1746
+ );
1747
+ }
1748
+ });
1749
+ }
1750
+
1751
+ // ============== JPEG CONVERSION (NEW FEATURE) ==============
1752
+
1753
+ /**
1754
+ * Convert RAW to JPEG with advanced options
1755
+ * @param {string} inputPath - Input RAW file path (optional, uses currently loaded file if not provided)
1756
+ * @param {string} outputPath - Output JPEG file path
1757
+ * @param {Object} options - JPEG conversion options
1758
+ * @param {number} [options.quality=85] - JPEG quality (1-100)
1759
+ * @param {number} [options.width] - Target width (maintains aspect ratio if height not specified)
1760
+ * @param {number} [options.height] - Target height (maintains aspect ratio if width not specified)
1761
+ * @param {boolean} [options.progressive=false] - Use progressive JPEG
1762
+ * @param {boolean} [options.mozjpeg=true] - Use mozjpeg encoder for better compression
1763
+ * @param {number} [options.chromaSubsampling='4:2:0'] - Chroma subsampling ('4:4:4', '4:2:2', '4:2:0')
1764
+ * @param {boolean} [options.trellisQuantisation=false] - Enable trellis quantisation
1765
+ * @param {boolean} [options.optimizeScans=false] - Optimize scan order
1766
+ * @param {number} [options.overshootDeringing=false] - Overshoot deringing
1767
+ * @param {boolean} [options.optimizeCoding=true] - Optimize Huffman coding
1768
+ * @param {string} [options.colorSpace='srgb'] - Output color space ('srgb', 'rec2020', 'p3', 'cmyk')
1769
+ * @returns {Promise<Object>} - Conversion result with metadata
1770
+ */
1771
+ async convertToJPEG(inputPath, outputPath, options = {}) {
1772
+ return new Promise(async (resolve, reject) => {
1773
+ try {
1774
+ // Handle parameter variations
1775
+ let actualInputPath, actualOutputPath, actualOptions;
1776
+
1777
+ if (typeof inputPath === 'string' && typeof outputPath === 'string') {
1778
+ // Three parameters: inputPath, outputPath, options
1779
+ actualInputPath = inputPath;
1780
+ actualOutputPath = outputPath;
1781
+ actualOptions = options || {};
1782
+ } else if (typeof inputPath === 'string' && typeof outputPath === 'object') {
1783
+ // Two parameters: outputPath, options (backward compatibility)
1784
+ actualInputPath = null; // Use currently loaded file
1785
+ actualOutputPath = inputPath;
1786
+ actualOptions = outputPath || {};
1787
+ } else {
1788
+ throw new Error('Invalid parameters. Expected: convertToJPEG(inputPath, outputPath, options) or convertToJPEG(outputPath, options)');
1789
+ }
1790
+
1791
+ // Load file if inputPath is provided and different from currently loaded file
1792
+ if (actualInputPath) {
1793
+ await this.loadFile(actualInputPath);
1794
+ }
1795
+
1796
+ // Create JPEG buffer first
1797
+ const result = await this.createJPEGBuffer(actualOptions);
1798
+
1799
+ // Write buffer to file
1800
+ const fs = require("fs");
1801
+ fs.writeFileSync(actualOutputPath, result.buffer);
1802
+
1803
+ // Get output file stats
1804
+ const stats = fs.statSync(actualOutputPath);
1805
+
1806
+ // Return result in the same format as before
1807
+ resolve({
1808
+ success: true,
1809
+ outputPath: actualOutputPath,
1810
+ metadata: {
1811
+ ...result.metadata,
1812
+ fileSize: {
1813
+ ...result.metadata.fileSize,
1814
+ compressed: stats.size,
1815
+ },
1816
+ },
1817
+ });
1818
+ } catch (error) {
1819
+ reject(new Error(`JPEG conversion failed: ${error.message}`));
1820
+ }
1821
+ });
1822
+ }
1823
+
1824
+ /**
1825
+ * Batch convert multiple RAW files to JPEG
1826
+ * @param {string[]} inputPaths - Array of input RAW file paths
1827
+ * @param {string} outputDir - Output directory for JPEG files
1828
+ * @param {Object} options - JPEG conversion options (same as convertToJPEG)
1829
+ * @returns {Promise<Object>} - Batch conversion results
1830
+ */
1831
+ async batchConvertToJPEG(inputPaths, outputDir, options = {}) {
1832
+ return new Promise(async (resolve, reject) => {
1833
+ try {
1834
+ const fs = require("fs");
1835
+ const path = require("path");
1836
+
1837
+ // Ensure output directory exists
1838
+ if (!fs.existsSync(outputDir)) {
1839
+ fs.mkdirSync(outputDir, { recursive: true });
1840
+ }
1841
+
1842
+ const results = {
1843
+ successful: [],
1844
+ failed: [],
1845
+ summary: {
1846
+ total: inputPaths.length,
1847
+ processed: 0,
1848
+ errors: 0,
1849
+ totalProcessingTime: 0,
1850
+ averageCompressionRatio: 0,
1851
+ totalOriginalSize: 0,
1852
+ totalCompressedSize: 0,
1853
+ },
1854
+ };
1855
+
1856
+ const startTime = process.hrtime.bigint();
1857
+
1858
+ for (const inputPath of inputPaths) {
1859
+ try {
1860
+ // Generate output filename
1861
+ const baseName = path.basename(inputPath, path.extname(inputPath));
1862
+ const outputPath = path.join(outputDir, `${baseName}.jpg`);
1863
+
1864
+ // Load the RAW file
1865
+ await this.close(); // Close any previous file
1866
+ await this.loadFile(inputPath);
1867
+
1868
+ // Convert to JPEG
1869
+ const result = await this.convertToJPEG(outputPath, options);
1870
+
1871
+ results.successful.push({
1872
+ input: inputPath,
1873
+ output: outputPath,
1874
+ result: result,
1875
+ });
1876
+
1877
+ results.summary.processed++;
1878
+ results.summary.totalOriginalSize +=
1879
+ result.metadata.fileSize.original;
1880
+ results.summary.totalCompressedSize +=
1881
+ result.metadata.fileSize.compressed;
1882
+ } catch (error) {
1883
+ results.failed.push({
1884
+ input: inputPath,
1885
+ error: error.message,
1886
+ });
1887
+ results.summary.errors++;
1888
+ }
1889
+ }
1890
+
1891
+ const endTime = process.hrtime.bigint();
1892
+ results.summary.totalProcessingTime =
1893
+ Number(endTime - startTime) / 1000000; // ms
1894
+
1895
+ if (results.summary.totalOriginalSize > 0) {
1896
+ results.summary.averageCompressionRatio = (
1897
+ results.summary.totalOriginalSize /
1898
+ results.summary.totalCompressedSize
1899
+ ).toFixed(2);
1900
+ }
1901
+
1902
+ results.summary.averageProcessingTimePerFile = (
1903
+ results.summary.totalProcessingTime / inputPaths.length
1904
+ ).toFixed(2);
1905
+
1906
+ resolve(results);
1907
+ } catch (error) {
1908
+ reject(new Error(`Batch JPEG conversion failed: ${error.message}`));
1909
+ }
1910
+ });
1911
+ }
1912
+
1913
+ /**
1914
+ * Get optimal JPEG conversion settings based on image analysis
1915
+ * @param {Object} analysisOptions - Options for image analysis
1916
+ * @returns {Promise<Object>} - Recommended JPEG settings
1917
+ */
1918
+ async getOptimalJPEGSettings(analysisOptions = {}) {
1919
+ return new Promise(async (resolve, reject) => {
1920
+ try {
1921
+ // Get image metadata and process for analysis
1922
+ const metadata = await this.getMetadata();
1923
+ const imageSize = await this.getImageSize();
1924
+
1925
+ // Analyze image characteristics
1926
+ const imageArea = metadata.width * metadata.height;
1927
+ const isHighRes = imageArea > 6000 * 4000; // > 24MP
1928
+ const isMediumRes = imageArea > 3000 * 2000; // > 6MP
1929
+
1930
+ // Default settings based on image characteristics
1931
+ let recommendedSettings = {
1932
+ quality: 85,
1933
+ progressive: false,
1934
+ mozjpeg: true,
1935
+ chromaSubsampling: "4:2:0",
1936
+ optimizeCoding: true,
1937
+ trellisQuantisation: false,
1938
+ optimizeScans: false,
1939
+ reasoning: [],
1940
+ };
1941
+
1942
+ // Adjust settings based on image size
1943
+ if (isHighRes) {
1944
+ recommendedSettings.quality = 80; // Slightly lower quality for large images
1945
+ recommendedSettings.progressive = true; // Progressive loading for large images
1946
+ recommendedSettings.trellisQuantisation = true; // Better compression for large images
1947
+ recommendedSettings.reasoning.push(
1948
+ "High resolution image detected - optimizing for file size"
1949
+ );
1950
+ } else if (isMediumRes) {
1951
+ recommendedSettings.quality = 85;
1952
+ recommendedSettings.reasoning.push(
1953
+ "Medium resolution image - balanced quality/size"
1954
+ );
1955
+ } else {
1956
+ recommendedSettings.quality = 90; // Higher quality for smaller images
1957
+ recommendedSettings.chromaSubsampling = "4:4:4"; // Better chroma for small images (Sharp compatible)
1958
+ recommendedSettings.reasoning.push(
1959
+ "Lower resolution image - prioritizing quality"
1960
+ );
1961
+ }
1962
+
1963
+ // Adjust for different use cases
1964
+ if (analysisOptions.usage === "web") {
1965
+ recommendedSettings.quality = Math.min(
1966
+ recommendedSettings.quality,
1967
+ 80
1968
+ );
1969
+ recommendedSettings.progressive = true;
1970
+ recommendedSettings.optimizeScans = true;
1971
+ recommendedSettings.reasoning.push(
1972
+ "Web usage - optimized for loading speed"
1973
+ );
1974
+ } else if (analysisOptions.usage === "print") {
1975
+ recommendedSettings.quality = Math.max(
1976
+ recommendedSettings.quality,
1977
+ 90
1978
+ );
1979
+ recommendedSettings.chromaSubsampling = "4:4:4"; // Use 4:4:4 instead of 4:2:2 for Sharp compatibility
1980
+ recommendedSettings.reasoning.push(
1981
+ "Print usage - optimized for quality"
1982
+ );
1983
+ } else if (analysisOptions.usage === "archive") {
1984
+ recommendedSettings.quality = 95;
1985
+ recommendedSettings.chromaSubsampling = "4:4:4";
1986
+ recommendedSettings.trellisQuantisation = true;
1987
+ recommendedSettings.reasoning.push(
1988
+ "Archive usage - maximum quality preservation"
1989
+ );
1990
+ }
1991
+
1992
+ // Camera-specific optimizations
1993
+ if (metadata.make) {
1994
+ const make = metadata.make.toLowerCase();
1995
+ if (make.includes("canon") || make.includes("nikon")) {
1996
+ // Professional cameras often benefit from slightly different settings
1997
+ recommendedSettings.reasoning.push(
1998
+ `${metadata.make} camera detected - professional settings`
1999
+ );
2000
+ }
2001
+ }
2002
+
2003
+ resolve({
2004
+ recommended: recommendedSettings,
2005
+ imageAnalysis: {
2006
+ dimensions: {
2007
+ width: metadata.width,
2008
+ height: metadata.height,
2009
+ area: imageArea,
2010
+ },
2011
+ category: isHighRes
2012
+ ? "high-resolution"
2013
+ : isMediumRes
2014
+ ? "medium-resolution"
2015
+ : "low-resolution",
2016
+ camera: {
2017
+ make: metadata.make,
2018
+ model: metadata.model,
2019
+ },
2020
+ },
2021
+ });
2022
+ } catch (error) {
2023
+ reject(
2024
+ new Error(
2025
+ `Failed to analyze image for optimal settings: ${error.message}`
2026
+ )
2027
+ );
2028
+ }
2029
+ });
2030
+ }
2031
+
2032
+ // ============== CANCELLATION SUPPORT ==============
2033
+
2034
+ /**
2035
+ * Set cancellation flag to stop processing
2036
+ * @returns {Promise<boolean>} - Success status
2037
+ */
2038
+ async setCancelFlag() {
2039
+ return new Promise((resolve, reject) => {
2040
+ try {
2041
+ const result = this._wrapper.setCancelFlag();
2042
+ resolve(result);
2043
+ } catch (error) {
2044
+ reject(error);
2045
+ }
2046
+ });
2047
+ }
2048
+
2049
+ /**
2050
+ * Clear cancellation flag
2051
+ * @returns {Promise<boolean>} - Success status
2052
+ */
2053
+ async clearCancelFlag() {
2054
+ return new Promise((resolve, reject) => {
2055
+ try {
2056
+ const result = this._wrapper.clearCancelFlag();
2057
+ resolve(result);
2058
+ } catch (error) {
2059
+ reject(error);
2060
+ }
2061
+ });
2062
+ }
2063
+
2064
+ // ============== VERSION INFORMATION (INSTANCE METHODS) ==============
2065
+
2066
+ /**
2067
+ * Get LibRaw version string
2068
+ * @returns {string} - Version string
2069
+ */
2070
+ version() {
2071
+ return this._wrapper.version();
2072
+ }
2073
+
2074
+ /**
2075
+ * Get LibRaw version as array [major, minor, patch]
2076
+ * @returns {number[]} - Version number array
2077
+ */
2078
+ versionNumber() {
2079
+ return this._wrapper.versionNumber();
2080
+ }
2081
+
2082
+ // ============== STATIC METHODS ==============
2083
+
2084
+ /**
2085
+ * Get LibRaw version
2086
+ * @returns {string} - Version string
2087
+ */
2088
+ static getVersion() {
2089
+ return librawAddon.LibRawWrapper.getVersion();
2090
+ }
2091
+
2092
+ /**
2093
+ * Get LibRaw capabilities
2094
+ * @returns {number} - Capabilities flags
2095
+ */
2096
+ static getCapabilities() {
2097
+ return librawAddon.LibRawWrapper.getCapabilities();
2098
+ }
2099
+
2100
+ /**
2101
+ * Get list of supported cameras
2102
+ * @returns {string[]} - Array of camera names
2103
+ */
2104
+ static getCameraList() {
2105
+ return librawAddon.LibRawWrapper.getCameraList();
2106
+ }
2107
+
2108
+ /**
2109
+ * Get count of supported cameras
2110
+ * @returns {number} - Number of supported cameras
2111
+ */
2112
+ static getCameraCount() {
2113
+ return librawAddon.LibRawWrapper.getCameraCount();
2114
+ }
2115
+
2116
+ /**
2117
+ * 检查文件是否为 LibRaw 支持的 RAW 格式
2118
+ * @param {string} filePath - 要检查的文件路径
2119
+ * @returns {Object} - 包含检查结果的对象
2120
+ * @example
2121
+ * const result = LibRaw.isRawFile('photo.cr2');
2122
+ * if (result.isRawFile) {
2123
+ * console.log('这是 LibRaw 支持的 RAW 文件');
2124
+ * } else {
2125
+ * console.log('不是支持的 RAW 文件:', result.message);
2126
+ * }
2127
+ */
2128
+ static isRawFile(filePath) {
2129
+ return librawAddon.LibRawWrapper.isRawFile(filePath);
2130
+ }
2131
+
2132
+ /**
2133
+ * High-performance fast JPEG conversion with minimal processing
2134
+ * @param {string} outputPath - Output JPEG file path
2135
+ * @param {Object} options - Speed-optimized JPEG options
2136
+ * @returns {Promise<Object>} - Conversion result
2137
+ */
2138
+ async convertToJPEGFast(outputPath, options = {}) {
2139
+ return this.convertToJPEG(outputPath, {
2140
+ fastMode: true,
2141
+ effort: 1, // Fastest encoding
2142
+ progressive: false,
2143
+ trellisQuantisation: false,
2144
+ optimizeScans: false,
2145
+ mozjpeg: false,
2146
+ quality: options.quality || 80,
2147
+ ...options,
2148
+ });
2149
+ }
2150
+
2151
+ /**
2152
+ * Create multiple JPEG sizes from single RAW (thumbnail, web, full)
2153
+ * @param {string} baseOutputPath - Base output path (without extension)
2154
+ * @param {Object} options - Multi-size options
2155
+ * @returns {Promise<Object>} - Multi-size conversion results
2156
+ */
2157
+ async convertToJPEGMultiSize(baseOutputPath, options = {}) {
2158
+ const sizes = options.sizes || [
2159
+ { name: "thumb", width: 400, quality: 85 },
2160
+ { name: "web", width: 1920, quality: 80 },
2161
+ { name: "full", quality: 85 },
2162
+ ];
2163
+
2164
+ // Process the RAW once (uses smart caching)
2165
+ if (!this._isProcessed) {
2166
+ await this.processImage();
2167
+ }
2168
+
2169
+ const results = {};
2170
+ const startTime = Date.now();
2171
+
2172
+ // Create all sizes sequentially to reuse cached data
2173
+ for (const sizeConfig of sizes) {
2174
+ const outputPath = `${baseOutputPath}_${sizeConfig.name}.jpg`;
2175
+ const sizeStart = Date.now();
2176
+
2177
+ const result = await this.convertToJPEG(outputPath, {
2178
+ fastMode: true,
2179
+ width: sizeConfig.width,
2180
+ height: sizeConfig.height,
2181
+ quality: sizeConfig.quality || 85,
2182
+ effort: sizeConfig.effort || 2,
2183
+ ...sizeConfig,
2184
+ });
2185
+
2186
+ const sizeEnd = Date.now();
2187
+
2188
+ results[sizeConfig.name] = {
2189
+ name: sizeConfig.name,
2190
+ outputPath,
2191
+ dimensions: result.metadata.outputDimensions,
2192
+ fileSize: result.metadata.fileSize.compressed,
2193
+ processingTime: sizeEnd - sizeStart,
2194
+ config: sizeConfig,
2195
+ };
2196
+ }
2197
+
2198
+ const endTime = Date.now();
2199
+ const totalTime = endTime - startTime;
2200
+
2201
+ return {
2202
+ success: true,
2203
+ sizes: results,
2204
+ originalDimensions: Object.values(results)[0]
2205
+ ? Object.values(results)[0].dimensions
2206
+ : { width: 0, height: 0 },
2207
+ totalProcessingTime: totalTime,
2208
+ averageTimePerSize: `${(totalTime / sizes.length).toFixed(2)}ms`,
2209
+ };
2210
+ }
2211
+
2212
+ /**
2213
+ * High-performance parallel batch conversion using worker threads
2214
+ * @param {string[]} inputPaths - Array of RAW file paths
2215
+ * @param {string} outputDir - Output directory
2216
+ * @param {Object} options - Conversion options
2217
+ * @returns {Promise<Object>} - Batch conversion results
2218
+ */
2219
+ static async batchConvertToJPEGParallel(inputPaths, outputDir, options = {}) {
2220
+ const fs = require("fs");
2221
+ const path = require("path");
2222
+ const os = require("os");
2223
+
2224
+ if (!fs.existsSync(outputDir)) {
2225
+ fs.mkdirSync(outputDir, { recursive: true });
2226
+ }
2227
+
2228
+ const maxConcurrency =
2229
+ options.maxConcurrency || Math.min(os.cpus().length, 4);
2230
+ const results = [];
2231
+ const errors = [];
2232
+ const startTime = Date.now();
2233
+
2234
+ // Process files in parallel batches
2235
+ for (let i = 0; i < inputPaths.length; i += maxConcurrency) {
2236
+ const batch = inputPaths.slice(i, i + maxConcurrency);
2237
+
2238
+ const batchPromises = batch.map(async (inputPath) => {
2239
+ try {
2240
+ const fileName = path.parse(inputPath).name;
2241
+ const outputPath = path.join(outputDir, `${fileName}.jpg`);
2242
+
2243
+ const libraw = new LibRaw();
2244
+ await libraw.loadFile(inputPath);
2245
+
2246
+ const result = await libraw.convertToJPEG(outputPath, {
2247
+ fastMode: true,
2248
+ effort: 1,
2249
+ quality: options.quality || 85,
2250
+ ...options,
2251
+ });
2252
+
2253
+ await libraw.close();
2254
+
2255
+ return {
2256
+ inputPath,
2257
+ outputPath,
2258
+ success: true,
2259
+ fileSize: result.metadata.fileSize.compressed,
2260
+ processingTime: result.metadata.processing.timeMs,
2261
+ };
2262
+ } catch (error) {
2263
+ errors.push({ inputPath, error: error.message });
2264
+ return {
2265
+ inputPath,
2266
+ success: false,
2267
+ error: error.message,
2268
+ };
2269
+ }
2270
+ });
2271
+
2272
+ const batchResults = await Promise.all(batchPromises);
2273
+ results.push(...batchResults);
2274
+ }
2275
+
2276
+ const endTime = Date.now();
2277
+ const successCount = results.filter((r) => r.success).length;
2278
+
2279
+ return {
2280
+ totalFiles: inputPaths.length,
2281
+ successCount,
2282
+ errorCount: errors.length,
2283
+ results,
2284
+ errors,
2285
+ totalProcessingTime: endTime - startTime,
2286
+ averageTimePerFile:
2287
+ successCount > 0 ? (endTime - startTime) / successCount : 0,
2288
+ };
2289
+ }
2290
+ }
2291
+
2292
+ module.exports = LibRaw;