react-native-ensys-camera-x 1.0.7

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 (506) hide show
  1. package/CustomCamera.podspec +20 -0
  2. package/LICENSE +20 -0
  3. package/README.md +833 -0
  4. package/android/build.gradle +135 -0
  5. package/android/consumer-rules.pro +47 -0
  6. package/android/src/main/AndroidManifest.xml +72 -0
  7. package/android/src/main/java/android/print/PdfPrint.java +51 -0
  8. package/android/src/main/java/com/customcamera/AnimatedImageViewManager.kt +199 -0
  9. package/android/src/main/java/com/customcamera/AudioPlayerView.kt +322 -0
  10. package/android/src/main/java/com/customcamera/AudioRecorder.kt +506 -0
  11. package/android/src/main/java/com/customcamera/BarcodeScannerActivity.kt +361 -0
  12. package/android/src/main/java/com/customcamera/BlurBackgroundView.kt +199 -0
  13. package/android/src/main/java/com/customcamera/CacheCleanupManager.kt +386 -0
  14. package/android/src/main/java/com/customcamera/CameraAspectRatioMode.kt +77 -0
  15. package/android/src/main/java/com/customcamera/CameraAsset.kt +211 -0
  16. package/android/src/main/java/com/customcamera/CameraTheme.kt +479 -0
  17. package/android/src/main/java/com/customcamera/CompressionCacheStore.kt +504 -0
  18. package/android/src/main/java/com/customcamera/CompressionFileNameUtils.kt +7 -0
  19. package/android/src/main/java/com/customcamera/CompressionProfile.kt +195 -0
  20. package/android/src/main/java/com/customcamera/CustomCameraActivity.kt +7291 -0
  21. package/android/src/main/java/com/customcamera/CustomCameraFileProvider.kt +9 -0
  22. package/android/src/main/java/com/customcamera/CustomCameraModule.kt +2479 -0
  23. package/android/src/main/java/com/customcamera/CustomCameraPackage.kt +53 -0
  24. package/android/src/main/java/com/customcamera/DisplayUtils.kt +9 -0
  25. package/android/src/main/java/com/customcamera/DocumentPreviewView.kt +846 -0
  26. package/android/src/main/java/com/customcamera/DrawingView.kt +214 -0
  27. package/android/src/main/java/com/customcamera/EmojiPickerData.kt +228 -0
  28. package/android/src/main/java/com/customcamera/FilterStripAdapter.kt +158 -0
  29. package/android/src/main/java/com/customcamera/GifSupport.kt +215 -0
  30. package/android/src/main/java/com/customcamera/GlobalAudioPlayer.kt +320 -0
  31. package/android/src/main/java/com/customcamera/ImageExporter.kt +1394 -0
  32. package/android/src/main/java/com/customcamera/ImageFormatSupport.kt +163 -0
  33. package/android/src/main/java/com/customcamera/Localization.kt +206 -0
  34. package/android/src/main/java/com/customcamera/MediaAdapters.kt +758 -0
  35. package/android/src/main/java/com/customcamera/MediaCacheManager.kt +782 -0
  36. package/android/src/main/java/com/customcamera/MediaExportFormats.kt +201 -0
  37. package/android/src/main/java/com/customcamera/MediaFileIo.kt +310 -0
  38. package/android/src/main/java/com/customcamera/MediaMetadataStore.kt +494 -0
  39. package/android/src/main/java/com/customcamera/MediaPreviewEditor.kt +14865 -0
  40. package/android/src/main/java/com/customcamera/MediaPublisher.kt +423 -0
  41. package/android/src/main/java/com/customcamera/MediaStorageWorkflow.kt +722 -0
  42. package/android/src/main/java/com/customcamera/MediaStoreRepository.kt +378 -0
  43. package/android/src/main/java/com/customcamera/MediaThumbnailView.kt +286 -0
  44. package/android/src/main/java/com/customcamera/MediaUtils.kt +37 -0
  45. package/android/src/main/java/com/customcamera/NativeVideoViewManager.kt +845 -0
  46. package/android/src/main/java/com/customcamera/OfficeDocumentConverter.kt +2791 -0
  47. package/android/src/main/java/com/customcamera/PendingCaptureCrops.kt +88 -0
  48. package/android/src/main/java/com/customcamera/PowerPointPreview.kt +4077 -0
  49. package/android/src/main/java/com/customcamera/RecentPickerStore.kt +74 -0
  50. package/android/src/main/java/com/customcamera/SecureFileEraser.kt +411 -0
  51. package/android/src/main/java/com/customcamera/SecureKeyModule.kt +88 -0
  52. package/android/src/main/java/com/customcamera/SecureMediaDeleter.kt +493 -0
  53. package/android/src/main/java/com/customcamera/StickerPickerData.kt +107 -0
  54. package/android/src/main/java/com/customcamera/SvgDrawable.kt +175 -0
  55. package/android/src/main/java/com/customcamera/SvgIconViewManager.kt +77 -0
  56. package/android/src/main/java/com/customcamera/TextEntryController.kt +553 -0
  57. package/android/src/main/java/com/customcamera/ThumbnailLoader.kt +455 -0
  58. package/android/src/main/java/com/customcamera/UploadService.kt +909 -0
  59. package/android/src/main/java/com/customcamera/VideoEditUtils.kt +210 -0
  60. package/android/src/main/java/com/customcamera/VideoRotationTranscoder.kt +1992 -0
  61. package/android/src/main/java/com/customcamera/gif/AnimatedGifEncoder.kt +473 -0
  62. package/android/src/main/java/com/customcamera/gif/GifDecoder.kt +690 -0
  63. package/android/src/main/java/com/customcamera/gif/GifFramesDrawable.kt +160 -0
  64. package/android/src/main/java/com/customcamera/gif/GifHttp.kt +112 -0
  65. package/android/src/main/java/com/customcamera/gif/GifImageLoader.kt +186 -0
  66. package/android/src/main/java/com/customcamera/gif/GifModels.kt +74 -0
  67. package/android/src/main/java/com/customcamera/gif/GifProvider.kt +49 -0
  68. package/android/src/main/java/com/customcamera/gif/GifProviders.kt +27 -0
  69. package/android/src/main/java/com/customcamera/gif/GifRepository.kt +124 -0
  70. package/android/src/main/java/com/customcamera/gif/GifSafety.kt +33 -0
  71. package/android/src/main/java/com/customcamera/gif/GiphyGifProvider.kt +146 -0
  72. package/android/src/main/java/com/customcamera/gif/LZWEncoder.kt +258 -0
  73. package/android/src/main/java/com/customcamera/gif/NeuQuant.kt +435 -0
  74. package/android/src/main/java/com/customcamera/gif/TenorGifProvider.kt +147 -0
  75. package/android/src/main/res/drawable/bg_brush_selected.xml +5 -0
  76. package/android/src/main/res/drawable/bg_color_swatch.xml +5 -0
  77. package/android/src/main/res/drawable/bg_editor_toolbar.xml +6 -0
  78. package/android/src/main/res/drawable/bg_icon_circle.xml +5 -0
  79. package/android/src/main/res/drawable/bg_icon_circle_light.xml +5 -0
  80. package/android/src/main/res/drawable/bg_mode_tab_active.xml +6 -0
  81. package/android/src/main/res/drawable/bg_pill.xml +6 -0
  82. package/android/src/main/res/drawable/bg_recording_dot.xml +6 -0
  83. package/android/src/main/res/drawable/bg_selection_badge.xml +8 -0
  84. package/android/src/main/res/drawable/bg_send_button.xml +5 -0
  85. package/android/src/main/res/drawable/bg_shutter_inner.xml +5 -0
  86. package/android/src/main/res/drawable/bg_shutter_recording.xml +6 -0
  87. package/android/src/main/res/drawable/bg_shutter_ring.xml +8 -0
  88. package/android/src/main/res/drawable/bg_shutter_video_idle.xml +5 -0
  89. package/android/src/main/res/drawable/bg_thumbnail.xml +9 -0
  90. package/android/src/main/res/drawable/ic_aspect_ratio.xml +17 -0
  91. package/android/src/main/res/drawable/ic_audio.xml +10 -0
  92. package/android/src/main/res/drawable/ic_back.xml +10 -0
  93. package/android/src/main/res/drawable/ic_brush_medium.xml +12 -0
  94. package/android/src/main/res/drawable/ic_brush_thick.xml +12 -0
  95. package/android/src/main/res/drawable/ic_brush_thin.xml +12 -0
  96. package/android/src/main/res/drawable/ic_check.xml +17 -0
  97. package/android/src/main/res/drawable/ic_chevron_down.xml +10 -0
  98. package/android/src/main/res/drawable/ic_chevron_up.xml +13 -0
  99. package/android/src/main/res/drawable/ic_clear_drawing.xml +10 -0
  100. package/android/src/main/res/drawable/ic_close.xml +10 -0
  101. package/android/src/main/res/drawable/ic_cover.xml +9 -0
  102. package/android/src/main/res/drawable/ic_crop.xml +10 -0
  103. package/android/src/main/res/drawable/ic_delete.xml +9 -0
  104. package/android/src/main/res/drawable/ic_document.xml +10 -0
  105. package/android/src/main/res/drawable/ic_done.xml +10 -0
  106. package/android/src/main/res/drawable/ic_download.xml +10 -0
  107. package/android/src/main/res/drawable/ic_emoji.xml +10 -0
  108. package/android/src/main/res/drawable/ic_filter.xml +10 -0
  109. package/android/src/main/res/drawable/ic_flash_auto.xml +7 -0
  110. package/android/src/main/res/drawable/ic_flash_off.xml +23 -0
  111. package/android/src/main/res/drawable/ic_flash_on.xml +16 -0
  112. package/android/src/main/res/drawable/ic_flip.xml +15 -0
  113. package/android/src/main/res/drawable/ic_gallery.xml +10 -0
  114. package/android/src/main/res/drawable/ic_gif.xml +24 -0
  115. package/android/src/main/res/drawable/ic_lock.xml +19 -0
  116. package/android/src/main/res/drawable/ic_lock_open.xml +22 -0
  117. package/android/src/main/res/drawable/ic_marker.xml +10 -0
  118. package/android/src/main/res/drawable/ic_more_vert.xml +18 -0
  119. package/android/src/main/res/drawable/ic_overlay_close.xml +19 -0
  120. package/android/src/main/res/drawable/ic_overlay_resize.xml +18 -0
  121. package/android/src/main/res/drawable/ic_pause.xml +10 -0
  122. package/android/src/main/res/drawable/ic_photo_mode.xml +10 -0
  123. package/android/src/main/res/drawable/ic_play.xml +10 -0
  124. package/android/src/main/res/drawable/ic_redo.xml +10 -0
  125. package/android/src/main/res/drawable/ic_rotate.xml +9 -0
  126. package/android/src/main/res/drawable/ic_send.xml +10 -0
  127. package/android/src/main/res/drawable/ic_share.xml +10 -0
  128. package/android/src/main/res/drawable/ic_stat_upload.xml +10 -0
  129. package/android/src/main/res/drawable/ic_sticker.xml +24 -0
  130. package/android/src/main/res/drawable/ic_text.xml +10 -0
  131. package/android/src/main/res/drawable/ic_text_align_center.xml +11 -0
  132. package/android/src/main/res/drawable/ic_text_align_left.xml +11 -0
  133. package/android/src/main/res/drawable/ic_text_align_right.xml +11 -0
  134. package/android/src/main/res/drawable/ic_text_bg.xml +11 -0
  135. package/android/src/main/res/drawable/ic_trim.xml +23 -0
  136. package/android/src/main/res/drawable/ic_undo.xml +10 -0
  137. package/android/src/main/res/drawable/ic_video_mode.xml +10 -0
  138. package/android/src/main/res/drawable/ic_video_note.xml +13 -0
  139. package/android/src/main/res/drawable/ic_volume_off.xml +9 -0
  140. package/android/src/main/res/drawable/ic_volume_on.xml +9 -0
  141. package/android/src/main/res/drawable/sticker_heart.xml +9 -0
  142. package/android/src/main/res/drawable/sticker_smile.xml +9 -0
  143. package/android/src/main/res/drawable/sticker_star.xml +9 -0
  144. package/android/src/main/res/drawable/sticker_thumbsup.xml +9 -0
  145. package/android/src/main/res/values/colors.xml +34 -0
  146. package/android/src/main/res/values/ids.xml +15 -0
  147. package/android/src/main/res/values/strings.xml +15 -0
  148. package/android/src/main/res/values/styles.xml +20 -0
  149. package/android/src/main/res/xml/file_paths.xml +34 -0
  150. package/ios/CustomCamera.h +5 -0
  151. package/ios/CustomCamera.mm +214 -0
  152. package/lib/module/AudioPlayerContext.js +233 -0
  153. package/lib/module/AudioPlayerContext.js.map +1 -0
  154. package/lib/module/CameraPreview.js +304 -0
  155. package/lib/module/CameraPreview.js.map +1 -0
  156. package/lib/module/NativeAnimatedImageView.js +41 -0
  157. package/lib/module/NativeAnimatedImageView.js.map +1 -0
  158. package/lib/module/NativeAudioPlayerView.js +33 -0
  159. package/lib/module/NativeAudioPlayerView.js.map +1 -0
  160. package/lib/module/NativeBlurView.js +35 -0
  161. package/lib/module/NativeBlurView.js.map +1 -0
  162. package/lib/module/NativeCustomCamera.js +128 -0
  163. package/lib/module/NativeCustomCamera.js.map +1 -0
  164. package/lib/module/NativeCustomCamera.web.js +143 -0
  165. package/lib/module/NativeCustomCamera.web.js.map +1 -0
  166. package/lib/module/NativeCustomVideoView.js +5 -0
  167. package/lib/module/NativeCustomVideoView.js.map +1 -0
  168. package/lib/module/NativeDocumentPreviewView.js +156 -0
  169. package/lib/module/NativeDocumentPreviewView.js.map +1 -0
  170. package/lib/module/NativeMediaThumbnailView.js +110 -0
  171. package/lib/module/NativeMediaThumbnailView.js.map +1 -0
  172. package/lib/module/NativeSvgIcon.js +32 -0
  173. package/lib/module/NativeSvgIcon.js.map +1 -0
  174. package/lib/module/ResponsivePreviewContainer.js +171 -0
  175. package/lib/module/ResponsivePreviewContainer.js.map +1 -0
  176. package/lib/module/accessibility.js +61 -0
  177. package/lib/module/accessibility.js.map +1 -0
  178. package/lib/module/config.js +352 -0
  179. package/lib/module/config.js.map +1 -0
  180. package/lib/module/cpuOptimization.js +296 -0
  181. package/lib/module/cpuOptimization.js.map +1 -0
  182. package/lib/module/db/DatabaseManager.js +191 -0
  183. package/lib/module/db/DatabaseManager.js.map +1 -0
  184. package/lib/module/db/MediaMapper.js +284 -0
  185. package/lib/module/db/MediaMapper.js.map +1 -0
  186. package/lib/module/db/MediaRepository.js +242 -0
  187. package/lib/module/db/MediaRepository.js.map +1 -0
  188. package/lib/module/db/index.js +41 -0
  189. package/lib/module/db/index.js.map +1 -0
  190. package/lib/module/db/migrations.js +180 -0
  191. package/lib/module/db/migrations.js.map +1 -0
  192. package/lib/module/db/react-native-sqlcipher.d.js +2 -0
  193. package/lib/module/db/react-native-sqlcipher.d.js.map +1 -0
  194. package/lib/module/db/secureKey.js +87 -0
  195. package/lib/module/db/secureKey.js.map +1 -0
  196. package/lib/module/db/types.js +57 -0
  197. package/lib/module/db/types.js.map +1 -0
  198. package/lib/module/db/useMediaDatabase.js +123 -0
  199. package/lib/module/db/useMediaDatabase.js.map +1 -0
  200. package/lib/module/defaultIcons.js +2259 -0
  201. package/lib/module/defaultIcons.js.map +1 -0
  202. package/lib/module/deviceCapabilities.js +408 -0
  203. package/lib/module/deviceCapabilities.js.map +1 -0
  204. package/lib/module/errors.js +267 -0
  205. package/lib/module/errors.js.map +1 -0
  206. package/lib/module/iconConfig.js +796 -0
  207. package/lib/module/iconConfig.js.map +1 -0
  208. package/lib/module/icons.js +514 -0
  209. package/lib/module/icons.js.map +1 -0
  210. package/lib/module/index.js +251 -0
  211. package/lib/module/index.js.map +1 -0
  212. package/lib/module/jest-globals.d.js +2 -0
  213. package/lib/module/jest-globals.d.js.map +1 -0
  214. package/lib/module/library/MediaLibrary.js +107 -0
  215. package/lib/module/library/MediaLibrary.js.map +1 -0
  216. package/lib/module/library/MediaLibraryScreen.js +2597 -0
  217. package/lib/module/library/MediaLibraryScreen.js.map +1 -0
  218. package/lib/module/library/components/AudioPreview.js +74 -0
  219. package/lib/module/library/components/AudioPreview.js.map +1 -0
  220. package/lib/module/library/components/DocumentPreview.js +331 -0
  221. package/lib/module/library/components/DocumentPreview.js.map +1 -0
  222. package/lib/module/library/components/ExpandableFab.js +343 -0
  223. package/lib/module/library/components/ExpandableFab.js.map +1 -0
  224. package/lib/module/library/components/FileTiles.js +251 -0
  225. package/lib/module/library/components/FileTiles.js.map +1 -0
  226. package/lib/module/library/components/ImagePreview.js +70 -0
  227. package/lib/module/library/components/ImagePreview.js.map +1 -0
  228. package/lib/module/library/components/MediaMetadataHeader.js +175 -0
  229. package/lib/module/library/components/MediaMetadataHeader.js.map +1 -0
  230. package/lib/module/library/components/RecordAudioScreen.js +816 -0
  231. package/lib/module/library/components/RecordAudioScreen.js.map +1 -0
  232. package/lib/module/library/components/VideoPreview.js +453 -0
  233. package/lib/module/library/components/VideoPreview.js.map +1 -0
  234. package/lib/module/library/components/ViewerCounter.js +55 -0
  235. package/lib/module/library/components/ViewerCounter.js.map +1 -0
  236. package/lib/module/library/compressionEstimate.js +507 -0
  237. package/lib/module/library/compressionEstimate.js.map +1 -0
  238. package/lib/module/library/fileMetadata.js +196 -0
  239. package/lib/module/library/fileMetadata.js.map +1 -0
  240. package/lib/module/library/index.js +42 -0
  241. package/lib/module/library/index.js.map +1 -0
  242. package/lib/module/library/libraryIconRegistry.js +69 -0
  243. package/lib/module/library/libraryIconRegistry.js.map +1 -0
  244. package/lib/module/library/libraryIcons.js +858 -0
  245. package/lib/module/library/libraryIcons.js.map +1 -0
  246. package/lib/module/library/localizedFormat.js +181 -0
  247. package/lib/module/library/localizedFormat.js.map +1 -0
  248. package/lib/module/library/palette.js +225 -0
  249. package/lib/module/library/palette.js.map +1 -0
  250. package/lib/module/library/responsive.js +53 -0
  251. package/lib/module/library/responsive.js.map +1 -0
  252. package/lib/module/locales.js +416 -0
  253. package/lib/module/locales.js.map +1 -0
  254. package/lib/module/localization.js +1064 -0
  255. package/lib/module/localization.js.map +1 -0
  256. package/lib/module/logger.js +20 -0
  257. package/lib/module/logger.js.map +1 -0
  258. package/lib/module/lowMemoryCache.js +206 -0
  259. package/lib/module/lowMemoryCache.js.map +1 -0
  260. package/lib/module/mediaHistory.js +33 -0
  261. package/lib/module/mediaHistory.js.map +1 -0
  262. package/lib/module/mediaStorageService.js +402 -0
  263. package/lib/module/mediaStorageService.js.map +1 -0
  264. package/lib/module/memory.js +79 -0
  265. package/lib/module/memory.js.map +1 -0
  266. package/lib/module/nativeActions.js +307 -0
  267. package/lib/module/nativeActions.js.map +1 -0
  268. package/lib/module/nativeComponentSupport.js +61 -0
  269. package/lib/module/nativeComponentSupport.js.map +1 -0
  270. package/lib/module/networkPerformance.js +24 -0
  271. package/lib/module/networkPerformance.js.map +1 -0
  272. package/lib/module/package.json +1 -0
  273. package/lib/module/performance.js +104 -0
  274. package/lib/module/performance.js.map +1 -0
  275. package/lib/module/performanceMonitor.js +155 -0
  276. package/lib/module/performanceMonitor.js.map +1 -0
  277. package/lib/module/permissions.js +370 -0
  278. package/lib/module/permissions.js.map +1 -0
  279. package/lib/module/rendering.js +40 -0
  280. package/lib/module/rendering.js.map +1 -0
  281. package/lib/module/security.js +18 -0
  282. package/lib/module/security.js.map +1 -0
  283. package/lib/module/state.js +266 -0
  284. package/lib/module/state.js.map +1 -0
  285. package/lib/module/storage.js +400 -0
  286. package/lib/module/storage.js.map +1 -0
  287. package/lib/module/theme.js +390 -0
  288. package/lib/module/theme.js.map +1 -0
  289. package/lib/module/types.js +4 -0
  290. package/lib/module/types.js.map +1 -0
  291. package/lib/module/utils.js +115 -0
  292. package/lib/module/utils.js.map +1 -0
  293. package/lib/module/validation.js +288 -0
  294. package/lib/module/validation.js.map +1 -0
  295. package/lib/typescript/package.json +1 -0
  296. package/lib/typescript/src/AudioPlayerContext.d.ts +27 -0
  297. package/lib/typescript/src/AudioPlayerContext.d.ts.map +1 -0
  298. package/lib/typescript/src/CameraPreview.d.ts +13 -0
  299. package/lib/typescript/src/CameraPreview.d.ts.map +1 -0
  300. package/lib/typescript/src/NativeAnimatedImageView.d.ts +33 -0
  301. package/lib/typescript/src/NativeAnimatedImageView.d.ts.map +1 -0
  302. package/lib/typescript/src/NativeAudioPlayerView.d.ts +12 -0
  303. package/lib/typescript/src/NativeAudioPlayerView.d.ts.map +1 -0
  304. package/lib/typescript/src/NativeBlurView.d.ts +12 -0
  305. package/lib/typescript/src/NativeBlurView.d.ts.map +1 -0
  306. package/lib/typescript/src/NativeCustomCamera.d.ts +167 -0
  307. package/lib/typescript/src/NativeCustomCamera.d.ts.map +1 -0
  308. package/lib/typescript/src/NativeCustomCamera.web.d.ts +47 -0
  309. package/lib/typescript/src/NativeCustomCamera.web.d.ts.map +1 -0
  310. package/lib/typescript/src/NativeCustomVideoView.d.ts +30 -0
  311. package/lib/typescript/src/NativeCustomVideoView.d.ts.map +1 -0
  312. package/lib/typescript/src/NativeDocumentPreviewView.d.ts +48 -0
  313. package/lib/typescript/src/NativeDocumentPreviewView.d.ts.map +1 -0
  314. package/lib/typescript/src/NativeMediaThumbnailView.d.ts +54 -0
  315. package/lib/typescript/src/NativeMediaThumbnailView.d.ts.map +1 -0
  316. package/lib/typescript/src/NativeSvgIcon.d.ts +25 -0
  317. package/lib/typescript/src/NativeSvgIcon.d.ts.map +1 -0
  318. package/lib/typescript/src/ResponsivePreviewContainer.d.ts +92 -0
  319. package/lib/typescript/src/ResponsivePreviewContainer.d.ts.map +1 -0
  320. package/lib/typescript/src/accessibility.d.ts +20 -0
  321. package/lib/typescript/src/accessibility.d.ts.map +1 -0
  322. package/lib/typescript/src/config.d.ts +145 -0
  323. package/lib/typescript/src/config.d.ts.map +1 -0
  324. package/lib/typescript/src/cpuOptimization.d.ts +63 -0
  325. package/lib/typescript/src/cpuOptimization.d.ts.map +1 -0
  326. package/lib/typescript/src/db/DatabaseManager.d.ts +48 -0
  327. package/lib/typescript/src/db/DatabaseManager.d.ts.map +1 -0
  328. package/lib/typescript/src/db/MediaMapper.d.ts +77 -0
  329. package/lib/typescript/src/db/MediaMapper.d.ts.map +1 -0
  330. package/lib/typescript/src/db/MediaRepository.d.ts +66 -0
  331. package/lib/typescript/src/db/MediaRepository.d.ts.map +1 -0
  332. package/lib/typescript/src/db/index.d.ts +23 -0
  333. package/lib/typescript/src/db/index.d.ts.map +1 -0
  334. package/lib/typescript/src/db/migrations.d.ts +31 -0
  335. package/lib/typescript/src/db/migrations.d.ts.map +1 -0
  336. package/lib/typescript/src/db/secureKey.d.ts +10 -0
  337. package/lib/typescript/src/db/secureKey.d.ts.map +1 -0
  338. package/lib/typescript/src/db/types.d.ts +115 -0
  339. package/lib/typescript/src/db/types.d.ts.map +1 -0
  340. package/lib/typescript/src/db/useMediaDatabase.d.ts +41 -0
  341. package/lib/typescript/src/db/useMediaDatabase.d.ts.map +1 -0
  342. package/lib/typescript/src/defaultIcons.d.ts +139 -0
  343. package/lib/typescript/src/defaultIcons.d.ts.map +1 -0
  344. package/lib/typescript/src/deviceCapabilities.d.ts +92 -0
  345. package/lib/typescript/src/deviceCapabilities.d.ts.map +1 -0
  346. package/lib/typescript/src/errors.d.ts +95 -0
  347. package/lib/typescript/src/errors.d.ts.map +1 -0
  348. package/lib/typescript/src/iconConfig.d.ts +176 -0
  349. package/lib/typescript/src/iconConfig.d.ts.map +1 -0
  350. package/lib/typescript/src/icons.d.ts +217 -0
  351. package/lib/typescript/src/icons.d.ts.map +1 -0
  352. package/lib/typescript/src/index.d.ts +104 -0
  353. package/lib/typescript/src/index.d.ts.map +1 -0
  354. package/lib/typescript/src/library/MediaLibrary.d.ts +57 -0
  355. package/lib/typescript/src/library/MediaLibrary.d.ts.map +1 -0
  356. package/lib/typescript/src/library/MediaLibraryScreen.d.ts +51 -0
  357. package/lib/typescript/src/library/MediaLibraryScreen.d.ts.map +1 -0
  358. package/lib/typescript/src/library/components/AudioPreview.d.ts +6 -0
  359. package/lib/typescript/src/library/components/AudioPreview.d.ts.map +1 -0
  360. package/lib/typescript/src/library/components/DocumentPreview.d.ts +10 -0
  361. package/lib/typescript/src/library/components/DocumentPreview.d.ts.map +1 -0
  362. package/lib/typescript/src/library/components/ExpandableFab.d.ts +39 -0
  363. package/lib/typescript/src/library/components/ExpandableFab.d.ts.map +1 -0
  364. package/lib/typescript/src/library/components/FileTiles.d.ts +8 -0
  365. package/lib/typescript/src/library/components/FileTiles.d.ts.map +1 -0
  366. package/lib/typescript/src/library/components/ImagePreview.d.ts +5 -0
  367. package/lib/typescript/src/library/components/ImagePreview.d.ts.map +1 -0
  368. package/lib/typescript/src/library/components/MediaMetadataHeader.d.ts +16 -0
  369. package/lib/typescript/src/library/components/MediaMetadataHeader.d.ts.map +1 -0
  370. package/lib/typescript/src/library/components/RecordAudioScreen.d.ts +8 -0
  371. package/lib/typescript/src/library/components/RecordAudioScreen.d.ts.map +1 -0
  372. package/lib/typescript/src/library/components/VideoPreview.d.ts +20 -0
  373. package/lib/typescript/src/library/components/VideoPreview.d.ts.map +1 -0
  374. package/lib/typescript/src/library/components/ViewerCounter.d.ts +13 -0
  375. package/lib/typescript/src/library/components/ViewerCounter.d.ts.map +1 -0
  376. package/lib/typescript/src/library/compressionEstimate.d.ts +313 -0
  377. package/lib/typescript/src/library/compressionEstimate.d.ts.map +1 -0
  378. package/lib/typescript/src/library/fileMetadata.d.ts +33 -0
  379. package/lib/typescript/src/library/fileMetadata.d.ts.map +1 -0
  380. package/lib/typescript/src/library/index.d.ts +40 -0
  381. package/lib/typescript/src/library/index.d.ts.map +1 -0
  382. package/lib/typescript/src/library/libraryIconRegistry.d.ts +35 -0
  383. package/lib/typescript/src/library/libraryIconRegistry.d.ts.map +1 -0
  384. package/lib/typescript/src/library/libraryIcons.d.ts +85 -0
  385. package/lib/typescript/src/library/libraryIcons.d.ts.map +1 -0
  386. package/lib/typescript/src/library/localizedFormat.d.ts +49 -0
  387. package/lib/typescript/src/library/localizedFormat.d.ts.map +1 -0
  388. package/lib/typescript/src/library/palette.d.ts +104 -0
  389. package/lib/typescript/src/library/palette.d.ts.map +1 -0
  390. package/lib/typescript/src/library/responsive.d.ts +15 -0
  391. package/lib/typescript/src/library/responsive.d.ts.map +1 -0
  392. package/lib/typescript/src/locales.d.ts +103 -0
  393. package/lib/typescript/src/locales.d.ts.map +1 -0
  394. package/lib/typescript/src/localization.d.ts +1051 -0
  395. package/lib/typescript/src/localization.d.ts.map +1 -0
  396. package/lib/typescript/src/logger.d.ts +4 -0
  397. package/lib/typescript/src/logger.d.ts.map +1 -0
  398. package/lib/typescript/src/lowMemoryCache.d.ts +64 -0
  399. package/lib/typescript/src/lowMemoryCache.d.ts.map +1 -0
  400. package/lib/typescript/src/mediaHistory.d.ts +3 -0
  401. package/lib/typescript/src/mediaHistory.d.ts.map +1 -0
  402. package/lib/typescript/src/mediaStorageService.d.ts +155 -0
  403. package/lib/typescript/src/mediaStorageService.d.ts.map +1 -0
  404. package/lib/typescript/src/memory.d.ts +21 -0
  405. package/lib/typescript/src/memory.d.ts.map +1 -0
  406. package/lib/typescript/src/nativeActions.d.ts +174 -0
  407. package/lib/typescript/src/nativeActions.d.ts.map +1 -0
  408. package/lib/typescript/src/nativeComponentSupport.d.ts +30 -0
  409. package/lib/typescript/src/nativeComponentSupport.d.ts.map +1 -0
  410. package/lib/typescript/src/networkPerformance.d.ts +12 -0
  411. package/lib/typescript/src/networkPerformance.d.ts.map +1 -0
  412. package/lib/typescript/src/performance.d.ts +32 -0
  413. package/lib/typescript/src/performance.d.ts.map +1 -0
  414. package/lib/typescript/src/performanceMonitor.d.ts +45 -0
  415. package/lib/typescript/src/performanceMonitor.d.ts.map +1 -0
  416. package/lib/typescript/src/permissions.d.ts +132 -0
  417. package/lib/typescript/src/permissions.d.ts.map +1 -0
  418. package/lib/typescript/src/rendering.d.ts +9 -0
  419. package/lib/typescript/src/rendering.d.ts.map +1 -0
  420. package/lib/typescript/src/security.d.ts +6 -0
  421. package/lib/typescript/src/security.d.ts.map +1 -0
  422. package/lib/typescript/src/state.d.ts +102 -0
  423. package/lib/typescript/src/state.d.ts.map +1 -0
  424. package/lib/typescript/src/storage.d.ts +117 -0
  425. package/lib/typescript/src/storage.d.ts.map +1 -0
  426. package/lib/typescript/src/theme.d.ts +15 -0
  427. package/lib/typescript/src/theme.d.ts.map +1 -0
  428. package/lib/typescript/src/types.d.ts +802 -0
  429. package/lib/typescript/src/types.d.ts.map +1 -0
  430. package/lib/typescript/src/utils.d.ts +50 -0
  431. package/lib/typescript/src/utils.d.ts.map +1 -0
  432. package/lib/typescript/src/validation.d.ts +52 -0
  433. package/lib/typescript/src/validation.d.ts.map +1 -0
  434. package/package.json +204 -0
  435. package/react-native.config.js +17 -0
  436. package/src/AudioPlayerContext.tsx +220 -0
  437. package/src/CameraPreview.tsx +352 -0
  438. package/src/NativeAnimatedImageView.tsx +71 -0
  439. package/src/NativeAudioPlayerView.tsx +39 -0
  440. package/src/NativeBlurView.tsx +40 -0
  441. package/src/NativeCustomCamera.ts +305 -0
  442. package/src/NativeCustomCamera.web.ts +192 -0
  443. package/src/NativeCustomVideoView.ts +30 -0
  444. package/src/NativeDocumentPreviewView.tsx +196 -0
  445. package/src/NativeMediaThumbnailView.tsx +167 -0
  446. package/src/NativeSvgIcon.tsx +46 -0
  447. package/src/ResponsivePreviewContainer.tsx +227 -0
  448. package/src/accessibility.ts +80 -0
  449. package/src/config.ts +406 -0
  450. package/src/cpuOptimization.ts +365 -0
  451. package/src/db/DatabaseManager.ts +212 -0
  452. package/src/db/MediaMapper.ts +377 -0
  453. package/src/db/MediaRepository.ts +313 -0
  454. package/src/db/index.ts +73 -0
  455. package/src/db/migrations.ts +222 -0
  456. package/src/db/react-native-sqlcipher.d.ts +76 -0
  457. package/src/db/secureKey.ts +100 -0
  458. package/src/db/types.ts +123 -0
  459. package/src/db/useMediaDatabase.ts +191 -0
  460. package/src/defaultIcons.tsx +2390 -0
  461. package/src/deviceCapabilities.ts +438 -0
  462. package/src/errors.ts +350 -0
  463. package/src/iconConfig.tsx +962 -0
  464. package/src/icons.tsx +788 -0
  465. package/src/index.tsx +763 -0
  466. package/src/jest-globals.d.ts +9 -0
  467. package/src/library/MediaLibrary.tsx +141 -0
  468. package/src/library/MediaLibraryScreen.tsx +3003 -0
  469. package/src/library/components/AudioPreview.tsx +73 -0
  470. package/src/library/components/DocumentPreview.tsx +361 -0
  471. package/src/library/components/ExpandableFab.tsx +342 -0
  472. package/src/library/components/FileTiles.tsx +252 -0
  473. package/src/library/components/ImagePreview.tsx +72 -0
  474. package/src/library/components/MediaMetadataHeader.tsx +208 -0
  475. package/src/library/components/RecordAudioScreen.tsx +845 -0
  476. package/src/library/components/VideoPreview.tsx +478 -0
  477. package/src/library/components/ViewerCounter.tsx +71 -0
  478. package/src/library/compressionEstimate.ts +662 -0
  479. package/src/library/fileMetadata.ts +212 -0
  480. package/src/library/index.ts +66 -0
  481. package/src/library/libraryIconRegistry.tsx +86 -0
  482. package/src/library/libraryIcons.tsx +928 -0
  483. package/src/library/localizedFormat.ts +207 -0
  484. package/src/library/palette.ts +281 -0
  485. package/src/library/responsive.ts +49 -0
  486. package/src/locales.ts +381 -0
  487. package/src/localization.ts +1947 -0
  488. package/src/logger.ts +20 -0
  489. package/src/lowMemoryCache.ts +218 -0
  490. package/src/mediaHistory.ts +42 -0
  491. package/src/mediaStorageService.ts +546 -0
  492. package/src/memory.ts +102 -0
  493. package/src/nativeActions.ts +422 -0
  494. package/src/nativeComponentSupport.ts +60 -0
  495. package/src/networkPerformance.ts +30 -0
  496. package/src/performance.ts +137 -0
  497. package/src/performanceMonitor.ts +219 -0
  498. package/src/permissions.ts +403 -0
  499. package/src/rendering.ts +47 -0
  500. package/src/security.ts +19 -0
  501. package/src/state.ts +333 -0
  502. package/src/storage.ts +453 -0
  503. package/src/theme.tsx +467 -0
  504. package/src/types.ts +946 -0
  505. package/src/utils.ts +177 -0
  506. package/src/validation.ts +372 -0
