@amazon-devices/expo-image 2.0.1758683737

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 (289) hide show
  1. package/.eslintrc.js +2 -0
  2. package/CHANGELOG.md +285 -0
  3. package/CMakeLists.txt +91 -0
  4. package/LICENSE +7 -0
  5. package/README.kepler.md +123 -0
  6. package/README.md +54 -0
  7. package/THIRD_PARTY_NOTICES.txt +24 -0
  8. package/android/build.gradle +124 -0
  9. package/android/proguard-rules.pro +28 -0
  10. package/android/src/main/AndroidManifest.xml +15 -0
  11. package/android/src/main/java/expo/modules/image/Exceptions.kt +9 -0
  12. package/android/src/main/java/expo/modules/image/ExpoImageAppGlideModule.kt +19 -0
  13. package/android/src/main/java/expo/modules/image/ExpoImageModule.kt +192 -0
  14. package/android/src/main/java/expo/modules/image/ExpoImageView.kt +220 -0
  15. package/android/src/main/java/expo/modules/image/ExpoImageViewWrapper.kt +652 -0
  16. package/android/src/main/java/expo/modules/image/GlideModel.kt +73 -0
  17. package/android/src/main/java/expo/modules/image/ImageUtils.kt +50 -0
  18. package/android/src/main/java/expo/modules/image/ImageViewWrapperTarget.kt +313 -0
  19. package/android/src/main/java/expo/modules/image/ResourceIdHelper.kt +47 -0
  20. package/android/src/main/java/expo/modules/image/ThumbnailRequestCoordinatorExtension.kt +21 -0
  21. package/android/src/main/java/expo/modules/image/YogaUtils.kt +20 -0
  22. package/android/src/main/java/expo/modules/image/blurhash/BlurHashFetcher.kt +32 -0
  23. package/android/src/main/java/expo/modules/image/blurhash/BlurhashDecoder.kt +189 -0
  24. package/android/src/main/java/expo/modules/image/blurhash/BlurhashModelLoader.kt +30 -0
  25. package/android/src/main/java/expo/modules/image/blurhash/BlurhashModelLoaderFactory.kt +14 -0
  26. package/android/src/main/java/expo/modules/image/blurhash/BlurhashModule.kt +17 -0
  27. package/android/src/main/java/expo/modules/image/dataurls/Base64DataFetcher.kt +27 -0
  28. package/android/src/main/java/expo/modules/image/dataurls/Base64ModelLoader.kt +24 -0
  29. package/android/src/main/java/expo/modules/image/dataurls/Base64ModelLoaderFactory.kt +12 -0
  30. package/android/src/main/java/expo/modules/image/dataurls/Base64Module.kt +16 -0
  31. package/android/src/main/java/expo/modules/image/drawing/OutlineProvider.kt +201 -0
  32. package/android/src/main/java/expo/modules/image/enums/ContentFit.kt +89 -0
  33. package/android/src/main/java/expo/modules/image/enums/ImageCacheType.kt +14 -0
  34. package/android/src/main/java/expo/modules/image/enums/Priority.kt +15 -0
  35. package/android/src/main/java/expo/modules/image/events/GlideRequestListener.kt +64 -0
  36. package/android/src/main/java/expo/modules/image/events/OkHttpProgressListener.kt +26 -0
  37. package/android/src/main/java/expo/modules/image/okhttp/ExpoImageOkHttpClientGlideModule.kt +80 -0
  38. package/android/src/main/java/expo/modules/image/okhttp/GlideUrlWrapperLoader.kt +55 -0
  39. package/android/src/main/java/expo/modules/image/records/CachePolicy.kt +10 -0
  40. package/android/src/main/java/expo/modules/image/records/ContentPosition.kt +89 -0
  41. package/android/src/main/java/expo/modules/image/records/ImageTransition.kt +8 -0
  42. package/android/src/main/java/expo/modules/image/records/SourceMap.kt +160 -0
  43. package/android/src/main/java/expo/modules/image/records/events.kt +25 -0
  44. package/android/src/main/java/expo/modules/image/svg/SVGDecoder.kt +33 -0
  45. package/android/src/main/java/expo/modules/image/svg/SVGDrawableTranscoder.kt +37 -0
  46. package/android/src/main/java/expo/modules/image/svg/SVGModule.kt +26 -0
  47. package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashDecoder.kt +365 -0
  48. package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashFetcher.kt +31 -0
  49. package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashModelLoader.kt +26 -0
  50. package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashModelLoaderFactory.kt +14 -0
  51. package/android/src/main/java/expo/modules/image/thumbhash/ThumbhashModule.kt +17 -0
  52. package/build/ExpoImage.d.ts +15 -0
  53. package/build/ExpoImage.d.ts.map +1 -0
  54. package/build/ExpoImage.js +75 -0
  55. package/build/ExpoImage.js.map +1 -0
  56. package/build/ExpoImage.kepler.d.ts +23 -0
  57. package/build/ExpoImage.kepler.d.ts.map +1 -0
  58. package/build/ExpoImage.kepler.js +71 -0
  59. package/build/ExpoImage.kepler.js.map +1 -0
  60. package/build/ExpoImage.web.d.ts +9 -0
  61. package/build/ExpoImage.web.d.ts.map +1 -0
  62. package/build/ExpoImage.web.js +90 -0
  63. package/build/ExpoImage.web.js.map +1 -0
  64. package/build/ExpoImageModules.d.ts +3 -0
  65. package/build/ExpoImageModules.d.ts.map +1 -0
  66. package/build/ExpoImageModules.js +4 -0
  67. package/build/ExpoImageModules.js.map +1 -0
  68. package/build/ExpoImageModules.kepler.d.ts +6 -0
  69. package/build/ExpoImageModules.kepler.d.ts.map +1 -0
  70. package/build/ExpoImageModules.kepler.js +5 -0
  71. package/build/ExpoImageModules.kepler.js.map +1 -0
  72. package/build/Image.d.ts +30 -0
  73. package/build/Image.d.ts.map +1 -0
  74. package/build/Image.js +49 -0
  75. package/build/Image.js.map +1 -0
  76. package/build/Image.types.d.ts +374 -0
  77. package/build/Image.types.d.ts.map +1 -0
  78. package/build/Image.types.js +2 -0
  79. package/build/Image.types.js.map +1 -0
  80. package/build/ImageBackground.d.ts +6 -0
  81. package/build/ImageBackground.d.ts.map +1 -0
  82. package/build/ImageBackground.js +13 -0
  83. package/build/ImageBackground.js.map +1 -0
  84. package/build/ImageViewNativeComponent.d.ts +20 -0
  85. package/build/ImageViewNativeComponent.d.ts.map +1 -0
  86. package/build/ImageViewNativeComponent.js +42 -0
  87. package/build/ImageViewNativeComponent.js.map +1 -0
  88. package/build/NativeImageLoaderKepler.d.ts +18 -0
  89. package/build/NativeImageLoaderKepler.d.ts.map +1 -0
  90. package/build/NativeImageLoaderKepler.js +3 -0
  91. package/build/NativeImageLoaderKepler.js.map +1 -0
  92. package/build/fabric/registerNativeComponent.d.ts +15 -0
  93. package/build/fabric/registerNativeComponent.d.ts.map +1 -0
  94. package/build/fabric/registerNativeComponent.js +47 -0
  95. package/build/fabric/registerNativeComponent.js.map +1 -0
  96. package/build/index.d.ts +4 -0
  97. package/build/index.d.ts.map +1 -0
  98. package/build/index.js +4 -0
  99. package/build/index.js.map +1 -0
  100. package/build/utils/AssetSourceResolver.web.d.ts +24 -0
  101. package/build/utils/AssetSourceResolver.web.d.ts.map +1 -0
  102. package/build/utils/AssetSourceResolver.web.js +67 -0
  103. package/build/utils/AssetSourceResolver.web.js.map +1 -0
  104. package/build/utils/blurhash/base83.d.ts +3 -0
  105. package/build/utils/blurhash/base83.d.ts.map +1 -0
  106. package/build/utils/blurhash/base83.js +103 -0
  107. package/build/utils/blurhash/base83.js.map +1 -0
  108. package/build/utils/blurhash/decode.d.ts +7 -0
  109. package/build/utils/blurhash/decode.d.ts.map +1 -0
  110. package/build/utils/blurhash/decode.js +92 -0
  111. package/build/utils/blurhash/decode.js.map +1 -0
  112. package/build/utils/blurhash/error.d.ts +4 -0
  113. package/build/utils/blurhash/error.d.ts.map +1 -0
  114. package/build/utils/blurhash/error.js +8 -0
  115. package/build/utils/blurhash/error.js.map +1 -0
  116. package/build/utils/blurhash/useBlurhash.d.ts +8 -0
  117. package/build/utils/blurhash/useBlurhash.d.ts.map +1 -0
  118. package/build/utils/blurhash/useBlurhash.js +64 -0
  119. package/build/utils/blurhash/useBlurhash.js.map +1 -0
  120. package/build/utils/blurhash/utils.d.ts +5 -0
  121. package/build/utils/blurhash/utils.d.ts.map +1 -0
  122. package/build/utils/blurhash/utils.js +21 -0
  123. package/build/utils/blurhash/utils.js.map +1 -0
  124. package/build/utils/resolveAssetSource.d.ts +3 -0
  125. package/build/utils/resolveAssetSource.d.ts.map +1 -0
  126. package/build/utils/resolveAssetSource.js +3 -0
  127. package/build/utils/resolveAssetSource.js.map +1 -0
  128. package/build/utils/resolveAssetSource.web.d.ts +9 -0
  129. package/build/utils/resolveAssetSource.web.d.ts.map +1 -0
  130. package/build/utils/resolveAssetSource.web.js +31 -0
  131. package/build/utils/resolveAssetSource.web.js.map +1 -0
  132. package/build/utils/resolveHashString.d.ts +14 -0
  133. package/build/utils/resolveHashString.d.ts.map +1 -0
  134. package/build/utils/resolveHashString.js +31 -0
  135. package/build/utils/resolveHashString.js.map +1 -0
  136. package/build/utils/resolveHashString.web.d.ts +20 -0
  137. package/build/utils/resolveHashString.web.d.ts.map +1 -0
  138. package/build/utils/resolveHashString.web.js +31 -0
  139. package/build/utils/resolveHashString.web.js.map +1 -0
  140. package/build/utils/resolveSources.d.ts +8 -0
  141. package/build/utils/resolveSources.d.ts.map +1 -0
  142. package/build/utils/resolveSources.js +45 -0
  143. package/build/utils/resolveSources.js.map +1 -0
  144. package/build/utils/thumbhash/thumbhash.d.ts +66 -0
  145. package/build/utils/thumbhash/thumbhash.d.ts.map +1 -0
  146. package/build/utils/thumbhash/thumbhash.js +338 -0
  147. package/build/utils/thumbhash/thumbhash.js.map +1 -0
  148. package/build/utils.d.ts +17 -0
  149. package/build/utils.d.ts.map +1 -0
  150. package/build/utils.js +85 -0
  151. package/build/utils.js.map +1 -0
  152. package/build/web/AnimationManager.d.ts +37 -0
  153. package/build/web/AnimationManager.d.ts.map +1 -0
  154. package/build/web/AnimationManager.js +155 -0
  155. package/build/web/AnimationManager.js.map +1 -0
  156. package/build/web/ColorTintFilter.d.ts +12 -0
  157. package/build/web/ColorTintFilter.d.ts.map +1 -0
  158. package/build/web/ColorTintFilter.js +30 -0
  159. package/build/web/ColorTintFilter.js.map +1 -0
  160. package/build/web/ImageWrapper.d.ts +5 -0
  161. package/build/web/ImageWrapper.d.ts.map +1 -0
  162. package/build/web/ImageWrapper.js +44 -0
  163. package/build/web/ImageWrapper.js.map +1 -0
  164. package/build/web/ImageWrapper.types.d.ts +29 -0
  165. package/build/web/ImageWrapper.types.d.ts.map +1 -0
  166. package/build/web/ImageWrapper.types.js +2 -0
  167. package/build/web/ImageWrapper.types.js.map +1 -0
  168. package/build/web/getImageWrapperEventHandler.d.ts +8 -0
  169. package/build/web/getImageWrapperEventHandler.d.ts.map +1 -0
  170. package/build/web/getImageWrapperEventHandler.js +25 -0
  171. package/build/web/getImageWrapperEventHandler.js.map +1 -0
  172. package/build/web/hooks.d.ts +13 -0
  173. package/build/web/hooks.d.ts.map +1 -0
  174. package/build/web/hooks.js +58 -0
  175. package/build/web/hooks.js.map +1 -0
  176. package/build/web/imageStyles.d.ts +2 -0
  177. package/build/web/imageStyles.d.ts.map +1 -0
  178. package/build/web/imageStyles.js +137 -0
  179. package/build/web/imageStyles.js.map +1 -0
  180. package/build/web/positioning.d.ts +11 -0
  181. package/build/web/positioning.d.ts.map +1 -0
  182. package/build/web/positioning.js +35 -0
  183. package/build/web/positioning.js.map +1 -0
  184. package/build/web/useSourceSelection.d.ts +14 -0
  185. package/build/web/useSourceSelection.d.ts.map +1 -0
  186. package/build/web/useSourceSelection.js +98 -0
  187. package/build/web/useSourceSelection.js.map +1 -0
  188. package/expo-module.config.json +9 -0
  189. package/ios/Blurhash.swift +326 -0
  190. package/ios/BlurhashLoader.swift +52 -0
  191. package/ios/ContentFit.swift +55 -0
  192. package/ios/ContentPosition.swift +108 -0
  193. package/ios/ExpoImage.podspec +30 -0
  194. package/ios/ImageCachePolicy.swift +24 -0
  195. package/ios/ImageCacheType.swift +21 -0
  196. package/ios/ImageModule.swift +127 -0
  197. package/ios/ImagePriority.swift +22 -0
  198. package/ios/ImageSource.swift +44 -0
  199. package/ios/ImageTransition.swift +67 -0
  200. package/ios/ImageUtils.swift +227 -0
  201. package/ios/ImageView.swift +469 -0
  202. package/ios/Loaders/PhotoLibraryAssetLoader.swift +146 -0
  203. package/ios/Thumbhash.swift +550 -0
  204. package/ios/ThumbhashLoader.swift +53 -0
  205. package/jest.config.js +3 -0
  206. package/kepler/ExpoImage.cpp +63 -0
  207. package/kepler/ExpoImage.h +29 -0
  208. package/kepler/ExpoImageCacheHandler.cpp +15 -0
  209. package/kepler/ExpoImageCacheHandler.h +28 -0
  210. package/kepler/ExpoImageComponent.cpp +579 -0
  211. package/kepler/ExpoImageComponent.h +199 -0
  212. package/kepler/ImageWrapper/BlurhashImageWrapper.cpp +37 -0
  213. package/kepler/ImageWrapper/BlurhashImageWrapper.h +23 -0
  214. package/kepler/ImageWrapper/CacheImageWrapper.cpp +80 -0
  215. package/kepler/ImageWrapper/CacheImageWrapper.h +41 -0
  216. package/kepler/ImageWrapper/HashImageWrapper.cpp +21 -0
  217. package/kepler/ImageWrapper/HashImageWrapper.h +22 -0
  218. package/kepler/ImageWrapper/ImageWrapper.cpp +24 -0
  219. package/kepler/ImageWrapper/ImageWrapper.h +33 -0
  220. package/kepler/ImageWrapper/LocalImageWrapper.cpp +61 -0
  221. package/kepler/ImageWrapper/LocalImageWrapper.h +30 -0
  222. package/kepler/ImageWrapper/ThumbhashImageWrapper.cpp +33 -0
  223. package/kepler/ImageWrapper/ThumbhashImageWrapper.h +20 -0
  224. package/kepler/KeplerImageViewComponent.h +64 -0
  225. package/kepler/KeplerInit.cpp +35 -0
  226. package/kepler/blurhash/common.h +32 -0
  227. package/kepler/blurhash/decode.cpp +187 -0
  228. package/kepler/blurhash/decode.h +58 -0
  229. package/kepler/contentposition/ImageContentPosition.cpp +86 -0
  230. package/kepler/contentposition/ImageContentPosition.h +48 -0
  231. package/kepler/enums/ImageContentFit.h +17 -0
  232. package/kepler/enums/ImagePriority.h +17 -0
  233. package/kepler/managers/ExpoImageManager.cpp +38 -0
  234. package/kepler/managers/ExpoImageManager.h +23 -0
  235. package/kepler/test/ExpoImage.cpp +73 -0
  236. package/kepler/test/ExpoImageComponent.cpp +290 -0
  237. package/kepler/test/blurhash/decode.cpp +39 -0
  238. package/kepler/test/contentposition/ImageContentPosition.cpp +100 -0
  239. package/kepler/test/managers/ExpoImageManager.cpp +39 -0
  240. package/kepler/test/thumbhash/decode.cpp +18 -0
  241. package/kepler/test/utils/LoaderDelegate.cpp +130 -0
  242. package/kepler/thumbhash/decode.cpp +166 -0
  243. package/kepler/thumbhash/decode.h +22 -0
  244. package/kepler/utils/PlaceholderImageLoaderDelegate.cpp +26 -0
  245. package/kepler/utils/PlaceholderImageLoaderDelegate.h +26 -0
  246. package/kepler/utils/PrefetchImageLoaderDelegate.cpp +55 -0
  247. package/kepler/utils/PrefetchImageLoaderDelegate.h +35 -0
  248. package/kepler/utils/SourceImageLoaderDelegate.cpp +47 -0
  249. package/kepler/utils/SourceImageLoaderDelegate.h +42 -0
  250. package/kepler/utils/SourceImageLoaderDelegateEmitter.cpp +15 -0
  251. package/kepler/utils/SourceImageLoaderDelegateEmitter.h +28 -0
  252. package/kepler-compatibility.json +8 -0
  253. package/package.json +1 -0
  254. package/react-native.config.js +22 -0
  255. package/src/ExpoImage.kepler.tsx +119 -0
  256. package/src/ExpoImage.tsx +119 -0
  257. package/src/ExpoImage.web.tsx +155 -0
  258. package/src/ExpoImageModules.kepler.ts +7 -0
  259. package/src/ExpoImageModules.ts +4 -0
  260. package/src/Image.tsx +82 -0
  261. package/src/Image.types.ts +450 -0
  262. package/src/ImageBackground.tsx +18 -0
  263. package/src/ImageViewNativeComponent.ts +59 -0
  264. package/src/NativeImageLoaderKepler.ts +22 -0
  265. package/src/fabric/registerNativeComponent.ts +70 -0
  266. package/src/index.ts +3 -0
  267. package/src/utils/AssetSourceResolver.web.ts +88 -0
  268. package/src/utils/blurhash/base83.ts +104 -0
  269. package/src/utils/blurhash/decode.ts +114 -0
  270. package/src/utils/blurhash/error.ts +7 -0
  271. package/src/utils/blurhash/useBlurhash.tsx +81 -0
  272. package/src/utils/blurhash/utils.ts +21 -0
  273. package/src/utils/resolveAssetSource.tsx +3 -0
  274. package/src/utils/resolveAssetSource.web.ts +40 -0
  275. package/src/utils/resolveHashString.tsx +36 -0
  276. package/src/utils/resolveHashString.web.tsx +33 -0
  277. package/src/utils/resolveSources.tsx +48 -0
  278. package/src/utils/thumbhash/thumbhash.ts +387 -0
  279. package/src/utils.ts +109 -0
  280. package/src/web/AnimationManager.tsx +224 -0
  281. package/src/web/ColorTintFilter.tsx +36 -0
  282. package/src/web/ImageWrapper.tsx +85 -0
  283. package/src/web/ImageWrapper.types.ts +36 -0
  284. package/src/web/getImageWrapperEventHandler.ts +29 -0
  285. package/src/web/hooks.ts +72 -0
  286. package/src/web/imageStyles.tsx +136 -0
  287. package/src/web/positioning.ts +48 -0
  288. package/src/web/useSourceSelection.ts +151 -0
  289. package/tsconfig.json +9 -0