@@ -0,0 +1,690 @@
1
+ package com.customcamera.gif
2
+
3
+ import android.graphics.Bitmap
4
+
5
+ /**
6
+ * Dependency-free decoder for animated (and static) GIF87a / GIF89a images.
7
+ *
8
+ * This is a faithful Kotlin port of the canonical public-domain animated-GIF decoder in the
9
+ * Kevin Weiner / `com.bumptech.glide.gifdecoder` lineage, itself derived from the GIF89a
10
+ * specification. It parses an entire GIF held in memory and produces fully-composited
11
+ * ARGB_8888 [Bitmap] frames, honouring per-frame delays, transparency, interlacing and all four
12
+ * GIF disposal methods.
13
+ *
14
+ * Only [android.graphics.Bitmap] and the standard Kotlin/Java runtime are used, so there are no
15
+ * third-party dependencies. Target: minSdk 24. Malformed input yields a non-OK status / `null`
16
+ * rather than throwing.
17
+ *
18
+ * One-shot usage:
19
+ * ```
20
+ * val gif = GifDecoder.decodeAll(bytes, maxDimension = 1024) ?: return
21
+ * // gif.frames, gif.delaysMs, gif.loopCount, gif.width, gif.height
22
+ * ```
23
+ * Manual usage:
24
+ * ```
25
+ * val decoder = GifDecoder()
26
+ * if (decoder.read(bytes) == GifDecoder.STATUS_OK) {
27
+ * val first = decoder.getFrame(0)
28
+ * }
29
+ * ```
30
+ */
31
+ class GifDecoder {
32
+
33
+ /** Logical screen width in pixels (valid after a successful [read]). */
34
+ var width: Int = 0
35
+ private set
36
+
37
+ /** Logical screen height in pixels (valid after a successful [read]). */
38
+ var height: Int = 0
39
+ private set
40
+
41
+ /** Number of frames successfully decoded from the current stream. */
42
+ var frameCount: Int = 0
43
+ private set
44
+
45
+ /**
46
+ * Netscape/Animexts loop count. `0` means "loop forever" and is also the default when the
47
+ * extension is absent.
48
+ */
49
+ var loopCount: Int = 0
50
+ private set
51
+
52
+ /** Current read status; one of [STATUS_OK], [STATUS_FORMAT_ERROR], [STATUS_OPEN_ERROR]. */
53
+ private var status: Int = STATUS_OK
54
+
55
+ // --- Raw input ------------------------------------------------------------
56
+ private var rawData: ByteArray = ByteArray(0)
57
+ private var rawPos: Int = 0
58
+
59
+ // --- Global (logical screen) descriptor -----------------------------------
60
+ private var gctFlag: Boolean = false
61
+ private var gctSize: Int = 0
62
+ private var gct: IntArray? = null
63
+ private var bgIndex: Int = 0
64
+ private var bgColor: Int = 0
65
+
66
+ // --- Current frame descriptor ---------------------------------------------
67
+ private var lctFlag: Boolean = false
68
+ private var interlace: Boolean = false
69
+ private var lctSize: Int = 0
70
+ private var lct: IntArray? = null
71
+ private var act: IntArray? = null
72
+ private var ix: Int = 0
73
+ private var iy: Int = 0
74
+ private var iw: Int = 0
75
+ private var ih: Int = 0
76
+ private var dispose: Int = 0
77
+ private var transparency: Boolean = false
78
+ private var transIndex: Int = 0
79
+ private var delay: Int = 0
80
+
81
+ // --- Previous frame tracking (for disposal) -------------------------------
82
+ private var lastDispose: Int = 0
83
+ private var lrx: Int = 0
84
+ private var lry: Int = 0
85
+ private var lrw: Int = 0
86
+ private var lrh: Int = 0
87
+ private var hasPreviousFrame: Boolean = false
88
+
89
+ // --- Composition buffers --------------------------------------------------
90
+ /** Persistent ARGB canvas reused across frames; each frame is composited here. */
91
+ private var mainScratch: IntArray = IntArray(0)
92
+
93
+ /** Snapshot of the last "leave in place" canvas, used to service DISPOSAL_PREVIOUS restores. */
94
+ private var previousImage: IntArray? = null
95
+
96
+ /** Decoded colour-table indices for the current frame. */
97
+ private var pixels: ByteArray? = null
98
+
99
+ // --- LZW working storage --------------------------------------------------
100
+ private var prefix: ShortArray? = null
101
+ private var suffix: ByteArray? = null
102
+ private var pixelStack: ByteArray? = null
103
+ private val block: ByteArray = ByteArray(256)
104
+ private var blockSize: Int = 0
105
+
106
+ // --- Decoded results ------------------------------------------------------
107
+ private val framesList: MutableList<Bitmap> = ArrayList()
108
+ private val delaysList: MutableList<Int> = ArrayList()
109
+
110
+ /**
111
+ * Parses an entire GIF from an in-memory byte array.
112
+ *
113
+ * @param data the complete GIF file bytes, or `null`.
114
+ * @return [STATUS_OK] on success, [STATUS_OPEN_ERROR] if [data] is null, or [STATUS_FORMAT_ERROR]
115
+ * if the bytes are not a decodable GIF.
116
+ */
117
+ fun read(data: ByteArray?): Int {
118
+ init()
119
+ if (data == null) {
120
+ status = STATUS_OPEN_ERROR
121
+ return status
122
+ }
123
+ rawData = data
124
+ rawPos = 0
125
+ try {
126
+ readHeader()
127
+ if (!err()) {
128
+ if (width <= 0 || height <= 0 ||
129
+ width.toLong() * height.toLong() > Int.MAX_VALUE.toLong()) {
130
+ status = STATUS_FORMAT_ERROR
131
+ } else {
132
+ mainScratch = IntArray(width * height)
133
+ readContents()
134
+ if (frameCount < 0) status = STATUS_FORMAT_ERROR
135
+ }
136
+ }
137
+ } catch (e: Exception) {
138
+ status = STATUS_FORMAT_ERROR
139
+ }
140
+ return status
141
+ }
142
+
143
+ /**
144
+ * Returns the fully-composited ARGB_8888 bitmap for frame [n] (0-based), with all preceding
145
+ * frames' disposal methods already applied, or `null` if [n] is out of range.
146
+ */
147
+ fun getFrame(n: Int): Bitmap? {
148
+ return if (n in 0 until frameCount && n < framesList.size) framesList[n] else null
149
+ }
150
+
151
+ /**
152
+ * Returns the display delay for frame [n] in milliseconds. Frames that specify a zero/absent
153
+ * delay report [DEFAULT_FRAME_DELAY_MS] (100 ms).
154
+ */
155
+ fun getDelay(n: Int): Int {
156
+ return if (n in 0 until frameCount && n < delaysList.size) delaysList[n] else DEFAULT_FRAME_DELAY_MS
157
+ }
158
+
159
+ // ---------------------------------------------------------------------------
160
+ // Parsing
161
+ // ---------------------------------------------------------------------------
162
+
163
+ private fun init() {
164
+ status = STATUS_OK
165
+ frameCount = 0
166
+ loopCount = 0
167
+ framesList.clear()
168
+ delaysList.clear()
169
+ gct = null
170
+ lct = null
171
+ act = null
172
+ previousImage = null
173
+ pixels = null
174
+ hasPreviousFrame = false
175
+ dispose = 0
176
+ lastDispose = 0
177
+ transparency = false
178
+ delay = 0
179
+ bgColor = 0
180
+ bgIndex = 0
181
+ }
182
+
183
+ private fun err(): Boolean = status != STATUS_OK
184
+
185
+ /** Reads the 6-byte signature, then the logical screen descriptor + global colour table. */
186
+ private fun readHeader() {
187
+ val id = StringBuilder()
188
+ for (i in 0 until 6) {
189
+ id.append((readByte() and 0xff).toChar())
190
+ }
191
+ if (!id.toString().startsWith("GIF")) {
192
+ status = STATUS_FORMAT_ERROR
193
+ return
194
+ }
195
+ readLSD()
196
+ if (gctFlag && !err()) {
197
+ gct = readColorTable(gctSize)
198
+ val table = gct
199
+ bgColor = if (table != null && bgIndex < table.size) table[bgIndex] else 0
200
+ }
201
+ }
202
+
203
+ /** Logical Screen Descriptor: screen size, global colour table flags, background index. */
204
+ private fun readLSD() {
205
+ width = readShort()
206
+ height = readShort()
207
+ val packed = readByte()
208
+ gctFlag = (packed and 0x80) != 0
209
+ gctSize = 2 shl (packed and 7) // 2^(N+1)
210
+ bgIndex = readByte()
211
+ readByte() // pixel aspect ratio (unused)
212
+ }
213
+
214
+ /** Reads a colour table of [ncolors] RGB triples into a 256-entry opaque-ARGB array. */
215
+ private fun readColorTable(ncolors: Int): IntArray? {
216
+ val nbytes = 3 * ncolors
217
+ if (ncolors <= 0 || rawPos + nbytes > rawData.size) {
218
+ status = STATUS_FORMAT_ERROR
219
+ return null
220
+ }
221
+ val tab = IntArray(256) // full size to avoid index bounds checks on lookup
222
+ var i = 0
223
+ var j = rawPos
224
+ while (i < ncolors) {
225
+ val r = rawData[j++].toInt() and 0xff
226
+ val g = rawData[j++].toInt() and 0xff
227
+ val b = rawData[j++].toInt() and 0xff
228
+ tab[i++] = 0xFF000000.toInt() or (r shl 16) or (g shl 8) or b
229
+ }
230
+ rawPos += nbytes
231
+ return tab
232
+ }
233
+
234
+ /** Main block loop: images, extensions and the trailer. */
235
+ private fun readContents() {
236
+ var done = false
237
+ while (!done && !err()) {
238
+ when (readByte()) {
239
+ 0x2C -> readImage() // image separator
240
+ 0x21 -> { // extension introducer
241
+ when (readByte()) {
242
+ 0xF9 -> readGraphicControlExt()
243
+ 0xFF -> { // application extension
244
+ readBlock()
245
+ val app = StringBuilder()
246
+ for (i in 0 until 11) {
247
+ app.append((block[i].toInt() and 0xff).toChar())
248
+ }
249
+ if (app.toString() == "NETSCAPE2.0") readNetscapeExt() else skip()
250
+ }
251
+ else -> skip() // comment / plain-text / unknown extension
252
+ }
253
+ }
254
+ 0x3B -> done = true // trailer
255
+ 0x00 -> { /* stray byte: tolerate and continue */ }
256
+ else -> status = STATUS_FORMAT_ERROR
257
+ }
258
+ }
259
+ }
260
+
261
+ /** Graphic Control Extension: disposal method, transparency flag/index and frame delay. */
262
+ private fun readGraphicControlExt() {
263
+ readByte() // block size (always 4)
264
+ val packed = readByte()
265
+ dispose = (packed and 0x1C) shr 2 // 0=unspecified 1=none 2=background 3=previous
266
+ transparency = (packed and 1) != 0
267
+ delay = readShort() * 10 // centiseconds -> milliseconds
268
+ transIndex = readByte()
269
+ readByte() // block terminator
270
+ }
271
+
272
+ /** Netscape 2.0 application extension: the animation loop count (0 = forever). */
273
+ private fun readNetscapeExt() {
274
+ do {
275
+ readBlock()
276
+ if (blockSize >= 3 && block[0].toInt() == 1) {
277
+ val b1 = block[1].toInt() and 0xff
278
+ val b2 = block[2].toInt() and 0xff
279
+ loopCount = (b2 shl 8) or b1
280
+ }
281
+ } while (blockSize > 0 && !err())
282
+ }
283
+
284
+ /** Image Descriptor + optional local colour table + LZW pixel data for one frame. */
285
+ private fun readImage() {
286
+ ix = readShort()
287
+ iy = readShort()
288
+ iw = readShort()
289
+ ih = readShort()
290
+
291
+ val packed = readByte()
292
+ lctFlag = (packed and 0x80) != 0
293
+ interlace = (packed and 0x40) != 0
294
+ lctSize = 2 shl (packed and 7)
295
+
296
+ if (lctFlag) {
297
+ lct = readColorTable(lctSize)
298
+ act = lct
299
+ } else {
300
+ act = gct
301
+ }
302
+
303
+ var save = 0
304
+ val active = act
305
+ if (transparency && active != null && transIndex < active.size) {
306
+ save = active[transIndex]
307
+ active[transIndex] = 0 // render the transparent index as fully transparent
308
+ }
309
+
310
+ if (act == null) {
311
+ status = STATUS_FORMAT_ERROR
312
+ return
313
+ }
314
+ if (err()) return
315
+
316
+ decodeImageData()
317
+ skip()
318
+ if (err()) return
319
+
320
+ setPixels()
321
+ framesList.add(Bitmap.createBitmap(mainScratch, width, height, Bitmap.Config.ARGB_8888))
322
+ delaysList.add(if (delay > 0) delay else DEFAULT_FRAME_DELAY_MS)
323
+ frameCount++
324
+
325
+ val active2 = act
326
+ if (transparency && active2 != null && transIndex < active2.size) {
327
+ active2[transIndex] = save // restore the shared colour-table entry
328
+ }
329
+ resetFrame()
330
+ }
331
+
332
+ /** Carries the just-drawn frame's disposal state forward as the "previous" state. */
333
+ private fun resetFrame() {
334
+ lastDispose = dispose
335
+ lrx = ix
336
+ lry = iy
337
+ lrw = iw
338
+ lrh = ih
339
+ hasPreviousFrame = true
340
+ dispose = 0
341
+ transparency = false
342
+ delay = 0
343
+ lct = null
344
+ }
345
+
346
+ // ---------------------------------------------------------------------------
347
+ // Compositing
348
+ // ---------------------------------------------------------------------------
349
+
350
+ /**
351
+ * Composites the freshly-decoded [pixels] onto [mainScratch]. First the *previous* frame's
352
+ * disposal method is applied to the persistent canvas, then this frame's sub-rectangle is
353
+ * blitted (de-interlacing and skipping transparent pixels). Finally the canvas is snapshotted
354
+ * when this frame "leaves in place", so a later DISPOSAL_PREVIOUS frame can restore it.
355
+ */
356
+ private fun setPixels() {
357
+ val dest = mainScratch
358
+ val size = dest.size
359
+
360
+ // First frame starts from a clean, fully-transparent canvas.
361
+ if (!hasPreviousFrame) {
362
+ previousImage = null
363
+ java.util.Arrays.fill(dest, 0)
364
+ }
365
+
366
+ // DISPOSAL_PREVIOUS with nothing saved to restore to -> clear.
367
+ if (hasPreviousFrame && lastDispose == DISPOSAL_PREVIOUS && previousImage == null) {
368
+ java.util.Arrays.fill(dest, 0)
369
+ }
370
+
371
+ // Apply the previous frame's disposal to the canvas before drawing this frame.
372
+ if (hasPreviousFrame && lastDispose > DISPOSAL_UNSPECIFIED) {
373
+ if (lastDispose == DISPOSAL_BACKGROUND) {
374
+ var c = 0
375
+ if (!transparency) {
376
+ c = bgColor
377
+ if (lct != null && bgIndex == transIndex) c = 0
378
+ }
379
+ val topLeft = lry * width + lrx
380
+ val bottomLeft = topLeft + lrh * width
381
+ var left = topLeft
382
+ while (left < bottomLeft) {
383
+ val right = left + lrw
384
+ var p = left
385
+ while (p < right) {
386
+ if (p in 0 until size) dest[p] = c
387
+ p++
388
+ }
389
+ left += width
390
+ }
391
+ } else if (lastDispose == DISPOSAL_PREVIOUS) {
392
+ val prev = previousImage
393
+ if (prev != null && prev.size == size) System.arraycopy(prev, 0, dest, 0, size)
394
+ }
395
+ }
396
+
397
+ // Blit this frame's sub-rectangle onto the canvas, de-interlacing as required.
398
+ val px = pixels ?: return
399
+ val actLocal = act ?: return
400
+ var pass = 1
401
+ var inc = 8
402
+ var iline = 0
403
+ var i = 0
404
+ while (i < ih) {
405
+ var line = i
406
+ if (interlace) {
407
+ if (iline >= ih) {
408
+ pass++
409
+ when (pass) {
410
+ 2 -> iline = 4
411
+ 3 -> { iline = 2; inc = 4 }
412
+ 4 -> { iline = 1; inc = 2 }
413
+ }
414
+ }
415
+ line = iline
416
+ iline += inc
417
+ }
418
+ line += iy
419
+ if (line < height) {
420
+ val k = line * width
421
+ var dx = k + ix
422
+ var dlim = dx + iw
423
+ if (k + width < dlim) dlim = k + width // clamp to the logical screen edge
424
+ var sx = i * iw
425
+ while (dx < dlim) {
426
+ if (sx < px.size) {
427
+ val index = px[sx].toInt() and 0xff
428
+ if (index < actLocal.size) {
429
+ val c = actLocal[index]
430
+ if (c != 0 && dx >= 0 && dx < size) dest[dx] = c // c == 0 means transparent
431
+ }
432
+ }
433
+ sx++
434
+ dx++
435
+ }
436
+ }
437
+ i++
438
+ }
439
+
440
+ // Snapshot the canvas so a later DISPOSAL_PREVIOUS frame can restore this state.
441
+ if (dispose == DISPOSAL_UNSPECIFIED || dispose == DISPOSAL_NONE) {
442
+ var prev = previousImage
443
+ if (prev == null || prev.size != size) {
444
+ prev = IntArray(size)
445
+ previousImage = prev
446
+ }
447
+ System.arraycopy(dest, 0, prev, 0, size)
448
+ }
449
+ }
450
+
451
+ // ---------------------------------------------------------------------------
452
+ // LZW decompression
453
+ // ---------------------------------------------------------------------------
454
+
455
+ /** Classic table-based LZW decode of the image data sub-blocks into [pixels]. */
456
+ private fun decodeImageData() {
457
+ val nullCode = -1
458
+ if (iw <= 0 || ih <= 0 || iw.toLong() * ih.toLong() > Int.MAX_VALUE.toLong()) {
459
+ status = STATUS_FORMAT_ERROR
460
+ return
461
+ }
462
+ val npix = iw * ih
463
+
464
+ var pxArr = pixels
465
+ if (pxArr == null || pxArr.size < npix) {
466
+ pxArr = ByteArray(npix)
467
+ pixels = pxArr
468
+ }
469
+ var pfx = prefix
470
+ if (pfx == null) { pfx = ShortArray(MAX_STACK_SIZE); prefix = pfx }
471
+ var sfx = suffix
472
+ if (sfx == null) { sfx = ByteArray(MAX_STACK_SIZE); suffix = sfx }
473
+ var pst = pixelStack
474
+ if (pst == null) { pst = ByteArray(MAX_STACK_SIZE + 1); pixelStack = pst }
475
+
476
+ val dataSize = readByte()
477
+ if (dataSize < 1 || dataSize > 8) { // guard the code-size shift against malformed input
478
+ status = STATUS_FORMAT_ERROR
479
+ return
480
+ }
481
+ val clear = 1 shl dataSize
482
+ val endOfInformation = clear + 1
483
+ var available = clear + 2
484
+ var oldCode = nullCode
485
+ var codeSize = dataSize + 1
486
+ var codeMask = (1 shl codeSize) - 1
487
+
488
+ var code = 0
489
+ while (code < clear) {
490
+ pfx[code] = 0
491
+ sfx[code] = code.toByte()
492
+ code++
493
+ }
494
+
495
+ var datum = 0
496
+ var bits = 0
497
+ var count = 0
498
+ var first = 0
499
+ var top = 0
500
+ var pi = 0
501
+ var bi = 0
502
+ var i = 0
503
+
504
+ while (i < npix) {
505
+ if (top == 0) {
506
+ if (bits < codeSize) {
507
+ if (count == 0) {
508
+ // Read the next data sub-block.
509
+ count = readBlock()
510
+ if (count <= 0) break
511
+ bi = 0
512
+ }
513
+ datum += (block[bi].toInt() and 0xff) shl bits
514
+ bits += 8
515
+ bi++
516
+ count--
517
+ continue
518
+ }
519
+
520
+ // Get the next code.
521
+ code = datum and codeMask
522
+ datum = datum shr codeSize
523
+ bits -= codeSize
524
+
525
+ // Interpret the code.
526
+ if (code > available || code == endOfInformation) break
527
+ if (code == clear) {
528
+ // Reset the decoder.
529
+ codeSize = dataSize + 1
530
+ codeMask = (1 shl codeSize) - 1
531
+ available = clear + 2
532
+ oldCode = nullCode
533
+ continue
534
+ }
535
+ if (oldCode == nullCode) {
536
+ pst[top++] = sfx[code]
537
+ oldCode = code
538
+ first = code
539
+ continue
540
+ }
541
+ val inCode = code
542
+ if (code == available) {
543
+ pst[top++] = first.toByte()
544
+ code = oldCode
545
+ }
546
+ while (code > clear) {
547
+ pst[top++] = sfx[code]
548
+ code = pfx[code].toInt()
549
+ }
550
+ first = sfx[code].toInt() and 0xff
551
+
552
+ // Add a new string to the table.
553
+ if (available >= MAX_STACK_SIZE) break
554
+ pst[top++] = first.toByte()
555
+ pfx[available] = oldCode.toShort()
556
+ sfx[available] = first.toByte()
557
+ available++
558
+ if ((available and codeMask) == 0 && available < MAX_STACK_SIZE) {
559
+ codeSize++
560
+ codeMask += available
561
+ }
562
+ oldCode = inCode
563
+ }
564
+ // Pop a pixel off the pixel stack into the output.
565
+ top--
566
+ pxArr[pi++] = pst[top]
567
+ i++
568
+ }
569
+
570
+ // Zero any pixels a truncated stream failed to produce.
571
+ while (pi < npix) {
572
+ pxArr[pi++] = 0
573
+ }
574
+ }
575
+
576
+ // ---------------------------------------------------------------------------
577
+ // Low-level byte / block reads
578
+ // ---------------------------------------------------------------------------
579
+
580
+ /** Reads one length-prefixed sub-block into [block]; returns the number of bytes read. */
581
+ private fun readBlock(): Int {
582
+ blockSize = readByte()
583
+ var n = 0
584
+ if (blockSize > 0) {
585
+ while (n < blockSize) {
586
+ val remaining = rawData.size - rawPos
587
+ if (remaining <= 0) break
588
+ val count = if (blockSize - n < remaining) blockSize - n else remaining
589
+ System.arraycopy(rawData, rawPos, block, n, count)
590
+ rawPos += count
591
+ n += count
592
+ }
593
+ if (n < blockSize) status = STATUS_FORMAT_ERROR
594
+ }
595
+ return n
596
+ }
597
+
598
+ /** Consumes sub-blocks until the block terminator (a zero-length block). */
599
+ private fun skip() {
600
+ do {
601
+ readBlock()
602
+ } while (blockSize > 0 && !err())
603
+ }
604
+
605
+ /** Reads a single unsigned byte, flagging a format error past end-of-data. */
606
+ private fun readByte(): Int {
607
+ if (rawPos >= rawData.size) {
608
+ status = STATUS_FORMAT_ERROR
609
+ return 0
610
+ }
611
+ return rawData[rawPos++].toInt() and 0xff
612
+ }
613
+
614
+ /** Reads a little-endian unsigned 16-bit value. */
615
+ private fun readShort(): Int = readByte() or (readByte() shl 8)
616
+
617
+ companion object {
618
+ /** [read] status: success. */
619
+ const val STATUS_OK = 0
620
+
621
+ /** [read] status: the data could not be parsed as a GIF. */
622
+ const val STATUS_FORMAT_ERROR = 1
623
+
624
+ /** [read] status: no input was supplied. */
625
+ const val STATUS_OPEN_ERROR = 2
626
+
627
+ /** Maximum number of LZW codes (12-bit code space). */
628
+ private const val MAX_STACK_SIZE = 4096
629
+
630
+ /** Fallback per-frame delay when a GIF specifies a zero / absent delay. */
631
+ private const val DEFAULT_FRAME_DELAY_MS = 100
632
+
633
+ // GIF89a disposal methods.
634
+ private const val DISPOSAL_UNSPECIFIED = 0
635
+ private const val DISPOSAL_NONE = 1
636
+ private const val DISPOSAL_BACKGROUND = 2
637
+ private const val DISPOSAL_PREVIOUS = 3
638
+
639
+ /**
640
+ * Convenience one-shot decode of every frame.
641
+ *
642
+ * @param data the complete GIF bytes.
643
+ * @param maxDimension when > 0, any composited frame whose larger side exceeds this value is
644
+ * proportionally down-scaled (and the full-size frame recycled) so its larger side equals
645
+ * [maxDimension].
646
+ * @return a [DecodedGif], or `null` on decode failure or if there are no frames.
647
+ */
648
+ fun decodeAll(data: ByteArray, maxDimension: Int = 0): DecodedGif? {
649
+ return try {
650
+ val decoder = GifDecoder()
651
+ decoder.read(data)
652
+ if (decoder.frameCount <= 0) return null
653
+ val frames = ArrayList<Bitmap>(decoder.frameCount)
654
+ val delays = ArrayList<Int>(decoder.frameCount)
655
+ for (i in 0 until decoder.frameCount) {
656
+ var frame = decoder.getFrame(i) ?: continue
657
+ if (maxDimension > 0) {
658
+ val larger = if (frame.width > frame.height) frame.width else frame.height
659
+ if (larger > maxDimension) {
660
+ val scale = maxDimension.toFloat() / larger.toFloat()
661
+ val newW = Math.max(1, Math.round(frame.width * scale))
662
+ val newH = Math.max(1, Math.round(frame.height * scale))
663
+ val scaled = Bitmap.createScaledBitmap(frame, newW, newH, true)
664
+ if (scaled != frame) frame.recycle()
665
+ frame = scaled
666
+ }
667
+ }
668
+ frames.add(frame)
669
+ delays.add(decoder.getDelay(i))
670
+ }
671
+ if (frames.isEmpty()) null
672
+ else DecodedGif(frames, delays, decoder.loopCount, decoder.width, decoder.height)
673
+ } catch (e: Exception) {
674
+ null
675
+ }
676
+ }
677
+ }
678
+
679
+ /**
680
+ * Result of [decodeAll]: the composited [frames], their per-frame [delaysMs], the animation
681
+ * [loopCount] (0 = loop forever) and the logical [width] / [height] of the GIF.
682
+ */
683
+ data class DecodedGif(
684
+ val frames: List<Bitmap>,
685
+ val delaysMs: List<Int>,
686
+ val loopCount: Int,
687
+ val width: Int,
688
+ val height: Int
689
+ )
690
+ }