@@ -0,0 +1,31 @@
1
+ function hashToUri(type, hash) {
2
+ const encodedBlurhash = encodeURI(hash).replace(/#/g, '%23').replace(/\?/g, '%3F');
3
+ return `${type}:/${encodedBlurhash}`;
4
+ }
5
+ /**
6
+ * Converts a blurhash string (`blurhash:/<hash>/<width>/<height>` or <hash>/<width>/<height>) into an `ImageSource`.
7
+ *
8
+ * @return An ImageSource representing the provided blurhash.
9
+ * */
10
+ export function resolveBlurhashString(str) {
11
+ const [blurhash, width, height] = str.replace(/^blurhash:\//, '').split('/');
12
+ return {
13
+ uri: hashToUri('blurhash', blurhash),
14
+ width: parseInt(width, 10) || 16,
15
+ height: parseInt(height, 10) || 16,
16
+ };
17
+ }
18
+ /**
19
+ * Converts a thumbhash string (`thumbhash:/<hash>` or `<hash>`) into an `ImageSource`.
20
+ *
21
+ * @return An ImageSource representing the provided thumbhash.
22
+ * */
23
+ export function resolveThumbhashString(str) {
24
+ // ThumbHash may contain slashes that could break the url when the slash is at the beginning.
25
+ // We replace slashes with backslashes to make sure we don't break the url's path.
26
+ const thumbhash = str.replace(/^thumbhash:\//, '').replace(/\//g, '\\');
27
+ return {
28
+ uri: hashToUri('thumbhash', thumbhash),
29
+ };
30
+ }
31
+ //# sourceMappingURL=resolveHashString.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveHashString.js","sourceRoot":"","sources":["../../src/utils/resolveHashString.tsx"],"names":[],"mappings":"AAIA,SAAS,SAAS,CAAC,IAAmB,EAAE,IAAY;IAClD,MAAM,eAAe,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACnF,OAAO,GAAG,IAAI,KAAK,eAAe,EAAE,CAAC;AACvC,CAAC;AAED;;;;KAIK;AACL,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7E,OAAO;QACL,GAAG,EAAE,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC;QACpC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE;QAChC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE;KACnC,CAAC;AACJ,CAAC;AAED;;;;KAIK;AACL,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAChD,6FAA6F;IAC7F,kFAAkF;IAClF,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACxE,OAAO;QACL,GAAG,EAAE,SAAS,CAAC,WAAW,EAAE,SAAS,CAAC;KACvC,CAAC;AACJ,CAAC","sourcesContent":["import { ImageSource } from '../Image.types';\n\ntype ImageHashType = 'blurhash' | 'thumbhash';\n\nfunction hashToUri(type: ImageHashType, hash: string): string {\n const encodedBlurhash = encodeURI(hash).replace(/#/g, '%23').replace(/\\?/g, '%3F');\n return `${type}:/${encodedBlurhash}`;\n}\n\n/**\n * Converts a blurhash string (`blurhash:/<hash>/<width>/<height>` or <hash>/<width>/<height>) into an `ImageSource`.\n *\n * @return An ImageSource representing the provided blurhash.\n * */\nexport function resolveBlurhashString(str: string): ImageSource {\n const [blurhash, width, height] = str.replace(/^blurhash:\\//, '').split('/');\n return {\n uri: hashToUri('blurhash', blurhash),\n width: parseInt(width, 10) || 16,\n height: parseInt(height, 10) || 16,\n };\n}\n\n/**\n * Converts a thumbhash string (`thumbhash:/<hash>` or `<hash>`) into an `ImageSource`.\n *\n * @return An ImageSource representing the provided thumbhash.\n * */\nexport function resolveThumbhashString(str: string): ImageSource {\n // ThumbHash may contain slashes that could break the url when the slash is at the beginning.\n // We replace slashes with backslashes to make sure we don't break the url's path.\n const thumbhash = str.replace(/^thumbhash:\\//, '').replace(/\\//g, '\\\\');\n return {\n uri: hashToUri('thumbhash', thumbhash),\n };\n}\n"]}
@@ -0,0 +1,20 @@
1
+ import { ImageSource } from '../Image.types';
2
+ /**
3
+ * Converts a string in blurhash format (`blurhash:/<hash>/<width>/<height>`
4
+ * or <hash>/<width>/<height>) into an `ImageSource`.
5
+ * Note: The blurhash:/ uri scheme is removed, because for backward compatibility reasons,
6
+ * strings without a scheme are assumed to be `blurhash` by default.
7
+ *
8
+ * @return An ImageSource representing the provided blurhash.
9
+ * */
10
+ export declare function resolveBlurhashString(str: string): ImageSource;
11
+ /**
12
+ * Converts a string in thumbhash format (`thumbhash:/<hash>` or `<hash>`)
13
+ * into an `ImageSource`.
14
+ * Note: Unlike the `resolveBlurhashString` the `thumbhash:/` scheme has to be present,
15
+ * as the scheme has to be explicitly stated to be interpreted a `thumbhash` source.
16
+ *
17
+ * @return An ImageSource representing the provided thumbhash.
18
+ * */
19
+ export declare function resolveThumbhashString(str: string): ImageSource;
20
+ //# sourceMappingURL=resolveHashString.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveHashString.web.d.ts","sourceRoot":"","sources":["../../src/utils/resolveHashString.web.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C;;;;;;;KAOK;AACL,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAO9D;AAED;;;;;;;KAOK;AACL,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAK/D"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Converts a string in blurhash format (`blurhash:/<hash>/<width>/<height>`
3
+ * or <hash>/<width>/<height>) into an `ImageSource`.
4
+ * Note: The blurhash:/ uri scheme is removed, because for backward compatibility reasons,
5
+ * strings without a scheme are assumed to be `blurhash` by default.
6
+ *
7
+ * @return An ImageSource representing the provided blurhash.
8
+ * */
9
+ export function resolveBlurhashString(str) {
10
+ const [blurhash, width, height] = str.replace(/^blurhash:\//, '').split('/');
11
+ return {
12
+ uri: blurhash,
13
+ width: parseInt(width, 10) || 16,
14
+ height: parseInt(height, 10) || 16,
15
+ };
16
+ }
17
+ /**
18
+ * Converts a string in thumbhash format (`thumbhash:/<hash>` or `<hash>`)
19
+ * into an `ImageSource`.
20
+ * Note: Unlike the `resolveBlurhashString` the `thumbhash:/` scheme has to be present,
21
+ * as the scheme has to be explicitly stated to be interpreted a `thumbhash` source.
22
+ *
23
+ * @return An ImageSource representing the provided thumbhash.
24
+ * */
25
+ export function resolveThumbhashString(str) {
26
+ const hash = str.replace(/^thumbhash:\//, '');
27
+ return {
28
+ uri: 'thumbhash:/' + hash,
29
+ };
30
+ }
31
+ //# sourceMappingURL=resolveHashString.web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveHashString.web.js","sourceRoot":"","sources":["../../src/utils/resolveHashString.web.tsx"],"names":[],"mappings":"AAEA;;;;;;;KAOK;AACL,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7E,OAAO;QACL,GAAG,EAAE,QAAQ;QACb,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE;QAChC,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE;KACnC,CAAC;AACJ,CAAC;AAED;;;;;;;KAOK;AACL,MAAM,UAAU,sBAAsB,CAAC,GAAW;IAChD,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAC9C,OAAO;QACL,GAAG,EAAE,aAAa,GAAG,IAAI;KAC1B,CAAC;AACJ,CAAC","sourcesContent":["import { ImageSource } from '../Image.types';\n\n/**\n * Converts a string in blurhash format (`blurhash:/<hash>/<width>/<height>`\n * or <hash>/<width>/<height>) into an `ImageSource`.\n * Note: The blurhash:/ uri scheme is removed, because for backward compatibility reasons,\n * strings without a scheme are assumed to be `blurhash` by default.\n *\n * @return An ImageSource representing the provided blurhash.\n * */\nexport function resolveBlurhashString(str: string): ImageSource {\n const [blurhash, width, height] = str.replace(/^blurhash:\\//, '').split('/');\n return {\n uri: blurhash,\n width: parseInt(width, 10) || 16,\n height: parseInt(height, 10) || 16,\n };\n}\n\n/**\n * Converts a string in thumbhash format (`thumbhash:/<hash>` or `<hash>`)\n * into an `ImageSource`.\n * Note: Unlike the `resolveBlurhashString` the `thumbhash:/` scheme has to be present,\n * as the scheme has to be explicitly stated to be interpreted a `thumbhash` source.\n *\n * @return An ImageSource representing the provided thumbhash.\n * */\nexport function resolveThumbhashString(str: string): ImageSource {\n const hash = str.replace(/^thumbhash:\\//, '');\n return {\n uri: 'thumbhash:/' + hash,\n };\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import { ImageNativeProps, ImageProps } from '../Image.types';
2
+ export declare function isBlurhashString(str: string): boolean;
3
+ export declare function isThumbhashString(str: string): boolean;
4
+ /**
5
+ * Resolves provided `source` prop to an array of objects expected by the native implementation.
6
+ */
7
+ export declare function resolveSources(sources?: ImageProps['source']): ImageNativeProps['source'];
8
+ //# sourceMappingURL=resolveSources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveSources.d.ts","sourceRoot":"","sources":["../../src/utils/resolveSources.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAe,MAAM,gBAAgB,CAAC;AAE3E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAID,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEtD;AA2BD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAKzF"}
@@ -0,0 +1,45 @@
1
+ import resolveAssetSource from './resolveAssetSource';
2
+ import { resolveBlurhashString, resolveThumbhashString } from './resolveHashString';
3
+ export function isBlurhashString(str) {
4
+ return /^(blurhash:\/)?[\w#$%*+,\-.:;=?@[\]^_{}|~]+(\/[\d.]+)*$/.test(str);
5
+ }
6
+ // Base64 strings will be recognized as blurhash by default (to keep compatibility),
7
+ // interpret as thumbhash only if correct uri scheme is provided
8
+ export function isThumbhashString(str) {
9
+ return str.startsWith('thumbhash:/');
10
+ }
11
+ function resolveSource(source) {
12
+ if (typeof source === 'string') {
13
+ if (isBlurhashString(source)) {
14
+ return resolveBlurhashString(source);
15
+ }
16
+ else if (isThumbhashString(source)) {
17
+ return resolveThumbhashString(source);
18
+ }
19
+ return { uri: source };
20
+ }
21
+ if (typeof source === 'number') {
22
+ return resolveAssetSource(source);
23
+ }
24
+ if (typeof source === 'object' && (source?.blurhash || source?.thumbhash)) {
25
+ const { blurhash, thumbhash, ...restSource } = source;
26
+ const resolved = thumbhash
27
+ ? resolveThumbhashString(thumbhash)
28
+ : resolveBlurhashString(blurhash);
29
+ return {
30
+ ...resolved,
31
+ ...restSource,
32
+ };
33
+ }
34
+ return source ?? null;
35
+ }
36
+ /**
37
+ * Resolves provided `source` prop to an array of objects expected by the native implementation.
38
+ */
39
+ export function resolveSources(sources) {
40
+ if (Array.isArray(sources)) {
41
+ return sources.map(resolveSource).filter(Boolean);
42
+ }
43
+ return [resolveSource(sources)].filter(Boolean);
44
+ }
45
+ //# sourceMappingURL=resolveSources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveSources.js","sourceRoot":"","sources":["../../src/utils/resolveSources.tsx"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGpF,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,yDAAyD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7E,CAAC;AAED,oFAAoF;AACpF,gEAAgE;AAChE,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,aAAa,CAAC,MAA6C;IAClE,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;aAAM,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;YACrC,OAAO,sBAAsB,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IACzB,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,EAAE,QAAQ,IAAI,MAAM,EAAE,SAAS,CAAC,EAAE,CAAC;QAC1E,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,CAAC;QACtD,MAAM,QAAQ,GAAG,SAAS;YACxB,CAAC,CAAC,sBAAsB,CAAC,SAAS,CAAC;YACnC,CAAC,CAAC,qBAAqB,CAAC,QAAkB,CAAC,CAAC;QAC9C,OAAO;YACL,GAAG,QAAQ;YACX,GAAG,UAAU;SACd,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,IAAI,IAAI,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,OAA8B;IAC3D,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,OAAO,CAAkB,CAAC;IACrE,CAAC;IACD,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAkB,CAAC;AACnE,CAAC","sourcesContent":["import resolveAssetSource from './resolveAssetSource';\nimport { resolveBlurhashString, resolveThumbhashString } from './resolveHashString';\nimport { ImageNativeProps, ImageProps, ImageSource } from '../Image.types';\n\nexport function isBlurhashString(str: string): boolean {\n return /^(blurhash:\\/)?[\\w#$%*+,\\-.:;=?@[\\]^_{}|~]+(\\/[\\d.]+)*$/.test(str);\n}\n\n// Base64 strings will be recognized as blurhash by default (to keep compatibility),\n// interpret as thumbhash only if correct uri scheme is provided\nexport function isThumbhashString(str: string): boolean {\n return str.startsWith('thumbhash:/');\n}\n\nfunction resolveSource(source?: ImageSource | string | number | null): ImageSource | null {\n if (typeof source === 'string') {\n if (isBlurhashString(source)) {\n return resolveBlurhashString(source);\n } else if (isThumbhashString(source)) {\n return resolveThumbhashString(source);\n }\n return { uri: source };\n }\n if (typeof source === 'number') {\n return resolveAssetSource(source);\n }\n if (typeof source === 'object' && (source?.blurhash || source?.thumbhash)) {\n const { blurhash, thumbhash, ...restSource } = source;\n const resolved = thumbhash\n ? resolveThumbhashString(thumbhash)\n : resolveBlurhashString(blurhash as string);\n return {\n ...resolved,\n ...restSource,\n };\n }\n return source ?? null;\n}\n\n/**\n * Resolves provided `source` prop to an array of objects expected by the native implementation.\n */\nexport function resolveSources(sources?: ImageProps['source']): ImageNativeProps['source'] {\n if (Array.isArray(sources)) {\n return sources.map(resolveSource).filter(Boolean) as ImageSource[];\n }\n return [resolveSource(sources)].filter(Boolean) as ImageSource[];\n}\n"]}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Encodes an RGBA image to a ThumbHash. RGB should not be premultiplied by A.
3
+ *
4
+ * @param w The width of the input image. Must be ≤100px.
5
+ * @param h The height of the input image. Must be ≤100px.
6
+ * @param rgba The pixels in the input image, row-by-row. Must have w*h*4 elements.
7
+ * @returns The ThumbHash as a Uint8Array.
8
+ */
9
+ export declare function rgbaToThumbHash(w: number, h: number, rgba: Uint8Array): Uint8Array<ArrayBuffer>;
10
+ /**
11
+ * Decodes a ThumbHash to an RGBA image. RGB is not be premultiplied by A.
12
+ *
13
+ * @param hash The bytes of the ThumbHash.
14
+ * @returns The width, height, and pixels of the rendered placeholder image.
15
+ */
16
+ export declare function thumbHashToRGBA(hash: Uint8Array): {
17
+ w: number;
18
+ h: number;
19
+ rgba: Uint8Array<ArrayBuffer>;
20
+ };
21
+ /**
22
+ * Extracts the average color from a ThumbHash. RGB is not be premultiplied by A.
23
+ *
24
+ * @param hash The bytes of the ThumbHash.
25
+ * @returns The RGBA values for the average color. Each value ranges from 0 to 1.
26
+ */
27
+ export declare function thumbHashToAverageRGBA(hash: Uint8Array): {
28
+ r: number;
29
+ g: number;
30
+ b: number;
31
+ a: number;
32
+ };
33
+ /**
34
+ * Extracts the approximate aspect ratio of the original image.
35
+ *
36
+ * @param hash The bytes of the ThumbHash.
37
+ * @returns The approximate aspect ratio (i.e. width / height).
38
+ */
39
+ export declare function thumbHashToApproximateAspectRatio(hash: Uint8Array): number;
40
+ /**
41
+ * Encodes an RGBA image to a PNG data URL. RGB should not be premultiplied by
42
+ * A. This is optimized for speed and simplicity and does not optimize for size
43
+ * at all. This doesn't do any compression (all values are stored uncompressed).
44
+ *
45
+ * @param w The width of the input image. Must be ≤100px.
46
+ * @param h The height of the input image. Must be ≤100px.
47
+ * @param rgba The pixels in the input image, row-by-row. Must have w*h*4 elements.
48
+ * @returns A data URL containing a PNG for the input image.
49
+ */
50
+ export declare function rgbaToDataURL(w: number, h: number, rgba: Uint8Array): string;
51
+ /**
52
+ * Decodes a ThumbHash to a PNG data URL. This is a convenience function that
53
+ * just calls "thumbHashToRGBA" followed by "rgbaToDataURL".
54
+ *
55
+ * @param hash The bytes of the ThumbHash.
56
+ * @returns A data URL containing a PNG for the rendered ThumbHash.
57
+ */
58
+ export declare function thumbHashToDataURL(hash: Uint8Array): string;
59
+ /**
60
+ * Convenience function added to the original thumbhash code, allows generating a thumbhash image directly from
61
+ * thumbhash string.
62
+ * @param thumbhash string from which thumbhashDataURL should be generated
63
+ * @returns A data URL containing a PNG for the rendered ThumbHash
64
+ */
65
+ export declare function thumbHashStringToDataURL(thumbhash: string): string;
66
+ //# sourceMappingURL=thumbhash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbhash.d.ts","sourceRoot":"","sources":["../../../src/utils/thumbhash/thumbhash.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,2BAuGrE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU;;;;EAuF/C;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU;;;;;EAiBtD;AAED;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,UAAU,UAOjE;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,UAsGnE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAG3D;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGlE"}
@@ -0,0 +1,338 @@
1
+ // Code copied and slightly modified from https://github.com/evanw/thumbhash
2
+ /**
3
+ * Encodes an RGBA image to a ThumbHash. RGB should not be premultiplied by A.
4
+ *
5
+ * @param w The width of the input image. Must be ≤100px.
6
+ * @param h The height of the input image. Must be ≤100px.
7
+ * @param rgba The pixels in the input image, row-by-row. Must have w*h*4 elements.
8
+ * @returns The ThumbHash as a Uint8Array.
9
+ */
10
+ export function rgbaToThumbHash(w, h, rgba) {
11
+ // Encoding an image larger than 100x100 is slow with no benefit
12
+ if (w > 100 || h > 100)
13
+ throw new Error(`${w}x${h} doesn't fit in 100x100`);
14
+ const { PI, round, max, cos, abs } = Math;
15
+ // Determine the average color
16
+ let avg_r = 0, avg_g = 0, avg_b = 0, avg_a = 0;
17
+ for (let i = 0, j = 0; i < w * h; i++, j += 4) {
18
+ const alpha = rgba[j + 3] / 255;
19
+ avg_r += (alpha / 255) * rgba[j];
20
+ avg_g += (alpha / 255) * rgba[j + 1];
21
+ avg_b += (alpha / 255) * rgba[j + 2];
22
+ avg_a += alpha;
23
+ }
24
+ if (avg_a) {
25
+ avg_r /= avg_a;
26
+ avg_g /= avg_a;
27
+ avg_b /= avg_a;
28
+ }
29
+ const hasAlpha = avg_a < w * h;
30
+ const l_limit = hasAlpha ? 5 : 7; // Use fewer luminance bits if there's alpha
31
+ const lx = max(1, round((l_limit * w) / max(w, h)));
32
+ const ly = max(1, round((l_limit * h) / max(w, h)));
33
+ const l = []; // luminance
34
+ const p = []; // yellow - blue
35
+ const q = []; // red - green
36
+ const a = []; // alpha
37
+ // Convert the image from RGBA to LPQA (composite atop the average color)
38
+ for (let i = 0, j = 0; i < w * h; i++, j += 4) {
39
+ const alpha = rgba[j + 3] / 255;
40
+ const r = avg_r * (1 - alpha) + (alpha / 255) * rgba[j];
41
+ const g = avg_g * (1 - alpha) + (alpha / 255) * rgba[j + 1];
42
+ const b = avg_b * (1 - alpha) + (alpha / 255) * rgba[j + 2];
43
+ l[i] = (r + g + b) / 3;
44
+ p[i] = (r + g) / 2 - b;
45
+ q[i] = r - g;
46
+ a[i] = alpha;
47
+ }
48
+ // Encode using the DCT into DC (constant) and normalized AC (varying) terms
49
+ const encodeChannel = (channel, nx, ny) => {
50
+ let dc = 0;
51
+ const ac = [];
52
+ let scale = 0;
53
+ const fx = [];
54
+ for (let cy = 0; cy < ny; cy++) {
55
+ for (let cx = 0; cx * ny < nx * (ny - cy); cx++) {
56
+ let f = 0;
57
+ for (let x = 0; x < w; x++)
58
+ fx[x] = cos((PI / w) * cx * (x + 0.5));
59
+ for (let y = 0; y < h; y++)
60
+ for (let x = 0, fy = cos((PI / h) * cy * (y + 0.5)); x < w; x++)
61
+ f += channel[x + y * w] * fx[x] * fy;
62
+ f /= w * h;
63
+ if (cx || cy) {
64
+ ac.push(f);
65
+ scale = max(scale, abs(f));
66
+ }
67
+ else {
68
+ dc = f;
69
+ }
70
+ }
71
+ }
72
+ if (scale)
73
+ for (let i = 0; i < ac.length; i++)
74
+ ac[i] = 0.5 + (0.5 / scale) * ac[i];
75
+ return [dc, ac, scale];
76
+ };
77
+ const [l_dc, l_ac, l_scale] = encodeChannel(l, max(3, lx), max(3, ly));
78
+ const [p_dc, p_ac, p_scale] = encodeChannel(p, 3, 3);
79
+ const [q_dc, q_ac, q_scale] = encodeChannel(q, 3, 3);
80
+ const [a_dc, a_ac, a_scale] = hasAlpha ? encodeChannel(a, 5, 5) : [];
81
+ // Write the constants
82
+ const isLandscape = w > h;
83
+ const header24 = round(63 * l_dc) |
84
+ (round(31.5 + 31.5 * p_dc) << 6) |
85
+ (round(31.5 + 31.5 * q_dc) << 12) |
86
+ (round(31 * l_scale) << 18) |
87
+ ((hasAlpha ? 1 : 0) << 23);
88
+ const header16 = (isLandscape ? ly : lx) |
89
+ (round(63 * p_scale) << 3) |
90
+ (round(63 * q_scale) << 9) |
91
+ ((isLandscape ? 1 : 0) << 15);
92
+ const hash = [
93
+ header24 & 255,
94
+ (header24 >> 8) & 255,
95
+ header24 >> 16,
96
+ header16 & 255,
97
+ header16 >> 8,
98
+ ];
99
+ const ac_start = hasAlpha ? 6 : 5;
100
+ let ac_index = 0;
101
+ if (hasAlpha)
102
+ hash.push(round(15 * a_dc) | (round(15 * a_scale) << 4));
103
+ // Write the varying factors
104
+ for (const ac of hasAlpha ? [l_ac, p_ac, q_ac, a_ac] : [l_ac, p_ac, q_ac])
105
+ for (const f of ac)
106
+ hash[ac_start + (ac_index >> 1)] |= round(15 * f) << ((ac_index++ & 1) << 2);
107
+ return new Uint8Array(hash);
108
+ }
109
+ /**
110
+ * Decodes a ThumbHash to an RGBA image. RGB is not be premultiplied by A.
111
+ *
112
+ * @param hash The bytes of the ThumbHash.
113
+ * @returns The width, height, and pixels of the rendered placeholder image.
114
+ */
115
+ export function thumbHashToRGBA(hash) {
116
+ const { PI, min, max, cos, round } = Math;
117
+ // Read the constants
118
+ const header24 = hash[0] | (hash[1] << 8) | (hash[2] << 16);
119
+ const header16 = hash[3] | (hash[4] << 8);
120
+ const l_dc = (header24 & 63) / 63;
121
+ const p_dc = ((header24 >> 6) & 63) / 31.5 - 1;
122
+ const q_dc = ((header24 >> 12) & 63) / 31.5 - 1;
123
+ const l_scale = ((header24 >> 18) & 31) / 31;
124
+ const hasAlpha = header24 >> 23;
125
+ const p_scale = ((header16 >> 3) & 63) / 63;
126
+ const q_scale = ((header16 >> 9) & 63) / 63;
127
+ const isLandscape = header16 >> 15;
128
+ const lx = max(3, isLandscape ? (hasAlpha ? 5 : 7) : header16 & 7);
129
+ const ly = max(3, isLandscape ? header16 & 7 : hasAlpha ? 5 : 7);
130
+ const a_dc = hasAlpha ? (hash[5] & 15) / 15 : 1;
131
+ const a_scale = (hash[5] >> 4) / 15;
132
+ // Read the varying factors (boost saturation by 1.25x to compensate for quantization)
133
+ const ac_start = hasAlpha ? 6 : 5;
134
+ let ac_index = 0;
135
+ const decodeChannel = (nx, ny, scale) => {
136
+ const ac = [];
137
+ for (let cy = 0; cy < ny; cy++)
138
+ for (let cx = cy ? 0 : 1; cx * ny < nx * (ny - cy); cx++)
139
+ ac.push((((hash[ac_start + (ac_index >> 1)] >> ((ac_index++ & 1) << 2)) & 15) / 7.5 - 1) * scale);
140
+ return ac;
141
+ };
142
+ const l_ac = decodeChannel(lx, ly, l_scale);
143
+ const p_ac = decodeChannel(3, 3, p_scale * 1.25);
144
+ const q_ac = decodeChannel(3, 3, q_scale * 1.25);
145
+ const a_ac = hasAlpha && decodeChannel(5, 5, a_scale);
146
+ // Decode using the DCT into RGB
147
+ const ratio = thumbHashToApproximateAspectRatio(hash);
148
+ const w = round(ratio > 1 ? 32 : 32 * ratio);
149
+ const h = round(ratio > 1 ? 32 / ratio : 32);
150
+ const rgba = new Uint8Array(w * h * 4), fx = [], fy = [];
151
+ for (let y = 0, i = 0; y < h; y++) {
152
+ for (let x = 0; x < w; x++, i += 4) {
153
+ let l = l_dc, p = p_dc, q = q_dc, a = a_dc;
154
+ // Precompute the coefficients
155
+ for (let cx = 0, n = max(lx, hasAlpha ? 5 : 3); cx < n; cx++)
156
+ fx[cx] = cos((PI / w) * (x + 0.5) * cx);
157
+ for (let cy = 0, n = max(ly, hasAlpha ? 5 : 3); cy < n; cy++)
158
+ fy[cy] = cos((PI / h) * (y + 0.5) * cy);
159
+ // Decode L
160
+ for (let cy = 0, j = 0; cy < ly; cy++)
161
+ for (let cx = cy ? 0 : 1, fy2 = fy[cy] * 2; cx * ly < lx * (ly - cy); cx++, j++)
162
+ l += l_ac[j] * fx[cx] * fy2;
163
+ // Decode P and Q
164
+ for (let cy = 0, j = 0; cy < 3; cy++) {
165
+ for (let cx = cy ? 0 : 1, fy2 = fy[cy] * 2; cx < 3 - cy; cx++, j++) {
166
+ const f = fx[cx] * fy2;
167
+ p += p_ac[j] * f;
168
+ q += q_ac[j] * f;
169
+ }
170
+ }
171
+ // Decode A
172
+ if (hasAlpha)
173
+ for (let cy = 0, j = 0; cy < 5; cy++)
174
+ for (let cx = cy ? 0 : 1, fy2 = fy[cy] * 2; cx < 5 - cy; cx++, j++)
175
+ a += a_ac[j] * fx[cx] * fy2;
176
+ // Convert to RGB
177
+ const b = l - (2 / 3) * p;
178
+ const r = (3 * l - b + q) / 2;
179
+ const g = r - q;
180
+ rgba[i] = max(0, 255 * min(1, r));
181
+ rgba[i + 1] = max(0, 255 * min(1, g));
182
+ rgba[i + 2] = max(0, 255 * min(1, b));
183
+ rgba[i + 3] = max(0, 255 * min(1, a));
184
+ }
185
+ }
186
+ return { w, h, rgba };
187
+ }
188
+ /**
189
+ * Extracts the average color from a ThumbHash. RGB is not be premultiplied by A.
190
+ *
191
+ * @param hash The bytes of the ThumbHash.
192
+ * @returns The RGBA values for the average color. Each value ranges from 0 to 1.
193
+ */
194
+ export function thumbHashToAverageRGBA(hash) {
195
+ const { min, max } = Math;
196
+ const header = hash[0] | (hash[1] << 8) | (hash[2] << 16);
197
+ const l = (header & 63) / 63;
198
+ const p = ((header >> 6) & 63) / 31.5 - 1;
199
+ const q = ((header >> 12) & 63) / 31.5 - 1;
200
+ const hasAlpha = header >> 23;
201
+ const a = hasAlpha ? (hash[5] & 15) / 15 : 1;
202
+ const b = l - (2 / 3) * p;
203
+ const r = (3 * l - b + q) / 2;
204
+ const g = r - q;
205
+ return {
206
+ r: max(0, min(1, r)),
207
+ g: max(0, min(1, g)),
208
+ b: max(0, min(1, b)),
209
+ a,
210
+ };
211
+ }
212
+ /**
213
+ * Extracts the approximate aspect ratio of the original image.
214
+ *
215
+ * @param hash The bytes of the ThumbHash.
216
+ * @returns The approximate aspect ratio (i.e. width / height).
217
+ */
218
+ export function thumbHashToApproximateAspectRatio(hash) {
219
+ const header = hash[3];
220
+ const hasAlpha = hash[2] & 0x80;
221
+ const isLandscape = hash[4] & 0x80;
222
+ const lx = isLandscape ? (hasAlpha ? 5 : 7) : header & 7;
223
+ const ly = isLandscape ? header & 7 : hasAlpha ? 5 : 7;
224
+ return lx / ly;
225
+ }
226
+ /**
227
+ * Encodes an RGBA image to a PNG data URL. RGB should not be premultiplied by
228
+ * A. This is optimized for speed and simplicity and does not optimize for size
229
+ * at all. This doesn't do any compression (all values are stored uncompressed).
230
+ *
231
+ * @param w The width of the input image. Must be ≤100px.
232
+ * @param h The height of the input image. Must be ≤100px.
233
+ * @param rgba The pixels in the input image, row-by-row. Must have w*h*4 elements.
234
+ * @returns A data URL containing a PNG for the input image.
235
+ */
236
+ export function rgbaToDataURL(w, h, rgba) {
237
+ const row = w * 4 + 1;
238
+ const idat = 6 + h * (5 + row);
239
+ const bytes = [
240
+ 137,
241
+ 80,
242
+ 78,
243
+ 71,
244
+ 13,
245
+ 10,
246
+ 26,
247
+ 10,
248
+ 0,
249
+ 0,
250
+ 0,
251
+ 13,
252
+ 73,
253
+ 72,
254
+ 68,
255
+ 82,
256
+ 0,
257
+ 0,
258
+ w >> 8,
259
+ w & 255,
260
+ 0,
261
+ 0,
262
+ h >> 8,
263
+ h & 255,
264
+ 8,
265
+ 6,
266
+ 0,
267
+ 0,
268
+ 0,
269
+ 0,
270
+ 0,
271
+ 0,
272
+ 0,
273
+ idat >>> 24,
274
+ (idat >> 16) & 255,
275
+ (idat >> 8) & 255,
276
+ idat & 255,
277
+ 73,
278
+ 68,
279
+ 65,
280
+ 84,
281
+ 120,
282
+ 1,
283
+ ];
284
+ const table = [
285
+ 0, 498536548, 997073096, 651767980, 1994146192, 1802195444, 1303535960, 1342533948, -306674912,
286
+ -267414716, -690576408, -882789492, -1687895376, -2032938284, -1609899400, -1111625188,
287
+ ];
288
+ let a = 1, b = 0;
289
+ for (let y = 0, i = 0, end = row - 1; y < h; y++, end += row - 1) {
290
+ bytes.push(y + 1 < h ? 0 : 1, row & 255, row >> 8, ~row & 255, (row >> 8) ^ 255, 0);
291
+ for (b = (b + a) % 65521; i < end; i++) {
292
+ const u = rgba[i] & 255;
293
+ bytes.push(u);
294
+ a = (a + u) % 65521;
295
+ b = (b + a) % 65521;
296
+ }
297
+ }
298
+ bytes.push(b >> 8, b & 255, a >> 8, a & 255, 0, 0, 0, 0, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130);
299
+ for (let [start, end] of [
300
+ [12, 29],
301
+ [37, 41 + idat],
302
+ ]) {
303
+ let c = ~0;
304
+ for (let i = start; i < end; i++) {
305
+ c ^= bytes[i];
306
+ c = (c >>> 4) ^ table[c & 15];
307
+ c = (c >>> 4) ^ table[c & 15];
308
+ }
309
+ c = ~c;
310
+ bytes[end++] = c >>> 24;
311
+ bytes[end++] = (c >> 16) & 255;
312
+ bytes[end++] = (c >> 8) & 255;
313
+ bytes[end++] = c & 255;
314
+ }
315
+ return 'data:image/png;base64,' + btoa(String.fromCharCode(...bytes));
316
+ }
317
+ /**
318
+ * Decodes a ThumbHash to a PNG data URL. This is a convenience function that
319
+ * just calls "thumbHashToRGBA" followed by "rgbaToDataURL".
320
+ *
321
+ * @param hash The bytes of the ThumbHash.
322
+ * @returns A data URL containing a PNG for the rendered ThumbHash.
323
+ */
324
+ export function thumbHashToDataURL(hash) {
325
+ const image = thumbHashToRGBA(hash);
326
+ return rgbaToDataURL(image.w, image.h, image.rgba);
327
+ }
328
+ /**
329
+ * Convenience function added to the original thumbhash code, allows generating a thumbhash image directly from
330
+ * thumbhash string.
331
+ * @param thumbhash string from which thumbhashDataURL should be generated
332
+ * @returns A data URL containing a PNG for the rendered ThumbHash
333
+ */
334
+ export function thumbHashStringToDataURL(thumbhash) {
335
+ const hash = Uint8Array.from(atob(thumbhash), (c) => c.charCodeAt(0));
336
+ return thumbHashToDataURL(hash);
337
+ }
338
+ //# sourceMappingURL=thumbhash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thumbhash.js","sourceRoot":"","sources":["../../../src/utils/thumbhash/thumbhash.ts"],"names":[],"mappings":"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","sourcesContent":["// Code copied and slightly modified from https://github.com/evanw/thumbhash\n\n/**\n * Encodes an RGBA image to a ThumbHash. RGB should not be premultiplied by A.\n *\n * @param w The width of the input image. Must be ≤100px.\n * @param h The height of the input image. Must be ≤100px.\n * @param rgba The pixels in the input image, row-by-row. Must have w*h*4 elements.\n * @returns The ThumbHash as a Uint8Array.\n */\n\nexport function rgbaToThumbHash(w: number, h: number, rgba: Uint8Array) {\n // Encoding an image larger than 100x100 is slow with no benefit\n if (w > 100 || h > 100) throw new Error(`${w}x${h} doesn't fit in 100x100`);\n const { PI, round, max, cos, abs } = Math;\n\n // Determine the average color\n let avg_r = 0,\n avg_g = 0,\n avg_b = 0,\n avg_a = 0;\n for (let i = 0, j = 0; i < w * h; i++, j += 4) {\n const alpha = rgba[j + 3] / 255;\n avg_r += (alpha / 255) * rgba[j];\n avg_g += (alpha / 255) * rgba[j + 1];\n avg_b += (alpha / 255) * rgba[j + 2];\n avg_a += alpha;\n }\n if (avg_a) {\n avg_r /= avg_a;\n avg_g /= avg_a;\n avg_b /= avg_a;\n }\n\n const hasAlpha = avg_a < w * h;\n const l_limit = hasAlpha ? 5 : 7; // Use fewer luminance bits if there's alpha\n const lx = max(1, round((l_limit * w) / max(w, h)));\n const ly = max(1, round((l_limit * h) / max(w, h)));\n const l: number[] = []; // luminance\n const p: number[] = []; // yellow - blue\n const q: number[] = []; // red - green\n const a: number[] = []; // alpha\n\n // Convert the image from RGBA to LPQA (composite atop the average color)\n for (let i = 0, j = 0; i < w * h; i++, j += 4) {\n const alpha = rgba[j + 3] / 255;\n const r = avg_r * (1 - alpha) + (alpha / 255) * rgba[j];\n const g = avg_g * (1 - alpha) + (alpha / 255) * rgba[j + 1];\n const b = avg_b * (1 - alpha) + (alpha / 255) * rgba[j + 2];\n l[i] = (r + g + b) / 3;\n p[i] = (r + g) / 2 - b;\n q[i] = r - g;\n a[i] = alpha;\n }\n\n // Encode using the DCT into DC (constant) and normalized AC (varying) terms\n const encodeChannel = (channel, nx, ny) => {\n let dc = 0;\n const ac: number[] = [];\n let scale = 0;\n const fx: number[] = [];\n for (let cy = 0; cy < ny; cy++) {\n for (let cx = 0; cx * ny < nx * (ny - cy); cx++) {\n let f = 0;\n for (let x = 0; x < w; x++) fx[x] = cos((PI / w) * cx * (x + 0.5));\n for (let y = 0; y < h; y++)\n for (let x = 0, fy = cos((PI / h) * cy * (y + 0.5)); x < w; x++)\n f += channel[x + y * w] * fx[x] * fy;\n f /= w * h;\n if (cx || cy) {\n ac.push(f);\n scale = max(scale, abs(f));\n } else {\n dc = f;\n }\n }\n }\n if (scale) for (let i = 0; i < ac.length; i++) ac[i] = 0.5 + (0.5 / scale) * ac[i];\n return [dc, ac, scale];\n };\n const [l_dc, l_ac, l_scale] = encodeChannel(l, max(3, lx), max(3, ly));\n const [p_dc, p_ac, p_scale] = encodeChannel(p, 3, 3);\n const [q_dc, q_ac, q_scale] = encodeChannel(q, 3, 3);\n const [a_dc, a_ac, a_scale] = hasAlpha ? encodeChannel(a, 5, 5) : [];\n\n // Write the constants\n const isLandscape = w > h;\n const header24 =\n round(63 * (l_dc as number)) |\n (round(31.5 + 31.5 * (p_dc as number)) << 6) |\n (round(31.5 + 31.5 * (q_dc as number)) << 12) |\n (round(31 * (l_scale as number)) << 18) |\n ((hasAlpha ? 1 : 0) << 23);\n const header16 =\n (isLandscape ? ly : lx) |\n (round(63 * (p_scale as number)) << 3) |\n (round(63 * (q_scale as number)) << 9) |\n ((isLandscape ? 1 : 0) << 15);\n const hash = [\n header24 & 255,\n (header24 >> 8) & 255,\n header24 >> 16,\n header16 & 255,\n header16 >> 8,\n ];\n const ac_start = hasAlpha ? 6 : 5;\n let ac_index = 0;\n if (hasAlpha) hash.push(round(15 * (a_dc as number)) | (round(15 * (a_scale as number)) << 4));\n\n // Write the varying factors\n for (const ac of hasAlpha ? [l_ac, p_ac, q_ac, a_ac] : [l_ac, p_ac, q_ac])\n for (const f of ac as number[])\n hash[ac_start + (ac_index >> 1)] |= round(15 * f) << ((ac_index++ & 1) << 2);\n return new Uint8Array(hash);\n}\n\n/**\n * Decodes a ThumbHash to an RGBA image. RGB is not be premultiplied by A.\n *\n * @param hash The bytes of the ThumbHash.\n * @returns The width, height, and pixels of the rendered placeholder image.\n */\nexport function thumbHashToRGBA(hash: Uint8Array) {\n const { PI, min, max, cos, round } = Math;\n\n // Read the constants\n const header24 = hash[0] | (hash[1] << 8) | (hash[2] << 16);\n const header16 = hash[3] | (hash[4] << 8);\n const l_dc = (header24 & 63) / 63;\n const p_dc = ((header24 >> 6) & 63) / 31.5 - 1;\n const q_dc = ((header24 >> 12) & 63) / 31.5 - 1;\n const l_scale = ((header24 >> 18) & 31) / 31;\n const hasAlpha = header24 >> 23;\n const p_scale = ((header16 >> 3) & 63) / 63;\n const q_scale = ((header16 >> 9) & 63) / 63;\n const isLandscape = header16 >> 15;\n const lx = max(3, isLandscape ? (hasAlpha ? 5 : 7) : header16 & 7);\n const ly = max(3, isLandscape ? header16 & 7 : hasAlpha ? 5 : 7);\n const a_dc = hasAlpha ? (hash[5] & 15) / 15 : 1;\n const a_scale = (hash[5] >> 4) / 15;\n\n // Read the varying factors (boost saturation by 1.25x to compensate for quantization)\n const ac_start = hasAlpha ? 6 : 5;\n let ac_index = 0;\n const decodeChannel = (nx, ny, scale) => {\n const ac: number[] = [];\n for (let cy = 0; cy < ny; cy++)\n for (let cx = cy ? 0 : 1; cx * ny < nx * (ny - cy); cx++)\n ac.push(\n (((hash[ac_start + (ac_index >> 1)] >> ((ac_index++ & 1) << 2)) & 15) / 7.5 - 1) * scale\n );\n return ac;\n };\n const l_ac = decodeChannel(lx, ly, l_scale);\n const p_ac = decodeChannel(3, 3, p_scale * 1.25);\n const q_ac = decodeChannel(3, 3, q_scale * 1.25);\n const a_ac = hasAlpha && decodeChannel(5, 5, a_scale);\n\n // Decode using the DCT into RGB\n const ratio = thumbHashToApproximateAspectRatio(hash);\n const w = round(ratio > 1 ? 32 : 32 * ratio);\n const h = round(ratio > 1 ? 32 / ratio : 32);\n const rgba = new Uint8Array(w * h * 4),\n fx: number[] = [],\n fy: number[] = [];\n for (let y = 0, i = 0; y < h; y++) {\n for (let x = 0; x < w; x++, i += 4) {\n let l = l_dc,\n p = p_dc,\n q = q_dc,\n a = a_dc;\n\n // Precompute the coefficients\n for (let cx = 0, n = max(lx, hasAlpha ? 5 : 3); cx < n; cx++)\n fx[cx] = cos((PI / w) * (x + 0.5) * cx);\n for (let cy = 0, n = max(ly, hasAlpha ? 5 : 3); cy < n; cy++)\n fy[cy] = cos((PI / h) * (y + 0.5) * cy);\n\n // Decode L\n for (let cy = 0, j = 0; cy < ly; cy++)\n for (let cx = cy ? 0 : 1, fy2 = fy[cy] * 2; cx * ly < lx * (ly - cy); cx++, j++)\n l += l_ac[j] * fx[cx] * fy2;\n\n // Decode P and Q\n for (let cy = 0, j = 0; cy < 3; cy++) {\n for (let cx = cy ? 0 : 1, fy2 = fy[cy] * 2; cx < 3 - cy; cx++, j++) {\n const f = fx[cx] * fy2;\n p += p_ac[j] * f;\n q += q_ac[j] * f;\n }\n }\n\n // Decode A\n if (hasAlpha)\n for (let cy = 0, j = 0; cy < 5; cy++)\n for (let cx = cy ? 0 : 1, fy2 = fy[cy] * 2; cx < 5 - cy; cx++, j++)\n a += a_ac[j] * fx[cx] * fy2;\n\n // Convert to RGB\n const b = l - (2 / 3) * p;\n const r = (3 * l - b + q) / 2;\n const g = r - q;\n rgba[i] = max(0, 255 * min(1, r));\n rgba[i + 1] = max(0, 255 * min(1, g));\n rgba[i + 2] = max(0, 255 * min(1, b));\n rgba[i + 3] = max(0, 255 * min(1, a));\n }\n }\n return { w, h, rgba };\n}\n\n/**\n * Extracts the average color from a ThumbHash. RGB is not be premultiplied by A.\n *\n * @param hash The bytes of the ThumbHash.\n * @returns The RGBA values for the average color. Each value ranges from 0 to 1.\n */\nexport function thumbHashToAverageRGBA(hash: Uint8Array) {\n const { min, max } = Math;\n const header = hash[0] | (hash[1] << 8) | (hash[2] << 16);\n const l = (header & 63) / 63;\n const p = ((header >> 6) & 63) / 31.5 - 1;\n const q = ((header >> 12) & 63) / 31.5 - 1;\n const hasAlpha = header >> 23;\n const a = hasAlpha ? (hash[5] & 15) / 15 : 1;\n const b = l - (2 / 3) * p;\n const r = (3 * l - b + q) / 2;\n const g = r - q;\n return {\n r: max(0, min(1, r)),\n g: max(0, min(1, g)),\n b: max(0, min(1, b)),\n a,\n };\n}\n\n/**\n * Extracts the approximate aspect ratio of the original image.\n *\n * @param hash The bytes of the ThumbHash.\n * @returns The approximate aspect ratio (i.e. width / height).\n */\nexport function thumbHashToApproximateAspectRatio(hash: Uint8Array) {\n const header = hash[3];\n const hasAlpha = hash[2] & 0x80;\n const isLandscape = hash[4] & 0x80;\n const lx = isLandscape ? (hasAlpha ? 5 : 7) : header & 7;\n const ly = isLandscape ? header & 7 : hasAlpha ? 5 : 7;\n return lx / ly;\n}\n\n/**\n * Encodes an RGBA image to a PNG data URL. RGB should not be premultiplied by\n * A. This is optimized for speed and simplicity and does not optimize for size\n * at all. This doesn't do any compression (all values are stored uncompressed).\n *\n * @param w The width of the input image. Must be ≤100px.\n * @param h The height of the input image. Must be ≤100px.\n * @param rgba The pixels in the input image, row-by-row. Must have w*h*4 elements.\n * @returns A data URL containing a PNG for the input image.\n */\nexport function rgbaToDataURL(w: number, h: number, rgba: Uint8Array) {\n const row = w * 4 + 1;\n const idat = 6 + h * (5 + row);\n const bytes = [\n 137,\n 80,\n 78,\n 71,\n 13,\n 10,\n 26,\n 10,\n 0,\n 0,\n 0,\n 13,\n 73,\n 72,\n 68,\n 82,\n 0,\n 0,\n w >> 8,\n w & 255,\n 0,\n 0,\n h >> 8,\n h & 255,\n 8,\n 6,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n idat >>> 24,\n (idat >> 16) & 255,\n (idat >> 8) & 255,\n idat & 255,\n 73,\n 68,\n 65,\n 84,\n 120,\n 1,\n ];\n const table = [\n 0, 498536548, 997073096, 651767980, 1994146192, 1802195444, 1303535960, 1342533948, -306674912,\n -267414716, -690576408, -882789492, -1687895376, -2032938284, -1609899400, -1111625188,\n ];\n let a = 1,\n b = 0;\n for (let y = 0, i = 0, end = row - 1; y < h; y++, end += row - 1) {\n bytes.push(y + 1 < h ? 0 : 1, row & 255, row >> 8, ~row & 255, (row >> 8) ^ 255, 0);\n for (b = (b + a) % 65521; i < end; i++) {\n const u = rgba[i] & 255;\n bytes.push(u);\n a = (a + u) % 65521;\n b = (b + a) % 65521;\n }\n }\n bytes.push(\n b >> 8,\n b & 255,\n a >> 8,\n a & 255,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 0,\n 73,\n 69,\n 78,\n 68,\n 174,\n 66,\n 96,\n 130\n );\n for (let [start, end] of [\n [12, 29],\n [37, 41 + idat],\n ]) {\n let c = ~0;\n for (let i = start; i < end; i++) {\n c ^= bytes[i];\n c = (c >>> 4) ^ table[c & 15];\n c = (c >>> 4) ^ table[c & 15];\n }\n c = ~c;\n bytes[end++] = c >>> 24;\n bytes[end++] = (c >> 16) & 255;\n bytes[end++] = (c >> 8) & 255;\n bytes[end++] = c & 255;\n }\n return 'data:image/png;base64,' + btoa(String.fromCharCode(...bytes));\n}\n\n/**\n * Decodes a ThumbHash to a PNG data URL. This is a convenience function that\n * just calls \"thumbHashToRGBA\" followed by \"rgbaToDataURL\".\n *\n * @param hash The bytes of the ThumbHash.\n * @returns A data URL containing a PNG for the rendered ThumbHash.\n */\nexport function thumbHashToDataURL(hash: Uint8Array): string {\n const image = thumbHashToRGBA(hash);\n return rgbaToDataURL(image.w, image.h, image.rgba);\n}\n\n/**\n * Convenience function added to the original thumbhash code, allows generating a thumbhash image directly from\n * thumbhash string.\n * @param thumbhash string from which thumbhashDataURL should be generated\n * @returns A data URL containing a PNG for the rendered ThumbHash\n */\nexport function thumbHashStringToDataURL(thumbhash: string): string {\n const hash = Uint8Array.from(atob(thumbhash), (c) => c.charCodeAt(0));\n return thumbHashToDataURL(hash);\n}\n"]}